// Flags: --allow-natives-syntax
'use strict';
const { skipIfSQLiteMissing } = require('../common');
skipIfSQLiteMissing();
const assert = require('node:assert');
const { Database } = require('node:sqlite');
const { suite, test } = require('node:test');
function assertSharedShape(rows) {
for (const row of rows) {
assert.strictEqual(Object.getPrototypeOf(row), null);
assert(eval('%HasFastProperties(row)'));
assert(eval('%HaveSameMap(row, rows[0])'));
}
}
suite('result row objects', () => {
const db = new Database(':memory:');
db.exec('CREATE TABLE t (a INTEGER, b TEXT, c REAL)');
const insert = db.prepare('INSERT INTO t VALUES (?, ?, ?)');
insert.run(1, 'x', 1.5);
insert.run(2, 'y', 2.5);
insert.run(3, null, null);
test('all() rows share a fast map', () => {
const rows = db.prepare('SELECT * FROM t ORDER BY a').all();
assert.deepStrictEqual(rows, [
{ __proto__: null, a: 1, b: 'x', c: 1.5 },
{ __proto__: null, a: 2, b: 'y', c: 2.5 },
{ __proto__: null, a: 3, b: null, c: null },
]);
assertSharedShape(rows);
});
test('get() rows share a fast map', () => {
const stmt = db.prepare('SELECT * FROM t WHERE a = ?');
assertSharedShape([stmt.get(1), stmt.get(2), stmt.get(3)]);
});
test('iterate() rows share a fast map', () => {
assertSharedShape(db.prepare('SELECT * FROM t ORDER BY a').iterate().toArray());
});
test('a re-prepared statement picks up the new columns', () => {
using db = new Database(':memory:');
db.exec('CREATE TABLE s (a INTEGER)');
db.exec('INSERT INTO s VALUES (1)');
const stmt = db.prepare('SELECT * FROM s');
assert.deepStrictEqual(stmt.get(), { __proto__: null, a: 1 });
db.exec('ALTER TABLE s ADD COLUMN b INTEGER DEFAULT 2');
assert.deepStrictEqual(stmt.get(), { __proto__: null, a: 1, b: 2 });
});
test('array-index column names', () => {
const stmt = db.prepare('SELECT 1 AS "0", 2 AS b');
assert.deepStrictEqual(stmt.get(), { __proto__: null, 0: 1, b: 2 });
assert.deepStrictEqual(stmt.all(), [{ __proto__: null, 0: 1, b: 2 }]);
});
test('duplicate column names keep the last value', () => {
const stmt = db.prepare('SELECT 1 AS a, 2 AS a');
assert.deepStrictEqual(stmt.get(), { __proto__: null, a: 2 });
assert.deepStrictEqual(stmt.iterate().toArray(),
[{ __proto__: null, a: 2 }]);
});
test('non-ASCII column names', () => {
const row = db.prepare('SELECT 1 AS "café", 2 AS "名前"').get();
assert.deepStrictEqual(row, { __proto__: null, café: 1, 名前: 2 });
});
test('rows wider than the template limit', () => {
const cols = Array.from({ length: 100 }, (_, i) => `${i} AS c${i}`);
const row = db.prepare(`SELECT ${cols.join(', ')}`).get();
const expected = { __proto__: null };
for (let i = 0; i < 100; i++) expected[`c${i}`] = i;
assert.deepStrictEqual(row, expected);
});
});