Skip to content

Commit a37340d

Browse files
Track dropped-rule spans and cover formatter boundaries
1 parent 5285729 commit a37340d

3 files changed

Lines changed: 69 additions & 8 deletions

File tree

‎src/ast/ddl.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6009,6 +6009,8 @@ impl From<AlterPolicy> for crate::ast::Statement {
60096009

60106010
/// DROP RULE statement.
60116011
///
6012+
/// Its source span covers `name` and `table_name`.
6013+
///
60126014
/// ```sql
60136015
/// DROP RULE [ IF EXISTS ] name ON table_name [ CASCADE | RESTRICT ]
60146016
/// ```

‎src/ast/spans.rs‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ use super::{
3333
AttachedToken, BeginEndStatements, CaseStatement, CloseCursor, ClusteredIndex, ColumnDef,
3434
ColumnOption, ColumnOptionDef, ConditionalStatementBlock, ConditionalStatements,
3535
ConflictTarget, ConnectByKind, ConstraintCharacteristics, CopySource, CreateIndex, CreateTable,
36-
CreateTableOptions, Cte, Delete, DoUpdate, ExceptSelectItem, ExcludeConstraintElement,
37-
ExcludeSelectItem, Expr, ExprWithAlias, Fetch, ForValues, FromTable, Function, FunctionArg,
38-
FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList, FunctionArguments, GroupByExpr,
39-
HavingBound, IfStatement, IlikeSelectItem, IndexColumn, Insert, Interpolate, InterpolateExpr,
40-
Join, JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView, LimitClause,
41-
MatchRecognizePattern, Measure, Merge, MergeAction, MergeClause, MergeInsertExpr,
42-
MergeInsertKind, MergeUpdateExpr, MergeUpdateKind, NamedParenthesizedList,
36+
CreateTableOptions, Cte, Delete, DoUpdate, DropRule, ExceptSelectItem,
37+
ExcludeConstraintElement, ExcludeSelectItem, Expr, ExprWithAlias, Fetch, ForValues, FromTable,
38+
Function, FunctionArg, FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList,
39+
FunctionArguments, GroupByExpr, HavingBound, IfStatement, IlikeSelectItem, IndexColumn, Insert,
40+
Interpolate, InterpolateExpr, Join, JoinConstraint, JoinOperator, JsonPath, JsonPathElem,
41+
LateralView, LimitClause, MatchRecognizePattern, Measure, Merge, MergeAction, MergeClause,
42+
MergeInsertExpr, MergeInsertKind, MergeUpdateExpr, MergeUpdateKind, NamedParenthesizedList,
4343
NamedWindowDefinition, ObjectName, ObjectNamePart, Offset, OnConflict, OnConflictAction,
4444
OnInsert, OpenStatement, OrderBy, OrderByExpr, OrderByKind, OutputClause, Parens, Partition,
4545
PartitionBoundValue, PivotValueSource, ProjectionSelect, Query, RaiseStatement,
@@ -490,7 +490,7 @@ impl Spanned for Statement {
490490
Statement::AlterPolicy { .. } => Span::empty(),
491491
Statement::AlterConnector { .. } => Span::empty(),
492492
Statement::DropPolicy { .. } => Span::empty(),
493-
Statement::DropRule { .. } => Span::empty(),
493+
Statement::DropRule(rule) => rule.span(),
494494
Statement::DropConnector { .. } => Span::empty(),
495495
Statement::ShowCatalogs { .. } => Span::empty(),
496496
Statement::ShowDatabases { .. } => Span::empty(),
@@ -529,6 +529,12 @@ impl Spanned for Statement {
529529
}
530530
}
531531

532+
impl Spanned for DropRule {
533+
fn span(&self) -> Span {
534+
self.name.span.union(&self.table_name.span())
535+
}
536+
}
537+
532538
impl Spanned for Use {
533539
fn span(&self) -> Span {
534540
match self {

‎tests/sqlparser_common.rs‎

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20213,6 +20213,59 @@ fn parse_drop_rule() {
2021320213
);
2021420214
}
2021520215

20216+
#[test]
20217+
fn parse_drop_rule_rejects_missing_names() {
20218+
for (sql, expected) in [
20219+
("DROP RULE", "Expected: identifier, found: EOF"),
20220+
("DROP RULE r ON", "Expected: identifier, found: EOF"),
20221+
("DROP 1", "Expected: COLLATION, CONNECTOR, DATABASE, EXTENSION, FUNCTION, INDEX, OPERATOR, POLICY, PROCEDURE, ROLE, RULE, SCHEMA, SECRET, SEQUENCE, STAGE, TABLE, TRIGGER, TYPE, VIEW, MATERIALIZED VIEW, USER or WAREHOUSE after DROP, found: 1"),
20222+
] {
20223+
assert_eq!(
20224+
all_dialects().parse_sql_statements(sql).unwrap_err(),
20225+
ParserError::ParserError(expected.to_string()),
20226+
);
20227+
}
20228+
}
20229+
20230+
#[test]
20231+
fn display_drop_rule_propagates_write_errors() {
20232+
use core::fmt::{self, Write};
20233+
20234+
struct RejectingWriter<'a>(&'a str);
20235+
20236+
impl Write for RejectingWriter<'_> {
20237+
fn write_str(&mut self, value: &str) -> fmt::Result {
20238+
if value.contains(self.0) {
20239+
Err(fmt::Error)
20240+
} else {
20241+
Ok(())
20242+
}
20243+
}
20244+
}
20245+
20246+
let statement = all_dialects().verified_stmt("DROP RULE r ON t");
20247+
let mut writer = RejectingWriter("DROP");
20248+
assert_eq!(write!(writer, "{statement}"), Err(fmt::Error));
20249+
20250+
let statement = all_dialects().verified_stmt("DROP RULE r ON t CASCADE");
20251+
let mut writer = RejectingWriter("CASCADE");
20252+
assert_eq!(write!(writer, "{statement}"), Err(fmt::Error));
20253+
}
20254+
20255+
#[test]
20256+
fn parse_drop_rule_spans() {
20257+
let dialects = all_dialects();
20258+
let sql = "DROP RULE r ON t CASCADE";
20259+
for dialect in &dialects.dialects {
20260+
let statements = Parser::parse_sql(dialect.as_ref(), sql).unwrap();
20261+
assert_eq!(
20262+
statements[0].span(),
20263+
Span::new(Location::new(1, 11), Location::new(1, 17)),
20264+
"{dialect:?} {sql}"
20265+
);
20266+
}
20267+
}
20268+
2021620269
#[test]
2021720270
fn parse_alter_table_column_position() {
2021820271
let dialects = all_dialects_where(|d| d.supports_alter_column_position());

0 commit comments

Comments
 (0)