Тип INTEGER в React native expo SQLite ограничен 4 байтами? - PullRequest
0 голосов
/ 16 декабря 2018

При попытке вставить целое число со знаком, равное 4 байтам - 1 бит (т. Е. 2 ​​^ 31, т. Е. 2147483648), я получаю условие переполнения целочисленного значения (т. Е. Оно преобразуется в -2147483648).

Документы sqliteсостояние типа INTEGER поддерживает целое число со знаком длиной до 8 байтов: https://www.sqlite.org/datatype3.html Кроме того, значения выше 8 байтов - 1 бит - 1 вызывают исключение.Так что это приводит к мысли, что это ошибка, связанная с экспозицией / реагированием.Это известная ошибка в Экспо / реакции-родной / что-то еще?Я не смог найти , откуда ExponentSQLite идет от .Также обратите внимание, что 2147483648 намного ниже javascript MAX_SAFE_INTEGER, поэтому, возможно, в коде Android параметры преобразуются в 4-байтовое целое число со знаком.

import { SQLite } from 'expo'

async function main() {
  const db = SQLite.openDatabase('mydb')

  await exec_sql({ db, sql: `DROP TABLE IF EXISTS table_name;` })
  await exec_sql({ db, sql: `CREATE TABLE table_name (id INTEGER PRIMARY KEY, created_at INTEGER NOT NULL);` })
  await exec_sql({ db, sql: `INSERT INTO table_name (created_at) VALUES (?);`, parameters: [Math.pow(2, (8 * 4) - 1) - 1] })
  await exec_sql({ db, sql: `INSERT INTO table_name (created_at) VALUES (?);`, parameters: [Math.pow(2, (8 * 4) - 1)] })

  await exec_sql({ db, sql: `INSERT INTO table_name (created_at) VALUES (9223372036854775000);`, parameters: [] })
  // set to 9223372036854775000 as javascript Number.MAX_SAFE_INTEGER means `Math.pow(2, (8 * 8) - 1) - 1`
  // is rounded higher to 9223372036854776000
  await exec_sql({ db, sql: `INSERT INTO table_name (created_at) VALUES (?);`, parameters: [9223372036854775000] })

// This will error with
  // Error in callNativeModules()
  // Over flow during conversion: 9223372036854776000 (rounding up due to javascript's Number.MAX_SAFE_INTEGER)
  // await exec_sql({ db, sql: `INSERT INTO table_name (created_at) VALUES (?);`, parameters: [Math.pow(2, (8 * 8) - 1)] })
  await exec_sql({ db, sql: `SELECT * FROM table_name;` })
}

main()

function exec_sql ({ db, sql, parameters = [] }) {
  return new Promise((resolve, reject) => {
    db.transaction(tx => {
      console.debug(`Executing ${sql} with parameters: ${parameters}`)
      tx.executeSql(sql, parameters,
        (_, result) => {
          console.debug(`Have result: ${JSON.stringify(result)}`)
          if (result && result.rows && result.rows._array) {
            resolve({ items: result.rows._array })
          } else {
            resolve()
          }
        },
        (_, err) => {
          console.error(`Error during executing sql: `, err)
          reject(err)
        }
      )
    })
  })
}

Это приведет к (отредактировано для краткости):

Executing CREATE TABLE IF NOT EXISTS table_name (id INTEGER PRIMARY KEY, created_at INTEGER NOT NULL); with parameters: 
Executing INSERT INTO table_name (created_at) VALUES (?); with parameters: 2147483647
Executing INSERT INTO table_name (created_at) VALUES (?); with parameters: 2147483648
Executing INSERT INTO table_name (created_at) VALUES (9223372036854775000); with parameters: 
Executing INSERT INTO table_name (created_at) VALUES (?); with parameters: 9223372036854775000
Executing SELECT * FROM table_name; with parameters: 
Have result: [{"id": 1, "created_at": 2147483647}, {"id": 2, "created_at": -2147483648}, {"id": 3, "created_at": -808},{"id": 4, "created_at": -1024}]

PRAGMA user_version -> 0 PRAGMA schema_version -> 46 выставочная версия -> 31.0.2

* Изменить 1 *

Я подалошибка, давайте посмотрим, что ответит: https://github.com/expo/expo/issues/3000

1 Ответ

0 голосов
/ 05 февраля 2019

Это была ошибка.Исправлено: https://github.com/expo/expo/pull/3005

...