🔍

Athena にて EXPRESSION_NOT_CONSTANT エラーが発生

2024/06/08に公開

発生した問題

Athena マネジメントコンソールにてSQLを組み立てていたところ、以下のエラーが発生した。

EXPRESSION_NOT_CONSTANT: line xxx: Constant expression cannot contain column references

原因

定数を指定すべき箇所で、テーブルの予約キーワードを指定していた。

より具体的には、SQL内で文字列リテラルを指定したい箇所にて、シングルクォートではなくダブルクォートを使用したことが原因。

-- EXECUTE は、パラメータ化されたクエリを実行するためのキーワード
-- 詳細 : https://docs.aws.amazon.com/ja_jp/athena/latest/ug/querying-with-prepared-statements.html
EXECUTE extract_mytable using "column1"; 

解決策

文字列リテラルを指定する場合、シングルクォートを使用する。

EXECUTE extract_mytable using 'column1'; 

ただし、「列名」など、テーブルに関するメタデータを指定する場合は、ダブルクォートを使用する。

select "column1", count(1) from my_table group by "column1";

ただし、Athena prepared statement を使用して、列指定部分 (group byorder by など)を EXECUTE で後から指定しようとするとうまくいかない(その他の問題に記載)。

そもそも prepared statement は、2024年6月現在だと where でしか利用できない。

現在、? パラメータは WHERE 句にのみ配置できます。SELECT ? FROM table のような構文はサポートされていません。

引用元 https://docs.aws.amazon.com/ja_jp/athena/latest/ug/querying-with-prepared-statements.html

列指定するようなステートメント( group byorder by )には、そもそも使用できなかった。

エラーの詳細

Athena では、ダブルクォートは、「Athenaの予約語をエスケープするための記号」という意味を持つ。

SQL の SELECT ステートメントや ビュー のクエリで予約キーワードをエスケープするには、二重引用符 ('') で囲みます。

引用元 : https://docs.aws.amazon.com/ja_jp/athena/latest/ug/reserved-words.html

文字列リテラルはシングルクォート、SQLクエリの予約語(列名など)はダブルクォートで囲む。

シングルクォート・ダブルクォートを間違えると、エラーをはじめとした意図しない挙動に見舞われる。

意図しない挙動の例

例えば、以下のようなテーブルがあったとする。

select * from worker;
id name department
34567 saburo 開発
12345 taro 営業
45678 goro 品質
34568 shiro 開発
23456 jiro 営業

このデータを、 department 列で集計したいとする。

この時、 department を ダブルクォートでくくるか、シングルクォートでくくるかで、結果が変化する。

◆ ダブルクォートでくくる(意図した挙動)

select "department", count(*) as department_count from worker group by "department";
department department_count
品質 1
開発 2
営業 2

◆ シングルクォートでくくる(意図しない挙動)

エラー扱いされずに動いてしまう。

select 'department', count(*) as department_count from worker group by 'department';
_col0 department_count
department 5

恐らく、"列名"ではなく、謎の文字列を指定した扱い。
group by Null 等と同じ挙動。

この時、列名をダブルクォートでくくる(or なにもくくらない)と、エラーが発生する。

select department, count(*) as department_count from worker group by 'department';

EXPRESSION_NOT_AGGREGATE: line 1:8: 'department' must be an aggregate expression or appear in GROUP BY clause

その他の問題

「Prepared Statement」の using で うまく列名指定出来ない

Athenaの Prepared Statement 機能を使って、 group by など列名部分を後から挿入することを考える。

エラーの詳細 にある通り、 group by など、列名を指定する時はダブルクォートでくくる必要がある。

しかし、ダブルクォートで列名を指定すると、本記事冒頭のエラーが発生する。

EXPRESSION_NOT_CONSTANT: line xxx: Constant expression cannot contain column references

恐らく、Prepared Statement の性質上どうしようもないと思われる。

(自分が知らないだけで、解決方法があるかも?)

最後に

たまにハマるので注意。

参考文献

Discussion