SQL互換性
ActQLのクエリテキストは、GoogleSQLとそのPipe構文を土台に、LLM、Effect、テーブル以外のCarrierのために拡張したものです。このページでは、SQLとしてどの形を受け付け、それぞれが何を意味し、何を拒否するかをまとめます。SQLをすでに知っていて、どこまでそのまま使えるかを知りたい人向けです。正確な文法はクエリテキストの仕様に、プログラムの書き方はプログラムを書くにあります。
全体を通しての原則はひとつです。GoogleSQLに書き方があるものは、GoogleSQLと同じ意味で使います。ActQLはGoogleSQLへの完全準拠を主張しません。主張するのは、受け付ける範囲についてはGoogleSQLと同じ意味を持つということです。受け付けない形は、検査の段階で名前の付いた理由とともに拒否され、近似されることはありません。
文
| 形 | 意味 |
|---|---|
SELECT … FROM … [WHERE] [GROUP BY] [HAVING] [QUALIFY] [WINDOW] [ORDER BY] [LIMIT [OFFSET]] | 通常のクエリ。各句はSQLの意味のままで、Pipeは不要。 |
FROM のない SELECT … | 論理的な1レコード。式とパラメーターだけ。 |
WITH name AS (…), … | 任意の種類(テーブル、グラフ、ベクトル、イベント)の途中の値に名前を付ける。名前を付ける以外のことはしない。プログラムを書くを参照。 |
FROM source [JOIN …] |> step |> … | Pipeクエリ。最初の FROM にはJOINを含められる。それ以降の演算はすべて |> で始める。 |
query ; に続く EFFECT … COMMAND … | 保持されたResultに対するCommand Effectの長い形式(構文リファレンス)。 |
CREATE TABLE target AS SELECT …、CREATE OR REPLACE TABLE target AS (…) | create または replace の束縛を公開しているConnectorの対象への、テーブル全体の書き込み。 |
UPDATE target SET … WHERE … | 更新EffectのSQL形式(|> EFFECT UPDATE と同じEffect)。 |
INSERT INTO target … | 追加EffectのSQL形式。 |
DELETE FROM target WHERE … | 削除EffectのSQL形式。 |
プログラムのテキストは、; の後ろのCommandの後置を除いて1文だけです。文字列の補間や、無関係な複数の文は拒否されます。
Pipe演算子
最初の FROM の後ろの演算子はすべて |> で始め、直前の出力を入力にします。ActQLの各演算子の完全な形は、各部、既定値、エラーとあわせて構文リファレンスにあります。
| 演算子 | 意味 |
|---|---|
|> WHERE condition | レコードを絞り込む。 |
|> SELECT expr AS name, … | 射影する。入力の範囲スコープはここで終わる。*、* EXCEPT (…)、* REPLACE (…)、alias.*、object.* に対応。 |
|> EXTEND expr AS name, … | 入力の列を残したまま、計算した列を足す。 |
|> SET name = expr, … | 列の値を置き換える。 |
|> RENAME name AS new, … | 列名を変える。 |
|> DROP name, … | 列を取り除く。 |
|> AS alias | 現在見えている列を、範囲の別名の下に束縛し直す。 |
|> AGGREGATE agg(…) AS name, … GROUP BY key, … | グループ化して集計する。 |
|> JOIN other ON … / USING (…) | 現在のレコードを別のRelationと結合する。 |
|> ORDER BY expr [ASC|DESC] [NULLS FIRST|LAST], … | 並べ替える。 |
|> LIMIT n [OFFSET m] | レコードを取り出す。n と m は整数リテラルか @parameters。 |
|> DISTINCT | 重複するレコードを取り除く。 |
|> UNION ALL / UNION DISTINCT / INTERSECT DISTINCT / EXCEPT DISTINCT other、任意で BY NAME [ON (…)] または CORRESPONDING | 集合演算。 |
|> PIVOT(agg(expr) FOR axis IN ('a', 'b', …))、|> UNPIVOT … | 形を変える。 |
|> ASSERT UNIQUE BY (col, …) | 以降の処理のためにキーの一意性を証明する。一意でなければRunを失敗させる。 |
|> RESULT name | 現在のレコードを名前付きのResultとして公開し、続ける。 |
|> INFER \model-task:…` [ITEM KEY (col, …)] INPUT (col, …) [KEEP (…)] AS name [MAX ITEMS n] [ON FAILURE FAIL]` | レコードごとにLLMに問い合わせる。構文リファレンスとLLMとINFERを参照。 |
|> NEAREST candidates [USING vector] [METRIC m] K n [KEEP (…)] AS name | 近傍検索。構文リファレンスを参照。 |
|> CROSS JOIN source [MAX_OUTPUT_ROWS n]、|> CROSS JOIN UNNEST(…) AS e | 交差結合。配列の展開。 |
|> name(key: value, …) | ベクトル、グラフ、イベントに対する名前付き呼び出し(構文リファレンス)。 |
|> MATCH pattern、|> node_rows()、|> edge_rows()、名前付きのグラフ呼び出し | Graph入力に対するグラフのパターン照会とグラフ演算(構文リファレンス)。 |
|> SERIALIZE FORMAT … ORDER BY … | PRESERVE ORDER OPTIONS (…) | レコードをコンテンツ(content_ref)にする。送るのは、その後ろの EFFECT STORE か EFFECT COMMAND。オブジェクトのリソースに対する EFFECT STORE には content の列が必要で、Relationがコンテンツになるのは SERIALIZE を通したときだけ。 |
|> EFFECT UPDATE target ID key SET (field = value, …) | 終端の更新Effect(短い形式)。 |
|> EFFECT UPSERT target ID key SET (field = value, …) | 終端の作成または更新のEffect。 |
|> EFFECT DELETE target ID key | 終端の削除Effect。 |
|> EFFECT INSERT target (col, …) [VALUES (expr, …)] | 終端の追加Effect。VALUES がなければ、各レコードの列挙した列を書き込む。 |
|> EFFECT STORE target SET (field = value, …) | 各レコードのコンテンツをファイルやオブジェクトとして、またはレコードを宣言されたテーブルに書き出す終端のEffect。フィールドで保存先を指定し、コンテンツを渡す。 |
|> EFFECT COMMAND connection.operation [TARGET expr] ID key [INPUT (field = value, …)] | レコードごとに名前付きの操作を1回実行する終端のEffect。契約が必要とするときは TARGET を書く。 |
|> CREATE [OR REPLACE] TABLE target | 終端のテーブル全体の書き込み。 |
INSERT INTO target (col, …) VALUES (…)、UPDATE target SET … WHERE key = …、DELETE FROM target WHERE key = … | 同じEffectのSQL文としての書き方。 |
Pipeは論理的な合成であって、実行の境界ではありません。物理的な順序を固定せず、Stageや Checkpoint を作らず、何かを認可することもありません。データを変えるEffectはプログラムのテキストに多くても1つで、常にPipeの最後のステップです。終端の ; の後ろにはCommandの後置を続けられます。各形式とその長い形式は構文リファレンスにあります。
JOIN
| JOIN | 対応 | 補足 |
|---|---|---|
[INNER] JOIN … ON / USING | あり | 等価キー。キーの連言。グループ化の括弧は透過的。 |
LEFT [OUTER] JOIN | あり | 一致しなかった右側の列は nullable になる。 |
RIGHT [OUTER] JOIN | あり | 一致しなかった左側の列は nullable になる。 |
CROSS JOIN | あり | |
FULL [OUTER] JOIN | 一部 | 両側でキーの同一性が証明されている必要がある。FULL JOINの連鎖は拒否。 |
… MAX_OUTPUT_ROWS n | あり | JOINの出力に対する作者のガード。超えるとRunが失敗する。 |
JOINのキーは、等価で比較される列か値テーブルの受け手です。算術、キャスト、レコード全体をキーにすることは拒否されます。USING はキー列を1つ、書いた順に、残りの左側の列、右側の列の前に出します。
集合演算
UNION ALL、UNION DISTINCT、INTERSECT DISTINCT、EXCEPT DISTINCT は、SQLの連鎖としてもPipe演算子としても使えます。列の対応は既定では位置によります。BY NAME、BY NAME ON (col, …)、CORRESPONDING、STRICT CORRESPONDING を付けると、GoogleSQLと同じ意味で名前による対応になります。INNER … BY NAME は共通の列だけを残します。FULL/LEFT による名前の伝播には対応していません。
式
| 領域 | 対応 |
|---|---|
| リテラル | 文字列(単一引用符、二重引用符、三重引用符、raw r'…'。隣接する断片は連結される)、整数(10進、16進)、有限の倍精度浮動小数点数、TRUE/FALSE、NULL、配列 […]、ARRAY[…]、ARRAY<T>[](空の配列には要素の型が要る) |
| パラメーター | @name。プログラムで宣言する。補間されることはない |
| 比較と論理 | =、<>、!=、<、<=、>、>=、AND、OR、NOT、IS [NOT] NULL、IN (…)、IN UNNEST(array)、BETWEEN |
| 条件 | CASE WHEN … THEN … ELSE … END、IF、IFNULL、COALESCE、NULLIF |
| キャスト | CAST(x AS STRING | NUMBER | FLOAT64 | DOUBLE | BOOLEAN | TIMESTAMP | DECIMAL(P,S))。同じ型へのキャストは恒等 |
| 文字列 | CONCAT、||、LENGTH、LOWER、UPPER、TRIM、LTRIM、RTRIM、LEFT、RIGHT、LPAD、RPAD、SUBSTRING、REPLACE、SPLIT、STARTS_WITH、ENDS_WITH、INSTR、STRPOS、BYTE_LENGTH、UNICODE、TRANSLATE、CONTAINS |
| 数値 | + - * /、ABS、SIGN、ROUND、TRUNC、FLOOR、SQRT、CBRT、POW、EXP、LN、LOG、LOG10、三角関数、GREATEST、LEAST、SAFE_DIVIDE とその他の SAFE_* |
| 集計 | COUNT(*)、COUNT(x)、COUNTIF、SUM、AVG、MIN、MAX、ARRAY_AGG(x ORDER BY …)、STRING_AGG(x, 'sep')、絞り込み付きの集計(呼び出しの中の … WHERE …) |
| ウィンドウ関数 | 対応している分析関数での OVER (PARTITION BY … ORDER BY … [ROWS …])、QUALIFY、名前付きの WINDOW 指定 |
| ベクトル | VECTOR_COSINE_SIMILARITY、VECTOR_INNER_PRODUCT、VECTOR_L2_DISTANCE、VECTOR_CONCAT |
型とNULLの規則を含む関数の一覧は型と関数にあります。
NULLの規則
NULLはSQLのNULL、つまり「不明」です。NULLとの比較はNULLになり、WHEREは条件がTRUEのレコードだけを残します。- スカラー関数は、型と関数の項目に別の記載がない限り、
NULLを伝播します。 CONCATと||はNULLを伝播します。ACTQL.CONCATは、NULLを飛ばす明示的な変種です。SUM、AVG、MIN、MAXはNULLを無視します。COUNT(x)はNULLでない値を数え、COUNT(*)はレコードを数えます。- 外部結合は、一致しなかった列を
NULLで埋め、検査済みのスキーマでは nullable として扱います。 - 外部システムが省略することのある列と、値が
NULLの列は別のものです。存在が保証されていない列の読み取りを、検査器は拒否します。
受け付けないもの
次の形は、検査の段階で名前の付いた理由とともに拒否されます。選んだGoogleSQLプロファイルの範囲外か、ActQLとして意図的に入れていないものです。
| 形 | 理由 |
|---|---|
ユーザー定義関数、CREATE FUNCTION、ラムダ、インラインのJavaScriptやPython | ActQLに抜け道はありません。言語の設計を参照。 |
手続き型SQL(BEGIN、LOOP、IF … THEN、変数、カーソル) | プログラムは終わりのある宣言的なものです。 |
SELECT … INTO、MERGE、CREATE [OR REPLACE] TABLE … AS 以外のDDL | 外部システムへの変更は、宣言された形を持つEffectです(MERGE の代わりは UPSERT)。 |
BYTES のリテラルと関数、照合順序、SAFE_CAST、:: キャスト、キャスト先としての DATE | 選んだプロファイルにありません。 |
計算された LIMIT/OFFSET、LIMIT 0 | 整数リテラルかパラメーターだけです。 |
| 等価でないJOINキー、計算したキーでのJOIN | キーは等価で比較される列です。 |
FULL JOIN の連鎖、FULL/LEFT BY NAME の集合演算 | 対応していません。 |
PIVOT での複数の集計、文字列以外の軸、計算したバケット | 単一の集計で文字列の軸を持つ形だけです。 |
| 未知の関数名や演算 | あいまい一致や同義語で解決することはありません。 |
|> CALL、独立したステップとしての |> WINDOW、|> TABLESAMPLE、|> ASSERT condition | 受け付ける範囲の外にあるGoogleSQLのPipe演算子。SELECT/EXTEND の中の WINDOW 句と |> ASSERT UNIQUE BY は受け付ける。 |
| 文字列の補間、1つのテキストに複数の文 | プログラムのテキストは1つのクエリで、データを変えるEffectは多くても1つ、; の後ろにCommandの後置を続けられる。 |
ここで定義されていることと、各環境が現時点で実行できることは別の問いです。実装状況を参照してください。
Source: actql/actql/docs/reference/sql-compatibility.md at d904416674e4 · Edit on GitHub