次のクエリは、ウィンドウストアされたSUM
を1500 total rows
の列ストアテーブルに対して実行します。それぞれの値は0または1であり、INT
データ型をオーバーフローします。なぜこうなった?
SELECT a, p, s, v, m, n,
SUM(CASE WHEN n IS NULL THEN 0 ELSE 1 END)
OVER (PARTITION BY s, v, a ORDER BY p) AS lastNonNullPartition
FROM (
SELECT a, p, s, v, m, n,
RANK() OVER (PARTITION BY v, s, a, p ORDER BY m) AS rank
FROM #t /* A columnstore table with 1,500 rows */
) x
WHERE x.rank = 1
--Msg 8115, Level 16, State 2, Line 1521
--Arithmetic overflow error converting expression to data type int.
完全なスクリプト
完全に含まれている再現スクリプトについては、このファイルを参照してください。
クエリプラン
これは、注釈付きの推定クエリプランです( プランの貼り付けの完全なXML )。
正常に実行される同様のクエリ
次のいずれかの変更が行われた場合、エラーは発生しません。
8649
を使用して、並列処理のコストしきい値に関係なく並列プランを優先します9453
を使用してバッチモードを無効にするCOUNT
関数の代わりにSUM
集約関数を使用するWHERE x.rank = 1
述語を削除するたとえば、次のクエリは正常に実行されます。
SELECT a, p, s, v, m, n,
SUM(CASE WHEN n IS NULL THEN 0 ELSE 1 END)
OVER (PARTITION BY s, v, a ORDER BY p) AS lastNonNullPartition
FROM (
SELECT a, p, s, v, m, n,
RANK() OVER (PARTITION BY v, s, a, p ORDER BY m) AS rank
FROM #t /* A columnstore table with 1,500 rows */
) x
WHERE x.rank = 1
OPTION (QUERYTRACEON 9453/* Disable batch mode */)
複数のコメント者がこの問題を再現できました。 SQL Server 2017 CU10で問題が解決したと当初は考えていましたが、CU10を含め、試行したすべてのバージョンのSQL Serverでエラーを再現できることがわかりました。ただし、一部のコメンターは、同じスクリプトが常にエラーをトリガーするとは限らない可能性のある要素を観察しました。
最大の合計が1,500である非負の数値のセット全体で合計を計算することが32ビット整数をオーバーフローする可能性がある論理的な方法がないため、これはバッチモードのウィンドウ集約演算子のバグであると考えられます。 SQL Server 2016の新しいオペレーターであるため、解決すべきEdgeのケースがまだある可能性があると想定するのは合理的です。
応答は:
これはSQL Server 2019 CTP 2.1で修正され、Azure SQL Databaseでもまもなく修正される予定です。