Skip to content

Commit 0456dba

Browse files
authored
parser: pg test suite burn down part 2 (#518)
fixing more errors also deleted the psql related files for now since we don't parse (or lex?) them!
1 parent 43323ef commit 0456dba

38 files changed

+296
-3413
lines changed

PLAN.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,16 @@ type: string
715715

716716
https://code.visualstudio.com/api/language-extensions/semantic-highlight-guide
717717

718+
### VSCode Syntax Highlighting
719+
720+
Aka a non-semantic version
721+
722+
### Monaco Support
723+
724+
- Monaco Syntax Highlighting
725+
726+
### Codemirror Support
727+
718728
### Show Syntax Tree Command
719729

720730
replicate what we have in WASM in IDE

crates/squawk_parser/src/generated/syntax_kind.rs

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/squawk_parser/src/grammar.rs

Lines changed: 71 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1776,6 +1776,13 @@ fn opt_interval_trailing(p: &mut Parser<'_>) {
17761776
(SECOND_KW, _) => {
17771777
interval_second(p);
17781778
}
1779+
(L_PAREN, _) => {
1780+
p.bump(L_PAREN);
1781+
if opt_numeric_literal(p).is_none() {
1782+
p.error("expected number")
1783+
}
1784+
p.bump(R_PAREN);
1785+
}
17791786
_ => (),
17801787
}
17811788
}
@@ -1795,6 +1802,12 @@ fn name_ref_(p: &mut Parser<'_>) -> Option<CompletedMarker> {
17951802
p.expect(ZONE_KW);
17961803
}
17971804
} else if p.eat(INTERVAL_KW) {
1805+
if p.eat(L_PAREN) {
1806+
if opt_numeric_literal(p).is_none() {
1807+
p.error("expected number");
1808+
}
1809+
p.expect(R_PAREN);
1810+
}
17981811
is_interval_cast = true;
17991812
} else {
18001813
p.bump_any();
@@ -2055,8 +2068,12 @@ fn current_op(p: &Parser<'_>, r: &Restrictions) -> (u8, SyntaxKind, Associativit
20552068
OVERLAPS_KW => (7, OVERLAPS_KW, Left),
20562069
// like
20572070
LIKE_KW => (6, LIKE_KW, Left),
2071+
// ilike
2072+
ILIKE_KW => (6, ILIKE_KW, Left),
20582073
// not like
20592074
NOT_KW if !r.not_disabled && p.at(NOT_LIKE) => (6, NOT_LIKE, Left),
2075+
// not ilike
2076+
NOT_KW if !r.not_disabled && p.at(NOT_ILIKE) => (6, NOT_ILIKE, Left),
20602077
// not in
20612078
NOT_KW if !r.not_disabled && p.at(NOT_IN) => (6, NOT_IN, Left),
20622079
// is distinct from
@@ -2713,7 +2730,7 @@ fn data_source(p: &mut Parser<'_>) {
27132730
json_table_fn(p);
27142731
opt_alias(p);
27152732
}
2716-
ROWS_KW => {
2733+
ROWS_KW if p.nth_at(1, FROM_KW) => {
27172734
p.bump(ROWS_KW);
27182735
p.expect(FROM_KW);
27192736
p.expect(L_PAREN);
@@ -3301,8 +3318,18 @@ fn opt_constraint_inner(p: &mut Parser<'_>) -> Option<SyntaxKind> {
33013318
p.expect(ALWAYS_KW);
33023319
}
33033320
p.expect(AS_KW);
3304-
p.expect(IDENTITY_KW);
3305-
opt_sequence_options(p);
3321+
if p.eat(L_PAREN) {
3322+
if expr(p).is_none() {
3323+
p.error("expected an expression");
3324+
}
3325+
p.expect(R_PAREN);
3326+
if !p.eat(STORED_KW) && !p.eat(VIRTUAL_KW) {
3327+
p.error("expected STORED or VIRTUAL");
3328+
}
3329+
} else {
3330+
p.expect(IDENTITY_KW);
3331+
opt_sequence_options(p);
3332+
}
33063333
GENERATED_CONSTRAINT
33073334
} else {
33083335
p.error("expected generated type");
@@ -8264,7 +8291,7 @@ fn create_materialized_view(p: &mut Parser<'_>) -> CompletedMarker {
82648291
},
82658292
);
82668293
match statement.map(|x| x.kind()) {
8267-
Some(SELECT | TABLE | VALUES) => (),
8294+
Some(SELECT | SELECT_INTO | COMPOUND_SELECT | TABLE | VALUES) => (),
82688295
Some(kind) => {
82698296
p.error(format!(
82708297
"expected SELECT, TABLE, or VALUES statement, got {:?}",
@@ -8373,7 +8400,7 @@ fn operator_class_option(p: &mut Parser<'_>) {
83738400
}
83748401
if p.eat(L_PAREN) {
83758402
type_name(p);
8376-
if p.eat(COMMA) {
8403+
while !p.at(EOF) && p.eat(COMMA) {
83778404
type_name(p);
83788405
}
83798406
p.expect(R_PAREN);
@@ -8400,7 +8427,7 @@ fn operator_drop_class_option(p: &mut Parser<'_>) {
84008427
}
84018428
if p.eat(L_PAREN) {
84028429
type_name(p);
8403-
if p.eat(COMMA) {
8430+
while !p.at(EOF) && !p.at(R_PAREN) && p.eat(COMMA) {
84048431
type_name(p);
84058432
}
84068433
p.expect(R_PAREN);
@@ -10045,14 +10072,13 @@ fn grant(p: &mut Parser<'_>) -> CompletedMarker {
1004510072
// ALL [ PRIVILEGES ]
1004610073
if p.eat(ALL_KW) {
1004710074
p.eat(PRIVILEGES_KW);
10075+
opt_column_list(p);
1004810076
} else if !p.at(TO_KW) {
1004910077
revoke_command(p);
1005010078
while !p.at(EOF) && p.eat(COMMA) {
1005110079
revoke_command(p);
1005210080
}
1005310081
}
10054-
// [ ( column_name [, ...] ) ]
10055-
opt_column_list(p);
1005610082
// ON { [ TABLE ] table_name [, ...]
1005710083
// | ALL TABLES IN SCHEMA schema_name [, ...] }
1005810084
// ON { SEQUENCE sequence_name [, ...]
@@ -10295,16 +10321,17 @@ const REVOKE_COMMAND_FIRST: TokenSet = TokenSet::new(&[
1029510321
]);
1029610322

1029710323
fn revoke_command(p: &mut Parser<'_>) {
10298-
if opt_role(p) {
10299-
return;
10300-
}
10301-
if p.eat(ALTER_KW) {
10302-
p.expect(SYSTEM_KW);
10303-
} else if p.at_ts(REVOKE_COMMAND_FIRST) {
10304-
p.bump_any();
10305-
} else {
10306-
p.error(format!("expected command name, got {:?}", p.current()))
10324+
if !opt_role(p) {
10325+
if p.eat(ALTER_KW) {
10326+
p.expect(SYSTEM_KW);
10327+
} else if p.at_ts(REVOKE_COMMAND_FIRST) {
10328+
p.bump_any();
10329+
} else {
10330+
p.error(format!("expected command name, got {:?}", p.current()))
10331+
}
1030710332
}
10333+
// [ ( column_name [, ...] ) ]
10334+
opt_column_list(p);
1030810335
}
1030910336

1031010337
// where role_specification can be:
@@ -10913,19 +10940,24 @@ fn opt_temp(p: &mut Parser<'_>) -> bool {
1091310940
p.eat(TEMP_KW) || p.eat(TEMPORARY_KW)
1091410941
}
1091510942

10916-
// DO [ LANGUAGE lang_name ] code
10917-
fn do_(p: &mut Parser<'_>) -> CompletedMarker {
10918-
assert!(p.at(DO_KW));
10919-
let m = p.start();
10920-
p.bump(DO_KW);
10943+
fn opt_language(p: &mut Parser<'_>) {
1092110944
if p.eat(LANGUAGE_KW) {
1092210945
if p.at_ts(NON_RESERVED_WORD) {
1092310946
p.bump_any();
1092410947
} else {
1092510948
string_literal(p);
1092610949
}
1092710950
}
10951+
}
10952+
10953+
// DO [ LANGUAGE lang_name ] code
10954+
fn do_(p: &mut Parser<'_>) -> CompletedMarker {
10955+
assert!(p.at(DO_KW));
10956+
let m = p.start();
10957+
p.bump(DO_KW);
10958+
opt_language(p);
1092810959
string_literal(p);
10960+
opt_language(p);
1092910961
m.complete(p, DO)
1093010962
}
1093110963

@@ -12155,6 +12187,9 @@ fn param(p: &mut Parser<'_>) {
1215512187
// foo(8)
1215612188
// ^
1215712189
L_PAREN => true,
12190+
// text[]
12191+
// ^
12192+
L_BRACK => true,
1215812193
// float8 order by
1215912194
// ^
1216012195
ORDER_KW => true,
@@ -12163,7 +12198,7 @@ fn param(p: &mut Parser<'_>) {
1216312198
_ => false,
1216412199
};
1216512200
if at_type {
12166-
name_or_type.complete(p, PATH_TYPE);
12201+
type_mods(p, name_or_type, true, PATH_TYPE);
1216712202
} else {
1216812203
name_or_type.complete(p, NAME);
1216912204
if !param_mode_seen {
@@ -12347,12 +12382,19 @@ fn opt_function_option(p: &mut Parser<'_>) -> bool {
1234712382
if p.eat(SEMICOLON) {
1234812383
continue;
1234912384
}
12350-
stmt(
12351-
p,
12352-
&StmtRestrictions {
12353-
begin_end_allowed: false,
12354-
},
12355-
);
12385+
// sql standard
12386+
if p.eat(RETURN_KW) {
12387+
if expr(p).is_none() {
12388+
p.error("expected expr")
12389+
}
12390+
} else {
12391+
stmt(
12392+
p,
12393+
&StmtRestrictions {
12394+
begin_end_allowed: false,
12395+
},
12396+
);
12397+
}
1235612398
if p.at(END_KW) {
1235712399
p.expect(SEMICOLON);
1235812400
}

crates/squawk_parser/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,13 @@ impl<'t> Parser<'t> {
263263
m.complete(self, SyntaxKind::NOT_LIKE);
264264
return true;
265265
}
266+
SyntaxKind::NOT_ILIKE => {
267+
let m = self.start();
268+
self.bump(SyntaxKind::NOT_KW);
269+
self.bump(SyntaxKind::ILIKE_KW);
270+
m.complete(self, SyntaxKind::NOT_ILIKE);
271+
return true;
272+
}
266273
SyntaxKind::NOT_IN => {
267274
let m = self.start();
268275
self.bump(SyntaxKind::NOT_KW);

crates/squawk_parser/tests/data/ok/create_function.sql

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,5 +405,7 @@ create function f(int8)
405405
returns void
406406
as '' language sql;
407407

408-
409-
408+
-- array type
409+
create function f (internal, text[], bool)
410+
returns void
411+
as '' language sql;

crates/squawk_parser/tests/data/ok/create_table.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ create table t
316316
partition of foo.bar
317317
for values from ('bar') to ('buzz');
318318

319+
create table t partition of u (
320+
c generated always as (b * 2) stored
321+
) for values from ('2016-09-01') to ('2016-10-01');
322+
319323
-- missing entries
320324
create table t ();
321325

crates/squawk_parser/tests/data/ok/select_casts.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ select '10 days'::interval year;
8787

8888
select '10 days'::interval month;
8989

90+
select '10 days'::interval(0);
91+
9092
select '10 days'::interval day;
9193

9294
select '10 days'::interval hour;

0 commit comments

Comments
 (0)