-
Notifications
You must be signed in to change notification settings - Fork 616
Support CONVERT
expressions
#1048
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Pull Request Test Coverage Report for Build 6915102482
💛 - Coveralls |
b222845
to
e5399b3
Compare
fixes apache#1047 adds support for the following CONVERT syntaxes: - `CONVERT('héhé' USING utf8mb4)` (MySQL, Postgres) - `CONVERT('héhé', CHAR CHARACTER SET utf8mb4)` (MySQL) - `CONVERT(DECIMAL(10, 5), 42)` (MSSQL) - the type comes first
e5399b3
to
bbd99a4
Compare
The "simple" function syntax already works (eg You can possibly make the code simpler by keep this behaviour and adding the more complex CONVERT statement parsing if it is detected. Adding something like the following in the parser.
This approach would remove the need for the check for function order and mean CONVERT struct would not need so many Optional types as you only ever use it for the "complex" CONVERT statements. |
@tobyhede , we cannot do a |
Does it ? I think |
I agree this is what it seems to do: $ echo "select CONVERT(DECIMAL(10, 5), 42)" > /tmp/foo.sql
$ cargo run --example cli -- /tmp/foo.sql
Finished dev [unoptimized + debuginfo] target(s) in 0.07s
Running `target/debug/examples/cli /tmp/foo.sql`
Parsing from file '/tmp/foo.sql' using GenericDialect
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] Parsing sql 'select CONVERT(DECIMAL(10, 5), 42)
'...
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] parsing expr
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] parsing expr
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] parsing expr
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] prefix: Value(Number("10", false))
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] get_next_precedence() TokenWithLocation { token: Comma, location: Location { line: 1, column: 26 } }
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] 0: , 1: 5 2: )
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] next precedence: 0
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] parsing expr
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] prefix: Value(Number("5", false))
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] get_next_precedence() TokenWithLocation { token: RParen, location: Location { line: 1, column: 29 } }
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] 0: ) 1: , 2: 42
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] next precedence: 0
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] prefix: Function(Function { name: ObjectName([Ident { value: "DECIMAL", quote_style: None }]), args: [Unnamed(Expr(Value(Number("10", false)))), Unnamed(Expr(Value(Number("5", false))))], filter: None, null_treatment: None, over: None, distinct: false, special: false, order_by: [] })
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] get_next_precedence() TokenWithLocation { token: Comma, location: Location { line: 1, column: 30 } }
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] 0: , 1: 42 2: )
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] next precedence: 0
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] parsing expr
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] prefix: Value(Number("42", false))
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] get_next_precedence() TokenWithLocation { token: RParen, location: Location { line: 1, column: 34 } }
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] 0: ) 1: EOF 2: EOF
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] next precedence: 0
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] prefix: Function(Function { name: ObjectName([Ident { value: "CONVERT", quote_style: None }]), args: [Unnamed(Expr(Function(Function { name: ObjectName([Ident { value: "DECIMAL", quote_style: None }]), args: [Unnamed(Expr(Value(Number("10", false)))), Unnamed(Expr(Value(Number("5", false))))], filter: None, null_treatment: None, over: None, distinct: false, special: false, order_by: [] }))), Unnamed(Expr(Value(Number("42", false))))], filter: None, null_treatment: None, over: None, distinct: false, special: false, order_by: [] })
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] get_next_precedence() TokenWithLocation { token: EOF, location: Location { line: 0, column: 0 } }
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] 0: EOF 1: EOF 2: EOF
2023-11-20T19:50:50.259Z DEBUG [sqlparser::parser] next precedence: 0
Round-trip:
'SELECT CONVERT(DECIMAL(10, 5), 42)'
Parse results:
[
Query(
Query {
with: None,
body: Select(
Select {
distinct: None,
top: None,
projection: [
UnnamedExpr(
Function(
Function {
name: ObjectName(
[
Ident {
value: "CONVERT",
quote_style: None,
},
],
),
args: [
Unnamed(
Expr(
Function(
Function {
name: ObjectName(
[
Ident {
value: "DECIMAL",
quote_style: None,
},
],
),
args: [
Unnamed(
Expr(
Value(
Number(
"10",
false,
),
),
),
),
Unnamed(
Expr(
Value(
Number(
"5",
false,
),
),
),
),
],
filter: None,
null_treatment: None,
over: None,
distinct: false,
special: false,
order_by: [],
},
),
),
),
Unnamed(
Expr(
Value(
Number(
"42",
false,
),
),
),
),
],
filter: None,
null_treatment: None,
over: None,
distinct: false,
special: false,
order_by: [],
},
),
),
],
into: None,
from: [],
lateral_views: [],
selection: None,
group_by: Expressions(
[],
),
cluster_by: [],
distribute_by: [],
sort_by: [],
having: None,
named_window: [],
qualify: None,
},
),
order_by: [],
limit: None,
limit_by: [],
offset: None,
fetch: None,
locks: [],
for_clause: None,
},
),
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me. Thank you for the contribution @lovasoa
/// The target data type | ||
data_type: Option<DataType>, | ||
/// The target character encoding | ||
charset: Option<ObjectName>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW Postgres calls this "conversion name" but that appears to be an ObjectName
so 👍
@@ -35,6 +35,12 @@ impl Dialect for MsSqlDialect { | |||
|| ch == '_' | |||
} | |||
|
|||
/// SQL Server has `CONVERT(type, value)` instead of `CONVERT(value, type)` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤯
CONVERT
expressions
fixes #1047
adds support for the following CONVERT syntaxes:
CONVERT('héhé' USING utf8mb4)
(MySQL, Postgres)CONVERT('héhé', CHAR CHARACTER SET utf8mb4)
(MySQL)CONVERT(DECIMAL(10, 5), 42)
(MSSQL) - the type comes first