Skip to content

feat: Initial prepare statement support for Postgres protocol#925

Merged
sunng87 merged 17 commits intoGreptimeTeam:developfrom
sunng87:feature/describe-statement
Feb 6, 2023
Merged

feat: Initial prepare statement support for Postgres protocol#925
sunng87 merged 17 commits intoGreptimeTeam:developfrom
sunng87:feature/describe-statement

Conversation

@sunng87
Copy link
Copy Markdown
Member

@sunng87 sunng87 commented Feb 1, 2023

I hereby agree to the terms of the GreptimeDB CLA

What's changed and what's your intention?

This is a proof-of-concept implementation of prepare statement for our postgres protocol adapter. In prepared statement, or extended query as in postgres, it follows a parse-bind-describe-execute process to run a query:

  • prepared statement are provided in parse phase, as well as type information of its parameters
  • in bind phase, the value of parameters are provided
  • describe request asks for schema of result set
  • and execute request actually run the query

When statement is cached in server-side, parse and describe can be omitted.

In order to support this process, we need a new ability to get schema out of a query statement without executing it. This implementation relies on datafusion's LogicalPlan to get schema. Parameter types are added into PlannerContext to make it work.

Limitations

  1. We'd better cache LogicalPlan and use its with_param_values for parameters replacement. And we also need a solution for parameter replacement on INSERT/DELETE/UPDATE
  2. More postgres types need to be supported, especially those date/time types. The current encoding of timestamp is not compatible with psycopg3 and jdbc. This needs to be corrected in next patch.
  3. rust-postgres compatibility: rust-postgres' query implementation doesn't include parameter type while datafusion requires types when there is placeholders in sql.

Checklist

  • I have written the necessary rustdoc comments.
  • I have added the necessary unit tests and integration tests.

Refer to a related PR or issue link (optional)

@sunng87 sunng87 force-pushed the feature/describe-statement branch 2 times, most recently from 88cd051 to 0f060a5 Compare February 1, 2023 14:14
@sunng87 sunng87 marked this pull request as ready for review February 1, 2023 14:15
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 2, 2023

Codecov Report

Merging #925 (88dca59) into develop (b0925d9) will decrease coverage by 0.19%.
The diff coverage is 53.30%.

@@             Coverage Diff             @@
##           develop     #925      +/-   ##
===========================================
- Coverage    85.88%   85.70%   -0.19%     
===========================================
  Files          443      443              
  Lines        59202    59427     +225     
===========================================
+ Hits         50848    50932      +84     
- Misses        8354     8495     +141     
Flag Coverage Δ
rust 85.70% <53.30%> (-0.19%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/datanode/src/instance/sql.rs 73.55% <0.00%> (-2.52%) ⬇️
src/frontend/src/error.rs 11.11% <0.00%> (-0.21%) ⬇️
src/frontend/src/instance.rs 69.23% <0.00%> (-0.39%) ⬇️
src/frontend/src/instance/distributed.rs 88.10% <0.00%> (-1.24%) ⬇️
src/frontend/src/instance/standalone.rs 61.70% <0.00%> (-7.35%) ⬇️
src/query/src/error.rs 36.36% <0.00%> (-1.74%) ⬇️
src/query/src/query_engine.rs 100.00% <ø> (ø)
src/servers/src/error.rs 43.10% <0.00%> (-0.76%) ⬇️
src/servers/src/http.rs 76.59% <0.00%> (-1.29%) ⬇️
src/servers/src/query_handler/sql.rs 36.53% <0.00%> (-4.77%) ⬇️
... and 18 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@sunng87 sunng87 marked this pull request as draft February 2, 2023 05:33
@sunng87 sunng87 marked this pull request as ready for review February 2, 2023 08:55
Comment thread src/datanode/src/error.rs Outdated
Comment thread src/servers/src/postgres/handler.rs Outdated
Comment thread src/servers/src/postgres/handler.rs
Comment thread src/servers/src/postgres/handler.rs
Comment thread src/servers/src/postgres/handler.rs
@MichaelScofield
Copy link
Copy Markdown
Collaborator

I have some doubts whether defining do_describe in SqlQueryHandler is a good idea. It seems to me that "describe" is only limited to pg, if we are to impl "prepare" feature in MySQL, can we reuse the "descirbe"? On the other hand, "describe" sits between the "parse sql" phase and "execute stmt" phase, if only we could restrict SqlQueryHandler to only execute stmt, we may achieve much cleaner code structure -- image how various Java dialects (eg scalar and kotlin) running in JVM.

@sunng87
Copy link
Copy Markdown
Member Author

sunng87 commented Feb 2, 2023

Mysql implementation won't use this API because its protocol combines column definition with its first batch of results.

If we remove do_describe from SqlQueryHandler, postgres server will need a reference to QueryEngine. I'm not sure if this will break our layered API design. (And do we really have a layered design here?)

Actually when implementing this, I feel there is increased need for QueryEngine access from both mysql and postgres server. Datafusion uses LogicalPlan for parameterized query, so for performance consideration, we'd better cache LogicalPlan instead of Statement as prepared query statement in both protocols. And if we do that, access to statement_to_plan in server tier is required as well.

@MichaelScofield
Copy link
Copy Markdown
Collaborator

@sunng87 I have a feeling that the problem roots in the lack of some abstraction regards to "prepare" stmt of pg and mysql in SqlQueryHandler. Currently I do not have any clear thoughts on this, can you leave a todo for me at do_describe in SqlQueryHandler? Just refer to this issue, thx. I'll revisit this problem when implementing mysql's "prepare".

@sunng87 sunng87 enabled auto-merge (squash) February 3, 2023 07:59
Comment thread Cargo.lock Outdated
Comment thread src/query/src/datafusion.rs Outdated
@sunng87 sunng87 force-pushed the feature/describe-statement branch 3 times, most recently from 7ef5b4c to 88dca59 Compare February 6, 2023 11:01
Copy link
Copy Markdown
Member

@waynexia waynexia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@sunng87 sunng87 merged commit 4ae63b7 into GreptimeTeam:develop Feb 6, 2023
paomian pushed a commit to paomian/greptimedb that referenced this pull request Oct 19, 2023
…meTeam#925)

* feat: add describe statement to query_engine

* feat: add ability to describe statement for sql handler

* refactor: return schema instead of wrapped ref

* test: resolve tests

* feat: add initial support for prepared statements

* feat: add parameter types to query statement

* test: fix parser test

* chore: add todo task

* fix: turn on integer_datetime for binary timestamp

* fix: format string using single quote

* test: add tests for prepared statement

* Apply suggestions from code review

Co-authored-by: LFC <bayinamine@gmail.com>

* refactor: use stream api from recordbatches

---------

Co-authored-by: LFC <bayinamine@gmail.com>
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.

3 participants