From fef0817dbb0d0fa36a4fce47449b0f07d5ba1754 Mon Sep 17 00:00:00 2001 From: jkaczman Date: Mon, 24 Aug 2026 17:04:12 -0400 Subject: [PATCH 1/3] refactor(query_parser_engine): deprecation warning for explicit set to 'pg_query_protobuf'; remove references in pgdog --- pgdog-config/src/core.rs | 4 +++ pgdog-config/src/sharding.rs | 8 ++--- pgdog/src/backend/pool/cluster.rs | 13 ++------ .../non_identity_columns_presence.rs | 2 -- .../logical/publisher/publisher_impl.rs | 30 ++++--------------- .../replication/logical/publisher/table.rs | 23 +++----------- .../replication/logical/subscriber/context.rs | 2 -- .../replication/logical/subscriber/tests.rs | 7 ----- pgdog/src/frontend/router/parser/cache/ast.rs | 6 ---- 9 files changed, 20 insertions(+), 75 deletions(-) diff --git a/pgdog-config/src/core.rs b/pgdog-config/src/core.rs index 491cd974..70db1a0b 100644 --- a/pgdog-config/src/core.rs +++ b/pgdog-config/src/core.rs @@ -627,6 +627,10 @@ impl Config { ); } + if !raw_query_parser { + warn!(r#""query_parser_engine" is deprecated and uses the "pg_query_raw" option now"#) + } + if !self.sharded_mappings.is_empty() { warn!( "`[[sharded_mappings]]` config is deprecated, use `[[sharded_tables.mapping]]` instead" diff --git a/pgdog-config/src/sharding.rs b/pgdog-config/src/sharding.rs index 94091da7..bc0ec1c3 100644 --- a/pgdog-config/src/sharding.rs +++ b/pgdog-config/src/sharding.rs @@ -473,10 +473,10 @@ pub enum QueryParserLevel { #[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash, Default, JsonSchema)] #[serde(rename_all = "snake_case", deny_unknown_fields)] pub enum QueryParserEngine { - /// Use the protobuf parse tree from `pg_query` (default). - #[default] + /// Use the protobuf parse tree from `pg_query`. PgQueryProtobuf, - /// Use the raw JSON parse tree from `pg_query`. + /// Use the raw JSON parse tree from `pg_query` (default). + #[default] PgQueryRaw, } @@ -727,7 +727,7 @@ database = "production" assert_eq!(config.query_parsers[0].level, QueryParserLevel::Auto); assert_eq!( config.query_parsers[0].engine, - QueryParserEngine::PgQueryProtobuf + QueryParserEngine::PgQueryRaw ); } } diff --git a/pgdog/src/backend/pool/cluster.rs b/pgdog/src/backend/pool/cluster.rs index 7e0f7bfe..d0f3e10f 100644 --- a/pgdog/src/backend/pool/cluster.rs +++ b/pgdog/src/backend/pool/cluster.rs @@ -3,8 +3,8 @@ use futures::future::try_join_all; use parking_lot::Mutex; use pgdog_config::{ - LoadSchema, PreparedStatements, QueryParser, QueryParserEngine, QueryParserLevel, Rewrite, - RewriteMode, users::PasswordKind, + LoadSchema, PreparedStatements, QueryParser, QueryParserLevel, Rewrite, RewriteMode, + users::PasswordKind, }; use std::{sync::Arc, time::Duration}; @@ -68,7 +68,6 @@ pub struct Cluster { expanded_explain: bool, query_parser: QueryParserLevel, client_connection_recovery: ConnectionRecovery, - query_parser_engine: QueryParserEngine, log_min_duration_parse: Option, log_query_sample_length: usize, reload_schema_on_ddl: bool, @@ -118,7 +117,6 @@ impl Default for Cluster { expanded_explain: Default::default(), query_parser: Default::default(), client_connection_recovery: Default::default(), - query_parser_engine: Default::default(), log_min_duration_parse: Default::default(), log_query_sample_length: Default::default(), reload_schema_on_ddl: Default::default(), @@ -150,8 +148,6 @@ pub struct ShardingSchema { pub schemas: ShardedSchemas, /// Rewrite config. pub rewrite: Rewrite, - /// Query parser engine. - pub query_parser_engine: QueryParserEngine, pub log_min_duration_parse: Option, pub log_query_sample_length: usize, } @@ -206,7 +202,6 @@ pub struct ClusterConfig<'a> { dry_run: bool, expanded_explain: bool, query_parser: QueryParserLevel, - query_parser_engine: QueryParserEngine, log_min_duration_parse: Option, log_query_sample_length: usize, client_connection_recovery: ConnectionRecovery, @@ -276,7 +271,6 @@ impl<'a> ClusterConfig<'a> { dry_run: general.dry_run, expanded_explain: general.expanded_explain, query_parser: query_parser.level, - query_parser_engine: query_parser.engine, log_min_duration_parse: general.log_min_duration_parse(), log_query_sample_length: general.log_query_sample_length, client_connection_recovery: general.client_connection_recovery, @@ -327,7 +321,6 @@ impl Cluster { query_parser, client_connection_recovery, lsn_check_interval, - query_parser_engine, log_min_duration_parse, log_query_sample_length, reload_schema_on_ddl, @@ -396,7 +389,6 @@ impl Cluster { expanded_explain, query_parser, client_connection_recovery, - query_parser_engine, log_min_duration_parse, log_query_sample_length, reload_schema_on_ddl, @@ -615,7 +607,6 @@ impl Cluster { tables: self.sharded_tables.clone(), schemas: self.sharded_schemas.clone(), rewrite: self.rewrite.clone(), - query_parser_engine: self.query_parser_engine, log_min_duration_parse: self.log_min_duration_parse, log_query_sample_length: self.log_query_sample_length, } diff --git a/pgdog/src/backend/replication/logical/publisher/non_identity_columns_presence.rs b/pgdog/src/backend/replication/logical/publisher/non_identity_columns_presence.rs index 04cfe3f0..5773ae6e 100644 --- a/pgdog/src/backend/replication/logical/publisher/non_identity_columns_presence.rs +++ b/pgdog/src/backend/replication/logical/publisher/non_identity_columns_presence.rs @@ -96,7 +96,6 @@ mod test { use crate::net::messages::replication::logical::tuple_data::{ TupleData, text_col, toasted_col, }; - use pgdog_config::QueryParserEngine; use pgdog_postgres_types::Oid; fn make_table(columns: Vec<(&str, bool)>) -> Table { @@ -124,7 +123,6 @@ mod test { }) .collect(), lsn: Lsn::default(), - query_parser_engine: QueryParserEngine::default(), } } diff --git a/pgdog/src/backend/replication/logical/publisher/publisher_impl.rs b/pgdog/src/backend/replication/logical/publisher/publisher_impl.rs index 9d16d213..837490c1 100644 --- a/pgdog/src/backend/replication/logical/publisher/publisher_impl.rs +++ b/pgdog/src/backend/replication/logical/publisher/publisher_impl.rs @@ -4,7 +4,6 @@ use std::time::Duration; use futures::stream::{FuturesUnordered, StreamExt}; use parking_lot::Mutex; -use pgdog_config::QueryParserEngine; use tokio::select; use tokio::task::JoinHandle; use tokio::time::Instant; @@ -51,8 +50,6 @@ pub struct Publisher { tables: HashMap>, /// Replication slots. slots: HashMap, - /// Query parser engine. - query_parser_engine: QueryParserEngine, /// Replication lag. replication_lag: Arc>>, /// Last transaction. @@ -62,16 +59,11 @@ pub struct Publisher { } impl Publisher { - pub fn new( - publication: &str, - query_parser_engine: QueryParserEngine, - slot_name: String, - ) -> Self { + pub fn new(publication: &str, slot_name: String) -> Self { Self { publication: publication.to_string(), tables: HashMap::new(), slots: HashMap::new(), - query_parser_engine, replication_lag: Arc::new(Mutex::new(HashMap::new())), last_transaction: Arc::new(Mutex::new(None)), slot_name, @@ -126,8 +118,7 @@ impl Publisher { for (number, shard) in source.shards().iter().enumerate() { // Load tables from publication. let mut primary = shard.primary(&Request::default()).await?; - let tables = - Table::load(&self.publication, &mut primary, self.query_parser_engine).await?; + let tables = Table::load(&self.publication, &mut primary).await?; // For data sync, split omni tables evenly between shards. if data_sync { @@ -562,7 +553,6 @@ mod test { identity: true, }], lsn: Lsn::from_i64(lsn), - query_parser_engine: QueryParserEngine::default(), } } @@ -594,7 +584,7 @@ mod test { fn distribute_omnisharded_tables_initializes_missing_shards() { let config = config(); let cluster = Cluster::new_test(&config); - let mut publisher = Publisher::new("test", QueryParserEngine::default(), "slot".into()); + let mut publisher = Publisher::new("test", "slot".into()); let table = make_table("public", "omni_only", 0); publisher.distribute_omnisharded_tables(HashMap::from([(table.key(), table)]), &cluster); @@ -638,11 +628,7 @@ mod test { source.launch(); let dest = Cluster::new_test(&config()); - let mut publisher = Publisher::new( - "publication_no_pk_validation", - QueryParserEngine::default(), - "sync_test_slot".into(), - ); + let mut publisher = Publisher::new("publication_no_pk_validation", "sync_test_slot".into()); // Validation must fire before the copy begins. let result = publisher @@ -700,11 +686,8 @@ mod test { source.launch(); let dest = Cluster::new_test(&config()); - let mut publisher = Publisher::new( - "publication_sync_only_no_pk", - QueryParserEngine::default(), - "sync_only_no_pk_slot".into(), - ); + let mut publisher = + Publisher::new("publication_sync_only_no_pk", "sync_only_no_pk_slot".into()); let cancel = CancellationToken::new(); cancel.cancel(); @@ -752,7 +735,6 @@ mod test { let mut publisher = Publisher::new( "pub_full_identity_nothing_test", - QueryParserEngine::default(), "pub_full_identity_nothing_slot".into(), ); diff --git a/pgdog/src/backend/replication/logical/publisher/table.rs b/pgdog/src/backend/replication/logical/publisher/table.rs index 77de017c..091ca3b8 100644 --- a/pgdog/src/backend/replication/logical/publisher/table.rs +++ b/pgdog/src/backend/replication/logical/publisher/table.rs @@ -2,7 +2,6 @@ use std::time::Duration; -use pgdog_config::QueryParserEngine; use tokio::select; use tracing::error; @@ -38,8 +37,6 @@ pub struct Table { pub columns: Vec, /// Table data as of this LSN. pub lsn: Lsn, - /// Query parser engine. - pub query_parser_engine: QueryParserEngine, } /// An enumerated view over a subset of a table's columns. @@ -141,11 +138,7 @@ where } impl Table { - pub async fn load( - publication: &str, - server: &mut Server, - query_parser_engine: QueryParserEngine, - ) -> Result, Error> { + pub async fn load(publication: &str, server: &mut Server) -> Result, Error> { let tables = PublicationTable::load(publication, server).await?; let mut results = vec![]; @@ -159,7 +152,6 @@ impl Table { identity, columns, lsn: Lsn::default(), - query_parser_engine, }); } @@ -526,7 +518,6 @@ mod test { }; use pg_raw_parse::parse; - use crate::config::config; use crate::net::messages::replication::logical::tuple_data::{ TupleData, text_col, toasted_col, }; @@ -558,7 +549,6 @@ mod test { }) .collect(), lsn: Lsn::default(), - query_parser_engine: QueryParserEngine::default(), } } @@ -834,13 +824,9 @@ mod test { crate::logger(); let mut publication = setup_publication().await; - let tables = Table::load( - "publication_test", - &mut publication.server, - config().config.general.query_parser_engine, - ) - .await - .unwrap(); + let tables = Table::load("publication_test", &mut publication.server) + .await + .unwrap(); assert_eq!(tables.len(), 2); @@ -878,7 +864,6 @@ mod test { identity, columns, lsn: Lsn::default(), - query_parser_engine: QueryParserEngine::default(), } } diff --git a/pgdog/src/backend/replication/logical/subscriber/context.rs b/pgdog/src/backend/replication/logical/subscriber/context.rs index de0f7791..17add18a 100644 --- a/pgdog/src/backend/replication/logical/subscriber/context.rs +++ b/pgdog/src/backend/replication/logical/subscriber/context.rs @@ -112,7 +112,6 @@ mod test { Column, Identifier, TupleData, text_col, toasted_col, }, }; - use pgdog_config::QueryParserEngine; use pgdog_postgres_types::{Format, Oid}; use super::*; @@ -142,7 +141,6 @@ mod test { }) .collect(), lsn: Default::default(), - query_parser_engine: QueryParserEngine::default(), } } diff --git a/pgdog/src/backend/replication/logical/subscriber/tests.rs b/pgdog/src/backend/replication/logical/subscriber/tests.rs index 1d7f012e..1545593a 100644 --- a/pgdog/src/backend/replication/logical/subscriber/tests.rs +++ b/pgdog/src/backend/replication/logical/subscriber/tests.rs @@ -1,5 +1,4 @@ use bytes::Bytes; -use pgdog_config::QueryParserEngine; use pgdog_postgres_types::Oid; use rand::Rng; @@ -79,7 +78,6 @@ fn make_sharded_table() -> Table { }, ], lsn: Lsn::default(), - query_parser_engine: QueryParserEngine::default(), } } @@ -113,7 +111,6 @@ fn make_sharded_test_b_table() -> Table { }, ], lsn: Lsn::default(), - query_parser_engine: QueryParserEngine::default(), } } @@ -907,7 +904,6 @@ fn make_posts_table() -> Table { }, ], lsn: Lsn::default(), - query_parser_engine: QueryParserEngine::default(), } } @@ -1284,7 +1280,6 @@ fn make_full_identity_sharded_table() -> Table { }, ], lsn: Lsn::default(), - query_parser_engine: QueryParserEngine::default(), } } @@ -1327,7 +1322,6 @@ fn make_full_identity_omni_table() -> Table { }, ], lsn: Lsn::default(), - query_parser_engine: QueryParserEngine::default(), } } @@ -2259,7 +2253,6 @@ fn make_settings_table() -> Table { }, ], lsn: Lsn::default(), - query_parser_engine: pgdog_config::QueryParserEngine::default(), } } diff --git a/pgdog/src/frontend/router/parser/cache/ast.rs b/pgdog/src/frontend/router/parser/cache/ast.rs index 5c2465dd..92578df6 100644 --- a/pgdog/src/frontend/router/parser/cache/ast.rs +++ b/pgdog/src/frontend/router/parser/cache/ast.rs @@ -1,5 +1,4 @@ use pg_raw_parse::{Node, Owned, StmtList, make}; -use pgdog_config::QueryParserEngine; use std::fmt::Debug; use std::ops::Deref; use std::time::Instant; @@ -28,8 +27,6 @@ pub struct Ast { pub comment_shard: Option, /// Role. pub comment_role: Option, - /// Parser query engine used. - pub query_parser_engine: QueryParserEngine, /// Sharding Key. pub comment_sharding_key: Option, /// Inner sync. @@ -120,7 +117,6 @@ impl Ast { cached: true, comment_shard: None, comment_role: None, - query_parser_engine: schema.query_parser_engine, comment_sharding_key: None, inner: Arc::new(AstInner { stats: Mutex::new(stats), @@ -156,7 +152,6 @@ impl Ast { comment_role: None, comment_shard: None, comment_sharding_key: None, - query_parser_engine: QueryParserEngine::default(), inner: Arc::new(AstInner::new(ast.into_inner())), }) } @@ -167,7 +162,6 @@ impl Ast { cached: true, comment_role: None, comment_shard: None, - query_parser_engine: QueryParserEngine::default(), comment_sharding_key: None, inner: Arc::new(AstInner::new(stmts)), } From 25e19c10bf292e91a472edc1c61711f4a4d0d560 Mon Sep 17 00:00:00 2001 From: jkaczman Date: Mon, 24 Aug 2026 17:09:33 -0400 Subject: [PATCH 2/3] fix: missed a removal --- .../src/backend/replication/logical/orchestrator.rs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/pgdog/src/backend/replication/logical/orchestrator.rs b/pgdog/src/backend/replication/logical/orchestrator.rs index a4a0d782..bd8121e3 100644 --- a/pgdog/src/backend/replication/logical/orchestrator.rs +++ b/pgdog/src/backend/replication/logical/orchestrator.rs @@ -79,11 +79,7 @@ impl Orchestrator { /// Replace the publisher entirely (discards LSN state). Only valid /// when starting a fresh replication phase, e.g. after cutover. fn refresh_publisher(&mut self) { - let publisher = Publisher::new( - &self.publication, - config().config.general.query_parser_engine, - self.replication_slot.clone(), - ); + let publisher = Publisher::new(&self.publication, self.replication_slot.clone()); self.publisher = Arc::new(Mutex::new(publisher)); } @@ -562,11 +558,7 @@ mod tests { let cluster = Cluster::new_test(config); let publication = "test_pub".to_owned(); let replication_slot = "test_slot".to_owned(); - let publisher = Publisher::new( - &publication, - config.config.general.query_parser_engine, - replication_slot.clone(), - ); + let publisher = Publisher::new(&publication, replication_slot.clone()); Self { source: cluster.clone(), destination: cluster, From cdd1f7c71f20bac3d415b8f59ff4c17daccb7740 Mon Sep 17 00:00:00 2001 From: jkaczman Date: Mon, 24 Aug 2026 17:16:37 -0400 Subject: [PATCH 3/3] fix: json schema update --- .schema/pgdog.schema.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.schema/pgdog.schema.json b/.schema/pgdog.schema.json index a6a6c124..f5008bad 100644 --- a/.schema/pgdog.schema.json +++ b/.schema/pgdog.schema.json @@ -92,7 +92,7 @@ "query_log_stdout": false, "query_parser": "auto", "query_parser_enabled": false, - "query_parser_engine": "pg_query_protobuf", + "query_parser_engine": "pg_query_raw", "query_size_limit": null, "query_size_limit_action": "warn", "query_timeout": 9223372036854775807, @@ -1094,7 +1094,7 @@ "query_parser_engine": { "description": "Underlying parser implementation used to analyze SQL queries.", "$ref": "#/$defs/QueryParserEngine", - "default": "pg_query_protobuf" + "default": "pg_query_raw" }, "query_size_limit": { "description": "Maximum size, in bytes, of a query message (`Query` or `Parse`)\nreceived from a client, including the 5-byte message header.\nProtects the query parser from very large SQL texts; other\nprotocol messages (e.g. `Bind`, `CopyData`) are not affected.\nDepending on the setting `query_size_limit_action` oversized messages are\neither logged or blocked.\n\n_Default:_ `None` (disabled)\n\n", @@ -1740,7 +1740,7 @@ "engine": { "description": "Query parser engine used.", "$ref": "#/$defs/QueryParserEngine", - "default": "pg_query_protobuf" + "default": "pg_query_raw" }, "level": { "description": "Query parser level.", @@ -1757,12 +1757,12 @@ "description": "Underlying parser implementation used to analyze SQL queries.", "oneOf": [ { - "description": "Use the protobuf parse tree from `pg_query` (default).", + "description": "Use the protobuf parse tree from `pg_query`.", "type": "string", "const": "pg_query_protobuf" }, { - "description": "Use the raw JSON parse tree from `pg_query`.", + "description": "Use the raw JSON parse tree from `pg_query` (default).", "type": "string", "const": "pg_query_raw" }