From 3a674ead238eba8a33f6df0bdea1ba2233b29088 Mon Sep 17 00:00:00 2001 From: JasonPanosso Date: Tue, 26 Dec 2023 16:52:41 -0500 Subject: [PATCH 1/2] feat: support `create conversion` --- crates/codegen/src/get_node_properties.rs | 16 +++++ crates/parser/src/codegen.rs | 20 ++++++ .../tests/data/statements/valid/0054.sql | 2 + .../snapshots/statements/valid/0054@1.snap | 62 ++++++++++++++++++ .../snapshots/statements/valid/0054@2.snap | 64 +++++++++++++++++++ 5 files changed, 164 insertions(+) create mode 100644 crates/parser/tests/data/statements/valid/0054.sql create mode 100644 crates/parser/tests/snapshots/statements/valid/0054@1.snap create mode 100644 crates/parser/tests/snapshots/statements/valid/0054@2.snap diff --git a/crates/codegen/src/get_node_properties.rs b/crates/codegen/src/get_node_properties.rs index b21dd3cf..3e189bd0 100644 --- a/crates/codegen/src/get_node_properties.rs +++ b/crates/codegen/src/get_node_properties.rs @@ -777,6 +777,22 @@ fn custom_handlers(node: &Node) -> TokenStream { tokens.push(TokenProperty::from(Token::Exists)); } }, + "CreateConversionStmt" => quote! { + tokens.push(TokenProperty::from(Token::Create)); + if n.def { + tokens.push(TokenProperty::from(Token::Default)); + } + tokens.push(TokenProperty::from(Token::ConversionP)); + if n.for_encoding_name.len() > 0 { + tokens.push(TokenProperty::from(Token::For)); + } + if n.to_encoding_name.len() > 0 { + tokens.push(TokenProperty::from(Token::To)); + } + if n.func_name.len() > 0 { + tokens.push(TokenProperty::from(Token::From)); + } + }, _ => quote! {}, } } diff --git a/crates/parser/src/codegen.rs b/crates/parser/src/codegen.rs index c4488bef..b6c1a661 100644 --- a/crates/parser/src/codegen.rs +++ b/crates/parser/src/codegen.rs @@ -297,4 +297,24 @@ mod tests { ], ) } + + #[test] + fn test_create_conversion() { + test_get_node_properties( + "CREATE DEFAULT CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;", + SyntaxKind::CreateConversionStmt, + vec![ + TokenProperty::from(SyntaxKind::Create), + TokenProperty::from(SyntaxKind::Default), + TokenProperty::from(SyntaxKind::ConversionP), + TokenProperty::from(SyntaxKind::For), + TokenProperty::from(SyntaxKind::To), + TokenProperty::from(SyntaxKind::From), + TokenProperty::from("utf8".to_string()), + TokenProperty::from("latin1".to_string()), + TokenProperty::from("myconv".to_string()), + TokenProperty::from("myfunc".to_string()), + ], + ) + } } diff --git a/crates/parser/tests/data/statements/valid/0054.sql b/crates/parser/tests/data/statements/valid/0054.sql new file mode 100644 index 00000000..4afd7bf2 --- /dev/null +++ b/crates/parser/tests/data/statements/valid/0054.sql @@ -0,0 +1,2 @@ +CREATE CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc; +CREATE DEFAULT CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc; diff --git a/crates/parser/tests/snapshots/statements/valid/0054@1.snap b/crates/parser/tests/snapshots/statements/valid/0054@1.snap new file mode 100644 index 00000000..385e235f --- /dev/null +++ b/crates/parser/tests/snapshots/statements/valid/0054@1.snap @@ -0,0 +1,62 @@ +--- +source: crates/parser/tests/statement_parser_test.rs +description: "CREATE CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;" +--- +Parse { + cst: SourceFile@0..60 + CreateConversionStmt@0..60 + Create@0..6 "CREATE" + Whitespace@6..7 " " + ConversionP@7..17 "CONVERSION" + Whitespace@17..18 " " + Ident@18..24 "myconv" + Whitespace@24..25 " " + For@25..28 "FOR" + Whitespace@28..29 " " + Sconst@29..35 "'UTF8'" + Whitespace@35..36 " " + To@36..38 "TO" + Whitespace@38..39 " " + Sconst@39..47 "'LATIN1'" + Whitespace@47..48 " " + From@48..52 "FROM" + Whitespace@52..53 " " + Ident@53..59 "myfunc" + Ascii59@59..60 ";" + , + errors: [], + stmts: [ + RawStmt { + stmt: CreateConversionStmt( + CreateConversionStmt { + conversion_name: [ + Node { + node: Some( + String( + String { + sval: "myconv", + }, + ), + ), + }, + ], + for_encoding_name: "UTF8", + to_encoding_name: "LATIN1", + func_name: [ + Node { + node: Some( + String( + String { + sval: "myfunc", + }, + ), + ), + }, + ], + def: false, + }, + ), + range: 0..59, + }, + ], +} diff --git a/crates/parser/tests/snapshots/statements/valid/0054@2.snap b/crates/parser/tests/snapshots/statements/valid/0054@2.snap new file mode 100644 index 00000000..42806a70 --- /dev/null +++ b/crates/parser/tests/snapshots/statements/valid/0054@2.snap @@ -0,0 +1,64 @@ +--- +source: crates/parser/tests/statement_parser_test.rs +description: "CREATE DEFAULT CONVERSION myconv FOR 'UTF8' TO 'LATIN1' FROM myfunc;" +--- +Parse { + cst: SourceFile@0..68 + CreateConversionStmt@0..68 + Create@0..6 "CREATE" + Whitespace@6..7 " " + Default@7..14 "DEFAULT" + Whitespace@14..15 " " + ConversionP@15..25 "CONVERSION" + Whitespace@25..26 " " + Ident@26..32 "myconv" + Whitespace@32..33 " " + For@33..36 "FOR" + Whitespace@36..37 " " + Sconst@37..43 "'UTF8'" + Whitespace@43..44 " " + To@44..46 "TO" + Whitespace@46..47 " " + Sconst@47..55 "'LATIN1'" + Whitespace@55..56 " " + From@56..60 "FROM" + Whitespace@60..61 " " + Ident@61..67 "myfunc" + Ascii59@67..68 ";" + , + errors: [], + stmts: [ + RawStmt { + stmt: CreateConversionStmt( + CreateConversionStmt { + conversion_name: [ + Node { + node: Some( + String( + String { + sval: "myconv", + }, + ), + ), + }, + ], + for_encoding_name: "UTF8", + to_encoding_name: "LATIN1", + func_name: [ + Node { + node: Some( + String( + String { + sval: "myfunc", + }, + ), + ), + }, + ], + def: true, + }, + ), + range: 0..67, + }, + ], +} From f2103cd4785a10b1aed978ad7bbeff4074c8e2e8 Mon Sep 17 00:00:00 2001 From: JasonPanosso Date: Thu, 28 Dec 2023 14:17:01 -0500 Subject: [PATCH 2/2] fix: panic when more than one function name defined in CreateConversionStmt --- crates/codegen/src/get_node_properties.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/codegen/src/get_node_properties.rs b/crates/codegen/src/get_node_properties.rs index 3e189bd0..b42caf3b 100644 --- a/crates/codegen/src/get_node_properties.rs +++ b/crates/codegen/src/get_node_properties.rs @@ -789,8 +789,10 @@ fn custom_handlers(node: &Node) -> TokenStream { if n.to_encoding_name.len() > 0 { tokens.push(TokenProperty::from(Token::To)); } - if n.func_name.len() > 0 { + if n.func_name.len() == 1 { tokens.push(TokenProperty::from(Token::From)); + } else if n.func_name.len() > 1 { + panic!("Encountered multiple defined func_name elements in CreateConversionStmt"); } }, _ => quote! {},