クエリのパース
- 完全な SQL パーサー (再帰下降パーサー) 。
- データフォーマットパーサー (高速なストリームパーサー) 。
INSERT クエリを除き、すべてのケースで使われます。
以下のクエリを見てみましょう。
INSERTクエリでは 2 種類のパーサーの両方が使われます。
INSERT INTO t VALUES の部分は完全パーサーで解析され、
データ (1, 'Hello, world'), (2, 'abc'), (3, 'def') はデータフォーマットパーサー、つまり高速ストリームパーサーで解析されます。
完全パーサーを有効にする
完全パーサーを有効にする
input_format_values_interpret_expressions 設定を使うと、
データに対して完全パーサーを有効にすることもできます。前述の設定が 1 に設定されている場合、
ClickHouse はまず高速ストリームパーサーで値を解析しようとします。
それに失敗すると、ClickHouse はデータを SQL の 式 として扱い、完全パーサーで解析しようとします。INSERTクエリに関する問題を避けるためです。これは、ClickHouse にデータを挿入する推奨方法でもあります。
INSERTクエリで Values フォーマットを使用する場合、
データは SELECTクエリ内の式と同じように解析されるように見えるかもしれませんが、実際にはそうではありません。
Values フォーマットは、はるかに制限が多くなっています。
この節の残りでは、完全パーサーについて説明します。
フォーマットパーサーの詳細については、Formats セクションを参照してください。
空白
- 構文要素の間には、任意の数の空白文字を入れられます (クエリの先頭と末尾を含む) 。
- 空白文字には、スペース、タブ、改行、CR、およびフォームフィードが含まれます。
コメント
- SQL スタイルのコメントは
--、#!、または#で始まり、行末まで続きます。--と#!の後のスペースは省略できます。 - C スタイルのコメント:
//(または/が 3 文字以上連続するもの) の後にテキストを記述し、行末までコメントとして扱われます。/の後にスペースは不要です。- 複数行コメントとして、
/*から*/まで記述することもできます。この場合もスペースは不要です。 - C スタイルのコメントはネストできます。
キーワード
- SQL 標準。たとえば、
SELECT、select、SeLeCtはいずれも有効です。 - 一般的な DBMS (MySQL や Postgres) の一部実装。たとえば、
DateTimeはdatetimeと同じです。
データ型名が大文字と小文字を区別するかどうかは、system.data_type_families テーブルで確認できます。
table_name に "FROM" という名前のカラムがある場合に有効です。
識別子
^[a-zA-Z_][0-9a-zA-Z_]*$ に一致する必要があり、キーワード と同じ名前にはできません。
有効な識別子と無効な識別子の例については、以下の表を参照してください。
| 有効な識別子 | 無効な識別子 |
|---|---|
xyz, _internal, Id_with_underscores_123_ | 1x, tom@gmail.com, äußerst_schön |
"id" や `id` のように、二重引用符またはバッククォートで囲んでください。
引用符付き識別子のエスケープに関する規則は、文字列リテラルにも同様に適用されます。詳細については String を参照してください。
リテラル
String
- シングルクォート文字
'の場合に限り、直前にシングルクォートを付けて''としてエスケープする、または - 直前にバックスラッシュを付け、下の表に示すサポートされているエスケープシーケンスを使用する。
バックスラッシュは、以下に挙げる文字以外の前にある場合、特別な意味を失います。つまり、文字どおりに解釈されます。
| サポートされるエスケープ | 説明 |
|---|---|
\xHH | 任意個の16進数桁 (H) が続く 8 ビット文字指定。 |
\N | 予約済みで、何もしません (例: SELECT 'a\Nb' は ab を返します) |
\a | ベル |
\b | バックスペース |
\e | エスケープ文字 |
\f | 改ページ |
\n | 改行文字 |
\r | 復帰 |
\t | 水平タブ |
\v | 垂直タブ |
\0 | null 文字 |
\\ | バックスラッシュ |
\' (or '') | シングルクォート |
\" | ダブルクォート |
` | バッククォート |
\/ | スラッシュ |
\= | 等号 |
| ASCII control characters (c <= 31). |
文字列リテラルでは、少なくとも
' と \ は、エスケープコード \' (または '') および \\ を使ってエスケープする必要があります。Numeric
- リテラルの先頭にマイナス記号
-が付いている場合、そのトークンはいったん読み飛ばされ、パース後に結果が負の値にされます。 - 数値リテラルはまず、strtoull 関数を使って 64 ビット符号なし整数としてパースされます。
- 値の先頭に
0bまたは0x/0Xが付いている場合、数値はそれぞれ 2 進数または 16 進数としてパースされます。 - 値が負で、その絶対値が 263 を超える場合は、エラーが返されます。
- 値の先頭に
- これに失敗した場合、次に strtod 関数を使って浮動小数点数としてパースされます。
- それ以外の場合は、エラーが返されます。
1はUInt8としてパースされます256はUInt16としてパースされます。
重要64 ビットを超える整数値 (こうすることで上記のアルゴリズムをバイパスし、任意精度をサポートするルーチンで整数がパースされます。そうしない場合、リテラルは浮動小数点数としてパースされるため、切り捨てによって精度が失われる可能性があります。
UInt128、Int128、UInt256、Int256) を正しくパースするには、より大きい型に CAST する必要があります。_ は無視され、可読性を高めるために使えます。
次の数値リテラルがサポートされています。
| 数値リテラル | 例 |
|---|---|
| 整数 | 1, 10_000_000, 18446744073709551615, 01 |
| 10 進数 | 0.1 |
| 指数表記 | 1e100, -1e-100 |
| 浮動小数点数 | 123.456, inf, nan |
| 16 進数 | 0xc0fe |
| SQL 標準互換の 16 進文字列 | x'c0fe' |
| 2 進数 | 0b1101 |
| SQL 標準互換の 2 進文字列 | b'1101' |
解釈ミスを避けるため、8 進数リテラルはサポートされていません。
複合型
[] で構築します: [1, 2, 3]。Tuple は () で構築します: (1, 'Hello, world!', 2)。
厳密には、これらはリテラルではなく、それぞれ Array 作成演算子および Tuple 作成演算子を使った式です。
Array は少なくとも 1 つの要素を含んでいる必要があり、Tuple は少なくとも 2 つの要素を含んでいる必要があります。
Tuple が
SELECT クエリの IN 句に現れる場合は、これとは別のケースです。
クエリ結果には Tuple を含めることができますが、Tuple をデータベースに保存することはできません (Memory エンジンを使用するテーブルを除く) 。NULL
NULL は、値が存在しないことを示すために使用されます。
テーブルのフィールドに NULL を格納するには、そのフィールドが Nullable 型である必要があります。
NULL については、次の点に注意してください。- データのフォーマット (入力または出力) によって、
NULLの表現は異なる場合があります。詳細は、data formats を参照してください。 NULLの処理には注意が必要です。たとえば、比較演算の引数のうち少なくとも 1 つがNULLの場合、その演算結果もNULLになります。これは乗算、加算、その他の演算でも同様です。各演算のドキュメントを参照することをお勧めします。- クエリでは、
IS NULLおよびIS NOT NULL演算子、ならびに関連する関数isNullとisNotNullを使用してNULLを確認できます。
ヒアドキュメント
$ 記号の間に置くカスタム文字列リテラルとして定義します。
例えば:
- 2 つのヒアドキュメントの間にある値は、“そのまま”処理されます。
クエリパラメータの定義と使用
SET param_<name>=<value>— クエリ内でSETコマンドを使用する方法。--param_<name>='<value>'— コマンドラインでclickhouse-clientに引数として渡す方法。param_<name>=<value>— HTTP インターフェイスの URL クエリ文字列パラメータとして指定する方法。
{<name>: <datatype>} を使って参照できます。ここで、<name> はクエリパラメータ名、<datatype> は変換先のデータ型です。
SET コマンドの例
SET コマンドの例
たとえば、次の SQL では
a、b、c、d という名前のパラメータを定義しており、それぞれ異なるデータ型を持ちます。clickhouse-client の例
clickhouse-client の例
clickhouse-client を使用している場合、パラメータは --param_name=value として指定します。たとえば、次のパラメータの名前は message で、String として取得されます。Identifier を使用してください。たとえば、次のクエリは uk_price_paid という名前のテーブルから行を返します。HTTP インターフェイスの例
HTTP インターフェイスの例
クエリパラメータは、
param_ プレフィックス付きの URL クエリ文字列パラメータとして渡せます。たとえば、次のようになります。Web UI の例
Web UI の例
組み込みの Web UI (
play.html) は、クエリ内の {name:Type} 形式のパラメータプレースホルダーを自動的に検出し、各パラメータに対応するラベル付きの入力フィールドを表示します。パラメータ値は HTTP リクエストに含まれ、さらにブックマークや共有のためにページ URL にも保持されます。クエリパラメータは、任意の SQL クエリの任意の場所で使える汎用的なテキスト置換ではありません。
主に、識別子またはリテラルの代わりとして
SELECT ステートメント内で使用することを想定して設計されています。関数
() で囲んだ引数のリスト (空の場合もあります) を続ける形で記述します。
標準SQLとは異なり、引数のリストが空であっても括弧は必須です。
例:
パラメーターのない集約関数の構文は、通常の関数と同じです。
演算子
データ型とデータベースのテーブルエンジン
CREATEクエリ内のデータ型とテーブルエンジンは、識別子や関数と同じように記述します。
つまり、括弧付きの引数リストを含むことも、含まないこともあります。
詳細については、以下のセクションを参照してください。
式
- 関数
- 識別子
- リテラル
- 演算子の適用
- 括弧で囲まれた式
- サブクエリ
- アスタリスク
式の別名
| 構文の要素 | 説明 | Example | 注記 |
|---|---|---|---|
AS | 別名を定義するためのキーワードです。AS キーワードを使わなくても、SELECT 句でテーブル名またはカラム名に別名を付けることができます。 | SELECT table_name_alias.column_name FROM table_name table_name_alias. | CAST 関数では、AS キーワードは別の意味で使われます。関数の説明を参照してください。 |
expr | ClickHouse でサポートされる任意の式です。 | SELECT column_name * 2 AS double FROM some_table | |
alias | expr に付ける名前です。別名は identifiers の構文に従う必要があります。 | SELECT "table t".column_name FROM table_name AS "table t". |
使用上の注意
- 別名はクエリまたはサブクエリ全体で有効で、任意の式に対する別名をクエリ内のどの部分でも定義できます。たとえば、次のようになります。
- 別名はサブクエリ内やサブクエリ同士の間では参照できません。たとえば、次のクエリを実行すると、ClickHouse は例外
Unknown identifier: numを返します。
- サブクエリの
SELECT句で結果のカラムに別名が定義されている場合、これらのカラムは外側のクエリから参照できます。たとえば:
- カラム名やテーブル名と同じ別名を付ける場合は注意してください。次の例を見てみましょう。
b を持つテーブル t を宣言しました。
次に、データを選択する際に、sum(b) AS b という別名を定義しました。
別名はグローバルであるため、
ClickHouse は式 argMax(a, b) 内の b を式 sum(b) に置き換えました。
この置換によって例外が発生しました。
この既定の動作は、prefer_column_name_to_alias を
1 に設定することで変更できます。アスタリスク
SELECTクエリでは、アスタリスクを式の代わりに使用できます。
詳しくは、SELECTのセクションを参照してください。