feat: implement PostgreSQL extended query protocol (Parse/Bind/Execute/Sync)#1141
Conversation
…tore When seek_to uses a relative or absolute time (e.g. '-15m') with enable_backfill_from_historical_store enabled, the query enters StreamingConcat mode which scans all historical MergeTree parts before streaming begins, causing the query to appear hung. This fix probes NativeLog first: if the streaming store still has the requested data, convert the time-based seek to a sequence-based seek and use QueryMode::Streaming, bypassing the expensive historical scan entirely. Falls back to existing StreamingConcat when the data has been compacted. Fixes timeplus-io#558
|
Hi @yokofly, Just following up on this PR. Could you please let me know if there is any feedback, review, or additional work needed from my side? I'd be happy to make any required changes or improvements. Thanks for your time and consideration. |
yokofly
left a comment
There was a problem hiding this comment.
I feel the implementation is too broad — there's a lot of behavior to get right across the full Parse → Bind → Execute → Sync flow, and without a concrete requirement driving the scope, it's hard for us to review and maintain. So let's hold on this one for now.
| if (upper_query.find("SET ") == 0) | ||
| { | ||
| message_transport->send( | ||
| PostgreSQLProtocol::Messaging::CommandComplete( | ||
| PostgreSQLProtocol::Messaging::CommandComplete::Command::SELECT, 0)); | ||
| return true; | ||
| } |
There was a problem hiding this comment.
Does SET unknown = 1 currently return fake success?
Since PG and Proton have different setting namespaces, no-oping every SET seems confusing.
Should we only no-op known PG bootstrap settings and let Proton settings like max_threads reach executeQuery()?
| case TypeIndex::Map: | ||
| return {ColumnType::JSONB, -1}; |
There was a problem hiding this comment.
have you verified the map<-> jsonB is work? can u add test cover?
This PR adds support for the PostgreSQL extended query protocol, which is needed for tools like DBeaver and pgAdmin to connect to Proton. Currently, the handler rejects all extended query messages (Parse, Bind, Describe, Execute, Sync, Close, Flush) with an error saying "proton doesn't support extended query mechanism". This means most modern PostgreSQL drivers and GUI tools fail on connect since they default to the extended query protocol for prepared statements and parameter binding.
The approach here is server-side parameter substitution — the client sends Parse/Bind with $1, $2 placeholders and parameter values, and we substitute them into the SQL before passing it to Proton's existing query engine. This way we get full client compatibility without any changes to the parser or interpreter. A new PreparedStatementManager handles the lifecycle of named and unnamed statements and portals.I also added interception for the various system queries that PG clients send on connect (pg_catalog, SET, SHOW server_version, SELECT version(), SELECT current_schema(), transaction commands, etc.) so that clients don't crash when they can't find system tables. The type mapping was expanded to cover Bool, DateTime, DateTime64, Enum, Map, Array, and large integer types.The parameter substitution is string-literal-aware (won't replace $1 inside single quotes) and escapes single quotes and backslashes to prevent SQL injection. Error handling follows the PG spec — after an error during extended query, all subsequent messages are skipped until a Sync message resets the pipeline.
"This is intentionally a compatibility layer — same approach CockroachDB used in their early PG wire support. Server-side substitution gives us 95% client compatibility with zero query engine changes. True prepared execution is a future enhancement."
Closes #225