Skip to content

Commit dd99b69

Browse files
committed
address reviewer comment
1 parent 126a330 commit dd99b69

8 files changed

Lines changed: 93 additions & 51 deletions

File tree

src/environmentd/tests/testdata/http/post

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ http
239239
{"query":"subscribe (select * from t)"}
240240
----
241241
200 OK
242-
{"results":[{"error":{"message":"unsupported via this API: SUBSCRIBE TO (SELECT * FROM t)","code":"XX000"},"notices":[]}]}
242+
{"results":[{"error":{"message":"unsupported via this API: SUBSCRIBE (SELECT * FROM t)","code":"XX000"},"notices":[]}]}
243243

244244
http
245245
{"query":"copy (select 1) to stdout"}
@@ -460,7 +460,7 @@ http
460460
{"queries":[{"query":"subscribe (select * from t)","params":[]}]}
461461
----
462462
200 OK
463-
{"results":[{"error":{"message":"unsupported via this API: SUBSCRIBE TO (SELECT * FROM t)","code":"XX000"},"notices":[]}]}
463+
{"results":[{"error":{"message":"unsupported via this API: SUBSCRIBE (SELECT * FROM t)","code":"XX000"},"notices":[]}]}
464464

465465
# Test detail and hint error fields.
466466
http

src/sql-parser/src/ast/defs/statement.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3921,11 +3921,14 @@ pub struct SubscribeStatement<T: AstInfo> {
39213921

39223922
impl<T: AstInfo> AstDisplay for SubscribeStatement<T> {
39233923
fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
3924-
// Always emit the optional `TO` keyword. Without it, a relation whose
3925-
// name is the bare keyword `to` (e.g. `SUBSCRIBE TO to`) would display
3926-
// as `SUBSCRIBE to`, which re-parses with `to` consumed as the optional
3927-
// keyword, dropping the relation name.
3928-
f.write_str("SUBSCRIBE TO ");
3924+
f.write_str("SUBSCRIBE ");
3925+
if self.relation.needs_explicit_to(f.simple()) {
3926+
// Without the optional `TO` keyword, a relation whose first name
3927+
// component is the bare keyword `to` (e.g. `SUBSCRIBE TO to`) would
3928+
// display as `SUBSCRIBE to`, which re-parses with `to` consumed as
3929+
// the optional keyword, dropping the relation name.
3930+
f.write_str("TO ");
3931+
}
39293932
f.write_node(&self.relation);
39303933
if !self.options.is_empty() {
39313934
f.write_str(" WITH (");
@@ -3951,6 +3954,25 @@ pub enum SubscribeRelation<T: AstInfo> {
39513954
Query(Query<T>),
39523955
}
39533956

3957+
impl<T: AstInfo> SubscribeRelation<T> {
3958+
/// Reports whether printing this relation after `SUBSCRIBE` requires the
3959+
/// optional `TO` keyword to avoid reparsing the first name component as that
3960+
/// keyword instead of as part of the relation name.
3961+
pub fn needs_explicit_to(&self, bare_identifiers: bool) -> bool {
3962+
let SubscribeRelation::Name(name) = self else {
3963+
return false;
3964+
};
3965+
bare_identifiers && name_starts_with_bare_to(&name.to_ast_string_simple())
3966+
}
3967+
}
3968+
3969+
fn name_starts_with_bare_to(name: &str) -> bool {
3970+
let Some(rest) = name.strip_prefix("to") else {
3971+
return false;
3972+
};
3973+
rest.is_empty() || rest.starts_with('.')
3974+
}
3975+
39543976
impl<T: AstInfo> AstDisplay for SubscribeRelation<T> {
39553977
fn fmt<W: fmt::Write>(&self, f: &mut AstFormatter<W>) {
39563978
match self {

src/sql-parser/tests/testdata/copy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Copy(CopyStatement { relation: Select(SelectStatement { query: Query { ctes: Sim
3737
parse-statement
3838
COPY (subscribe (SELECT 1)) TO STDOUT
3939
----
40-
COPY (SUBSCRIBE TO (SELECT 1)) TO STDOUT
40+
COPY (SUBSCRIBE (SELECT 1)) TO STDOUT
4141
=>
4242
Copy(CopyStatement { relation: Subscribe(SubscribeStatement { relation: Query(Query { ctes: Simple([]), body: Select(Select { distinct: None, projection: [Expr { expr: Value(Number("1")), alias: None }], from: [], selection: None, group_by: [], having: None, qualify: None, options: [] }), order_by: [], limit: None, offset: None }), options: [], as_of: None, up_to: None, output: Diffs }), direction: To, target: Stdout, options: [] })
4343

src/sql-parser/tests/testdata/cursor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Declare(DeclareStatement { name: Ident("c"), stmt: Select(SelectStatement { quer
2323
parse-statement
2424
DECLARE c CURSOR FOR SUBSCRIBE t
2525
----
26-
DECLARE c CURSOR FOR SUBSCRIBE TO t
26+
DECLARE c CURSOR FOR SUBSCRIBE t
2727
=>
2828
Declare(DeclareStatement { name: Ident("c"), stmt: Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("t")]))), options: [], as_of: None, up_to: None, output: Diffs }), sql: "SUBSCRIBE t" })
2929

src/sql-parser/tests/testdata/ddl

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,42 +1337,56 @@ DropObjects(DropObjectsStatement { object_type: Index, if_exists: true, names: [
13371337
parse-statement
13381338
SUBSCRIBE foo.bar
13391339
----
1340-
SUBSCRIBE TO foo.bar
1340+
SUBSCRIBE foo.bar
13411341
=>
13421342
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: None, up_to: None, output: Diffs })
13431343

13441344
parse-statement
13451345
SUBSCRIBE TO foo.bar
13461346
----
1347-
SUBSCRIBE TO foo.bar
1347+
SUBSCRIBE foo.bar
13481348
=>
13491349
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: None, up_to: None, output: Diffs })
13501350

1351+
parse-statement
1352+
SUBSCRIBE TO to
1353+
----
1354+
SUBSCRIBE TO to
1355+
=>
1356+
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("to")]))), options: [], as_of: None, up_to: None, output: Diffs })
1357+
1358+
parse-statement
1359+
SUBSCRIBE TO to.foo
1360+
----
1361+
SUBSCRIBE TO to.foo
1362+
=>
1363+
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("to"), Ident("foo")]))), options: [], as_of: None, up_to: None, output: Diffs })
1364+
13511365
parse-statement
13521366
SUBSCRIBE foo.bar AS OF 123
13531367
----
1354-
SUBSCRIBE TO foo.bar AS OF 123
1368+
SUBSCRIBE foo.bar AS OF 123
13551369
=>
13561370
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: Some(At(Value(Number("123")))), up_to: None, output: Diffs })
13571371

13581372
parse-statement
13591373
SUBSCRIBE foo.bar AS OF now()
13601374
----
1361-
SUBSCRIBE TO foo.bar AS OF now()
1375+
SUBSCRIBE foo.bar AS OF now()
13621376
=>
13631377
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: Some(At(Function(Function { name: Name(UnresolvedItemName([Ident("now")])), args: Args { args: [], order_by: [] }, filter: None, over: None, distinct: false }))), up_to: None, output: Diffs })
13641378

13651379
parse-statement
13661380
SUBSCRIBE foo.bar WITH (SNAPSHOT) AS OF now()
13671381
----
1368-
SUBSCRIBE TO foo.bar WITH (SNAPSHOT) AS OF now()
1382+
SUBSCRIBE foo.bar WITH (SNAPSHOT) AS OF now()
13691383
=>
13701384
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [SubscribeOption { name: Snapshot, value: None }], as_of: Some(At(Function(Function { name: Name(UnresolvedItemName([Ident("now")])), args: Args { args: [], order_by: [] }, filter: None, over: None, distinct: false }))), up_to: None, output: Diffs })
13711385

13721386
parse-statement
13731387
SUBSCRIBE foo.bar WITH (PROGRESS) AS OF now()
13741388
----
1375-
SUBSCRIBE TO foo.bar WITH (PROGRESS) AS OF now()
1389+
SUBSCRIBE foo.bar WITH (PROGRESS) AS OF now()
13761390
=>
13771391
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [SubscribeOption { name: Progress, value: None }], as_of: Some(At(Function(Function { name: Name(UnresolvedItemName([Ident("now")])), args: Args { args: [], order_by: [] }, filter: None, over: None, distinct: false }))), up_to: None, output: Diffs })
13781392

@@ -1386,35 +1400,35 @@ SUBSCRIBE foo.bar WITH (SNAPSHOT = false, TIMESTAMPS) AS OF now()
13861400
parse-statement
13871401
SUBSCRIBE foo.bar WITH (SNAPSHOT false)
13881402
----
1389-
SUBSCRIBE TO foo.bar WITH (SNAPSHOT = false)
1403+
SUBSCRIBE foo.bar WITH (SNAPSHOT = false)
13901404
=>
13911405
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [SubscribeOption { name: Snapshot, value: Some(Value(Boolean(false))) }], as_of: None, up_to: None, output: Diffs })
13921406

13931407
parse-statement
13941408
SUBSCRIBE (SELECT * FROM a)
13951409
----
1396-
SUBSCRIBE TO (SELECT * FROM a)
1410+
SUBSCRIBE (SELECT * FROM a)
13971411
=>
13981412
Subscribe(SubscribeStatement { relation: Query(Query { ctes: Simple([]), body: Select(Select { distinct: None, projection: [Wildcard], from: [TableWithJoins { relation: Table { name: Name(UnresolvedItemName([Ident("a")])), alias: None }, joins: [] }], selection: None, group_by: [], having: None, qualify: None, options: [] }), order_by: [], limit: None, offset: None }), options: [], as_of: None, up_to: None, output: Diffs })
13991413

14001414
parse-statement
14011415
SUBSCRIBE foo.bar AS OF now() UP TO now() + interval '1' day
14021416
----
1403-
SUBSCRIBE TO foo.bar AS OF now() UP TO now() + INTERVAL '1' DAY
1417+
SUBSCRIBE foo.bar AS OF now() UP TO now() + INTERVAL '1' DAY
14041418
=>
14051419
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: Some(At(Function(Function { name: Name(UnresolvedItemName([Ident("now")])), args: Args { args: [], order_by: [] }, filter: None, over: None, distinct: false }))), up_to: Some(Op { op: Op { namespace: None, op: "+" }, expr1: Function(Function { name: Name(UnresolvedItemName([Ident("now")])), args: Args { args: [], order_by: [] }, filter: None, over: None, distinct: false }), expr2: Some(Value(Interval(IntervalValue { value: "1", precision_high: Year, precision_low: Day, fsec_max_precision: None }))) }), output: Diffs })
14061420

14071421
parse-statement
14081422
SUBSCRIBE foo.bar UP TO now() + interval '1' day
14091423
----
1410-
SUBSCRIBE TO foo.bar UP TO now() + INTERVAL '1' DAY
1424+
SUBSCRIBE foo.bar UP TO now() + INTERVAL '1' DAY
14111425
=>
14121426
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: None, up_to: Some(Op { op: Op { namespace: None, op: "+" }, expr1: Function(Function { name: Name(UnresolvedItemName([Ident("now")])), args: Args { args: [], order_by: [] }, filter: None, over: None, distinct: false }), expr2: Some(Value(Interval(IntervalValue { value: "1", precision_high: Year, precision_low: Day, fsec_max_precision: None }))) }), output: Diffs })
14131427

14141428
parse-statement
14151429
SUBSCRIBE foo.bar AS OF AT LEAST 1
14161430
----
1417-
SUBSCRIBE TO foo.bar AS OF AT LEAST 1
1431+
SUBSCRIBE foo.bar AS OF AT LEAST 1
14181432
=>
14191433
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: Some(AtLeast(Value(Number("1")))), up_to: None, output: Diffs })
14201434

@@ -1435,7 +1449,7 @@ SUBSCRIBE foo.bar ENVELOPE UPSERT KEY (a, b, c, d, e)
14351449
parse-statement
14361450
SUBSCRIBE foo.bar ENVELOPE UPSERT (KEY (a, b, c, d, e))
14371451
----
1438-
SUBSCRIBE TO foo.bar ENVELOPE UPSERT (KEY (a, b, c, d, e))
1452+
SUBSCRIBE foo.bar ENVELOPE UPSERT (KEY (a, b, c, d, e))
14391453
=>
14401454
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: None, up_to: None, output: EnvelopeUpsert { key_columns: [Ident("a"), Ident("b"), Ident("c"), Ident("d"), Ident("e")] } })
14411455

@@ -1456,14 +1470,14 @@ SUBSCRIBE foo.bar ENVELOPE DEBEZIUM KEY (a, b, c, d, e)
14561470
parse-statement
14571471
SUBSCRIBE foo.bar ENVELOPE DEBEZIUM (KEY (c))
14581472
----
1459-
SUBSCRIBE TO foo.bar ENVELOPE DEBEZIUM (KEY (c))
1473+
SUBSCRIBE foo.bar ENVELOPE DEBEZIUM (KEY (c))
14601474
=>
14611475
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: None, up_to: None, output: EnvelopeDebezium { key_columns: [Ident("c")] } })
14621476

14631477
parse-statement
14641478
SUBSCRIBE foo.bar ENVELOPE DEBEZIUM (KEY (a, b, c, d, e))
14651479
----
1466-
SUBSCRIBE TO foo.bar ENVELOPE DEBEZIUM (KEY (a, b, c, d, e))
1480+
SUBSCRIBE foo.bar ENVELOPE DEBEZIUM (KEY (a, b, c, d, e))
14671481
=>
14681482
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: None, up_to: None, output: EnvelopeDebezium { key_columns: [Ident("a"), Ident("b"), Ident("c"), Ident("d"), Ident("e")] } })
14691483

@@ -1485,14 +1499,14 @@ SUBSCRIBE foo.bar ENVELOPE
14851499
parse-statement
14861500
SUBSCRIBE foo.bar WITHIN TIMESTAMP ORDER BY a ASC NULLS LAST, b, c DESC
14871501
----
1488-
SUBSCRIBE TO foo.bar WITHIN TIMESTAMP ORDER BY a ASC NULLS LAST, b, c DESC
1502+
SUBSCRIBE foo.bar WITHIN TIMESTAMP ORDER BY a ASC NULLS LAST, b, c DESC
14891503
=>
14901504
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: None, up_to: None, output: WithinTimestampOrderBy { order_by: [OrderByExpr { expr: Identifier([Ident("a")]), asc: Some(true), nulls_last: Some(true) }, OrderByExpr { expr: Identifier([Ident("b")]), asc: None, nulls_last: None }, OrderByExpr { expr: Identifier([Ident("c")]), asc: Some(false), nulls_last: None }] } })
14911505

14921506
parse-statement
14931507
SUBSCRIBE (SELECT *, f1 + f2 FROM foo.bar) WITHIN TIMESTAMP ORDER BY foo.bar.baz DESC, f1 + f2
14941508
----
1495-
SUBSCRIBE TO (SELECT *, f1 + f2 FROM foo.bar) WITHIN TIMESTAMP ORDER BY foo.bar.baz DESC, f1 + f2
1509+
SUBSCRIBE (SELECT *, f1 + f2 FROM foo.bar) WITHIN TIMESTAMP ORDER BY foo.bar.baz DESC, f1 + f2
14961510
=>
14971511
Subscribe(SubscribeStatement { relation: Query(Query { ctes: Simple([]), body: Select(Select { distinct: None, projection: [Wildcard, Expr { expr: Op { op: Op { namespace: None, op: "+" }, expr1: Identifier([Ident("f1")]), expr2: Some(Identifier([Ident("f2")])) }, alias: None }], from: [TableWithJoins { relation: Table { name: Name(UnresolvedItemName([Ident("foo"), Ident("bar")])), alias: None }, joins: [] }], selection: None, group_by: [], having: None, qualify: None, options: [] }), order_by: [], limit: None, offset: None }), options: [], as_of: None, up_to: None, output: WithinTimestampOrderBy { order_by: [OrderByExpr { expr: Identifier([Ident("foo"), Ident("bar"), Ident("baz")]), asc: Some(false), nulls_last: None }, OrderByExpr { expr: Op { op: Op { namespace: None, op: "+" }, expr1: Identifier([Ident("f1")]), expr2: Some(Identifier([Ident("f2")])) }, asc: None, nulls_last: None }] } })
14981512

@@ -1507,21 +1521,21 @@ SUBSCRIBE foo.bar WITHIN TIMESTAMP ORDER BY
15071521
parse-statement
15081522
SUBSCRIBE foo.bar ENVELOPE UPSERT (KEY (a)) AS OF 1 UP TO 2
15091523
----
1510-
SUBSCRIBE TO foo.bar AS OF 1 UP TO 2 ENVELOPE UPSERT (KEY (a))
1524+
SUBSCRIBE foo.bar AS OF 1 UP TO 2 ENVELOPE UPSERT (KEY (a))
15111525
=>
15121526
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: Some(At(Value(Number("1")))), up_to: Some(Value(Number("2"))), output: EnvelopeUpsert { key_columns: [Ident("a")] } })
15131527

15141528
parse-statement
15151529
SUBSCRIBE foo.bar ENVELOPE UPSERT (KEY (a)) AS OF 1
15161530
----
1517-
SUBSCRIBE TO foo.bar AS OF 1 ENVELOPE UPSERT (KEY (a))
1531+
SUBSCRIBE foo.bar AS OF 1 ENVELOPE UPSERT (KEY (a))
15181532
=>
15191533
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: Some(At(Value(Number("1")))), up_to: None, output: EnvelopeUpsert { key_columns: [Ident("a")] } })
15201534

15211535
parse-statement
15221536
SUBSCRIBE foo.bar ENVELOPE UPSERT (KEY (a)) WITH (SNAPSHOT = true)
15231537
----
1524-
SUBSCRIBE TO foo.bar WITH (SNAPSHOT = true) ENVELOPE UPSERT (KEY (a))
1538+
SUBSCRIBE foo.bar WITH (SNAPSHOT = true) ENVELOPE UPSERT (KEY (a))
15251539
=>
15261540
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [SubscribeOption { name: Snapshot, value: Some(Value(Boolean(true))) }], as_of: None, up_to: None, output: EnvelopeUpsert { key_columns: [Ident("a")] } })
15271541

@@ -1535,7 +1549,7 @@ SUBSCRIBE foo.bar ENVELOPE UPSERT (KEY (a)) WITH (SNAPSHOT = true) WITHIN TIMEST
15351549
parse-statement
15361550
SUBSCRIBE foo.bar ENVELOPE UPSERT (KEY (a)) UP TO 2
15371551
----
1538-
SUBSCRIBE TO foo.bar UP TO 2 ENVELOPE UPSERT (KEY (a))
1552+
SUBSCRIBE foo.bar UP TO 2 ENVELOPE UPSERT (KEY (a))
15391553
=>
15401554
Subscribe(SubscribeStatement { relation: Name(Name(UnresolvedItemName([Ident("foo"), Ident("bar")]))), options: [], as_of: None, up_to: Some(Value(Number("2"))), output: EnvelopeUpsert { key_columns: [Ident("a")] } })
15411555

0 commit comments

Comments
 (0)