tursodatabase / tursodatabase/libsql-js

Named arguments are not recognized (v0.5.20, v0.6.0-pre.18)

Open
#202 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
335
Forks
48
Avg merge
3d 2h
Merged PRs (30d)
3

Description

Named arguments are not being recognized by the library.

Started tryng this out in Node's REPL but wrote a small test suite to validate.

The integration-tests in the repo clearly show named arguments being used, for example:
https://github.com/tursodatabase/libsql-js/blob/f41d1babc528e5c4e5803d50184c0103f80bd435/integration-tests/tests/async.test.js#L101
But I have not been able to replicate this behaviour.

This is an example query:

SELECT * FROM plep LIMIT $limit

and running it with

// Synchronous DB
const statement = db.prepare(query);
const result = statement.get({ limit: 5 });

Fails with

 SqliteError: Hrana: 'cursor error: 'error at step 0: (error code: ARGS_INVALID) 'Arguments do not match SQL parameters: value for parameter $limit not found'''

This is the result summary of the entire test suite (ran using npx mocha ./libsql-test-args.js), and formatted as diff to show colors in GitHub:

  Params test
    Synchronous test
      Named args
-        1) .get(): SELECT * FROM plep LIMIT $limit
-        2) .run(): SELECT * FROM plep LIMIT $limit
-        3) .all(): SELECT * FROM plep LIMIT $limit
-        4) .get(): SELECT * FROM plep WHERE quantity = $q
-        5) .run(): SELECT * FROM plep WHERE quantity = $q
-        6) .all(): SELECT * FROM plep WHERE quantity = $q
-        7) .get(): SELECT * FROM plep WHERE quantity = $quantity
-        8) .run(): SELECT * FROM plep WHERE quantity = $quantity
-        9) .all(): SELECT * FROM plep WHERE quantity = $quantity
      Positional args
+        ✔ .get(): SELECT * FROM plep LIMIT ?
+        ✔ .run(): SELECT * FROM plep LIMIT ?
+        ✔ .all(): SELECT * FROM plep LIMIT ?
+        ✔ .get(): SELECT * FROM plep WHERE quantity = ?
+        ✔ .run(): SELECT * FROM plep WHERE quantity = ?
+        ✔ .all(): SELECT * FROM plep WHERE quantity = ?
+        ✔ .get(): SELECT * FROM plep WHERE quantity = ?
+        ✔ .run(): SELECT * FROM plep WHERE quantity = ?
+        ✔ .all(): SELECT * FROM plep WHERE quantity = ?


    Asynchronous test
      Named
-        10) .get(): SELECT * FROM plep LIMIT $limit
-        11) .run(): SELECT * FROM plep LIMIT $limit
-        12) .all(): SELECT * FROM plep LIMIT $limit
-        13) .get(): SELECT * FROM plep WHERE quantity = $q
-        14) .run(): SELECT * FROM plep WHERE quantity = $q
-        15) .all(): SELECT * FROM plep WHERE quantity = $q
-        16) .get(): SELECT * FROM plep WHERE quantity = $quantity
-        17) .run(): SELECT * FROM plep WHERE quantity = $quantity
-        18) .all(): SELECT * FROM plep WHERE quantity = $quantity
      Positional
+        ✔ .get(): SELECT * FROM plep LIMIT ?
+        ✔ .run(): SELECT * FROM plep LIMIT ?
+        ✔ .all(): SELECT * FROM plep LIMIT ?
+        ✔ .get(): SELECT * FROM plep WHERE quantity = ?
+        ✔ .run(): SELECT * FROM plep WHERE quantity = ?
+        ✔ .all(): SELECT * FROM plep WHERE quantity = ?
+        ✔ .get(): SELECT * FROM plep WHERE quantity = ?
+        ✔ .run(): SELECT * FROM plep WHERE quantity = ?
+        ✔ .all(): SELECT * FROM plep WHERE quantity = ?

Here is the full test suite

Test suite
const SyncDB = require('libsql');
// Change if using v0.5.20 or v0.6.0
const { Database: AsyncDB } = require('libsql/promise');
// const AsyncDB = require('libsql/promise');


const named_queries = [
	['SELECT * FROM plep LIMIT $limit', { limit: 5 }],
	['SELECT * FROM plep WHERE quantity = $q', { q: 5 }],
	['SELECT * FROM plep WHERE quantity = $quantity', { quantity: 5 }]
];

const positional_queries = [
	['SELECT * FROM plep LIMIT ?', [5]],
	['SELECT * FROM plep WHERE quantity = ?', [5]],
	['SELECT * FROM plep WHERE quantity = ?', [5]]
];

describe('Params test', () => {
	let syncDB;
	let asyncDB;

	beforeEach(() => {
		syncDB = new SyncDB('http://localhost:8080');
		asyncDB = new AsyncDB('http://localhost:8080');
	});

	describe('Synchronous test', () => {
		describe('Named args', () => {
			for(const [query, named_args] of named_queries) {
				it(`.get(): ${query}`, () => {
					const statement = syncDB.prepare(query);
					const result = statement.get(named_args);
				});

				it(`.run(): ${query}`, () => {
					const statement = syncDB.prepare(query);
					const result = statement.run(named_args);
				});

				it(`.all(): ${query}`, () => {
					const statement = syncDB.prepare(query);
					const result = statement.all(named_args);
				});
			}
		});

		describe('Positional args', () => {
			for(const [query, positional_args] of positional_queries) {
				it(`.get(): ${query}`, () => {
					const statement = syncDB.prepare(query);
					const result = statement.get(...positional_args);
				});

				it(`.run(): ${query}`, () => {
					const statement = syncDB.prepare(query);
					const result = statement.run(...positional_args);
				});

				it(`.all(): ${query}`, () => {
					const statement = syncDB.prepare(query);
					const result = statement.all(...positional_args);
				});
			};
		});
	});

	describe('Asynchronous test', () => {
		describe('Named', () => {
			for(const [query, named_args] of named_queries) {
				it(`.get(): ${query}`, async () => {
					const statement = await asyncDB.prepare(query);
					const result = await statement.get(named_args);
				});

				it(`.run(): ${query}`, async () => {
					const statement = await asyncDB.prepare(query);
					const result = await statement.run(named_args);
				});

				it(`.all(): ${query}`, async () => {
					const statement = await asyncDB.prepare(query);
					const result = await statement.all(named_args);
				});
			}
		});

		describe('Positional', () => {
			for(const [query, positional_args] of positional_queries) {
				it(`.get(): ${query}`, async () => {
					const statement = await asyncDB.prepare(query);
					const result = await statement.get(...positional_args);
				});

				it(`.run(): ${query}`, async () => {
					const statement = await asyncDB.prepare(query);
					const result = await statement.run(...positional_args);
				});

				it(`.all(): ${query}`, async () => {
					const statement = await asyncDB.prepare(query);
					const result = await statement.all(...positional_args);
				});
			};
		});
	});
});

As well as the full output:


  Params test
    Synchronous test
      Named args
        1) .get(): SELECT * FROM plep LIMIT $limit
        2) .run(): SELECT * FROM plep LIMIT $limit
        3) .all(): SELECT * FROM plep LIMIT $limit
        4) .get(): SELECT * FROM plep WHERE quantity = $q
        5) .run(): SELECT * FROM plep WHERE quantity = $q
        6) .all(): SELECT * FROM plep WHERE quantity = $q
        7) .get(): SELECT * FROM plep WHERE quantity = $quantity
        8) .run(): SELECT * FROM plep WHERE quantity = $quantity
        9) .all(): SELECT * FROM plep WHERE quantity = $quantity
      Positional args
        ✔ .get(): SELECT * FROM plep LIMIT ?
        ✔ .run(): SELECT * FROM plep LIMIT ?
        ✔ .all(): SELECT * FROM plep LIMIT ?
        ✔ .get(): SELECT * FROM plep WHERE quantity = ?
        ✔ .run(): SELECT * FROM plep WHERE quantity = ?
        ✔ .all(): SELECT * FROM plep WHERE quantity = ?
        ✔ .get(): SELECT * FROM plep WHERE quantity = ?
        ✔ .run(): SELECT * FROM plep WHERE quantity = ?
        ✔ .all(): SELECT * FROM plep WHERE quantity = ?
    Asynchronous test
      Named
        10) .get(): SELECT * FROM plep LIMIT $limit
        11) .run(): SELECT * FROM plep LIMIT $limit
        12) .all(): SELECT * FROM plep LIMIT $limit
        13) .get(): SELECT * FROM plep WHERE quantity = $q
        14) .run(): SELECT * FROM plep WHERE quantity = $q
        15) .all(): SELECT * FROM plep WHERE quantity = $q
        16) .get(): SELECT * FROM plep WHERE quantity = $quantity
        17) .run(): SELECT * FROM plep WHERE quantity = $quantity
        18) .all(): SELECT * FROM plep WHERE quantity = $quantity
      Positional
        ✔ .get(): SELECT * FROM plep LIMIT ?
        ✔ .run(): SELECT * FROM plep LIMIT ?
        ✔ .all(): SELECT * FROM plep LIMIT ?
        ✔ .get(): SELECT * FROM plep WHERE quantity = ?
        ✔ .run(): SELECT * FROM plep WHERE quantity = ?
        ✔ .all(): SELECT * FROM plep WHERE quantity = ?
        ✔ .get(): SELECT * FROM plep WHERE quantity = ?
        ✔ .run(): SELECT * FROM plep WHERE quantity = ?
        ✔ .all(): SELECT * FROM plep WHERE quantity = ?


  18 passing (9s)
  18 failing

  1) Params test
       Synchronous test
         Named args
           .get(): SELECT * FROM plep LIMIT $limit:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $limit not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.get (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:281:13)
      at Context.<anonymous> (libsql-test-args.js:30:31)
      at process.processImmediate (node:internal/timers:511:21)

  2) Params test
       Synchronous test
         Named args
           .run(): SELECT * FROM plep LIMIT $limit:
     SqliteError: Hrana: `stream error: `Error { message: "Arguments do not match SQL parameters: value for parameter $limit not found", code: "ARGS_INVALID" }``
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.run (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:268:13)
      at Context.<anonymous> (libsql-test-args.js:35:31)
      at process.processImmediate (node:internal/timers:511:21)

  3) Params test
       Synchronous test
         Named args
           .all(): SELECT * FROM plep LIMIT $limit:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $limit not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.all (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:321:13)
      at Context.<anonymous> (libsql-test-args.js:40:31)
      at process.processImmediate (node:internal/timers:511:21)

  4) Params test
       Synchronous test
         Named args
           .get(): SELECT * FROM plep WHERE quantity = $q:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $q not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.get (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:281:13)
      at Context.<anonymous> (libsql-test-args.js:30:31)
      at process.processImmediate (node:internal/timers:511:21)

  5) Params test
       Synchronous test
         Named args
           .run(): SELECT * FROM plep WHERE quantity = $q:
     SqliteError: Hrana: `stream error: `Error { message: "Arguments do not match SQL parameters: value for parameter $q not found", code: "ARGS_INVALID" }``
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.run (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:268:13)
      at Context.<anonymous> (libsql-test-args.js:35:31)
      at process.processImmediate (node:internal/timers:511:21)

  6) Params test
       Synchronous test
         Named args
           .all(): SELECT * FROM plep WHERE quantity = $q:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $q not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.all (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:321:13)
      at Context.<anonymous> (libsql-test-args.js:40:31)
      at process.processImmediate (node:internal/timers:511:21)

  7) Params test
       Synchronous test
         Named args
           .get(): SELECT * FROM plep WHERE quantity = $quantity:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $quantity not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.get (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:281:13)
      at Context.<anonymous> (libsql-test-args.js:30:31)
      at process.processImmediate (node:internal/timers:511:21)

  8) Params test
       Synchronous test
         Named args
           .run(): SELECT * FROM plep WHERE quantity = $quantity:
     SqliteError: Hrana: `stream error: `Error { message: "Arguments do not match SQL parameters: value for parameter $quantity not found", code: "ARGS_INVALID" }``
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.run (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:268:13)
      at Context.<anonymous> (libsql-test-args.js:35:31)
      at process.processImmediate (node:internal/timers:511:21)

  9) Params test
       Synchronous test
         Named args
           .all(): SELECT * FROM plep WHERE quantity = $quantity:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $quantity not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.all (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:321:13)
      at Context.<anonymous> (libsql-test-args.js:40:31)
      at process.processImmediate (node:internal/timers:511:21)

  10) Params test
       Asynchronous test
         Named
           .get(): SELECT * FROM plep LIMIT $limit:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $limit not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.get (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:281:13)
      at Context.<anonymous> (libsql-test-args.js:70:37)

  11) Params test
       Asynchronous test
         Named
           .run(): SELECT * FROM plep LIMIT $limit:
     SqliteError: Hrana: `stream error: `Error { message: "Arguments do not match SQL parameters: value for parameter $limit not found", code: "ARGS_INVALID" }``
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.run (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:268:13)
      at Context.<anonymous> (libsql-test-args.js:75:37)

  12) Params test
       Asynchronous test
         Named
           .all(): SELECT * FROM plep LIMIT $limit:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $limit not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.all (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:321:13)
      at Context.<anonymous> (libsql-test-args.js:80:37)

  13) Params test
       Asynchronous test
         Named
           .get(): SELECT * FROM plep WHERE quantity = $q:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $q not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.get (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:281:13)
      at Context.<anonymous> (libsql-test-args.js:70:37)

  14) Params test
       Asynchronous test
         Named
           .run(): SELECT * FROM plep WHERE quantity = $q:
     SqliteError: Hrana: `stream error: `Error { message: "Arguments do not match SQL parameters: value for parameter $q not found", code: "ARGS_INVALID" }``
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.run (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:268:13)
      at Context.<anonymous> (libsql-test-args.js:75:37)

  15) Params test
       Asynchronous test
         Named
           .all(): SELECT * FROM plep WHERE quantity = $q:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $q not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.all (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:321:13)
      at Context.<anonymous> (libsql-test-args.js:80:37)

  16) Params test
       Asynchronous test
         Named
           .get(): SELECT * FROM plep WHERE quantity = $quantity:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $quantity not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.get (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:281:13)
      at Context.<anonymous> (libsql-test-args.js:70:37)

  17) Params test
       Asynchronous test
         Named
           .run(): SELECT * FROM plep WHERE quantity = $quantity:
     SqliteError: Hrana: `stream error: `Error { message: "Arguments do not match SQL parameters: value for parameter $quantity not found", code: "ARGS_INVALID" }``
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.run (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:268:13)
      at Context.<anonymous> (libsql-test-args.js:75:37)

  18) Params test
       Asynchronous test
         Named
           .all(): SELECT * FROM plep WHERE quantity = $quantity:
     SqliteError: Hrana: `cursor error: `error at step 0: (error code: ARGS_INVALID) `Arguments do not match SQL parameters: value for parameter $quantity not found```
      at convertError (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:21:18)
      at Statement.all (/Users/jocolina/Weez/em/node_modules/libsql/compat.js:321:13)
      at Context.<anonymous> (libsql-test-args.js:80:37)


(Also interesting to note that the error for .all and .get is a cursor error but run is a stream error)

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the parameter-binding paths exercised by libsql-test-args.js and compare them with the named-argument examples in integration-tests/tests/async.test.js. Run npx mocha ./libsql-test-args.js; done means named parameters work for synchronous and asynchronous .get(), .run(), and .all() while positional cases continue to pass.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs, sqlite
Domain
api, databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.