24.3 では、新しいクエリアナライザがデフォルトで有効化されました。
その動作の詳細については、こちらをご覧ください。
既知の非互換性
無効なクエリは最適化されなくなりました
例 1
toString(number) のみであるにもかかわらず、PROJECTIONリストでカラム number を使用しています。
古いアナライザでは、GROUP BY toString(number) は GROUP BY number, に最適化されることで、このクエリは有効とみなされていました。
例 2
number は、別のキーで集約した後に使用されています。
以前のクエリアナライザは、number > 5 のフィルタを HAVING 句から WHERE 句へ移動することで、このクエリを修正していました。
WHERE 句に移動する必要があります。
無効なクエリを含む CREATE VIEW
SELECT クエリを含む VIEW を作成できました。
その場合、最初の SELECT または INSERT の実行時に失敗していました (MATERIALIZED VIEW の場合) 。
このような方法で VIEW を作成することは、現在ではできません。
例
JOIN句の既知の非互換性
PROJECTIONのカラムを使った JOIN
SELECT リストのエイリアスは、デフォルトでは JOIN USING のキーとして使用できません。
新しい設定 analyzer_compatibility_join_using_top_level_identifier を有効にすると、JOIN USING の動作が変わり、左側のテーブルのカラムを直接使う代わりに、SELECT クエリのPROJECTIONリスト内の式に基づいて識別子を優先的に解決するようになります。
例えば:
analyzer_compatibility_join_using_top_level_identifier を true に設定すると、以前のバージョンと同様に、結合条件は t1.a + 1 = t2.b と解釈されます。
結果は 2, 'two' になります。
この設定が false の場合、結合条件はデフォルトで t1.b = t2.b となり、クエリは 2, 'one' を返します。
t1 に b が存在しない場合、クエリはエラーで失敗します。
JOIN USING と ALIAS/MATERIALIZED カラムに関する動作の変更
ALIAS または MATERIALIZED カラムを含む JOIN USING クエリで * を使用すると、デフォルトでそれらのカラムも結果セットに含まれます。
たとえば:
id とともに payload カラムが含まれます。
一方、以前のアナライザでは、特定の設定 (asterisk_include_alias_columns または asterisk_include_materialized_columns) が有効になっている場合にのみ、これらの ALIAS カラムが含まれ、
カラムの順序も異なる場合がありました。
一貫性があり期待どおりの結果を得るため、特に古いクエリをアナライザに移行する際は、* を使うのではなく、SELECT 句でカラムを明示的に指定することを推奨します。
USING 句におけるカラムの型修飾子の扱い
USING 句で指定されたカラムの共通スーパータイプを決定するルールが標準化され、より予測可能な結果が得られるようになりました。特に、LowCardinality や Nullable のような型修飾子を扱う場合にその傾向が顕著です。
LowCardinality(T)とT: 型LowCardinality(T)のカラムを型Tのカラムと JOIN した場合、結果の共通スーパータイプはTとなり、LowCardinality修飾子は実質的に破棄されます。Nullable(T)とT: 型Nullable(T)のカラムを型Tのカラムと JOIN した場合、結果の共通スーパータイプはNullable(T)となり、Nullable の性質が保持されます。
id の共通スーパータイプは String と判定され、t1 の LowCardinality 修飾子は無視されます。
PROJECTIONのカラム名に関する変更
互換性のない関数引数の型
if 関数の引数は常に共通のスーパータイプを持っている必要があります。
たとえば、次のクエリは There is no supertype for types Array(UInt8), String because some of them are Array and some of them are not というエラーで失敗します。
異種クラスター
enable_analyzer 設定の値が異なるサーバー間では、分散クエリを実行できません。
ミューテーションは従来のアナライザで解釈されます
QUALIFY 句です。
状況はこちらで確認できます。
サポートされていない機能
- Annoy 索引。
- Hypothesis 索引。こちらで実装が進められています。
- Window view はサポートされていません。今後もサポートされる予定はありません。
Cloud 移行
移行ワークフロー
normalized_query_hashでsystem.query_logをフィルタリングし、クエリを特定します。
- これらの設定を追加してアナライザを有効にし、クエリを実行します。
- クエリを見直して結果を検証し、アナライザを無効にした場合に生成される出力と一致することを確認します。
不明な式識別子
Unknown expression identifier ... in scope ... (UNKNOWN_IDENTIFIER). 例外コード: 47
原因: フィルター内で計算済みの別名を参照する、曖昧なサブクエリの投影、「動的」な CTE スコープを使うといった、非標準で緩い従来の動作に依存するクエリは、現在では無効として正しく判定され、即座に拒否されます。
解決策: SQL を次のように修正してください。
- フィルター条件: 結果に対して絞り込む場合は、条件を WHERE から HAVING に移します。元データに対して絞り込む場合は、WHERE 句に同じ式を明示的に記述します。
- サブクエリのスコープ: 外側のクエリで必要になるすべてのカラムを明示的に選択します。
- JOIN の結合キー: キーが別名の場合は、USING ではなく完全な式を指定した ON を使用します。
- 外側のクエリでは、その内部のテーブルではなく、サブクエリ/CTE 自体の別名を参照します。
GROUP BY における非集計カラム
Column ... is not under aggregate function and not in GROUP BY keys (NOT_AN_AGGREGATE). Exception code: 215
原因: 旧アナライザでは、GROUP BY 句に含まれていないカラムも SELECT できていました (多くの場合、任意の値が選ばれていました) 。アナライザは標準 SQL に従うため、SELECT するすべてのカラムは、集計関数を適用するか、グルーピングキーである必要があります。
解決策: カラムを any() または argMax() で囲むか、GROUP BY に追加してください。
重複するCTE名
CTE with name ... already exists (MULTIPLE_EXPRESSIONS_FOR_ALIAS)。Exception code: 179
原因: 以前のアナライザでは、同じ名前の共通テーブル式 (WITH …) を複数定義し、先に定義したものを後から定義したものでシャドーイングすることが許可されていました。アナライザでは、このような曖昧さは許可されません。
解決策: 重複するCTEの名前を変更して、一意にしてください。
曖昧なカラム識別子
JOIN [JOIN TYPE] ambiguous identifier ... (AMBIGUOUS_IDENTIFIER) Exception code: 207
原因: クエリで、どのテーブルのものかを指定せずに、JOIN 内の複数のテーブルに存在するカラム名を参照しています。古いアナライザは内部ロジックに基づいてカラムを推測することがよくありましたが、アナライザでは明示的に名前を指定する必要があります。
解決策: table_alias.column_name のように、カラムを完全修飾してください。
FINAL の無効な使用
Table expression modifiers FINAL are not supported for subquery... または Storage ... doesn't support FINAL (UNSUPPORTED_METHOD)。例外コード: 1, 181
原因: FINAL はテーブルストレージ (特に [Shared]ReplacingMergeTree) の修飾子です。アナライザは、次の対象に FINAL を適用すると拒否します。
- サブクエリまたは派生テーブル (例: FROM (SELECT …) FINAL) 。
- FINAL をサポートしていないテーブルエンジン (例: SharedMergeTree) 。
countDistinct() 関数の大文字・小文字の区別
Function with name countdistinct does not exist (UNKNOWN_FUNCTION)。Exception code: 46
原因: 関数名では大文字・小文字が区別されるか、アナライザで厳密にマッピングされます。countdistinct (すべて小文字) は、今後は自動的に解決されません。
対処法: 標準の countDistinct (camelCase) または ClickHouse 固有の uniq を使用してください。