LucaCappelletti94 commented on code in PR #2618:
URL: 
https://github.com/apache/datafusion-sqlparser-rs/pull/2618#discussion_r4284927578


##########
src/ast/spans.rs:
##########
@@ -2634,6 +2633,18 @@ impl Spanned for comments::CommentWithSpan {
     }
 }
 
+impl Spanned for DoStatement {
+    fn span(&self) -> Span {
+        let DoStatement { language, code } = self;
+        union_spans(
+            language
+                .iter()
+                .map(|l| l.span)
+                .chain(core::iter::once(code.span)),
+        )
+    }
+}

Review Comment:
   You should span the option list, each item by its name or literal.
   
   ```suggestion
   impl Spanned for DoStatement {
       fn span(&self) -> Span {
           union_spans(self.options.iter().map(|option| option.span()))
       }
   }
   
   impl Spanned for DoOption {
       fn span(&self) -> Span {
           match self {
               DoOption::Language(language) => language.span,
               DoOption::LanguageLiteral(value) | DoOption::Code(value) => 
value.span,
           }
       }
   }
   ```



##########
src/ast/spans.rs:
##########
@@ -33,13 +33,13 @@ use super::{
     AttachedToken, BeginEndStatements, CaseStatement, CloseCursor, 
ClusteredIndex, ColumnDef,
     ColumnOption, ColumnOptionDef, ConditionalStatementBlock, 
ConditionalStatements,
     ConflictTarget, ConnectByKind, ConstraintCharacteristics, CopySource, 
CreateIndex, CreateTable,
-    CreateTableOptions, Cte, Delete, DoUpdate, ExceptSelectItem, 
ExcludeConstraintElement,
-    ExcludeSelectItem, Expr, ExprWithAlias, Fetch, ForValues, FromTable, 
Function, FunctionArg,
-    FunctionArgExpr, FunctionArgumentClause, FunctionArgumentList, 
FunctionArguments, GroupByExpr,
-    HavingBound, IfStatement, IlikeSelectItem, IndexColumn, Insert, 
Interpolate, InterpolateExpr,
-    Join, JoinConstraint, JoinOperator, JsonPath, JsonPathElem, LateralView, 
LimitClause,
-    MatchRecognizePattern, Measure, Merge, MergeAction, MergeClause, 
MergeInsertExpr,
-    MergeInsertKind, MergeUpdateExpr, MergeUpdateKind, NamedParenthesizedList,
+    CreateTableOptions, Cte, Delete, DoStatement, DoUpdate, ExceptSelectItem,

Review Comment:
   You should import the new `DoOption`.
   
   ```suggestion
       CreateTableOptions, Cte, Delete, DoOption, DoStatement, DoUpdate, 
ExceptSelectItem,
   ```



##########
tests/sqlparser_common.rs:
##########
@@ -20511,3 +20511,59 @@ fn 
parse_position_in_connect_by_list_after_state_change() {
         assert_eq!(positions, 1, "{dialect:?}");
     }
 }
+
+#[test]
+fn parse_do_statement() {
+    let dialects = all_dialects_where(|d| d.supports_do_statement());
+
+    match dialects.verified_stmt("DO $$BEGIN RAISE NOTICE 'hi'; END$$") {
+        Statement::Do(DoStatement { language, code }) => {
+            assert_eq!(language, None);
+            assert_eq!(
+                code.value,
+                Value::DollarQuotedString(DollarQuotedString {
+                    value: "BEGIN RAISE NOTICE 'hi'; END".to_string(),
+                    tag: None,
+                })
+            );
+        }
+        _ => unreachable!(),
+    }
+
+    match dialects.verified_stmt("DO LANGUAGE plpgsql $body$BEGIN NULL; 
END$body$") {
+        Statement::Do(DoStatement { language, .. }) => {
+            assert_eq!(language, Some(Ident::new("plpgsql")));
+        }
+        _ => unreachable!(),
+    }
+
+    dialects.verified_stmt("DO 'BEGIN NULL; END'");
+    dialects.verified_stmt("DO U&'BEGIN NULL; END'");
+    dialects.one_statement_parses_to(
+        "DO $$BEGIN NULL; END$$ LANGUAGE plpgsql",
+        "DO LANGUAGE plpgsql $$BEGIN NULL; END$$",
+    );
+    assert_eq!(
+        dialects
+            .parse_sql_statements("DO LANGUAGE plpgsql $$BEGIN NULL; END$$ 
LANGUAGE sql")
+            .unwrap_err(),
+        ParserError::ParserError("Expected: end of statement, found: 
LANGUAGE".to_string())
+    );

Review Comment:
   More red tests.
   
   ```suggestion
       match dialects.verified_stmt("DO $$BEGIN RAISE NOTICE 'hi'; END$$") {
           Statement::Do(DoStatement { options }) => assert_eq!(
               options,
               vec![DoOption::Code(
                   Value::DollarQuotedString(DollarQuotedString {
                       value: "BEGIN RAISE NOTICE 'hi'; END".to_string(),
                       tag: None,
                   })
                   .with_empty_span()
               )]
           ),
           _ => unreachable!(),
       }
   
       match dialects.verified_stmt("DO LANGUAGE plpgsql $body$BEGIN NULL; 
END$body$") {
           Statement::Do(DoStatement { options }) => {
               assert_eq!(options[0], 
DoOption::Language(Ident::new("plpgsql")));
           }
           _ => unreachable!(),
       }
   
       dialects.verified_stmt("DO 'BEGIN NULL; END'");
       dialects.verified_stmt("DO U&'BEGIN NULL; END'");
       dialects.verified_stmt("DO $$BEGIN NULL; END$$ LANGUAGE plpgsql");
       dialects.verified_stmt("DO LANGUAGE 'plpgsql' $$BEGIN NULL; END$$");
       dialects.verified_stmt("DO LANGUAGE $$plpgsql$$ $$BEGIN NULL; END$$");
       dialects.verified_stmt("DO $$BEGIN NULL; END$$ LANGUAGE E'plpgsql'");
       dialects.verified_stmt("DO LANGUAGE plpgsql");
       dialects.verified_stmt("DO $$BEGIN NULL; END$$ $$BEGIN NULL; END$$");
       dialects.verified_stmt("DO LANGUAGE plpgsql LANGUAGE sql $$BEGIN NULL; 
END$$");
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to