# Presto 0 205から317へのマイグレーション 2020

Treasure DataのPrestoリリースは、Presto 317のオープンソースリリースに基づいています。以前のリリースはPresto 0.205に基づいていました。この記事には以下が含まれます:

* [新しいマジックコメント機能](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h1_1921683457)
* [parse_decimal_literals_as_double](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2__584086195)
* [Distributed_Sort](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2__1974809204)
* [time_partitioning_range](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2__1734486412)
* [非推奨の機能](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h1__1821394898)
* [分散結合のマイグレーション](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2_2028709490)
* [Prestoの更新](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h1__1516417081)
* [サイドバイサイド環境について](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2__1521992254)
* [Presto 317とPresto 0.205でのコード実行](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2__1437983654)
* [クエリ構文の修正](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h1__87043302)
* [ORの述語が多すぎます。最大500個のORが許可されています](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2_1448312120)
* [マップにキーが存在しません: XXX](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2_756987314)
* [配列の添字が範囲外です](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2__599545120)
* [カラムエイリアスリストには1つのエントリがありますが、't'にはN個のカラムがあります'](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2_1644950305)
* [Windowはdistinctをサポートしていません](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2__285762603)
* [null要素を含む配列のARRAY比較はサポートされていません](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2__1682355132)
* ['XXX'は集約式であるか、GROUP BY句に含まれている必要があります](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2_2060302521)
* [長さゼロの区切り識別子は許可されていません](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2__852805306)
* [関数codepointの予期しないパラメータ (char(1))。期待値: codepoint(varchar(1))](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2__190112671)
* [無効なフォーマット: "XXX"が不正な形式です / 無効なタイムゾーン: "XXX"が不正な形式です](/ja/products/customer-data-platform/data-workbench/queries/archives/presto-0-205-to-317-migration-2020#h2_1996712627)


互換性とパフォーマンスの退行問題を特定するため、社内テストを実施しました。

# 新しいマジックコメント機能

## parse_decimal_literals_as_double

**parse_decimal_literals_as_double** セッションプロパティは、マジックコメントとしてサポートされています。

明示的な型指定子を持たない10進リテラル(例: 1.2)は、デフォルトでDOUBLE型の値として扱われます。

このマジックコメントを使用すると、この動作を無効化し、10進リテラルをDECIMAL型の値として使用できます。例:


```sql
-- set session parse_decimal_literals_as_double = 'false'
    SELECT typeof(1.1);
```

## Distributed_Sort

**distributed_sort** セッションプロパティは、マジックコメントとしてサポートされています。

分散ソートを使用すると、`query.max-memory-per-node`を超えるデータのソートが可能になります。分散ソートは、`distributed_sort`セッションプロパティ、またはコーディネーターの`etc/config.properties`に設定された`distributed-sort`設定プロパティを通じて有効化されます。分散ソートはデフォルトで有効になっています。

分散ソートが有効な場合、ソート演算子はクラスター内の複数のノードで並列実行されます。各ワーカーノードから部分的にソートされたデータは、最終的なマージのために単一のワーカーノードにストリーミングされます。この手法により、ソートのために複数のワーカーノードのメモリを活用できます。分散ソートの主な目的は、通常は単一ノードのメモリに収まらないデータセットのソートを可能にすることです。パフォーマンスの向上が期待できますが、データを単一ノードでマージする必要があるため、ノード数に対して線形にスケールすることはありません。


```sql
-- set session distributed_sort = 'true'
    SELECT * FROM large_table, small_table
    WHERE small_table.id = large_table.id
```

## time_partitioning_range

time_partitioning_rangeセッションプロパティは、マジックコメントとしてサポートされています。


```sql
-- 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の更新

## サイドバイサイド環境について

テストのため、Presto 0.205とPresto 317がサイドバイサイドで利用可能であり、アップグレード前にコードのテストが可能です。

## Presto 317とPresto 0.205でのコード実行

Presto 317とPresto 0.205からの移行期間中、2つのリリースがサイドバイサイドで利用可能です。

以下のクエリヒントを使用して、どのPrestoリリースでコードを実行するかを制御できます:

| **バージョン** | **クエリヒント** |
|  --- | --- |
| Presto 317 | `-- @TD engine_version: 317` |
| Presto 0.205 | `-- @TD engine_version: 0.205` |


# クエリ構文の修正

以前のバージョンで動作していたクエリを実行すると、エラーメッセージが発生する場合があります。各ケースについて、メッセージ、エラーを引き起こすクエリ、およびクエリの書き換え方法の例を示します。

## ORの述語が多すぎます。最大500個のORが許可されています

エラーの原因となる元のコード:


```sql
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';
```

エラーを修正したコード:


```sql
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

エラーの原因となる元のコード:


```sql
SELECT MAP(ARRAY [1, 3], ARRAY [2, 4])[5];
```

エラーを修正したコード:


```sql
SELECT element_at(MAP(ARRAY [1, 3], ARRAY [2, 4]), 5);
```

クエリを書き直すには、関数[element_at](https://trino.io/docs/423/functions/map.html)を使用できます。関数[element_at](https://trino.io/docs/423/functions/map.html)は、v0.205とv317の両方のクラスターバージョンでサポートされています。前述のクエリは両方のクラスターで実行できます。

## 

Array subscript out of bounds

エラーの原因となる元のコード:


```sql
SELECT
     numbers[99] -- key isn't exist
    FROM
     (VALUES (ARRAY[1,2,3]) ) AS t(numbers);
```

エラーを修正したコード:


```sql
SELECT
      element_at(numbers, 99) -- key isn't exist
    FROM
      (VALUES (ARRAY[1,2,3]) ) AS t(numbers);
```

関数[element_at](https://trino.io/docs/423/functions/array.html)は、v0.205とv317の両方のクラスターバージョンでサポートされています。

前述のクエリは両方のクラスターで実行できます。

## 

Column alias list has 1 entry but 't' has N columns available'

エラーの原因となる元のコード:


```sql
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;
```

エラーを修正したコード:


```sql
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

エラーの原因となる元のコード:


```sql
SELECT
      UPPER(DISTINCT(id)) AS user_id
    FROM (VALUES ('foo'), ('bar')) AS t(id);
```

エラーを修正したコード:


```sql
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;
```

エラーを修正したコード:


```sql
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](https://trino.io/docs/423/functions/map.html)は、両方のクラスターバージョン、v0.205とv317でサポートされています。上記のクエリは両方のクラスターで実行されます。

### このエラーの詳細: array_agg関数の動作変更

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`というメッセージを返します。

## 'XXX' must be an aggregate expression or appear in a GROUP BY clause

エラーを引き起こす元のコード:


```sql
SELECT code FROM sample_datasets.www_access
    HAVING code IS NOT NULL;
```

エラーを修正したコード:


```sql
SELECT code FROM sample_datasets.www_access
    WHERE code IS NOT NULL;
```

HAVING句をWHERE句として使用すると、このエラーが表示されます。

## 

Zero-length delimited identifier not allowed

エラーを引き起こす元のコード:


```sql
SELECT 1 AS "";
```

エラーを修正したコード:


```sql
SELECT 1 AS "A";
```

## Unexpected parameters (char(1)) for function codepoint. Expected: codepoint(varchar(1))

エラーを引き起こす元のコード:


```sql
SELECT codepoint(CAST('a' AS CHAR));
```

エラーを修正したコード:


```sql
SELECT codepoint(CAST('a' AS VARCHAR(1)));
```

## Invalid format: "XXX" is malformed / Invalid timezone: "XXX" is malformed

v317ではエラー処理が改善されました。無効な引数が渡された場合、現在のPrestoはNULLを返しますが、新しいPrestoはエラーを返します。

エラーを引き起こす元のコード:


```sql
SELECT td_time_range(1567890000, 'yyyy-MM-dd','JST', NULL);
```

エラーを修正したコード:


```sql
SELECT td_time_range(1567890000, '2019-09-08', 'JST', NULL);
```