The database driver currently supports unnamed parameters (?) and named parameters (:AAAA, @AAAA, $AAAA). However, there is a missing feature for positional parameters with indexes (?NNN) that has been asked for by many users (see issues).
Initially, based on comments indicating that positional parameters with indexes were not supported, I assumed this meant they were not supported at all on the server side. The Hrana protocol seemed to lack distinction for positional arguments with indexes, unlike named arguments. Furthermore, the code check positionalParametersOffset+positionalParamsCount > len(queryParams.positional) suggested the same.
As a result, my first attempt involved having the client unpack queries with positional parameters with indexes into regular positional parameters.
query: "select * from x where y = ?2 and z = ?1" args: "a, b"
becomes...
query: select * from x where y = ? and z = ? args: "b, a"
However, upon investigating the libsql codebase, I discovered that the server already supported positional parameters with indexes, as evidenced by the following code:
More over the WebSocket driver implementation does not have the same checks that the HTTP driver implementation does and therefore while manually testing with sqld could see that positional parameter with indexes already worked for the WebSocket variant.
Solution
This meant that what had to be done was to just update the http implementation to allow positional parameters with indexes and adjust the code accordingly to maintain existing behavior.
Tests were added for both WebSocket and HTTP variants.
Problem
The database driver currently supports unnamed parameters (?) and named parameters (:AAAA, @AAAA, $AAAA). However, there is a missing feature for positional parameters with indexes (?NNN) that has been asked for by many users (see issues).
This PR solves the following issues:
Fixes https://github.com/tursodatabase/libsql-client-go/issues/100 Fixes https://github.com/tursodatabase/libsql-client-go/issues/106
Context
Initially, based on comments indicating that positional parameters with indexes were not supported, I assumed this meant they were not supported at all on the server side. The Hrana protocol seemed to lack distinction for positional arguments with indexes, unlike named arguments. Furthermore, the code check
positionalParametersOffset+positionalParamsCount > len(queryParams.positional)
suggested the same.As a result, my first attempt involved having the client unpack queries with positional parameters with indexes into regular positional parameters.
query: "select * from x where y = ?2 and z = ?1" args: "a, b"
becomes...
query: select * from x where y = ? and z = ? args: "b, a"
However, upon investigating the libsql codebase, I discovered that the server already supported positional parameters with indexes, as evidenced by the following code:
https://github.com/tursodatabase/libsql/blob/cb89097a577a34b05a300732b26c95764c1d6c66/libsql/src/params.rs#L40
https://github.com/tursodatabase/libsql/blob/cb89097a577a34b05a300732b26c95764c1d6c66/libsql/examples/example.rs#L25
More over the WebSocket driver implementation does not have the same checks that the HTTP driver implementation does and therefore while manually testing with sqld could see that positional parameter with indexes already worked for the WebSocket variant.
Solution
This meant that what had to be done was to just update the http implementation to allow positional parameters with indexes and adjust the code accordingly to maintain existing behavior.
Tests were added for both WebSocket and HTTP variants.