-
Notifications
You must be signed in to change notification settings - Fork 129
Fix server crash when EXPLAINing a prepared statement #660
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
Conversation
58db8d3
to
f1f3604
Compare
Custom Scan (DuckDBScan) (cost=0.00..0.00 rows=0 width=0) | ||
Output: duckdb_scan.explain_key, duckdb_scan.explain_value | ||
Output: duckdb_scan."Count" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is nice additional benefit of this change. The VERBOSE flag now actually lists the columns that the scan returns. For INSERT statements this isn't actually true though, because in postgres those don't return a column at all.
src/pgduckdb_planner.cpp
Outdated
Query *copied_query = (Query *)copyObjectImpl(query); | ||
const char *query_string = pgduckdb_get_querydef(copied_query); | ||
|
||
if (ActivePortal && ActivePortal->commandTag == CMDTAG_EXPLAIN) { | ||
if (allow_explain && ActivePortal && ActivePortal->commandTag == CMDTAG_EXPLAIN) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should't the condition be:
if (allow_explain && ActivePortal && ActivePortal->commandTag == CMDTAG_EXPLAIN) { | |
if (ActivePortal && ActivePortal->commandTag == CMDTAG_EXPLAIN) { | |
if (!allow_explain) { | |
elog(ERROR, ...); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No it shouldn't, but I totally agree that the argument name suggested that. Instead of renaming it I moved the logic outside of DuckdbPrepare
function now.
With a specific query order it was possible that Postgres would cache the plan for the EXPLAINed version of a query instead of the plan for the actual query. This fixes that by only ever adding EXPLAIN to a query when actually executing the query, not also when only planning it. This way the plan that will be cached is always the actual query plan, but at execution time that might be changed in case the query is EXPLAINed.
f1f3604
to
305b227
Compare
assert "Total Time:" in plan | ||
# The insert should have been executed exactly once | ||
assert cur.sql("SELECT * FROM test_table ORDER BY id") == [1, 2, 3, 4, 5] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is currently failing on main...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat! Thanks!
With a specific query order it was possible that Postgres would cache the plan for the EXPLAINed version of a query instead of the plan for the actual query. This fixes that by only ever adding EXPLAIN to a query when actually executing the query, not also when only planning it. This way the plan that will be cached is always the actual query plan, but at execution time that might be changed in case the query is EXPLAINed.
This also fixes two bugs involving EXPLAIN ANALYZE:
Fixes #410