|
|
|
|
@ -93,14 +93,66 @@ module.exports = grammar({
|
|
|
|
|
$.create_domain_statement,
|
|
|
|
|
$.create_index_statement,
|
|
|
|
|
$.create_table_statement,
|
|
|
|
|
$.create_function_statement,
|
|
|
|
|
$.create_schema_statement,
|
|
|
|
|
$.create_role_statement,
|
|
|
|
|
$.create_extension_statement,
|
|
|
|
|
$.create_trigger_statement,
|
|
|
|
|
$.create_function_statement,
|
|
|
|
|
),
|
|
|
|
|
optional(";"),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
_simple_statement: $ =>
|
|
|
|
|
prec.right(
|
|
|
|
|
seq(
|
|
|
|
|
choice(
|
|
|
|
|
$.pg_command,
|
|
|
|
|
$.select_statement,
|
|
|
|
|
$.update_statement,
|
|
|
|
|
$.insert_statement,
|
|
|
|
|
$.delete_statement,
|
|
|
|
|
$.set_statement,
|
|
|
|
|
$.grant_statement,
|
|
|
|
|
$.drop_statement,
|
|
|
|
|
$.create_statement,
|
|
|
|
|
$.alter_statement,
|
|
|
|
|
$.create_type_statement,
|
|
|
|
|
$.create_domain_statement,
|
|
|
|
|
$.create_table_statement,
|
|
|
|
|
$.create_index_statement,
|
|
|
|
|
$.create_schema_statement,
|
|
|
|
|
$.create_role_statement,
|
|
|
|
|
$.create_extension_statement,
|
|
|
|
|
$.return_statement,
|
|
|
|
|
$.declare_statement,
|
|
|
|
|
),
|
|
|
|
|
optional(";"),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
with_clause: $ =>
|
|
|
|
|
seq(kw("WITH"), optional(kw("RECURSIVE")), commaSep1($.cte)),
|
|
|
|
|
|
|
|
|
|
cte: $ =>
|
|
|
|
|
seq(
|
|
|
|
|
$.identifier,
|
|
|
|
|
kw("AS"),
|
|
|
|
|
optional(seq(optional(kw("NOT")), kw("MATERIALIZED"))),
|
|
|
|
|
"(",
|
|
|
|
|
choice(
|
|
|
|
|
$.select_statement,
|
|
|
|
|
$.delete_statement,
|
|
|
|
|
$.insert_statement,
|
|
|
|
|
$.update_statement,
|
|
|
|
|
),
|
|
|
|
|
")",
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
select_statement: $ => seq(optional($.with_clause), $._select_statement),
|
|
|
|
|
insert_statement: $ => seq(optional($.with_clause), $._insert_statement),
|
|
|
|
|
update_statement: $ => seq(optional($.with_clause), $._update_statement),
|
|
|
|
|
delete_statement: $ => seq(optional($.with_clause), $._delete_statement),
|
|
|
|
|
|
|
|
|
|
begin_statement: $ =>
|
|
|
|
|
seq(kw("BEGIN"), optional(choice(kw("WORK"), kw("TRANSACTION")))),
|
|
|
|
|
commit_statement: $ =>
|
|
|
|
|
@ -178,57 +230,103 @@ module.exports = grammar({
|
|
|
|
|
$.alter_table_action_set,
|
|
|
|
|
),
|
|
|
|
|
sequence: $ =>
|
|
|
|
|
seq(
|
|
|
|
|
kw("SEQUENCE"),
|
|
|
|
|
optional(seq(kw("IF"), optional(kw("NOT")), kw("EXISTS"))),
|
|
|
|
|
$._identifier,
|
|
|
|
|
optional(seq(kw("AS"), $.type)),
|
|
|
|
|
repeat(
|
|
|
|
|
choice(
|
|
|
|
|
seq(kw("START"), kw("WITH"), $.number),
|
|
|
|
|
seq(kw("INCREMENT"), optional(kw("BY")), $.number),
|
|
|
|
|
seq(kw("NO"), choice(kw("MINVALUE"), kw("MAXVALUE"))),
|
|
|
|
|
seq(kw("CACHE"), $.number),
|
|
|
|
|
seq(kw("OWNED BY"), choice($._identifier)),
|
|
|
|
|
prec.right(
|
|
|
|
|
seq(
|
|
|
|
|
kw("SEQUENCE"),
|
|
|
|
|
optional(seq(kw("IF"), optional(kw("NOT")), kw("EXISTS"))),
|
|
|
|
|
$._identifier,
|
|
|
|
|
optional(seq(kw("AS"), $.type)),
|
|
|
|
|
repeat(
|
|
|
|
|
choice(
|
|
|
|
|
seq(kw("START"), kw("WITH"), $.number),
|
|
|
|
|
seq(kw("INCREMENT"), optional(kw("BY")), $.number),
|
|
|
|
|
seq(kw("NO"), choice(kw("MINVALUE"), kw("MAXVALUE"))),
|
|
|
|
|
seq(kw("CACHE"), $.number),
|
|
|
|
|
seq(kw("OWNED BY"), choice($._identifier)),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
pg_command: $ => seq(/\\[a-zA-Z]+/, /.*/),
|
|
|
|
|
|
|
|
|
|
_compound_statement: $ =>
|
|
|
|
|
prec.right(
|
|
|
|
|
seq(
|
|
|
|
|
optional(seq(field("begin_label", $.identifier), ":")),
|
|
|
|
|
kw("BEGIN"),
|
|
|
|
|
optional(kw("ATOMIC")),
|
|
|
|
|
repeat1($._simple_statement),
|
|
|
|
|
kw("END"),
|
|
|
|
|
optional(field("end_label", $.identifier)),
|
|
|
|
|
optional(";"),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
return_statement: $ =>
|
|
|
|
|
seq(kw("RETURN"), choice($._expression, $.select_statement)),
|
|
|
|
|
declare_statement: $ =>
|
|
|
|
|
seq(kw("DECLARE"), $.identifier, $._type, optional($.default_clause)),
|
|
|
|
|
|
|
|
|
|
create_function_statement: $ =>
|
|
|
|
|
seq(
|
|
|
|
|
createOrReplace("FUNCTION"),
|
|
|
|
|
$._identifier,
|
|
|
|
|
$.create_function_parameters,
|
|
|
|
|
kw("RETURNS"),
|
|
|
|
|
$._create_function_return_type,
|
|
|
|
|
repeat(
|
|
|
|
|
choice(
|
|
|
|
|
$._function_language,
|
|
|
|
|
$.function_body,
|
|
|
|
|
$.optimizer_hint,
|
|
|
|
|
$.parallel_hint,
|
|
|
|
|
$.null_hint,
|
|
|
|
|
prec.right(
|
|
|
|
|
seq(
|
|
|
|
|
choice(createOrReplace("FUNCTION"), createOrReplace("PROCEDURE")),
|
|
|
|
|
$._identifier,
|
|
|
|
|
$.create_function_parameters,
|
|
|
|
|
optional(seq(kw("RETURNS"), $._create_function_return_type)),
|
|
|
|
|
repeat(
|
|
|
|
|
choice(
|
|
|
|
|
$._function_language,
|
|
|
|
|
seq(kw("TRANSFORM FOR TYPE"), commaSep1($.identifier)),
|
|
|
|
|
kw("WINDOW"),
|
|
|
|
|
seq(optional(kw("NOT")), kw("LEAKPROOF")),
|
|
|
|
|
seq(kw("COST"), $.number),
|
|
|
|
|
seq(kw("ROWS"), $.number),
|
|
|
|
|
seq(kw("SUPPORT"), $.identifier),
|
|
|
|
|
$.external_hint,
|
|
|
|
|
$.optimizer_hint,
|
|
|
|
|
$.parallel_hint,
|
|
|
|
|
$.null_hint,
|
|
|
|
|
$.deterministic_hint,
|
|
|
|
|
$.sql_hint,
|
|
|
|
|
$.sql_security_hint,
|
|
|
|
|
$.function_body,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
optimizer_hint: $ => choice(kw("VOLATILE"), kw("IMMUTABLE"), kw("STABLE")),
|
|
|
|
|
parallel_hint: $ =>
|
|
|
|
|
external_hint: $ =>
|
|
|
|
|
choice(
|
|
|
|
|
kw("PARALLEL"),
|
|
|
|
|
choice(kw("SAFE"), kw("UNSAFE"), kw("RESTRICTED")),
|
|
|
|
|
seq(optional(kw("EXTERNAL")), kw("SECURITY INVOKER")),
|
|
|
|
|
seq(optional(kw("EXTERNAL")), kw("SECURITY DEFINER")),
|
|
|
|
|
),
|
|
|
|
|
optimizer_hint: $ => choice(kw("VOLATILE"), kw("IMMUTABLE"), kw("STABLE")),
|
|
|
|
|
parallel_hint: $ =>
|
|
|
|
|
seq(kw("PARALLEL"), choice(kw("SAFE"), kw("UNSAFE"), kw("RESTRICTED"))),
|
|
|
|
|
null_hint: $ =>
|
|
|
|
|
choice(
|
|
|
|
|
kw("CALLED ON NULL INPUT"),
|
|
|
|
|
kw("RETURNS NULL ON NULL INPUT"),
|
|
|
|
|
kw("STRICT"),
|
|
|
|
|
),
|
|
|
|
|
// MySQL hints
|
|
|
|
|
deterministic_hint: $ => seq(optional(kw("NOT")), kw("DETERMINISTIC")),
|
|
|
|
|
sql_hint: $ =>
|
|
|
|
|
choice(
|
|
|
|
|
kw("CONTAINS SQL"),
|
|
|
|
|
kw("NO SQL"),
|
|
|
|
|
kw("READS SQL DATA"),
|
|
|
|
|
kw("MODIFIES SQL DATA"),
|
|
|
|
|
),
|
|
|
|
|
sql_security_hint: $ =>
|
|
|
|
|
seq(kw("SQL SECURITY"), choice(kw("DEFINER"), kw("INVOKER"))),
|
|
|
|
|
|
|
|
|
|
_function_language: $ =>
|
|
|
|
|
seq(kw("LANGUAGE"), alias($.identifier, $.language)),
|
|
|
|
|
_create_function_return_type: $ =>
|
|
|
|
|
choice($._type, $.setof, $.constrained_type),
|
|
|
|
|
setof: $ => seq(kw("SETOF"), choice($._type, $.constrained_type)),
|
|
|
|
|
constrained_type: $ => seq(seq($._type, $.null_constraint)),
|
|
|
|
|
prec.right(choice($.setof, $._type, $.constrained_type)),
|
|
|
|
|
setof: $ =>
|
|
|
|
|
prec.right(seq(kw("SETOF"), choice($._type, $.constrained_type))),
|
|
|
|
|
constrained_type: $ => seq($._type, $.null_constraint),
|
|
|
|
|
create_function_parameter: $ =>
|
|
|
|
|
seq(
|
|
|
|
|
field(
|
|
|
|
|
@ -240,12 +338,92 @@ module.exports = grammar({
|
|
|
|
|
optional(seq("=", alias($._expression, $.default))),
|
|
|
|
|
),
|
|
|
|
|
create_function_parameters: $ =>
|
|
|
|
|
seq("(", commaSep1($.create_function_parameter), ")"),
|
|
|
|
|
function_body: $ => seq(kw("AS"), $.string),
|
|
|
|
|
seq("(", optional(commaSep1($.create_function_parameter)), ")"),
|
|
|
|
|
function_body: $ =>
|
|
|
|
|
choice(
|
|
|
|
|
$._simple_statement,
|
|
|
|
|
$._compound_statement,
|
|
|
|
|
seq(kw("AS"), field("script", $.string)),
|
|
|
|
|
seq(
|
|
|
|
|
kw("AS"),
|
|
|
|
|
field("obj_file", $.string),
|
|
|
|
|
field("link_symbol", $.string),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
create_trigger_statement: $ =>
|
|
|
|
|
seq(
|
|
|
|
|
kw("CREATE"),
|
|
|
|
|
optional(kw("OR REPLACE")),
|
|
|
|
|
optional(kw("CONSTRAINT")),
|
|
|
|
|
kw("TRIGGER"),
|
|
|
|
|
optional(kw("IF NOT EXISTS")),
|
|
|
|
|
field("name", $.identifier),
|
|
|
|
|
$.trigger_time,
|
|
|
|
|
$.trigger_event,
|
|
|
|
|
kw("ON"),
|
|
|
|
|
field("on_table", $._identifier),
|
|
|
|
|
optional($.trigger_reference),
|
|
|
|
|
optional($.trigger_preferencing),
|
|
|
|
|
optional(
|
|
|
|
|
seq(
|
|
|
|
|
kw("FOR"),
|
|
|
|
|
optional(kw("EACH")),
|
|
|
|
|
choice(kw("ROW"), kw("STATEMENT")),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
optional($.trigger_condition),
|
|
|
|
|
optional($.trigger_order),
|
|
|
|
|
$.trigger_body,
|
|
|
|
|
),
|
|
|
|
|
trigger_reference: $ => seq(kw("FROM"), $._identifier),
|
|
|
|
|
trigger_preferencing: $ =>
|
|
|
|
|
seq(
|
|
|
|
|
kw("REFERENCING"),
|
|
|
|
|
repeat1(
|
|
|
|
|
seq(
|
|
|
|
|
choice(kw("NEW"), kw("OLD")),
|
|
|
|
|
kw("TABLE"),
|
|
|
|
|
optional(kw("AS")),
|
|
|
|
|
$.identifier,
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
trigger_time: $ => choice(kw("BEFORE"), kw("AFTER"), kw("INSTEAD OF")),
|
|
|
|
|
trigger_event: $ =>
|
|
|
|
|
choice(
|
|
|
|
|
kw("INSERT"),
|
|
|
|
|
kw("DELETE"),
|
|
|
|
|
kw("TRUNCATE"),
|
|
|
|
|
seq(kw("UPDATE"), optional(seq(kw("OF"), repeat1($._identifier)))),
|
|
|
|
|
),
|
|
|
|
|
// PostgreSQL trigger condition
|
|
|
|
|
trigger_condition: $ => seq(kw("WHEN"), $._expression),
|
|
|
|
|
// MySQL trigger order
|
|
|
|
|
trigger_order: $ =>
|
|
|
|
|
seq(choice(kw("FOLLOWS"), kw("PRECEDES")), $._identifier),
|
|
|
|
|
trigger_body: $ =>
|
|
|
|
|
choice(
|
|
|
|
|
// PostgreSQL style trigger body
|
|
|
|
|
seq(
|
|
|
|
|
kw("EXECUTE"),
|
|
|
|
|
choice(kw("FUNCTION"), kw("PROCEDURE")),
|
|
|
|
|
seq(
|
|
|
|
|
field("function", $.identifier),
|
|
|
|
|
"(",
|
|
|
|
|
optional(field("arguments", commaSep1($.string))),
|
|
|
|
|
")",
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
// MySQL style trigger body
|
|
|
|
|
$._simple_statement,
|
|
|
|
|
$._compound_statement,
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
create_extension_statement: $ =>
|
|
|
|
|
seq(kw("CREATE EXTENSION"), optional(kw("IF NOT EXISTS")), $._identifier),
|
|
|
|
|
create_role_statement: $ =>
|
|
|
|
|
prec.left(
|
|
|
|
|
prec.right(
|
|
|
|
|
seq(
|
|
|
|
|
kw("CREATE ROLE"),
|
|
|
|
|
$._identifier,
|
|
|
|
|
@ -271,7 +449,7 @@ module.exports = grammar({
|
|
|
|
|
choice($._expression, kw("DEFAULT")),
|
|
|
|
|
),
|
|
|
|
|
grant_statement: $ =>
|
|
|
|
|
prec.left(
|
|
|
|
|
prec.right(
|
|
|
|
|
seq(
|
|
|
|
|
kw("GRANT"),
|
|
|
|
|
choice(
|
|
|
|
|
@ -303,14 +481,16 @@ module.exports = grammar({
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
create_domain_statement: $ =>
|
|
|
|
|
seq(
|
|
|
|
|
kw("CREATE DOMAIN"),
|
|
|
|
|
$._identifier,
|
|
|
|
|
optional(
|
|
|
|
|
seq(
|
|
|
|
|
kw("AS"),
|
|
|
|
|
$._type,
|
|
|
|
|
repeat(choice($.null_constraint, $.check_constraint)),
|
|
|
|
|
prec.right(
|
|
|
|
|
seq(
|
|
|
|
|
kw("CREATE DOMAIN"),
|
|
|
|
|
$._identifier,
|
|
|
|
|
optional(
|
|
|
|
|
seq(
|
|
|
|
|
kw("AS"),
|
|
|
|
|
$._type,
|
|
|
|
|
repeat(choice($.null_constraint, $.check_constraint)),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
@ -334,8 +514,12 @@ module.exports = grammar({
|
|
|
|
|
kw("CREATE"),
|
|
|
|
|
optional($.unique_constraint),
|
|
|
|
|
kw("INDEX"),
|
|
|
|
|
field("name", $._identifier),
|
|
|
|
|
optional(kw("CONCURRENTLY")),
|
|
|
|
|
optional(
|
|
|
|
|
seq(optional(kw("IF NOT EXISTS")), field("name", $.identifier)),
|
|
|
|
|
),
|
|
|
|
|
kw("ON"),
|
|
|
|
|
optional(kw("ONLY")),
|
|
|
|
|
field("table_name", $._identifier),
|
|
|
|
|
optional($.using_clause),
|
|
|
|
|
$.index_table_parameters,
|
|
|
|
|
@ -345,13 +529,13 @@ module.exports = grammar({
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
table_column: $ =>
|
|
|
|
|
prec.left(
|
|
|
|
|
prec.right(
|
|
|
|
|
seq(
|
|
|
|
|
field("name", $._identifier),
|
|
|
|
|
field("type", $._type),
|
|
|
|
|
repeat(
|
|
|
|
|
choice(
|
|
|
|
|
$.column_default,
|
|
|
|
|
$.default_clause,
|
|
|
|
|
$.primary_key_constraint,
|
|
|
|
|
$.check_constraint,
|
|
|
|
|
$.references_constraint,
|
|
|
|
|
@ -371,10 +555,11 @@ module.exports = grammar({
|
|
|
|
|
choice(
|
|
|
|
|
$._parenthesized_expression,
|
|
|
|
|
$.string,
|
|
|
|
|
$.number,
|
|
|
|
|
$.identifier,
|
|
|
|
|
$.function_call,
|
|
|
|
|
),
|
|
|
|
|
column_default: $ =>
|
|
|
|
|
default_clause: $ =>
|
|
|
|
|
seq(
|
|
|
|
|
kw("DEFAULT"),
|
|
|
|
|
// TODO: this should be specific variable-free expression https://www.postgresql.org/docs/9.1/sql-createtable.html
|
|
|
|
|
@ -387,17 +572,19 @@ module.exports = grammar({
|
|
|
|
|
initial_mode: $ =>
|
|
|
|
|
seq(kw("INITIALLY"), choice(kw("DEFERRED"), kw("IMMEDIATE"))),
|
|
|
|
|
_table_constraint: $ =>
|
|
|
|
|
seq(
|
|
|
|
|
optional(seq(kw("CONSTRAINT"), field("name", $._identifier))),
|
|
|
|
|
choice(
|
|
|
|
|
alias($.table_constraint_foreign_key, $.foreign_key),
|
|
|
|
|
alias($.table_constraint_unique, $.unique),
|
|
|
|
|
alias($.table_constraint_primary_key, $.primary_key),
|
|
|
|
|
alias($.table_constraint_check, $.check),
|
|
|
|
|
alias($.table_constraint_exclude, $.exclude),
|
|
|
|
|
prec.right(
|
|
|
|
|
seq(
|
|
|
|
|
optional(seq(kw("CONSTRAINT"), field("name", $._identifier))),
|
|
|
|
|
choice(
|
|
|
|
|
alias($.table_constraint_foreign_key, $.foreign_key),
|
|
|
|
|
alias($.table_constraint_unique, $.unique),
|
|
|
|
|
alias($.table_constraint_primary_key, $.primary_key),
|
|
|
|
|
alias($.table_constraint_check, $.check),
|
|
|
|
|
alias($.table_constraint_exclude, $.exclude),
|
|
|
|
|
),
|
|
|
|
|
optional($.mode),
|
|
|
|
|
optional($.initial_mode),
|
|
|
|
|
),
|
|
|
|
|
optional($.mode),
|
|
|
|
|
optional($.initial_mode),
|
|
|
|
|
),
|
|
|
|
|
table_constraint_check: $ => seq(kw("CHECK"), $._expression),
|
|
|
|
|
op_class: $ => $._identifier,
|
|
|
|
|
@ -485,10 +672,16 @@ module.exports = grammar({
|
|
|
|
|
_aliased_expression: $ =>
|
|
|
|
|
seq($._expression, optional(kw("AS")), $.identifier),
|
|
|
|
|
_aliasable_expression: $ =>
|
|
|
|
|
choice($._expression, alias($._aliased_expression, $.alias)),
|
|
|
|
|
select_clause_body: $ => commaSep1($._aliasable_expression),
|
|
|
|
|
prec.right(choice($._expression, alias($._aliased_expression, $.alias))),
|
|
|
|
|
select_clause_body: $ =>
|
|
|
|
|
commaSep1(
|
|
|
|
|
seq(
|
|
|
|
|
$._aliasable_expression,
|
|
|
|
|
optional(seq(kw("INTO"), field("into", $.identifier))),
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
select_clause: $ =>
|
|
|
|
|
prec.left(seq(kw("SELECT"), optional($.select_clause_body))),
|
|
|
|
|
prec.right(seq(kw("SELECT"), optional($.select_clause_body))),
|
|
|
|
|
from_clause: $ => seq(kw("FROM"), commaSep1($._aliasable_expression)),
|
|
|
|
|
join_type: $ =>
|
|
|
|
|
seq(
|
|
|
|
|
@ -530,7 +723,7 @@ module.exports = grammar({
|
|
|
|
|
kw("INSERT"),
|
|
|
|
|
kw("INTO"),
|
|
|
|
|
$._identifier,
|
|
|
|
|
choice($.values_clause, $.select_statement),
|
|
|
|
|
choice($.values_clause, $.select_statement, $.set_clause),
|
|
|
|
|
),
|
|
|
|
|
values_clause: $ => seq(kw("VALUES"), "(", $.values_clause_body, ")"),
|
|
|
|
|
values_clause_body: $ => commaSep1($._expression),
|
|
|
|
|
@ -653,7 +846,7 @@ module.exports = grammar({
|
|
|
|
|
$._identifier,
|
|
|
|
|
optional(kw("VARYING")), // CHARACTER/BIT VARYING
|
|
|
|
|
optional(kw("PRECISION")), // DOUBLE PRECISION
|
|
|
|
|
optional(seq("(", $.number, ")")),
|
|
|
|
|
optional(seq("(", commaSep1($.number), ")")),
|
|
|
|
|
optional(seq(choice(kw("WITH"), kw("WITHOUT")), kw("TIME ZONE"))), // TIME/TIMESTAMP (n) WITH/WITHOUT TIME ZONE
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
|