Dlaczego agregacja okna w trybie wsadowym powoduje przepełnienie arytmetyczne?

11

Poniższe zapytanie wykonuje SUMokno nad tabelą magazynu kolumn 1500 total rows, z których każda ma wartość 0 lub 1, i przepełnia INTtyp danych. Dlaczego to się dzieje?

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.

Pełny skrypt

Zobacz ten plik, aby uzyskać w pełni zawarty skrypt do odtwarzania.

Plan zapytań

Oto szacowany plan zapytań z adnotacjami ( pełny kod XML na temat Wklej plan ).

wprowadź opis zdjęcia tutaj

Podobne zapytania, które zostały wykonane pomyślnie

W przypadku wprowadzenia dowolnej z poniższych modyfikacji błąd nie występuje:

  • Użyj flagi śledzenia, 8649aby preferować plan równoległy, niezależnie od progu kosztów dla równoległości
  • Użyj flagi śledzenia, 9453aby wyłączyć tryb wsadowy
  • Użyj COUNTfunkcji agregacji zamiast SUMfunkcji
  • Usuń WHERE x.rank = 1predykat

Na przykład to zapytanie wykonuje się pomyślnie:

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 */) 
Geoff Patterson
źródło

Odpowiedzi:

6

Wielu komentujących udało się odtworzyć ten problem. Początkowo myśleliśmy, że SQL Server 2017 CU10 rozwiązał problem, ale potem stwierdziliśmy, że błąd można odtworzyć we wszystkich wersjach SQL Server, które wypróbowaliśmy, w tym CU10. Jednak niektórzy komentatorzy zauważyli przypadek, w którym ten sam skrypt nie zawsze wyzwalał błąd.

Ponieważ nie ma logicznego sposobu, aby obliczenie sumy w zbiorze liczb nieujemnych, których maksymalna możliwa suma wynosi 1500, mogło przepełnić 32-bitową liczbę całkowitą, uważamy, że jest to błąd w operatorze agregacji okien w trybie wsadowym. Będąc nowym operatorem w SQL Server 2016, można założyć, że nadal mogą istnieć pewne przypadki krawędzi do rozwiązania.

Oto raport o błędzie, który złożyliśmy w Microsoft.

Odpowiedź brzmiała:

Zostało to naprawione w programie SQL Server 2019 CTP 2.1, a wkrótce zostanie również naprawione w bazie danych Azure SQL.

Geoff Patterson
źródło