Por que a janela do modo em lote agregado gera estouro aritmético?

11

A consulta a seguir executa uma janela SUMsobre uma tabela columnstore com 1500 total rows, cada qual com o valor 0 ou 1, e excede o INTtipo de dados. Por que isso está acontecendo?

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.

Script completo

Consulte este arquivo para obter um script de reprodução completo.

Plano de consulta

Aqui está um plano de consulta estimado anotado ( XML completo em Colar o plano ).

insira a descrição da imagem aqui

Consultas semelhantes que são executadas com sucesso

Se alguma das seguintes modificações for feita, o erro não ocorrerá:

  • Use sinalizador de rastreamento 8649para preferir um plano paralelo, independentemente do limite de custo para paralelismo
  • Use o sinalizador de rastreamento 9453para desativar o modo em lote
  • Use a COUNTfunção de agregação em vez da SUMfunção
  • Remova o WHERE x.rank = 1predicado

Por exemplo, esta consulta é executada com sucesso:

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
fonte

Respostas:

6

Vários comentaristas conseguiram reproduzir esse problema. Inicialmente, pensamos que o CU10 do SQL Server 2017 resolveu o problema, mas descobrimos que o erro pode ser reproduzido em todas as versões do SQL Server que tentamos, incluindo o CU10. No entanto, alguns comentaristas observaram um elemento de chance em que o mesmo script nem sempre acionava o erro.

Como não há uma maneira lógica de calcular uma soma através de um conjunto de números não negativos cuja soma máxima possível é 1.500 pode exceder um número inteiro de 32 bits, acreditamos que esse seja um erro no operador agregado da janela no modo em lote. Sendo um novo operador no SQL Server 2016, é razoável supor que ainda possa haver alguns casos extremos a serem resolvidos.

Aqui está o relatório de bug que arquivamos na Microsoft.

A resposta foi:

Isso foi corrigido no SQL Server 2019 CTP 2.1 e também será corrigido em breve no Banco de Dados SQL do Azure.

Geoff Patterson
fonte