@@ -5273,7 +5273,7 @@ impl<'a> Parser<'a> {
52735273 // forms (including single-quoted aliases) for broad compatibility.
52745274 // PostgreSQL `CREATE STATISTICS` is stricter, so we enforce those rules
52755275 // here without tightening FROM parsing globally.
5276- self.validate_pg_statistics_from_list (&from)?;
5276+ self.enforce_pg_statistics_identifier_rules_in_from (&from)?;
52775277
52785278 Ok(CreateStatistics {
52795279 if_not_exists,
@@ -5284,30 +5284,38 @@ impl<'a> Parser<'a> {
52845284 })
52855285 }
52865286
5287- /// Validate `FROM from_list` after generic table-factor parsing .
5287+ /// Enforce PostgreSQL identifier rules for `CREATE STATISTICS ... FROM` .
52885288 ///
52895289 /// This pass is required because `CREATE STATISTICS` uses PostgreSQL object
52905290 /// name semantics for relation and alias identifiers, while the shared table
52915291 /// parser accepts additional legacy forms in other contexts.
5292- fn validate_pg_statistics_from_list(&self, from: &[TableWithJoins]) -> Result<(), ParserError> {
5292+ ///
5293+ /// The parser already uses this post-parse pattern for context-specific
5294+ /// constraints in other places (for example, `parse_all_or_distinct`,
5295+ /// `parse_duplicate_treatment`, DROP option-combination checks, and
5296+ /// `ALTER STATISTICS IF EXISTS` operation checks).
5297+ fn enforce_pg_statistics_identifier_rules_in_from(
5298+ &self,
5299+ from: &[TableWithJoins],
5300+ ) -> Result<(), ParserError> {
52935301 for table_with_joins in from {
5294- self.validate_pg_statistics_table_with_joins (table_with_joins)?;
5302+ self.enforce_pg_statistics_identifier_rules_in_table_with_joins (table_with_joins)?;
52955303 }
52965304 Ok(())
52975305 }
52985306
5299- fn validate_pg_statistics_table_with_joins (
5307+ fn enforce_pg_statistics_identifier_rules_in_table_with_joins (
53005308 &self,
53015309 table_with_joins: &TableWithJoins,
53025310 ) -> Result<(), ParserError> {
5303- self.validate_pg_statistics_table_factor (&table_with_joins.relation)?;
5311+ self.enforce_pg_statistics_identifier_rules_in_table_factor (&table_with_joins.relation)?;
53045312 for join in &table_with_joins.joins {
5305- self.validate_pg_statistics_table_factor (&join.relation)?;
5313+ self.enforce_pg_statistics_identifier_rules_in_table_factor (&join.relation)?;
53065314 }
53075315 Ok(())
53085316 }
53095317
5310- fn validate_pg_statistics_table_factor (
5318+ fn enforce_pg_statistics_identifier_rules_in_table_factor (
53115319 &self,
53125320 relation: &TableFactor,
53135321 ) -> Result<(), ParserError> {
@@ -5317,47 +5325,47 @@ impl<'a> Parser<'a> {
53175325 TableFactor::Table { name, alias, .. }
53185326 | TableFactor::Function { name, alias, .. }
53195327 | TableFactor::SemanticView { name, alias, .. } => {
5320- self.validate_no_single_quoted_object_name (name)?;
5321- self.validate_pg_statistics_table_alias (alias.as_ref())
5328+ self.enforce_pg_object_name_identifier_rules (name)?;
5329+ self.enforce_pg_identifier_rules_in_table_alias (alias.as_ref())
53225330 }
53235331 TableFactor::NestedJoin {
53245332 table_with_joins,
53255333 alias,
53265334 } => {
5327- self.validate_pg_statistics_table_with_joins (table_with_joins)?;
5328- self.validate_pg_statistics_table_alias (alias.as_ref())
5335+ self.enforce_pg_statistics_identifier_rules_in_table_with_joins (table_with_joins)?;
5336+ self.enforce_pg_identifier_rules_in_table_alias (alias.as_ref())
53295337 }
53305338 TableFactor::Pivot { table, alias, .. }
53315339 | TableFactor::Unpivot { table, alias, .. }
53325340 | TableFactor::MatchRecognize { table, alias, .. } => {
5333- self.validate_pg_statistics_table_factor (table)?;
5334- self.validate_pg_statistics_table_alias (alias.as_ref())
5341+ self.enforce_pg_statistics_identifier_rules_in_table_factor (table)?;
5342+ self.enforce_pg_identifier_rules_in_table_alias (alias.as_ref())
53355343 }
53365344 TableFactor::Derived { alias, .. }
53375345 | TableFactor::TableFunction { alias, .. }
53385346 | TableFactor::UNNEST { alias, .. }
53395347 | TableFactor::JsonTable { alias, .. }
53405348 | TableFactor::OpenJsonTable { alias, .. }
53415349 | TableFactor::XmlTable { alias, .. } => {
5342- self.validate_pg_statistics_table_alias (alias.as_ref())
5350+ self.enforce_pg_identifier_rules_in_table_alias (alias.as_ref())
53435351 }
53445352 }
53455353 }
53465354
5347- fn validate_pg_statistics_table_alias (
5355+ fn enforce_pg_identifier_rules_in_table_alias (
53485356 &self,
53495357 alias: Option<&TableAlias>,
53505358 ) -> Result<(), ParserError> {
53515359 if let Some(alias) = alias {
5352- self.validate_pg_statistics_identifier (&alias.name)?;
5360+ self.enforce_pg_identifier_token_rules (&alias.name)?;
53535361 for column in &alias.columns {
5354- self.validate_pg_statistics_identifier (&column.name)?;
5362+ self.enforce_pg_identifier_token_rules (&column.name)?;
53555363 }
53565364 }
53575365 Ok(())
53585366 }
53595367
5360- fn validate_pg_statistics_identifier (&self, ident: &Ident) -> Result<(), ParserError> {
5368+ fn enforce_pg_identifier_token_rules (&self, ident: &Ident) -> Result<(), ParserError> {
53615369 // Single-quoted text is a string literal in PostgreSQL, not an identifier.
53625370 if ident.quote_style == Some('\'') {
53635371 return self.expected(
@@ -5368,17 +5376,17 @@ impl<'a> Parser<'a> {
53685376 Ok(())
53695377 }
53705378
5371- fn validate_no_single_quoted_object_name (
5379+ fn enforce_pg_object_name_identifier_rules (
53725380 &self,
53735381 object_name: &ObjectName,
53745382 ) -> Result<(), ParserError> {
53755383 for part in &object_name.0 {
53765384 match part {
53775385 ObjectNamePart::Identifier(ident) => {
5378- self.validate_pg_statistics_identifier (ident)?
5386+ self.enforce_pg_identifier_token_rules (ident)?
53795387 }
53805388 ObjectNamePart::Function(func) => {
5381- self.validate_pg_statistics_identifier (&func.name)?
5389+ self.enforce_pg_identifier_token_rules (&func.name)?
53825390 }
53835391 }
53845392 }
0 commit comments