@@ -5229,7 +5229,7 @@ impl<'a> Parser<'a> {
52295229 // forms (including single-quoted aliases) for broad compatibility.
52305230 // PostgreSQL `CREATE STATISTICS` is stricter, so we enforce those rules
52315231 // here without tightening FROM parsing globally.
5232- self.validate_pg_statistics_from_list (&from)?;
5232+ self.enforce_pg_statistics_identifier_rules_in_from (&from)?;
52335233
52345234 Ok(CreateStatistics {
52355235 if_not_exists,
@@ -5240,30 +5240,38 @@ impl<'a> Parser<'a> {
52405240 })
52415241 }
52425242
5243- /// Validate `FROM from_list` after generic table-factor parsing .
5243+ /// Enforce PostgreSQL identifier rules for `CREATE STATISTICS ... FROM` .
52445244 ///
52455245 /// This pass is required because `CREATE STATISTICS` uses PostgreSQL object
52465246 /// name semantics for relation and alias identifiers, while the shared table
52475247 /// parser accepts additional legacy forms in other contexts.
5248- fn validate_pg_statistics_from_list(&self, from: &[TableWithJoins]) -> Result<(), ParserError> {
5248+ ///
5249+ /// The parser already uses this post-parse pattern for context-specific
5250+ /// constraints in other places (for example, `parse_all_or_distinct`,
5251+ /// `parse_duplicate_treatment`, DROP option-combination checks, and
5252+ /// `ALTER STATISTICS IF EXISTS` operation checks).
5253+ fn enforce_pg_statistics_identifier_rules_in_from(
5254+ &self,
5255+ from: &[TableWithJoins],
5256+ ) -> Result<(), ParserError> {
52495257 for table_with_joins in from {
5250- self.validate_pg_statistics_table_with_joins (table_with_joins)?;
5258+ self.enforce_pg_statistics_identifier_rules_in_table_with_joins (table_with_joins)?;
52515259 }
52525260 Ok(())
52535261 }
52545262
5255- fn validate_pg_statistics_table_with_joins (
5263+ fn enforce_pg_statistics_identifier_rules_in_table_with_joins (
52565264 &self,
52575265 table_with_joins: &TableWithJoins,
52585266 ) -> Result<(), ParserError> {
5259- self.validate_pg_statistics_table_factor (&table_with_joins.relation)?;
5267+ self.enforce_pg_statistics_identifier_rules_in_table_factor (&table_with_joins.relation)?;
52605268 for join in &table_with_joins.joins {
5261- self.validate_pg_statistics_table_factor (&join.relation)?;
5269+ self.enforce_pg_statistics_identifier_rules_in_table_factor (&join.relation)?;
52625270 }
52635271 Ok(())
52645272 }
52655273
5266- fn validate_pg_statistics_table_factor (
5274+ fn enforce_pg_statistics_identifier_rules_in_table_factor (
52675275 &self,
52685276 relation: &TableFactor,
52695277 ) -> Result<(), ParserError> {
@@ -5273,47 +5281,47 @@ impl<'a> Parser<'a> {
52735281 TableFactor::Table { name, alias, .. }
52745282 | TableFactor::Function { name, alias, .. }
52755283 | TableFactor::SemanticView { name, alias, .. } => {
5276- self.validate_no_single_quoted_object_name (name)?;
5277- self.validate_pg_statistics_table_alias (alias.as_ref())
5284+ self.enforce_pg_object_name_identifier_rules (name)?;
5285+ self.enforce_pg_identifier_rules_in_table_alias (alias.as_ref())
52785286 }
52795287 TableFactor::NestedJoin {
52805288 table_with_joins,
52815289 alias,
52825290 } => {
5283- self.validate_pg_statistics_table_with_joins (table_with_joins)?;
5284- self.validate_pg_statistics_table_alias (alias.as_ref())
5291+ self.enforce_pg_statistics_identifier_rules_in_table_with_joins (table_with_joins)?;
5292+ self.enforce_pg_identifier_rules_in_table_alias (alias.as_ref())
52855293 }
52865294 TableFactor::Pivot { table, alias, .. }
52875295 | TableFactor::Unpivot { table, alias, .. }
52885296 | TableFactor::MatchRecognize { table, alias, .. } => {
5289- self.validate_pg_statistics_table_factor (table)?;
5290- self.validate_pg_statistics_table_alias (alias.as_ref())
5297+ self.enforce_pg_statistics_identifier_rules_in_table_factor (table)?;
5298+ self.enforce_pg_identifier_rules_in_table_alias (alias.as_ref())
52915299 }
52925300 TableFactor::Derived { alias, .. }
52935301 | TableFactor::TableFunction { alias, .. }
52945302 | TableFactor::UNNEST { alias, .. }
52955303 | TableFactor::JsonTable { alias, .. }
52965304 | TableFactor::OpenJsonTable { alias, .. }
52975305 | TableFactor::XmlTable { alias, .. } => {
5298- self.validate_pg_statistics_table_alias (alias.as_ref())
5306+ self.enforce_pg_identifier_rules_in_table_alias (alias.as_ref())
52995307 }
53005308 }
53015309 }
53025310
5303- fn validate_pg_statistics_table_alias (
5311+ fn enforce_pg_identifier_rules_in_table_alias (
53045312 &self,
53055313 alias: Option<&TableAlias>,
53065314 ) -> Result<(), ParserError> {
53075315 if let Some(alias) = alias {
5308- self.validate_pg_statistics_identifier (&alias.name)?;
5316+ self.enforce_pg_identifier_token_rules (&alias.name)?;
53095317 for column in &alias.columns {
5310- self.validate_pg_statistics_identifier (&column.name)?;
5318+ self.enforce_pg_identifier_token_rules (&column.name)?;
53115319 }
53125320 }
53135321 Ok(())
53145322 }
53155323
5316- fn validate_pg_statistics_identifier (&self, ident: &Ident) -> Result<(), ParserError> {
5324+ fn enforce_pg_identifier_token_rules (&self, ident: &Ident) -> Result<(), ParserError> {
53175325 // Single-quoted text is a string literal in PostgreSQL, not an identifier.
53185326 if ident.quote_style == Some('\'') {
53195327 return self.expected(
@@ -5324,17 +5332,17 @@ impl<'a> Parser<'a> {
53245332 Ok(())
53255333 }
53265334
5327- fn validate_no_single_quoted_object_name (
5335+ fn enforce_pg_object_name_identifier_rules (
53285336 &self,
53295337 object_name: &ObjectName,
53305338 ) -> Result<(), ParserError> {
53315339 for part in &object_name.0 {
53325340 match part {
53335341 ObjectNamePart::Identifier(ident) => {
5334- self.validate_pg_statistics_identifier (ident)?
5342+ self.enforce_pg_identifier_token_rules (ident)?
53355343 }
53365344 ObjectNamePart::Function(func) => {
5337- self.validate_pg_statistics_identifier (&func.name)?
5345+ self.enforce_pg_identifier_token_rules (&func.name)?
53385346 }
53395347 }
53405348 }
0 commit comments