Skip to content

Perda de precisão em inteiros grandes (SqlValue: int64 -> double) #47

Description

@Gabriel-Pereira1788

Status: ⬜ Não iniciado
Prioridade: P3 (robustez, não bloqueia MVP)
Área: C++ (core)
Relacionado a: TASK-007 (#8) — encontrado durante a investigação/implementação daquela issue, mas deliberadamente deixado fora de escopo por mudar um contrato mais amplo.

Descrição

SQLiteConnection::execute (cpp/database/SQLiteConnection.cpp) lê toda coluna SQLITE_INTEGER via sqlite3_column_int64 e converte pra double antes de colocar em SqlValue (std::variant<nitro::NullType, bool, std::shared_ptr<ArrayBuffer>, std::string, double>):

case SQLITE_INTEGER: {
  ...
  row.emplace_back(static_cast<double>(intVal));
  ...
}

double só representa inteiros exatamente até 2^53 (Number.MAX_SAFE_INTEGER no JS). Um valor de coluna integer acima disso (ex: um ID grande, um timestamp em nanossegundos, etc.) perde precisão silenciosamente ao cruzar a fronteira JSI — o valor que chega no JS não é o mesmo que foi gravado no SQLite (que internamente guarda int64 de verdade).

datetime (epoch millis) está seguro no intervalo prático de datas por bastante tempo (~1.7e12 hoje, teto seguro é ~9e15), então não é urgente — mas colunas integer genéricas (chaves primárias, contadores, etc.) não têm essa garantia.

Por que não foi resolvido junto com a TASK-007

SqlValue é o tipo usado por toda leitura de coluna do core, não só pelo Query Executor — mudar isso é uma mudança de contrato mais ampla (provavelmente exige mudar src/specs/types/SqlValue.ts também, e decidir como representar inteiros de 64 bits no lado JS: BigInt? Manter number e documentar o limite? Adicionar um tipo integer explícito no SqlValue?). Não é algo que os critérios de aceite da TASK-007 pediam.

Possíveis abordagens (não decidido)

  • Expor int64 como BigInt no lado JS quando o valor excede Number.MAX_SAFE_INTEGER, mantendo number pros demais casos (custo: SqlValue no TS passa a aceitar bigint, toda a stack de tipos/inferência de TASK-013 precisa saber disso).
  • Documentar o limite de 2^53 como uma restrição conhecida do MVP e não mudar nada agora (custo: usuários com PKs/IDs grandes vão ter bugs silenciosos).
  • Alguma combinação: manter number como padrão, mas oferecer um jeito explícito de ler uma coluna como "big integer" quando necessário.

Critérios de aceite (sugeridos, a validar)

  • Decisão de design registrada (provavelmente em docs/query-layer.md) sobre como inteiros acima de 2^53 são representados do lado JS.
  • SqlValue (C++ e TS) atualizado conforme a decisão.
  • Teste cobrindo um valor de coluna integer acima de 2^53 ida-e-volta sem perda de precisão (ou documentando explicitamente o comportamento escolhido, se a decisão for "não suportar").

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions