テーブルの作成
db_path— データベースを含む SQLite ファイルへのパス。table— SQLite データベース内のテーブル名、またはそのまま SQLite に渡されるクエリ (テーブル名の代わりにクエリを渡す を参照) 。
テーブル名の代わりにクエリを渡す
table 引数には、テーブル名の代わりに SELECT クエリを指定することもでき、このクエリは SQLite にそのまま渡されます。テーブルの構造はクエリ結果から推論されます。SQLite が宣言型を報告するのは、テーブルのカラムをそのまま参照する結果カラムに限られ、expression (式) 、リテラル、集約に対しては何も報告しません。String にマッピングされる宣言型 (型マッピングを参照) は、そのまま使用されます。宣言型を持たないカラムの型は、クエリ結果の最初の行にある値のストレージクラスによって決まります。INTEGER 値であれば Int64、REAL 値であれば Float64 となり、それ以外の値 (TEXT、BLOB、NULL) や結果が空の場合は String となります。数値の宣言型も、同様に最初の行と照合されます。SQLite は複合 SELECT に対しても宣言型を報告しますが、その型はいずれか 1 つの分岐から取得される一方、行はすべての分岐から返されるためです。数値の宣言型は、値のストレージクラスが宣言型と一致する場合 (整数型であれば INTEGER、浮動小数点型であれば INTEGER または REAL) に維持されます。また、値が NULL の場合や結果が空の場合も、宣言型と矛盾し得る型情報を一切持たないため、宣言型は維持されます。それ以外の場合は、宣言型を持たないカラムと同様に、ストレージクラスから型が決定されます。したがって、推論される型が拡張されることはあっても、変換される (精度が下がる) ことはありません。このようなカラムの型を推論する時点で、SQLite でクエリが開始されます。ただし、最初の行が残りの行を代表するとは限りません。SQLite は行ごとに異なるストレージクラスを返す可能性があるため (例: CASE WHEN id = 1 THEN 1 ELSE 1.5 END) 、クエリに基づく読み取りでは、宣言型を持たないカラムに限らず、数値型で読み取るすべてのカラムがフェイルクローズとなります。ストレージクラスがその型と一致しない値や、その型で正確に表現できない値 (UInt8 カラム内の 300 という INTEGER セル、Float32 カラム内の 16777217 という REAL セルなど) は、暗黙的に型変換されることなく、読み取りエラーとなります。ストレージクラスが混在するカラムを読み取るには、そのカラムを String として宣言するか、SQLite のクエリ内でテキストにキャストしてください。推論されるカラムはすべて Nullable です。クエリは、サブクエリとして記述することも、query 関数でラップすることもできます。
SELECT ... FROM (<query>) でラップしてから SQLite に送信するため、クエリの末尾にセミコロンを付けないでください。
このようなテーブルは読み取り専用であり、INSERT で挿入することはできません。同じ構文は sqlite テーブル関数でもサポートされています。
サブクエリ形式
(SELECT ...) は ClickHouse によってパースされ、SQLite に送信される前に再シリアライズされます。そのため、有効な ClickHouse SQL である必要があります。ClickHouse がパースしない SQLite 固有の構文を渡すには、query('...') 形式を使用してください。この形式では、テキストがそのまま SQLite に送信されます。周囲の ClickHouse クエリにある外側の WHERE、LIMIT、集約などは、渡したクエリには プッシュダウンされず、完全なクエリ結果を取得した後に ClickHouse で適用されます。SQLite から読み取るデータを制限するには、渡すクエリの中にフィルターを含めてください。external_table_strict_query = 1 を指定すると、このテーブルのカラムに対する外側のフィルターは、渡したクエリにプッシュダウンできないため、ローカルで適用される代わりに例外を返して拒否されます。このチェックの対象は、トップレベルの WHERE の predicate と、トップレベルの AND の各項です。このテーブルのカラムに対する PREWHERE は、この設定の対象ではありません。このテーブルエンジンは PREWHERE をサポートしておらず、そのようなクエリは設定に関係なく ILLEGAL_PREWHERE で拒否されます。このチェックはフィルターをプッシュダウンできる可能性がある場所でのみ実行されます。すなわち、このテーブルがクエリ内の唯一のテーブルである場合、INNER JOIN のいずれかの側にある場合、または外部結合の保持側 (LEFT JOIN の左側、RIGHT JOIN の右側) にある場合です。LEFT/RIGHT JOIN の非保持側や FULL JOIN のいずれの側でも、何もプッシュダウンされず、何もチェックされないため、このテーブルのカラムに対するフィルターは、厳格モードであっても結合の後にローカルで適用されます。チェックが実行される場所では、周囲のクエリで結合されている他のテーブルを参照する predicate はプッシュダウンされず、チェックの対象から除外されます。これは、結合側のみを参照する場合でも、AND 以外の 1 つの expression (たとえば OR) の中でこのテーブルと混在させている場合でも同様です。そのような predicate は通常の ClickHouse での評価位置 (結合の後の WHERE、その前の PREWHERE) を保持し、拒否されることはありません。サポートされるデータ型
テーブル定義で ClickHouse のカラム型を明示的に指定すると、SQLite の TEXT カラムから以下の ClickHouse 型をパースできます。- Date, Date32
- DateTime, DateTime64
- UUID
- Enum8, Enum16
- Decimal32, Decimal64, Decimal128, Decimal256
- FixedString
- すべての整数型 (UInt8, UInt16, UInt32, UInt64, UInt128, UInt256, Int8, Int16, Int32, Int64, Int128, Int256)
- Float32, Float64
NULL を、明示的に Nullable ではない型として定義された ClickHouse カラムに読み込むと、CANNOT_INSERT_NULL_IN_ORDINARY_COLUMN 例外が送出されます。NULL 値を読み込むには、カラムを Nullable として宣言してください。スキーマを推論する場合は SQLite のメタデータに従い、NOT NULL と宣言されていないカラムは Nullable になります。