Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support extended protocol and prepared statements #147

Merged
merged 13 commits into from
Sep 23, 2024
Merged

Conversation

JelteF
Copy link
Collaborator

@JelteF JelteF commented Aug 22, 2024

Previously prepared statements and the extended protocol were broken. We need to support this feature because pretty much every client library uses it. The reason that prepared statements did not work is that for prepared statements to work, a Postgres plan needs to be fully copyable using Postgres functionality. We were previously storing the DuckDB plan in the Postgres plan, but since Postgres did not know how to copy the DuckDB plan it would fail.

To work around that problem we now store the full Postgres Query structure inside the DuckDB CustomScan node. Then during execution we use this Query structure to re-plan the query during execution. This works but it has the big downside that we're now planning the query twice in DuckDB, once during planning to get the the column types of the result and once during execution. For now that seems acceptable, so we can at least support prepared statements and the extended protocol. In the future we might want to do something smarter though, like serializing and deserializing the DuckDB plan that is created at planning time.

Note: This does not support all our supported types as arguments to a prepared statement yet. After merging I'll open separate issue to track adding the rest of these types.

Fixes #118

@JelteF JelteF force-pushed the duckdb-singleton branch 2 times, most recently from 3bdc96b to 98376a1 Compare August 22, 2024 16:29
src/pgduckdb_duckdb.cpp Outdated Show resolved Hide resolved
@JelteF JelteF changed the title Make DuckDB a connection singleton to support extended protocol Make DuckDB connection a singleton to support extended protocol Aug 23, 2024
@JelteF JelteF requested review from Tishj and mkaruza August 23, 2024 16:21
case FLOAT8OID: {
return duckdb::Value::DOUBLE(DatumGetFloat8(value));
}
// case duckdb::LogicalTypeId::DECIMAL: {
Copy link
Collaborator Author

@JelteF JelteF Aug 23, 2024

Choose a reason for hiding this comment

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

As you can see there's a few types that we support in other places that I didn't implement here yet. Also if you look at the added tests you'll see that there are a bunch of issues with floats and string arguments for some reason not working as expected in comparisons.

In my opinion it's important to support them and fix those errors, but I don't think it necessarily needs to be part of this PR. This PR is already a bit larger than I'd like it to be. So I'd rather merge this soonish if we're happy with the general design, and then fix the remaining issues in follow up PRs. Especially since making DuckDB a singleton is a significant change in architecture that I feel would benefit from early use by developers to find bugs.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This function is only used for binding? Maybe rename it, also we don't need to have commented out what is not supported (probably ticket should be created at this point).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I renamed the function a bit and removed the commented out code. After we merge this I'll create a ticket to track support for the other types.

src/pgduckdb_planner.cpp Outdated Show resolved Hide resolved
@JelteF JelteF requested a review from Y-- August 23, 2024 16:38
Y--
Y-- previously approved these changes Aug 27, 2024
Copy link
Collaborator

@Y-- Y-- left a comment

Choose a reason for hiding this comment

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

Overall LGTM, thanks for picking up! Would like to hear what other thinks too cc @Tishj @mkaruza

src/pgduckdb_node.cpp Outdated Show resolved Hide resolved
src/pgduckdb_node.cpp Outdated Show resolved Hide resolved
src/pgduckdb_types.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@mkaruza mkaruza left a comment

Choose a reason for hiding this comment

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

Personally i would like to see this PR split int two parts. One is which enabled singleton duckdb object and another that deals with binding.

src/pgduckdb_duckdb.cpp Outdated Show resolved Hide resolved
case FLOAT8OID: {
return duckdb::Value::DOUBLE(DatumGetFloat8(value));
}
// case duckdb::LogicalTypeId::DECIMAL: {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This function is only used for binding? Maybe rename it, also we don't need to have commented out what is not supported (probably ticket should be created at this point).

@JelteF JelteF force-pushed the duckdb-singleton branch 2 times, most recently from 2136ffe to 7a5087a Compare September 12, 2024 11:27
@JelteF JelteF mentioned this pull request Sep 12, 2024
@JelteF JelteF changed the base branch from main to duckdb-singleton-only September 12, 2024 11:55
JelteF added a commit that referenced this pull request Sep 12, 2024
Based on work by @Y-- and PR #102 and #147. This basically extracts the
work from there into a separate PR, so it can be merged before some of
the open TODOs related to prepared statements/extended protocol are
resolved.

Co-authored-by: Y. <[email protected]>
Base automatically changed from duckdb-singleton-only to main September 12, 2024 13:42
@JelteF JelteF dismissed Y--’s stale review September 12, 2024 13:42

The base branch was changed.

@@ -2,7 +2,7 @@


def test_explain(cur: Cursor):
cur.sql("CREATE TABLE test_table (id int primary key, name text)")
cur.sql("CREATE TABLE test_table (id int, name text)")
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I needed to change this definition to not create an index because index scans are currently broken, see #183 for details.

@JelteF JelteF mentioned this pull request Sep 17, 2024
@JelteF JelteF changed the title Make DuckDB connection a singleton to support extended protocol Support extended protocol and prepared statements Sep 17, 2024
@wuputah wuputah added this to the 0.1.0 milestone Sep 17, 2024
@JelteF JelteF changed the base branch from main to str-filter-op September 19, 2024 15:55
@JelteF JelteF requested a review from mkaruza September 19, 2024 15:55
@JelteF JelteF merged commit 007d882 into main Sep 23, 2024
3 checks passed
@JelteF JelteF deleted the duckdb-singleton branch September 23, 2024 07:06
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.

Error with extended query protocol
4 participants