Skip to content

Instantly share code, notes, and snippets.

@Comamoca
Created October 31, 2025 07:35
Show Gist options
  • Save Comamoca/4cb071cca33a0ccfd2ae5bb637203242 to your computer and use it in GitHub Desktop.
Save Comamoca/4cb071cca33a0ccfd2ae5bb637203242 to your computer and use it in GitHub Desktop.
Deno issue draft: node:sqlite numbered positional parameters (?1, ?2) not supported

node:sqlite: Numbered positional parameters (?1, ?2) are not supported

Description

Deno's node:sqlite implementation does not support numbered positional parameters like ?1, ?2, etc. This causes a "column index out of range" error when using this SQLite parameter syntax, which is a deviation from Node.js behavior and standard SQLite functionality.

Environment

  • Deno version: 2.2.0+ (tested on latest)
  • Platform: Linux
  • Related Node.js version: v24.7.0+ (where this works correctly)

Reproduction

import { DatabaseSync } from 'node:sqlite';

const db = new DatabaseSync(':memory:');

db.exec(`
  CREATE TABLE users (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    email TEXT NOT NULL
  )
`);

// This fails in Deno but works in Node.js
const stmt = db.prepare('INSERT INTO users (name, email) VALUES (?1, ?2)');
stmt.run('Alice', '[email protected]');

Error in Deno

error: Uncaught (in promise) Error: column index out of range
stmt.run('Alice', '[email protected]');
     ^

Success in Node.js (v24.7.0+)

✓ Data inserted successfully

Current Workarounds

In Deno, you must use one of these alternatives:

  1. Implicit positional parameters (recommended for Deno):
const stmt = db.prepare('INSERT INTO users (name, email) VALUES (?, ?)');
stmt.run('Alice', '[email protected]'); // ✓ Works
  1. Named parameters:
const stmt = db.prepare('INSERT INTO users (name, email) VALUES (:name, :email)');
stmt.run({ name: 'Alice', email: '[email protected]' }); // ✓ Works
  1. Dollar-sign named parameters:
const stmt = db.prepare('INSERT INTO users (name, email) VALUES ($name, $email)');
stmt.run({ $name: 'Alice', $email: '[email protected]' }); // ✓ Works

Expected Behavior

Numbered positional parameters (?1, ?2, etc.) should be bound positionally, just like implicit ? parameters. This is the standard SQLite behavior and is supported in:

  • Node.js v24.7.0+ (fixed in nodejs/node#59350)
  • Python's sqlite3 module
  • Other SQLite implementations

Comparison with Node.js

Node.js had the same issue (nodejs/node#59340) but fixed it in v24.7.0 via PR #59350. The fix allows ?NNN parameters to be bound positionally:

// Node.js v24.7.0+
stmt.run(value1, value2, value3); // Binds to ?1, ?2, ?3 respectively

Additional Context

This issue affects compatibility with existing SQLite code and documentation that uses numbered positional parameters. Many SQLite tutorials and examples use ?1, ?2 syntax for clarity when the same parameter is referenced multiple times:

SELECT * FROM users WHERE id = ?1 OR parent_id = ?1

Related Issues/PRs

  • Deno #28134: Named parameters support (fixed in #28154)
  • Node.js #59340: Same issue in Node.js (fixed in #59350)

Suggested Solution

Implement support for numbered positional parameters (?NNN) in ext/node/ops/sqlite/statement.rs, similar to how Node.js handles them after PR #59350. The binding logic should recognize ?NNN patterns and bind them positionally when arguments are provided as a list rather than an object.

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