Skip to content

Support prepared statements and parameters#21

Draft
vhiairrassary wants to merge 1 commit intoQuery-farm:mainfrom
vhiairrassary:vhiairrassary/support-bind-variables
Draft

Support prepared statements and parameters#21
vhiairrassary wants to merge 1 commit intoQuery-farm:mainfrom
vhiairrassary:vhiairrassary/support-bind-variables

Conversation

@vhiairrassary
Copy link
Copy Markdown
Collaborator

@vhiairrassary vhiairrassary commented Dec 15, 2024

Hello,

I need to support untrusted inputs so I have created this PR as a starting point to see if you would be interested to have this feature merged upstream, and if yes, to discuss about the details.

How it works

  • If there is no parameter then execution did not change
  • If there is at least one parameter then I prepare a statement, extract the named values (this PoC does not support positional parameters, but it can be easily done. As a personal note I find them confusing, and even saw they are a syntactic sugar for named parameters under the hood) and execute the prepared statement

How to test it

It can be tested using:

make

DUCKDB_HTTPSERVER_DEBUG=1 \
DUCKDB_HTTPSERVER_FOREGROUND=1 \
duckdb -unsigned \
  -c "FORCE INSTALL httpserver FROM './build/release/repository';" \
  -c "LOAD httpserver;" \
  -c "SELECT 890;" \
  -c "SELECT httpserve_start('0.0.0.0', 4000, '');"

and

curl -X POST -d 'SELECT typeof($ABC), $abc, typeof($DEF), $def' -g 'http://localhost:4000?parameters={"abc":{"type":"TEXT","value":"7"},"def":{"type":"BOOLEAN","value":true}}'
# {"typeof($ABC)":"VARCHAR","$abc":"7","typeof($DEF)":"BOOLEAN","$def":"true"}

Questions/notes

  • I am relying on exceptions to split the code in separated functions and make it easier to read (see the refactored CheckAuthentication and ExtractFormat functions for example). They are not on the happy path and should not impact performances (assuming the database is not publicly available, which sounds reasonable)
  • I tried to follow what is done by Snowflake
  • For the PoC I expect the query's parameters to be a JSON string in the HTTP parameter parameter. This sounds weird and I would be happy to move all the parameters (format, query/q and parameters) inside a single JSON body. Wdyt? We could either:
    • keep the GET (with format and query/q), the POST (with format and query/q) and POST with a JSON body (with format and query/q and parameters)
    • or keep the GET as above and unify both POST with a JSON body (with format and query/q and parameters), but it would be a breaking change
  • I am not sure if I need to do something to drop the prepared statement (In SQL there is an explicit DEALLOCATE operation)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants