Repository navigation
Fix PostgreSQL native queries other than SELECT failing with server-side cursor - #8
Open
maharanay22 wants to merge 1 commit into
Open
maharanay22 wants to merge 1 commit into
maharanay22 wants to merge 1 commit into
Conversation
|
All contributors have signed the CLA ✍️ ✅ |
Author
|
I have read the CLA Document and I hereby sign the CLA |
…ide cursor Since the data streaming change, native queries are run through a server-side cursor (DECLARE ... CURSOR FOR <query>). PostgreSQL only accepts SELECT and VALUES there, so UPDATE, DELETE, CREATE, ALTER, TRUNCATE, SHOW, EXPLAIN and similar statements failed with 'syntax error at or near "UPDATE"'. Only INSERT and DROP were retried on the client side, based on the error text. Fall back to a client side cursor whenever DECLARE rejects the statement with SyntaxError or FeatureNotSupported. DECLARE rejects the statement before running it, so running it again is safe. Also return an empty result for 'SELECT * FROM db (<statement>)' when the handler answers with OkResponse, instead of failing with "'OkResponse' object has no attribute 'data_frame'".
maharanay22
force-pushed
the
fix-postgres-native-query-cursor
branch
from
October 13, 2026 15:57
85526d8 to
5f176aa
Compare
Author
|
@lucas-koontz could you take a look at this and #9 to #14 when you have time? They are small connector fixes, all green |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Since 26.1.0, native queries to a PostgreSQL integration fail for anything that isn't a plain SELECT. For example,
SELECT * FROM pg (UPDATE demo SET status = 'done' WHERE id = 1)returns:The same happens for DELETE, CREATE, ALTER, TRUNCATE, SHOW, EXPLAIN and data-modifying CTEs. Before 26.1.0, native queries didn't go through a server-side cursor
Repro: connect a PostgreSQL database with
CREATE DATABASE pg WITH ENGINE = 'postgres', PARAMETERS = {...}, then run any of the queries above throughSELECT * FROM pg (...)Root cause: the data streaming change (#12018 in the old repo) runs every native query through a psycopg server-side cursor, which sends
DECLARE ... CURSOR FOR <query>. PostgreSQL only accepts SELECT and VALUES in a cursor. There was a fallback to a client side cursor, but it only kicked in when the error text started withsyntax error at or near "insert"or"drop"The fix falls back to the client side cursor whenever DECLARE fails with
SyntaxErrororFeatureNotSupported(the error PostgreSQL raises forWITH x AS (UPDATE ...) SELECT ...), and drops the error text matching. DECLARE rejects the statement before running it, so running it again on the client side doesn't apply anything twice. I went with this over checking the first keyword up front because the server is the only reliable judge here: a keyword check gets comments, parentheses,SELECT ... INTOandWITHwith UPDATE wrong. Other errors such as a missing table are still returned right away without a retry, and SELECT queries still stream through the server-side cursorOnce the handler ran these statements, they still failed one step later with
'OkResponse' object has no attribute 'data_frame'. This happened becauseFetchDataframeStepCallexpected a table forSELECT * FROM db (...). It now returns an empty result for anOkResponse, which matches how the pre-26.1.0 code handled responses without a table (from reading the code, I didn't run 26.0.1). DROP TABLE hit this error even before the change, since it already went through the old fallbackI used an AI assistant to help investigate this and draft the change and tests, and I reviewed and tested it myself
Fixes: no issue to link, because issues are disabled on this repo. The bug is described above
Type of change
Verification Process
To ensure the changes are working as expected:
tests/unit/handlers/test_postgres.py,tests/unit/executor/test_executor.py, and a local MindsDB (python -m mindsdb --api http) on top of a real PostgreSQL 16.2 serverPOST /api/sql/query, once onmainand once on this branchBefore (main):
After (this branch):
I also called
PostgresHandler.native_querydirectly against the same server. A data-modifying CTE that increments a counter ran exactly once (max(w)is 1 afterwards), SELECT still streams, and an invalid query still returns its syntax error:The new unit tests fail on main (8 subtests in
test_native_query_stream_falls_back_to_client_side_when_cursor_is_not_allowed, plustest_integration_native_query_without_result) and pass on this branchAdditional Media:
Checklist: