fix: preserve effective query option SHOW across SQL protocols

Signed-off-by: discord9 <55937128+discord9@users.noreply.github.com>
This commit is contained in:
discord9
2026-10-09 17:45:27 +08:00
parent 813ed77571
commit 764940eff8
2 changed files with 105 additions and 2 deletions
+39 -1
View File
@@ -44,7 +44,7 @@ static SHOW_LOWER_CASE_PATTERN: Lazy<Regex> = Lazy::new(|| {
});
static SHOW_VARIABLES_LIKE_PATTERN: Lazy<Regex> = Lazy::new(|| {
Regex::new(&format!(
"(?i)^(SHOW {VARIABLES_SCOPE}VARIABLES( LIKE (.*))?)"
"(?i)^\\s*SHOW {VARIABLES_SCOPE}VARIABLES( LIKE (.*))?\\s*;?\\s*$"
))
.unwrap()
});
@@ -644,6 +644,44 @@ mod test {
test(query, expected);
}
#[test]
fn test_show_named_variables_reach_query_handler() {
let session = Arc::new(Session::new(None, Channel::Mysql, Default::default(), 0));
for query in [
"SHOW VARIABLES query.parallelism",
"SHOW VARIABLES datafusion.optimizer.prefer_hash_join",
"SHOW VARIABLES query.allow_query_fallback",
"SHOW VARIABLES query.enable_remote_dynamic_filter_pushdown",
"SHOW GLOBAL VARIABLES datafusion.optimizer.prefer_hash_join",
"SHOW SESSION VARIABLES query.parallelism",
"SHOW LOCAL VARIABLES query.allow_query_fallback",
" SHOW VARIABLES query.parallelism ",
"SHOW VARIABLES query.parallelism;",
] {
assert!(
check(query, QueryContext::arc(), session.clone()).is_none(),
"{query} should reach the query handler"
);
}
for query in [
"SHOW VARIABLES",
"SHOW VARIABLES;",
"SHOW GLOBAL VARIABLES",
"SHOW SESSION VARIABLES",
"SHOW LOCAL VARIABLES",
"SHOW GLOBAL VARIABLES LIKE 'event_scheduler'",
"SHOW SESSION VARIABLES LIKE 'event_scheduler'",
"SHOW LOCAL VARIABLES LIKE 'event_scheduler'",
] {
assert!(
check(query, QueryContext::arc(), session.clone()).is_some(),
"{query} should retain federated compatibility handling"
);
}
}
#[test]
fn test_show_warnings() {
// Test SHOW WARNINGS with no warnings
+66 -1
View File
@@ -84,7 +84,7 @@ impl SimpleQueryHandler for PostgresServerHandlerInner {
let query = if let Ok(statements) = &parsed_query {
statements
.iter()
.map(|s| s.to_string())
.map(statement_to_query)
.collect::<Vec<_>>()
.join(";")
} else {
@@ -119,6 +119,24 @@ impl SimpleQueryHandler for PostgresServerHandlerInner {
}
}
fn statement_to_query(statement: &SqlParserStatement) -> String {
if let SqlParserStatement::ShowVariable { variable } = statement
&& variable.len() > 1
&& (variable[0].value.eq_ignore_ascii_case("query")
|| variable[0].value.eq_ignore_ascii_case("datafusion"))
{
return format!(
"SHOW {}",
variable
.iter()
.map(ToString::to_string)
.collect::<Vec<_>>()
.join(".")
);
}
statement.to_string()
}
async fn send_warning_opt<C>(client: &mut C, query_context: QueryContextRef) -> PgWireResult<()>
where
C: Sink<PgWireBackendMessage> + Unpin + Send + Sync,
@@ -772,6 +790,53 @@ mod tests {
use super::*;
#[test]
fn test_dotted_show_query_options() {
for (sql, expected) in [
("SHOW QUERY.PARALLELISM", "SHOW QUERY.PARALLELISM"),
(
"SHOW query.allow_query_fallback",
"SHOW query.allow_query_fallback",
),
(
"SHOW datafusion.optimizer.enable_dynamic_filter_pushdown",
"SHOW datafusion.optimizer.enable_dynamic_filter_pushdown",
),
(
"SET query.parallelism = 2; SHOW query.parallelism",
"SET query.parallelism = 2;SHOW query.parallelism",
),
(
"/* comment */ SHOW query.parallelism",
"SHOW query.parallelism",
),
(
"SHOW \"query\".\"allow_query_fallback\"",
"SHOW \"query\".\"allow_query_fallback\"",
),
] {
let actual = PostgresCompatibilityParser::new()
.parse(sql)
.unwrap()
.iter()
.map(statement_to_query)
.collect::<Vec<_>>()
.join(";");
assert_eq!(actual, expected, "for SQL: {sql}");
}
}
#[test]
fn test_other_postgres_show_serialization_is_unchanged() {
for sql in ["SHOW ordinary_variable", "SHOW search_path"] {
let statement = PostgresCompatibilityParser::new()
.parse(sql)
.unwrap()
.remove(0);
assert_eq!(statement_to_query(&statement), statement.to_string());
}
}
fn parse_copy_statement(sql: &str) -> SqlParserStatement {
let parser = PostgresCompatibilityParser::new();
let statements = parser.parse(sql).unwrap();