Skip to content

Commit d821088

Browse files
committed
review: collapse duplicate parse arms, real spans, honest doc comments
- Collapse the four near-identical parse arms in parse_create_text_search; parse the subtype keyword once, then parse name and options once, then map the subtype to the Statement variant. - Spanned impls now return the name's span instead of Span::empty(), matching sibling Create* statements. - Doc comments on each `options: Vec<SqlOption>` no longer claim the parser enforces required keys; they note PostgreSQL's requirements and clarify that enforcement is left to the engine. - Add a test exercising schema-qualified option values (e.g. PARSER = pg_catalog.default) to guard the round-trip.
1 parent e568fea commit d821088

4 files changed

Lines changed: 57 additions & 41 deletions

File tree

src/ast/ddl.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5768,7 +5768,9 @@ impl From<AlterPolicy> for crate::ast::Statement {
57685768
pub struct CreateTextSearchConfiguration {
57695769
/// Name of the text search configuration being created.
57705770
pub name: ObjectName,
5771-
/// Options list — must include `PARSER = parser_name`.
5771+
/// Options list. PostgreSQL requires `PARSER = parser_name`; the
5772+
/// parser does not enforce required keys (matching other options-list
5773+
/// handling in this crate).
57725774
pub options: Vec<SqlOption>,
57735775
}
57745776

@@ -5799,7 +5801,8 @@ impl From<CreateTextSearchConfiguration> for crate::ast::Statement {
57995801
pub struct CreateTextSearchDictionary {
58005802
/// Name of the text search dictionary being created.
58015803
pub name: ObjectName,
5802-
/// Options list — must include `TEMPLATE = template_name`.
5804+
/// Options list. PostgreSQL requires `TEMPLATE = template_name`; the
5805+
/// parser does not enforce required keys.
58035806
pub options: Vec<SqlOption>,
58045807
}
58055808

@@ -5830,7 +5833,9 @@ impl From<CreateTextSearchDictionary> for crate::ast::Statement {
58305833
pub struct CreateTextSearchParser {
58315834
/// Name of the text search parser being created.
58325835
pub name: ObjectName,
5833-
/// Options list — must include `START`, `GETTOKEN`, `END`, `LEXTYPES` (and optionally `HEADLINE`).
5836+
/// Options list. PostgreSQL requires `START`, `GETTOKEN`, `END`, and
5837+
/// `LEXTYPES` (with `HEADLINE` optional); the parser does not enforce
5838+
/// required keys.
58345839
pub options: Vec<SqlOption>,
58355840
}
58365841

@@ -5861,7 +5866,8 @@ impl From<CreateTextSearchParser> for crate::ast::Statement {
58615866
pub struct CreateTextSearchTemplate {
58625867
/// Name of the text search template being created.
58635868
pub name: ObjectName,
5864-
/// Options list — must include `LEXIZE` (and optionally `INIT`).
5869+
/// Options list. PostgreSQL requires `LEXIZE` (with `INIT` optional);
5870+
/// the parser does not enforce required keys.
58655871
pub options: Vec<SqlOption>,
58665872
}
58675873

src/ast/spans.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -391,10 +391,10 @@ impl Spanned for Statement {
391391
Statement::CreateRole(create_role) => create_role.span(),
392392
Statement::CreateExtension(create_extension) => create_extension.span(),
393393
Statement::CreateCollation(create_collation) => create_collation.span(),
394-
Statement::CreateTextSearchConfiguration(_) => Span::empty(),
395-
Statement::CreateTextSearchDictionary(_) => Span::empty(),
396-
Statement::CreateTextSearchParser(_) => Span::empty(),
397-
Statement::CreateTextSearchTemplate(_) => Span::empty(),
394+
Statement::CreateTextSearchConfiguration(stmt) => stmt.name.span(),
395+
Statement::CreateTextSearchDictionary(stmt) => stmt.name.span(),
396+
Statement::CreateTextSearchParser(stmt) => stmt.name.span(),
397+
Statement::CreateTextSearchTemplate(stmt) => stmt.name.span(),
398398
Statement::DropExtension(drop_extension) => drop_extension.span(),
399399
Statement::DropOperator(drop_operator) => drop_operator.span(),
400400
Statement::DropOperatorFamily(drop_operator_family) => drop_operator_family.span(),

src/parser/mod.rs

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -8180,45 +8180,45 @@ impl<'a> Parser<'a> {
81808180

81818181
/// Parse a PostgreSQL-specific `CREATE TEXT SEARCH CONFIGURATION | DICTIONARY | PARSER | TEMPLATE` statement.
81828182
pub fn parse_create_text_search(&mut self) -> Result<Statement, ParserError> {
8183-
if self.parse_keyword(Keyword::CONFIGURATION) {
8184-
let name = self.parse_object_name(false)?;
8185-
self.expect_token(&Token::LParen)?;
8186-
let options = self.parse_comma_separated(Parser::parse_sql_option)?;
8187-
self.expect_token(&Token::RParen)?;
8188-
Ok(Statement::CreateTextSearchConfiguration(
8189-
CreateTextSearchConfiguration { name, options },
8190-
))
8183+
let subtype = if self.parse_keyword(Keyword::CONFIGURATION) {
8184+
Keyword::CONFIGURATION
81918185
} else if self.parse_keyword(Keyword::DICTIONARY) {
8192-
let name = self.parse_object_name(false)?;
8193-
self.expect_token(&Token::LParen)?;
8194-
let options = self.parse_comma_separated(Parser::parse_sql_option)?;
8195-
self.expect_token(&Token::RParen)?;
8196-
Ok(Statement::CreateTextSearchDictionary(
8197-
CreateTextSearchDictionary { name, options },
8198-
))
8186+
Keyword::DICTIONARY
81998187
} else if self.parse_keyword(Keyword::PARSER) {
8200-
let name = self.parse_object_name(false)?;
8201-
self.expect_token(&Token::LParen)?;
8202-
let options = self.parse_comma_separated(Parser::parse_sql_option)?;
8203-
self.expect_token(&Token::RParen)?;
8204-
Ok(Statement::CreateTextSearchParser(CreateTextSearchParser {
8205-
name,
8206-
options,
8207-
}))
8188+
Keyword::PARSER
82088189
} else if self.parse_keyword(Keyword::TEMPLATE) {
8209-
let name = self.parse_object_name(false)?;
8210-
self.expect_token(&Token::LParen)?;
8211-
let options = self.parse_comma_separated(Parser::parse_sql_option)?;
8212-
self.expect_token(&Token::RParen)?;
8213-
Ok(Statement::CreateTextSearchTemplate(
8214-
CreateTextSearchTemplate { name, options },
8215-
))
8190+
Keyword::TEMPLATE
82168191
} else {
8217-
self.expected_ref(
8192+
return self.expected_ref(
82188193
"CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE after CREATE TEXT SEARCH",
82198194
self.peek_token_ref(),
8220-
)
8221-
}
8195+
);
8196+
};
8197+
8198+
let name = self.parse_object_name(false)?;
8199+
self.expect_token(&Token::LParen)?;
8200+
let options = self.parse_comma_separated(Parser::parse_sql_option)?;
8201+
self.expect_token(&Token::RParen)?;
8202+
8203+
Ok(match subtype {
8204+
Keyword::CONFIGURATION => Statement::CreateTextSearchConfiguration(
8205+
CreateTextSearchConfiguration { name, options },
8206+
),
8207+
Keyword::DICTIONARY => {
8208+
Statement::CreateTextSearchDictionary(CreateTextSearchDictionary { name, options })
8209+
}
8210+
Keyword::PARSER => {
8211+
Statement::CreateTextSearchParser(CreateTextSearchParser { name, options })
8212+
}
8213+
Keyword::TEMPLATE => {
8214+
Statement::CreateTextSearchTemplate(CreateTextSearchTemplate { name, options })
8215+
}
8216+
unexpected => {
8217+
return Err(ParserError::ParserError(format!(
8218+
"Internal parser error: unexpected CREATE TEXT SEARCH subtype `{unexpected}`"
8219+
)))
8220+
}
8221+
})
82228222
}
82238223

82248224
/// Parse a PostgreSQL-specific [Statement::DropExtension] statement.

tests/sqlparser_postgres.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,16 @@ fn parse_create_text_search_template() {
10691069
);
10701070
}
10711071

1072+
#[test]
1073+
fn parse_create_text_search_schema_qualified_option_value() {
1074+
// PostgreSQL's TEXT SEARCH options accept schema-qualified names as
1075+
// values (e.g. `PARSER = pg_catalog.default`). Ensure they round-trip.
1076+
pg().verified_stmt(
1077+
"CREATE TEXT SEARCH CONFIGURATION public.myconfig (PARSER = pg_catalog.default)",
1078+
);
1079+
pg().verified_stmt("CREATE TEXT SEARCH DICTIONARY public.d (TEMPLATE = pg_catalog.simple)");
1080+
}
1081+
10721082
#[test]
10731083
fn parse_create_text_search_invalid_subtype() {
10741084
assert_eq!(

0 commit comments

Comments
 (0)