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
4 changes: 2 additions & 2 deletions crates/squawk_ide/src/column_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ fn name_from_name_ref(
}
SyntaxKind::FLOAT_KW => {
let precision = arg_list.and_then(|arg| {
arg.args_().find_map(|arg| {
if let ast::Expr::Literal(lit) = arg.expr()? {
arg.args().find_map(|arg| {
if let ast::Arg::Expr(ast::Expr::Literal(lit)) = arg {
lit.syntax().text().to_string().parse::<u32>().ok()
} else {
None
Expand Down
2 changes: 2 additions & 0 deletions crates/squawk_ide/src/expand_selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ const DELIMITED_LIST_KINDS: &[SyntaxKind] = &[
SyntaxKind::ARG_LIST,
SyntaxKind::ATTRIBUTE_LIST,
SyntaxKind::BEGIN_FUNC_OPTION_LIST,
SyntaxKind::CHECKPOINT_OPTION_LIST,
SyntaxKind::COLUMN_LIST,
SyntaxKind::CONFLICT_INDEX_ITEM_LIST,
SyntaxKind::CONSTRAINT_EXCLUSION_LIST,
SyntaxKind::COPY_OPTION_LIST,
SyntaxKind::DROP_OP_CLASS_OPTION_LIST,
SyntaxKind::EXPLAIN_OPTION_LIST,
SyntaxKind::FDW_OPTION_LIST,
SyntaxKind::FUNCTION_SIG_LIST,
SyntaxKind::GROUP_BY_LIST,
Expand Down
2 changes: 2 additions & 0 deletions crates/squawk_ide/src/folding_ranges.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,13 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
| SyntaxKind::ALTER_OPTION_LIST
| SyntaxKind::ATTRIBUTE_LIST
| SyntaxKind::BEGIN_FUNC_OPTION_LIST
| SyntaxKind::CHECKPOINT_OPTION_LIST
| SyntaxKind::COLUMN_LIST
| SyntaxKind::CONFLICT_INDEX_ITEM_LIST
| SyntaxKind::CONSTRAINT_EXCLUSION_LIST
| SyntaxKind::COPY_OPTION_LIST
| SyntaxKind::DATABASE_OPTION_LIST
| SyntaxKind::EXPLAIN_OPTION_LIST
| SyntaxKind::DROP_OP_CLASS_OPTION_LIST
| SyntaxKind::FDW_OPTION_LIST
| SyntaxKind::FUNCTION_SIG_LIST
Expand Down
4 changes: 2 additions & 2 deletions crates/squawk_ide/src/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -749,11 +749,11 @@ fn fallback_type_alias(type_name: &Name) -> Option<Name> {

fn resolve_float_precision(name_ref: &ast::NameRef, type_name: Name) -> Name {
if type_name.0.as_str() == "float"
&& let Some(ast::Expr::Literal(lit)) = name_ref
&& let Some(ast::Arg::Expr(ast::Expr::Literal(lit))) = name_ref
.syntax()
.ancestors()
.find_map(ast::PathType::cast)
.and_then(|x| x.arg_list()?.args_().next()?.expr())
.and_then(|x| x.arg_list()?.args().next())
{
let precision: u32 = lit.syntax().text().to_string().parse().unwrap_or(0);
return Name::from_string(if precision <= 24 { "float4" } else { "float8" });
Expand Down
6 changes: 5 additions & 1 deletion crates/squawk_parser/src/generated/syntax_kind.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

115 changes: 81 additions & 34 deletions crates/squawk_parser/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1789,16 +1789,7 @@ fn type_mods(
COMMA,
|| "unexpected comma".to_string(),
EXPR_FIRST,
|p| {
let m = p.start();
if expr(p).is_some() {
m.complete(p, ARG);
true
} else {
m.abandon(p);
false
}
},
|p| expr(p).is_some(),
);
m.complete(p, ARG_LIST);
}
Expand Down Expand Up @@ -3884,6 +3875,10 @@ fn opt_column_constraint(p: &mut Parser<'_>) -> Option<CompletedMarker> {
// [ column_constraint [ ... ] ]
fn opt_column_constraint_list(p: &mut Parser<'_>) {
while !p.at(EOF) {
if p.at(COLLATE_KW) {
opt_collate(p);
continue;
}
if opt_column_constraint(p).is_none() {
break;
}
Expand Down Expand Up @@ -5582,9 +5577,10 @@ fn opt_on_commit(p: &mut Parser<'_>) -> Option<CompletedMarker> {
fn commit(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(COMMIT_KW) || p.at(END_KW));
let m = p.start();
let is_commit = p.at(COMMIT_KW);
p.bump_any();
// PREPARED transaction_id
if p.eat(PREPARED_KW) {
if is_commit && p.eat(PREPARED_KW) {
string_literal(p);
} else {
// [ WORK | TRANSACTION ] [ AND [ NO ] CHAIN ]
Expand Down Expand Up @@ -10365,8 +10361,10 @@ fn create_text_search_template(p: &mut Parser<'_>) -> CompletedMarker {
}

// CREATE [ OR REPLACE ] TRANSFORM FOR type_name LANGUAGE lang_name (
// FROM SQL WITH FUNCTION from_sql_function_name [ (argument_type [, ...]) ],
// TO SQL WITH FUNCTION to_sql_function_name [ (argument_type [, ...]) ]
// FROM SQL WITH FUNCTION from_sql_function_name [ (argument_type [, ...]) ]
// | TO SQL WITH FUNCTION to_sql_function_name [ (argument_type [, ...]) ]
// [, FROM SQL WITH FUNCTION from_sql_function_name [ (argument_type [, ...]) ]
// | TO SQL WITH FUNCTION to_sql_function_name [ (argument_type [, ...]) ]]
// );
fn create_transform(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(CREATE_KW));
Expand All @@ -10379,14 +10377,23 @@ fn create_transform(p: &mut Parser<'_>) -> CompletedMarker {
p.expect(LANGUAGE_KW);
name_ref(p);
p.expect(L_PAREN);
transform_from_func(p);
p.expect(COMMA);
transform_to_func(p);
transform_func(p);
if p.eat(COMMA) {
transform_func(p);
}
p.expect(R_PAREN);
p.eat(SEMICOLON);
m.complete(p, CREATE_TRANSFORM)
}

fn transform_func(p: &mut Parser<'_>) {
match p.current() {
FROM_KW => transform_from_func(p),
TO_KW => transform_to_func(p),
_ => p.error("expected transform function"),
}
}

fn transform_to_func(p: &mut Parser<'_>) {
let m = p.start();
p.expect(TO_KW);
Expand Down Expand Up @@ -11147,8 +11154,9 @@ fn explain(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(EXPLAIN_KW));
let m = p.start();
p.bump(EXPLAIN_KW);
let pre_pg_9_syntax = p.eat(ANALYZE_KW) || p.eat(VERBOSE_KW);
if !pre_pg_9_syntax {
let has_analyze = p.eat(ANALYZE_KW) || p.eat(ANALYSE_KW);
let has_verbose = p.eat(VERBOSE_KW);
if !(has_analyze || has_verbose) {
opt_explain_option_list(p);
}
// statement is SELECT, INSERT, UPDATE, DELETE, MERGE, VALUES, EXECUTE, DECLARE, CREATE TABLE AS, or CREATE MATERIALIZED VIEW AS
Expand Down Expand Up @@ -11183,10 +11191,11 @@ fn explain(p: &mut Parser<'_>) -> CompletedMarker {
m.complete(p, EXPLAIN)
}

fn opt_explain_option_list(p: &mut Parser<'_>) {
fn opt_explain_option_list(p: &mut Parser<'_>) -> Option<CompletedMarker> {
if !p.at(L_PAREN) || (p.at(L_PAREN) && p.nth_at_ts(1, SELECT_FIRST)) {
return;
return None;
}
let m = p.start();
delimited(
p,
L_PAREN,
Expand All @@ -11196,6 +11205,7 @@ fn opt_explain_option_list(p: &mut Parser<'_>) {
EXPLAIN_OPTION_FIRST,
opt_explain_option,
);
Some(m.complete(p, EXPLAIN_OPTION_LIST))
}

const EXPLAIN_OPTION_FIRST: TokenSet =
Expand All @@ -11219,22 +11229,30 @@ fn opt_explain_option(p: &mut Parser<'_>) -> bool {
if !p.at_ts(EXPLAIN_OPTION_FIRST) {
return false;
}
p.bump_any();
// WAL [ boolean ]
if opt_bool_literal(p) {
return true;
}
// [ { NONE | TEXT | BINARY } ]
if p.eat(NONE_KW) || p.eat(TEXT_KW) || p.eat(BINARY_KW) {
return true;
}
// { TEXT | XML | JSON | YAML }
if p.eat(TEXT_KW) || p.eat(XML_KW) || p.eat(JSON_KW) || opt_ident(p) {
return true;
}
let m = p.start();
col_label(p);
opt_explain_option_value(p);
m.complete(p, EXPLAIN_OPTION);
true
}

fn opt_explain_option_value(p: &mut Parser<'_>) -> Option<CompletedMarker> {
let m = p.start();
// boolean, { NONE | TEXT | BINARY }, or { TEXT | XML | JSON | YAML }
if opt_bool_literal(p)
|| p.eat(NONE_KW)
|| p.eat(TEXT_KW)
|| p.eat(BINARY_KW)
|| p.eat(XML_KW)
|| p.eat(JSON_KW)
|| opt_ident(p)
{
return Some(m.complete(p, EXPLAIN_OPTION_VALUE));
}
m.abandon(p);
None
}

// [ OPTIONS ( option 'value' [, ... ] ) ]
fn opt_alter_option_list(p: &mut Parser<'_>) -> bool {
if !p.at(OPTIONS_KW) {
Expand Down Expand Up @@ -12373,15 +12391,44 @@ fn unlisten(p: &mut Parser<'_>) -> CompletedMarker {
m.complete(p, UNLISTEN)
}

// CHECKPOINT
// CHECKPOINT [ ( option [, ...] ) ]
fn checkpoint(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(CHECKPOINT_KW));
let m = p.start();
p.bump(CHECKPOINT_KW);
opt_checkpoint_option_list(p);
p.eat(SEMICOLON);
m.complete(p, CHECKPOINT)
}

fn opt_checkpoint_option_list(p: &mut Parser<'_>) -> Option<CompletedMarker> {
if !p.at(L_PAREN) {
return None;
}
let m = p.start();
delimited(
p,
L_PAREN,
R_PAREN,
COMMA,
|| "unexpected comma".to_string(),
NAME_FIRST,
opt_checkpoint_option,
);
Some(m.complete(p, CHECKPOINT_OPTION_LIST))
}

fn opt_checkpoint_option(p: &mut Parser<'_>) -> bool {
if !p.at_ts(NAME_FIRST) {
return false;
}
let m = p.start();
name(p);
opt_expr(p);
m.complete(p, CHECKPOINT_OPTION);
true
}

// DEALLOCATE [ PREPARE ] { name | ALL }
fn deallocate(p: &mut Parser<'_>) -> CompletedMarker {
assert!(p.at(DEALLOCATE_KW));
Expand Down
6 changes: 6 additions & 0 deletions crates/squawk_parser/tests/data/ok/checkpoint.sql
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
-- checkpoint
checkpoint;

-- checkpoint options
checkpoint (mode fast);
checkpoint (mode spread, flush_unlogged true);
checkpoint (flush_unlogged false);
checkpoint (flush_unlogged);

5 changes: 5 additions & 0 deletions crates/squawk_parser/tests/data/ok/create_table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,8 @@ CREATE TABLE t (
quarter int,
PRIMARY KEY (symbol, period, year, quarter)
);

-- collate can appear in many places
CREATE TABLE t (id varchar COLLATE "C" PRIMARY KEY);
CREATE TABLE t (id VARCHAR PRIMARY KEY COLLATE "C");
CREATE TABLE t (id varchar NOT NULL COLLATE "C" UNIQUE);
16 changes: 16 additions & 0 deletions crates/squawk_parser/tests/data/ok/create_transform.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,19 @@ create or replace transform for foo.t(10231) language l (
to sql with function g
);

-- from only
create transform for only_from language l (
from sql with function t
);

-- to only
create transform for only_to language l (
to sql with function g
);

-- reverse order
create transform for reverse_order language l (
to sql with function g,
from sql with function t
);

6 changes: 6 additions & 0 deletions crates/squawk_parser/tests/data/ok/explain.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ explain select * from t;
-- explain_analyze
explain analyze select a from t;

-- explain_analyze_verbose
explain analyze verbose select a from t;

-- explain_parenthesized_options
explain (analyze, buffers) select 1;

-- all_options
explain (
analyze,
Expand Down
Loading
Loading