Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 27 additions & 32 deletions crates/squawk_parser/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ fn json_object_fn_arg_list(p: &mut Parser<'_>) {
p.bump(COMMA);
continue;
} else {
p.error("expected a comma");
p.err_and_bump("expected a comma");
}
}
opt_json_null_clause(p);
Expand Down Expand Up @@ -2064,7 +2064,7 @@ fn opt_interval_trailing(p: &mut Parser<'_>) {
if opt_numeric_literal(p).is_none() {
p.error("expected number")
}
p.bump(R_PAREN);
p.expect(R_PAREN);
}
_ => (),
}
Expand Down Expand Up @@ -3031,7 +3031,6 @@ const JOIN_TYPE_FIRST: TokenSet =
// RIGHT [ OUTER ] JOIN
// FULL [ OUTER ] JOIN
fn join_type(p: &mut Parser<'_>) -> Option<CompletedMarker> {
assert!(p.at_ts(JOIN_TYPE_FIRST));
let m = p.start();
let kind = match p.current() {
CROSS_KW => {
Expand Down Expand Up @@ -4098,9 +4097,8 @@ fn opt_virtual_or_stored(p: &mut Parser<'_>) {
fn opt_no_inherit(p: &mut Parser<'_>) {
let m = p.start();
if p.eat(NO_KW) {
if p.eat(INHERIT_KW) {
m.complete(p, NO_INHERIT);
}
p.expect(INHERIT_KW);
m.complete(p, NO_INHERIT);
} else {
m.abandon(p);
}
Expand Down Expand Up @@ -5895,7 +5893,7 @@ fn stmt(p: &mut Parser, r: &StmtRestrictions) -> Option<CompletedMarker> {
PARSER_KW => Some(alter_text_search_parser(p)),
TEMPLATE_KW => Some(alter_text_search_template(p)),
_ => {
p.error("expected TEMPLATE, CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE");
p.err_and_bump("expected TEMPLATE, CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE");
None
}
},
Expand Down Expand Up @@ -5991,7 +5989,7 @@ fn stmt(p: &mut Parser, r: &StmtRestrictions) -> Option<CompletedMarker> {
PARSER_KW => Some(create_text_search_parser(p)),
TEMPLATE_KW => Some(create_text_search_template(p)),
_ => {
p.error("expected TEMPLATE, CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE");
p.err_and_bump("expected TEMPLATE, CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE");
None
}
},
Expand Down Expand Up @@ -6019,7 +6017,7 @@ fn stmt(p: &mut Parser, r: &StmtRestrictions) -> Option<CompletedMarker> {
DATA_KW => Some(drop_foreign_data(p)),
TABLE_KW => Some(drop_foreign_table(p)),
_ => {
p.error("expected DATA or TABLE");
p.err_and_bump("expected DATA or TABLE");
None
}
},
Expand Down Expand Up @@ -6054,7 +6052,7 @@ fn stmt(p: &mut Parser, r: &StmtRestrictions) -> Option<CompletedMarker> {
PARSER_KW => Some(drop_text_search_parser(p)),
TEMPLATE_KW => Some(drop_text_search_template(p)),
_ => {
p.error("expected TEMPLATE, CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE");
p.err_and_bump("expected TEMPLATE, CONFIGURATION, DICTIONARY, PARSER, or TEMPLATE");
None
}
},
Expand Down Expand Up @@ -6300,7 +6298,11 @@ fn alter_rule(p: &mut Parser<'_>) -> CompletedMarker {
p.bump(RULE_KW);
name_ref(p);
on_table(p);
rename_to(p);
if p.at(RENAME_KW) {
rename_to(p);
} else {
p.error("expected RENAME");
}
p.eat(SEMICOLON);
m.complete(p, ALTER_RULE)
}
Expand Down Expand Up @@ -6911,7 +6913,7 @@ fn alter_index(p: &mut Parser<'_>) -> CompletedMarker {
} else {
DEPENDS_ON_EXTENSION
};
p.bump(DEPENDS_KW);
p.expect(DEPENDS_KW);
p.expect(ON_KW);
p.expect(EXTENSION_KW);
path_name_ref(p);
Expand Down Expand Up @@ -7105,17 +7107,12 @@ fn alter_foreign_table(p: &mut Parser<'_>) -> CompletedMarker {
// ALTER FOREIGN DATA WRAPPER name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
// ALTER FOREIGN DATA WRAPPER name RENAME TO new_name
fn alter_foreign_data_wrapper(p: &mut Parser<'_>) -> CompletedMarker {
assert!(
p.at(ALTER_KW)
&& p.nth_at(1, FOREIGN_KW)
&& p.nth_at(2, DATA_KW)
&& p.nth_at(3, WRAPPER_KW)
);
assert!(p.at(ALTER_KW) && p.nth_at(1, FOREIGN_KW) && p.nth_at(2, DATA_KW));
let m = p.start();
p.bump(ALTER_KW);
p.bump(FOREIGN_KW);
p.bump(DATA_KW);
p.bump(WRAPPER_KW);
p.expect(WRAPPER_KW);
name_ref(p);
let found_option = match p.current() {
OWNER_KW => {
Expand Down Expand Up @@ -7303,7 +7300,7 @@ fn alter_extension(p: &mut Parser<'_>) -> CompletedMarker {
}
LANGUAGE_KW | PROCEDURAL_KW => {
p.eat(PROCEDURAL_KW);
p.bump(LANGUAGE_KW);
p.expect(LANGUAGE_KW);
name_ref(p);
}
TEXT_KW => {
Expand Down Expand Up @@ -10714,14 +10711,12 @@ fn function_sig_list(p: &mut Parser<'_>) {

// DROP FOREIGN DATA WRAPPER [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
fn drop_foreign_data(p: &mut Parser<'_>) -> CompletedMarker {
assert!(
p.at(DROP_KW) && p.nth_at(1, FOREIGN_KW) && p.nth_at(2, DATA_KW) && p.nth_at(3, WRAPPER_KW)
);
assert!(p.at(DROP_KW) && p.nth_at(1, FOREIGN_KW) && p.nth_at(2, DATA_KW));
let m = p.start();
p.bump(DROP_KW);
p.bump(FOREIGN_KW);
p.bump(DATA_KW);
p.bump(WRAPPER_KW);
p.expect(WRAPPER_KW);
opt_if_exists(p);
name_ref_list(p);
opt_cascade_or_restrict(p);
Expand All @@ -10745,11 +10740,11 @@ fn drop_foreign_table(p: &mut Parser<'_>) -> CompletedMarker {

// DROP ACCESS METHOD [ IF EXISTS ] name [ CASCADE | RESTRICT ]
fn drop_access_method(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(DROP_KW) && p.nth_at(1, ACCESS_KW) && p.nth_at(2, METHOD_KW));
assert!(p.at(DROP_KW) && p.nth_at(1, ACCESS_KW));
let m = p.start();
p.bump(DROP_KW);
p.bump(ACCESS_KW);
p.bump(METHOD_KW);
p.expect(METHOD_KW);
opt_if_exists(p);
name_ref(p);
opt_cascade_or_restrict(p);
Expand Down Expand Up @@ -10848,11 +10843,11 @@ fn drop_domain(p: &mut Parser<'_>) -> CompletedMarker {

// DROP EVENT TRIGGER [ IF EXISTS ] name [ CASCADE | RESTRICT ]
fn drop_event_trigger(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(DROP_KW) && p.nth_at(1, EVENT_KW) && p.nth_at(2, TRIGGER_KW));
assert!(p.at(DROP_KW) && p.nth_at(1, EVENT_KW));
let m = p.start();
p.bump(DROP_KW);
p.bump(EVENT_KW);
p.bump(TRIGGER_KW);
p.expect(TRIGGER_KW);
opt_if_exists(p);
name_ref(p);
opt_cascade_or_restrict(p);
Expand All @@ -10875,11 +10870,11 @@ fn drop_extension(p: &mut Parser<'_>) -> CompletedMarker {

// DROP MATERIALIZED VIEW [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
fn drop_materialized_view(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(DROP_KW) && p.nth_at(1, MATERIALIZED_KW) && p.nth_at(2, VIEW_KW));
assert!(p.at(DROP_KW) && p.nth_at(1, MATERIALIZED_KW));
let m = p.start();
p.bump(DROP_KW);
p.bump(MATERIALIZED_KW);
p.bump(VIEW_KW);
p.expect(VIEW_KW);
opt_if_exists(p);
path_name_ref_list(p);
opt_cascade_or_restrict(p);
Expand Down Expand Up @@ -14150,7 +14145,7 @@ fn create_index(p: &mut Parser<'_>) -> CompletedMarker {
let m = p.start();
p.bump(CREATE_KW);
p.eat(UNIQUE_KW);
p.bump(INDEX_KW);
p.expect(INDEX_KW);
p.eat(CONCURRENTLY_KW);
// [ [ IF NOT EXISTS ] name ]
if opt_if_not_exists(p).is_some() {
Expand Down Expand Up @@ -15290,7 +15285,7 @@ fn opt_alter_table_action(p: &mut Parser<'_>) -> Option<CompletedMarker> {
CLUSTER_KW => {
let m = p.start();
p.bump(CLUSTER_KW);
p.bump(ON_KW);
p.expect(ON_KW);
name_ref(p);
m.complete(p, CLUSTER_ON)
}
Expand Down
3 changes: 3 additions & 0 deletions crates/squawk_parser/tests/data/err/alter_extension.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- PROCEDURAL with no LANGUAGE
alter extension e add procedural;
alter extension e drop procedural;
2 changes: 2 additions & 0 deletions crates/squawk_parser/tests/data/err/alter_index.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- missing trailing depends
alter index idx no;
2 changes: 2 additions & 0 deletions crates/squawk_parser/tests/data/err/create_domain.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- missing trailing inherit
create domain d as int check (v > 0) no;
3 changes: 3 additions & 0 deletions crates/squawk_parser/tests/data/err/create_table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ create table t (a text,);
-- missing columns / constraints
create table t (,,,,,);

-- missing inherit
create table t ( c int check (c > 10) no;

-- a column list with SET DEFAULT is only supported for ON DELETE actions
create table t (
a int,
Expand Down
4 changes: 4 additions & 0 deletions crates/squawk_parser/tests/data/err/join_natural.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- NATURAL with no following join type
merge into t using u natural;
select * from a natural;
select * from a join natural;
4 changes: 4 additions & 0 deletions crates/squawk_parser/tests/data/err/json_object.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- avoid parser getting stuck
select json_object(]);
select json_object(;);
select json_object(1, ]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
source: crates/squawk_parser/tests/tests.rs
input_file: crates/squawk_parser/tests/data/err/alter_extension.sql
---
SOURCE_FILE
COMMENT "-- PROCEDURAL with no LANGUAGE"
WHITESPACE "\n"
ALTER_EXTENSION
ALTER_KW "alter"
WHITESPACE " "
EXTENSION_KW "extension"
WHITESPACE " "
NAME_REF
IDENT "e"
WHITESPACE " "
ADD_KW "add"
WHITESPACE " "
PROCEDURAL_KW "procedural"
SEMICOLON ";"
WHITESPACE "\n"
ALTER_EXTENSION
ALTER_KW "alter"
WHITESPACE " "
EXTENSION_KW "extension"
WHITESPACE " "
NAME_REF
IDENT "e"
WHITESPACE " "
DROP_KW "drop"
WHITESPACE " "
PROCEDURAL_KW "procedural"
SEMICOLON ";"
WHITESPACE "\n"
---
error[syntax-error]: expected LANGUAGE_KW
╭▸
2 │ alter extension e add procedural;
╰╴ ━
error[syntax-error]: expected name
╭▸
2 │ alter extension e add procedural;
╰╴ ━
error[syntax-error]: expected LANGUAGE_KW
╭▸
3 │ alter extension e drop procedural;
╰╴ ━
error[syntax-error]: expected name
╭▸
3 │ alter extension e drop procedural;
╰╴ ━
38 changes: 38 additions & 0 deletions crates/squawk_parser/tests/snapshots/tests__alter_index_err.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
source: crates/squawk_parser/tests/tests.rs
input_file: crates/squawk_parser/tests/data/err/alter_index.sql
---
SOURCE_FILE
COMMENT "-- missing trailing depends"
WHITESPACE "\n"
ALTER_INDEX
ALTER_KW "alter"
WHITESPACE " "
INDEX_KW "index"
WHITESPACE " "
PATH
PATH_SEGMENT
NAME_REF
IDENT "idx"
WHITESPACE " "
NO_DEPENDS_ON_EXTENSION
NO_KW "no"
SEMICOLON ";"
WHITESPACE "\n"
---
error[syntax-error]: expected DEPENDS_KW
╭▸
2 │ alter index idx no;
╰╴ ━
error[syntax-error]: expected ON_KW
╭▸
2 │ alter index idx no;
╰╴ ━
error[syntax-error]: expected EXTENSION_KW
╭▸
2 │ alter index idx no;
╰╴ ━
error[syntax-error]: expected path name
╭▸
2 │ alter index idx no;
╰╴ ━
48 changes: 48 additions & 0 deletions crates/squawk_parser/tests/snapshots/tests__create_domain_err.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
source: crates/squawk_parser/tests/tests.rs
input_file: crates/squawk_parser/tests/data/err/create_domain.sql
---
SOURCE_FILE
COMMENT "-- missing trailing inherit"
WHITESPACE "\n"
CREATE_DOMAIN
CREATE_KW "create"
WHITESPACE " "
DOMAIN_KW "domain"
WHITESPACE " "
PATH
PATH_SEGMENT
NAME
IDENT "d"
WHITESPACE " "
AS_KW "as"
WHITESPACE " "
PATH_TYPE
PATH
PATH_SEGMENT
NAME_REF
INT_KW "int"
WHITESPACE " "
CHECK_CONSTRAINT
CHECK_KW "check"
WHITESPACE " "
L_PAREN "("
BIN_EXPR
NAME_REF
IDENT "v"
WHITESPACE " "
R_ANGLE ">"
WHITESPACE " "
LITERAL
INT_NUMBER "0"
R_PAREN ")"
WHITESPACE " "
NO_INHERIT
NO_KW "no"
SEMICOLON ";"
WHITESPACE "\n"
---
error[syntax-error]: expected INHERIT_KW
╭▸
2 │ create domain d as int check (v > 0) no;
╰╴ ━
Loading
Loading