Treasure DataのPrestoリリースは、Presto 317のオープンソースリリースに基づいています。以前のリリースはPresto 0.205に基づいていました。この記事には以下が含まれます:
- 新しいマジックコメント機能
- parse_decimal_literals_as_double
- Distributed_Sort
- time_partitioning_range
- 非推奨の機能
- 分散結合のマイグレーション
- Prestoの更新
- サイドバイサイド環境について
- Presto 317とPresto 0.205でのコード実行
- クエリ構文の修正
- ORの述語が多すぎます。最大500個のORが許可されています
- マップにキーが存在しません: XXX
- 配列の添字が範囲外です
- カラムエイリアスリストには1つのエントリがありますが、't'にはN個のカラムがあります'
- Windowはdistinctをサポートしていません
- null要素を含む配列のARRAY比較はサポートされていません
- 'XXX'は集約式であるか、GROUP BY句に含まれている必要があります
- 長さゼロの区切り識別子は許可されていません
- 関数codepointの予期しないパラメータ (char(1))。期待値: codepoint(varchar(1))
- 無効なフォーマット: "XXX"が不正な形式です / 無効なタイムゾーン: "XXX"が不正な形式です
互換性とパフォーマンスの退行問題を特定するため、社内テストを実施しました。
parse_decimal_literals_as_double セッションプロパティは、マジックコメントとしてサポートされています。
明示的な型指定子を持たない10進リテラル(例: 1.2)は、デフォルトでDOUBLE型の値として扱われます。
このマジックコメントを使用すると、この動作を無効化し、10進リテラルをDECIMAL型の値として使用できます。例:
-- set session parse_decimal_literals_as_double = 'false'
SELECT typeof(1.1);distributed_sort セッションプロパティは、マジックコメントとしてサポートされています。
分散ソートを使用すると、query.max-memory-per-nodeを超えるデータのソートが可能になります。分散ソートは、distributed_sortセッションプロパティ、またはコーディネーターのetc/config.propertiesに設定されたdistributed-sort設定プロパティを通じて有効化されます。分散ソートはデフォルトで有効になっています。
分散ソートが有効な場合、ソート演算子はクラスター内の複数のノードで並列実行されます。各ワーカーノードから部分的にソートされたデータは、最終的なマージのために単一のワーカーノードにストリーミングされます。この手法により、ソートのために複数のワーカーノードのメモリを活用できます。分散ソートの主な目的は、通常は単一ノードのメモリに収まらないデータセットのソートを可能にすることです。パフォーマンスの向上が期待できますが、データを単一ノードでマージする必要があるため、ノード数に対して線形にスケールすることはありません。
-- set session distributed_sort = 'true'
SELECT * FROM large_table, small_table
WHERE small_table.id = large_table.idtime_partitioning_rangeセッションプロパティは、マジックコメントとしてサポートされています。
-- set session time_partitioning_range = 'value`
値は以下のいずれかです
* none
* タイムパーティショニングなし
* 単位付きの数値
* 許可される単位は`h, d, mo, q, y` (時間、日、月、四半期、年)
* 例) 12h, 2d, 1mo, 1q, 1y
# 非推奨の機能
## 分散結合のマイグレーション
**distributed_join** セッションプロパティは削除されました。
代わりに**join_distribution_type** セッションプロパティを使用してください。**join_distribution_type** システムプロパティは、以下の値を受け付けます:
* PARTITIONED
* BROADCAST
非推奨のコード:
```sql
-- set session distributed_join = 'true'
SELECT * FROM large_table, small_table
WHERE small_table.id = large_table.id
更新されたコード:
```sql
-- set session join_distribution_type = 'PARTITIONED'
SELECT *
FROM large_table, small_table
WHERE small_table.id = large_table.idテストのため、Presto 0.205とPresto 317がサイドバイサイドで利用可能であり、アップグレード前にコードのテストが可能です。
Presto 317とPresto 0.205からの移行期間中、2つのリリースがサイドバイサイドで利用可能です。
以下のクエリヒントを使用して、どのPrestoリリースでコードを実行するかを制御できます:
| バージョン | クエリヒント |
|---|---|
| Presto 317 | -- @TD engine_version: 317 |
| Presto 0.205 | -- @TD engine_version: 0.205 |
以前のバージョンで動作していたクエリを実行すると、エラーメッセージが発生する場合があります。各ケースについて、メッセージ、エラーを引き起こすクエリ、およびクエリの書き換え方法の例を示します。
エラーの原因となる元のコード:
SELECT path FROM (
SELECT * FROM sample_datasets.www_access ) WHERE
path = 'foo1' OR path = 'foo2' OR path = 'foo3'
-- Query having a lot of "OR" clauses
OR path = 'foo559';エラーを修正したコード:
SELECT path FROM (
SELECT * FROM sample_datasets.www_access ) WHERE
path IN (
'foo1', 'foo2', 'foo3' ,
-- Query having a lot of conditions
'foo559');通常、IN句を使用してクエリを書き直すことで、この問題は解決されます。
Key not present in map: XXX
エラーの原因となる元のコード:
SELECT MAP(ARRAY [1, 3], ARRAY [2, 4])[5];エラーを修正したコード:
SELECT element_at(MAP(ARRAY [1, 3], ARRAY [2, 4]), 5);クエリを書き直すには、関数element_atを使用できます。関数element_atは、v0.205とv317の両方のクラスターバージョンでサポートされています。前述のクエリは両方のクラスターで実行できます。
Array subscript out of bounds
エラーの原因となる元のコード:
SELECT
numbers[99] -- key isn't exist
FROM
(VALUES (ARRAY[1,2,3]) ) AS t(numbers);エラーを修正したコード:
SELECT
element_at(numbers, 99) -- key isn't exist
FROM
(VALUES (ARRAY[1,2,3]) ) AS t(numbers);関数element_atは、v0.205とv317の両方のクラスターバージョンでサポートされています。
前述のクエリは両方のクラスターで実行できます。
Column alias list has 1 entry but 't' has N columns available'
エラーの原因となる元のコード:
WITH
dataset AS (
SELECT ARRAY[
CAST(ROW('Amy', 'devops') AS ROW(name VARCHAR, department VARCHAR))
] AS users
),
u AS (
SELECT person
FROM
dataset,
UNNEST(dataset.users) AS t(person)
)
SELECT
person.name,
person.department
FROM u;エラーを修正したコード:
WITH
dataset AS (
SELECT ARRAY[
CAST(ROW('Amy', 'devops') AS ROW(name VARCHAR, department VARCHAR))
] AS users
),
u AS (
SELECT
name, department
FROM
dataset,
UNNEST(dataset.users) AS person(name, department)
)
SELECT
name,
department
FROM u;Window does not support distinct
エラーの原因となる元のコード:
SELECT
UPPER(DISTINCT(id)) AS user_id
FROM (VALUES ('foo'), ('bar')) AS t(id);エラーを修正したコード:
SELECT
UPPER(id) AS user_id
FROM (
SELECT DISTINCT id FROM (VALUES ('foo'), ('bar')
) AS t (id));
## null要素を含む配列の配列比較はサポートされていません
エラーを引き起こす元のコード:
```sql
SELECT id, array_agg(value)
FROM (
VALUES
(1, 3), (1, 4), (1, 5), (2, 6), (2, 7), (3, null)
) AS t(id, value)
GROUP BY 1 ORDER BY 2;エラーを修正したコード:
SELECT id, array_agg(value) FILTER (where value is not null)
FROM (
VALUES
(1, 3), (1, 4), (1, 5), (2, 6), (2, 7), (3, null)
) AS t(id, value)
GROUP BY 1 ORDER BY 2;関数element_atは、両方のクラスターバージョン、v0.205とv317でサポートされています。上記のクエリは両方のクラスターで実行されます。
Presto 0.205では、array_agg関数はNULL値を無視します。
presto> SELECT id, array_agg(value) FROM ( VALUES (1, null), (1, 0) ) AS t(id, value) GROUP BY 1;
id | _col1
----+-------
1 | [0]
(1 row)
presto> SELECT id, array_agg(value) FROM ( VALUES (1, null) ) AS t(id, value) GROUP BY 1;
id | _col1
----+-------
1 | NULL
(1 row)
Presto 0.205では、array_agg関数のこのレガシー動作を維持するために、_deprecated_._legacyagg_プロパティがtrueに設定されています。
このプロパティはPresto 317で削除され、レガシー動作をロールバックする機能はありません。
Presto 317では、array_agg関数はNULL値を無視せず、NULL値を含む配列を返します。
presto> SELECT id, array_agg(value) FROM ( VALUES (1, null), (1, 0) ) AS t(id, value) GROUP BY 1; id | _col1 ----+----------- 1 | [null, 0] (1 row)
presto> SELECT id, array_agg(value) FROM ( VALUES (1, null) ) AS t(id, value) GROUP BY 1; id | _col1 ----+-------- 1 | [null] (1 row)
その結果、PrestoがNULL値を含む配列を持つカラムと比較を行うと、PrestoはARRAY comparison not supported for arrays with null elementsというメッセージを返します。
エラーを引き起こす元のコード:
SELECT code FROM sample_datasets.www_access
HAVING code IS NOT NULL;エラーを修正したコード:
SELECT code FROM sample_datasets.www_access
WHERE code IS NOT NULL;HAVING句をWHERE句として使用すると、このエラーが表示されます。
Zero-length delimited identifier not allowed
エラーを引き起こす元のコード:
SELECT 1 AS "";エラーを修正したコード:
SELECT 1 AS "A";エラーを引き起こす元のコード:
SELECT codepoint(CAST('a' AS CHAR));エラーを修正したコード:
SELECT codepoint(CAST('a' AS VARCHAR(1)));v317ではエラー処理が改善されました。無効な引数が渡された場合、現在のPrestoはNULLを返しますが、新しいPrestoはエラーを返します。
エラーを引き起こす元のコード:
SELECT td_time_range(1567890000, 'yyyy-MM-dd','JST', NULL);エラーを修正したコード:
SELECT td_time_range(1567890000, '2019-09-08', 'JST', NULL);