# Presto 0.188から0.205への移行 2018 2018年10月2日 * [本番環境のPresto 0.205 アップグレードに向けた準備](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h1__1534007424) * [サイドバイサイド環境](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h2_875219085) * [移行タイムライン](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h2_328935467) * [Presto 0.205とPresto 0.188でのコード実行](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h2__958187426) * [Presto 0.205に必要なSQL変更](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h1_844570931) * [新しいシステム関数 current_user](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h2__1117537908) * [構文エラーを発生させるクエリ](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h1__456405141) * [ORDER BY動作の変更](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h2_1886465859) * [USINGを使用したJOIN](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h2_1179465342) * [エラーメッセージ: Given correlated subquery is not supported](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h2_464978500) * [推奨される更新: TD_SESSIONIZEをTD_SESSIONIZE_WINDOWに置き換える](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h1_839700295) # 本番環境のPresto 0.205 アップグレードに向けた準備 Treasure Dataの新しいPrestoリリース(2018年10月1日提供開始)は、オープンソースのPresto 0.205リリースをベースにしています。以前のリリースはPresto 0.188をベースにしていました。 互換性とパフォーマンス低下の問題を特定するため、独自の内部テストを実施しており、その内容を以下に記載しています。 ## サイドバイサイド環境 お客様も独自にテストを行う必要があることを理解しています。そのため、今回のリリースではPresto 0.188とPresto 0.205をサイドバイサイドで提供し、お客様がアップグレード前に自身でコードをテストできるようにしています。 ## 移行タイムライン 2018年10月31日までは、デフォルト環境はPresto 0.188となります。2018年11月1日に、デフォルト環境はPresto 0.205に切り替わります。Presto 0.188は2018年11月15日まで利用可能で、移行を完了する時間を確保しています。 10月31日より前に互換性テストを完了した場合は、Treasure Dataサポートにご連絡いただければ、お客様のデフォルトを早期にPresto 0.205に変更することができます。 サイドバイサイド環境と段階的な移行期間は、今後のリリースでも継続して実施されます。 ## Presto 0.205とPresto 0.188でのコード実行 Presto 0.188からPresto 0.205への移行期間中、2つのリリースは2018年10月1日から2018年11月15日までサイドバイサイドで利用可能です。 以下のクエリヒントを使用して、どのPrestoリリースでコードを実行するかを制御できます: ```sql -- @TD engine_version: 0.188 ``` または ```sql -- @TD engine_version: 0.205 ``` # Presto 0.205に必要なSQL変更 今回のリリースでは、主にANSI SQL標準への準拠を強化することに焦点を当てた、多数のPresto構文変更があります。 既存のクエリの一部は、新しいPresto環境で実行する前に修正が必要になります。以下で説明する変更については、クエリはPresto 0.188とも互換性があることに注意してください。したがって、**結果を変更することなく、Presto 0.188環境でこれらの変更を行うことができます。**新しいリリースに移行しても、クエリは引き続き動作します。 ここに記載されている必須の変更は、既存のお客様のコードを実行することで特定されました。 各変更について、Prestoでの変更内容、互換性のないPresto SQLがある場合のエラーメッセージ、および推奨される書き換え方法を説明します。 ## 新しいシステム関数 current_user Prestoに新しいcurrent_user()関数が追加されました。この関数は現在のユーザー名を返します。その結果、current_user()という名前のカラムやエイリアスがある場合は、そのカラムへの参照を引用符で囲む必要があります。 例えば、変更前にこのコードがある場合: ```sql SELECT current_user FROM table1 ``` "current_user"を引用符で囲むように更新します: ```sql SELECT "current_user" FROM table1 -- tab."current_user"カラムの値をリストします ``` # 構文エラーを発生させるクエリ ## ORDER BY動作の変更 PrestoはANSI SQL標準のORDER BY句により厳密に準拠するようになりました。 ORDER BY動作の一般的なルールは次のようになります: * ORDER BYは射影(projection)の後に実行されます * ORDER BYは可能な限り序数エイリアスを優先します * 入力カラムと出力カラムはORDER BY句で使用できますが、曖昧さがある場合は出力カラムが**より高い優先順位**を持ちます このPrestoの変更により、いくつかのエラーメッセージが発生する可能性があります。 以下のすべてのケースの問題は、クエリ内の命名の競合によるものです。つまり、SELECTまたはORDER BYでのエイリアスの使用が、入力のカラム名またはテーブル名と衝突しています。エイリアスを使用すると、元の入力テーブルまたはカラムへの参照ができなくなります。 書き換えは一般的に、入力テーブルまたはカラム名と一致しないエイリアスを使用するか、ORDER BY句で序数を使用することを含みます。 各ケースについて、メッセージ、エラーを引き起こすクエリ、およびクエリを書き換える方法の例を示します。 ### エラーメッセージ: Mismatched types: varchar(1) vs varchar エラーを引き起こす元のコード: ```sql SELECT * FROM page_view WHERE CAST(week_page_total_actions as VARCHAR) IS DISTINCT FROM '0'; ``` エラーを修正する修正コード: ``` ```sql SELECT * FROM page_view WHERE CAST(week_page_total_actions as VARCHAR (1)) IS DISTINCT FROM '0'; ``` ``` ### エラーメッセージ: Non deterministic ORDER BY expression is not supported with SELECT DISTINCT エラーの原因となる元のコード: ```sql SELECT week_page_total_actions FROM ( SELECT DISTINCT week_page_total_actions, rand() FROM page_view WHERE week_page_total_actions NOT LIKE '1' ORDER BY rand() LIMIT 20 ) sub ``` エラーを修正したコード: ```sql SELECT week_page_total_actions FROM ( SELECT DISTINCT week_page_total_actions, rand() FROM page_view WHERE week_page_total_actions NOT LIKE '1' LIMIT 20 ) sub -- ORDER BY 句から関数または式を削除する ``` ``` ### エラーメッセージ: Invalid reference to output projection attribute from ORDER BY aggregation エラーの原因となる元のコード: ```sql SELECT code, count(code) AS cnt FROM www_access GROUP BY code ORDER BY count(code) -- 出力カラムの code が ORDER BY 集約で使用されている ``` エラーを修正したコード: ```sql SELECT code, count(code) AS cnt FROM www_access GROUP BY code ORDER BY count(www_access.code) -- (または) ORDER BY cnt (または) ORDER BY 2 ``` ``` ### エラーメッセージ: Expression XXX is not of type ROW エラーの原因となるコード例: ```sql SELECT TD_TIME_FORMAT(time, 'yyyy-MM-dd HH:mm:ss z', 'JST') AS time, code AS access -- 優先度が高い FROM www_access access -- 優先度が低い ORDER BY access.time -- access はここではエイリアスカラム "code" を参照する -- そのため access.time は意味をなさない ``` エラーを修正したコード: ```sql SELECT TD_TIME_FORMAT(time, 'yyyy-MM-dd HH:mm:ss z', 'JST') AS time, code AS access_another -- 名前の競合を回避する FROM www_access access ORDER BY access.time ``` 次のクエリ(識別子 **time** で名前の衝突が発生する場合)は、上記の書き換えと同等ではないことに注意してください。**time** としてエイリアスされたTD_TIME_FORMATの戻り値は、タイムスタンプではなく日付フォーマットされたVARCHARになります: ```sql SELECT TD_TIME_FORMAT(time, 'yyyy-MM-dd HH:mm:ss z', 'JST') AS time, -- エイリアスの優先度が高く、ORDER BY で使用される count(*) AS access FROM access_log access ORDER BY time -- (または) ORDER BY 1 ``` ### エラーメッセージ: For SELECT DISTINCT, ORDER BY expressions must appear in select list エラーの原因となるコード例: ```sql SELECT DISTINCT TD_TIME_FORMAT(time, 'yyyy-MM-dd HH:mm:ss z', 'JST') AS time, code FROM www_access access ORDER BY TD_TIME_FORMAT(time, 'yyyy-MM-dd HH:mm:ss z', 'JST') -- このTD_TIME_FORMATの呼び出しはSELECTリストの式と一致しません。 -- ORDER BY内のtimeは、TD_TIME_FORMATによって返されたvarcharを参照しているためです ``` エラーを修正した修正コード: ```sql SELECT DISTINCT TD_TIME_FORMAT(time, 'yyyy-MM-dd HH:mm:ss z', 'JST') AS time, -- より高い優先順位、入力時刻カラムをオーバーライドします code FROM www_access access ORDER BY time -- ORDER BY 1 を使用することもできます ``` ### エラーメッセージ: 関数名は異なりますが、解決策は同じです。 関数 **td_time_format** に予期しないパラメータ (varchar, varchar(21), varchar(3)) があります。期待される形式: td_time_format(bigint, varchar, varchar) , td_time_format(bigint, varchar) 関数 **date_trunc** に予期しないパラメータ (varchar(5), varchar) があります。期待される形式: date_trunc(varchar(x), date) , date_trunc(varchar(x), time) , date_trunc(varchar(x), time with time zone) , date_trunc(varchar(x), timestamp) , date_trunc(varchar(x), timestamp with time zone) エラーを引き起こす **td_time_format** のコード例: ```sql SELECT TD_TIME_FORMAT(time, 'yyyy-MM-dd HH:mm:ss z', 'JST') AS time, -- より高い優先順位、入力時刻カラムをオーバーライドします code FROM www_access access ORDER BY TD_TIME_FORMAT(time, 'yyyy-MM-dd HH:mm:ss z', 'JST')-- ここのtimeはSELECTリストのvarchar出力カラムであり、 -- タイムスタンプ入力カラムではありません -- したがって、ここの式はSELECTリストの式と同じではありません ``` エラーを修正する **td_time_format** の修正コード: ```sql SELECT TD_TIME_FORMAT(time, 'yyyy-MM-dd HH:mm:ss z', 'JST') AS time, -- より高い優先順位 code FROM www_access access ORDER BY time -- (または) ORDER BY 1 ``` ## USINGを使用したJOIN SELECT… JOIN... でUSING句を使用した等結合の場合、USING句で指定されたカラムは、結合内の各テーブルごとに1回ずつ表示されるのではなく、修飾されていない名前で出力に1回だけ表示されます。修飾名でソーステーブルのカラムを参照するとエラーになります。 以前のPrestoと比較して、この変更により次のエラーメッセージが発生する可能性があります。それぞれについて、クエリを書き直す方法の例を示します。 ### エラーメッセージ: Column 'xxx.yyyy' cannot be resolved エラーを引き起こすコード例: ```sql SELECT lineitem.orderkey, lineitem.quantity, orders.totalprice, orders.orderkey FROM lineitem JOIN orders USING (orderkey); ``` lineitem.orderkey と orders.orderkey への参照に注意してください。 エラーを修正する修正コード: ```sql SELECT orderkey, lineitem.quantity, orders.totalprice FROM lineitem JOIN orders USING (orderkey); ``` 相関サブクエリとLIMIT ## エラーメッセージ: Given correlated subquery is not supported アップグレード後、相関サブクエリはLIMIT句の使用をサポートしなくなりました。 LIMIT句を必要としないように相関サブクエリを書き直してください。 エラーを引き起こすコード例: ```sql SELECT * FROM region r, LATERAL ( SELECT * FROM nation n WHERE n.regionkey = r.regionkey LIMIT 1 ) -- これは失敗します ``` エラーを修正する修正コード: ```sql SELECT * FROM region r, LATERAL ( SELECT * FROM nation n WHERE n.regionkey = r.regionkey ) ``` この問題については、変更によってコードの意味が変わらないことを確認するために、コードを注意深く確認する必要があります。 # 推奨される更新: TD_SESSIONIZEをTD_SESSIONIZE_WINDOWに置き換える このアップデートのためにコードを確認する際に、TD_SESSIONIZEを使用している既存のクエリに対して重要なアップグレードを行うこともお勧めします。TD_SESSIONIZE() 関数は、パフォーマンスの問題と一貫性のない結果のため廃止されました。代替となるPrestoウィンドウ関数TD_SESSIONIZE_WINDOW()は2016年に追加されました。これはTD_SESSIONIZEの問題に対処しています。クエリを書き直すための詳細な手順はこちらにあります: [Presto TD_SESSIONIZE() から TD_SESSIONIZE_WINDOW() への移行](/ja/products/customer-data-platform/data-workbench/queries/presto-0-188-to-0-205-migration-2018#h1_839700295)