Skip to content

Commit 6b6c815

Browse files
committed
nom-sql: Lowercase unquoted no-paren functions in Postgres
This is just to add some consistency to our Postgres identifier casing approach (which is to lowercase them during parsing), so that we can treat identifiers uniformly when converting from sqlparser-rs. This entire approach may go away in the future, and I would rather such a hack/special case be in nom-sql rather than in readyset-sql. Change-Id: I288e827d4ba3a3ca9bbc2552285777a187253d5a Reviewed-on: https://gerrit.readyset.name/c/readyset/+/9041 Reviewed-by: Johnathan Davis <jcd@readyset.io> Tested-by: Buildkite CI
1 parent 235f17d commit 6b6c815

File tree

4 files changed

+41
-28
lines changed

4 files changed

+41
-28
lines changed

nom-sql/src/common.rs

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -126,31 +126,37 @@ fn delim_fx_args(
126126
}
127127
}
128128

129-
fn function_call_without_parens(i: LocatedSpan<&[u8]>) -> NomSqlResult<&[u8], FunctionExpr> {
130-
// Some functions can be called without parentheses, in both mysql and postgres
131-
let (i, name) = map(
132-
alt((
133-
tag_no_case("now"),
134-
tag_no_case("current_date"),
135-
tag_no_case("current_timestamp"),
136-
tag_no_case("current_time"),
137-
tag_no_case("localtimestamp"),
138-
tag_no_case("localtime"),
139-
)),
140-
|n: LocatedSpan<&[u8]>| {
141-
String::from_utf8(n.to_vec())
142-
.expect("Only constant string literals")
143-
.into()
144-
},
145-
)(i)?;
146-
147-
Ok((
148-
i,
149-
FunctionExpr::Call {
150-
name,
151-
arguments: vec![],
152-
},
153-
))
129+
fn function_call_without_parens(
130+
dialect: Dialect,
131+
) -> impl Fn(LocatedSpan<&[u8]>) -> NomSqlResult<&[u8], FunctionExpr> {
132+
move |i| {
133+
// Some functions can be called without parentheses, in both mysql and postgres
134+
let (i, name) = map(
135+
alt((
136+
tag_no_case("now"),
137+
tag_no_case("current_date"),
138+
tag_no_case("current_timestamp"),
139+
tag_no_case("current_time"),
140+
tag_no_case("localtimestamp"),
141+
tag_no_case("localtime"),
142+
)),
143+
|n: LocatedSpan<&[u8]>| {
144+
let s = String::from_utf8(n.to_vec()).expect("Only constant string literals");
145+
match dialect {
146+
Dialect::MySQL => s.into(),
147+
Dialect::PostgreSQL => s.to_lowercase().into(),
148+
}
149+
},
150+
)(i)?;
151+
152+
Ok((
153+
i,
154+
FunctionExpr::Call {
155+
name,
156+
arguments: vec![],
157+
},
158+
))
159+
}
154160
}
155161

156162
fn timestamp_field() -> impl Fn(LocatedSpan<&[u8]>) -> NomSqlResult<&[u8], TimestampField> {
@@ -400,7 +406,7 @@ pub fn function_expr(
400406
upper(dialect),
401407
substring(dialect),
402408
function_call(dialect),
403-
function_call_without_parens,
409+
function_call_without_parens(dialect),
404410
))(i)
405411
}
406412
}

nom-sql/src/insert.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ mod tests {
324324
Expr::Literal("test".into()),
325325
Expr::Literal("test".into()),
326326
Expr::Call(FunctionExpr::Call {
327-
name: "CURRENT_TIMESTAMP".into(),
327+
name: "current_timestamp".into(),
328328
arguments: vec![],
329329
}),
330330
],],

nom-sql/src/select.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1887,7 +1887,7 @@ mod tests {
18871887
Expr::Literal(Literal::String("foo".to_owned()),)
18881888
),
18891889
FieldDefinitionExpr::from(Expr::Call(FunctionExpr::Call {
1890-
name: "CURRENT_TIME".into(),
1890+
name: "current_time".into(),
18911891
arguments: vec![]
18921892
})),
18931893
],

readyset-sql-parsing/tests/parity.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,3 +325,10 @@ fn test_convert_with_using() {
325325
fn test_empty_insert() {
326326
check_parse_mysql!("INSERT INTO t () VALUES ()");
327327
}
328+
329+
#[test]
330+
fn test_column_default_without_parens() {
331+
check_parse_both!(
332+
"CREATE TABLE IF NOT EXISTS m (version VARCHAR(50) PRIMARY KEY NOT NULL, run_on TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP);"
333+
);
334+
}

0 commit comments

Comments
 (0)