Compare commits

...

4 Commits

6 changed files with 69669 additions and 72491 deletions

View File

@ -1,13 +1,9 @@
function kw(word, aliasAsWord = true) {
let pattern = "";
for (const letter of word) {
pattern += `[${letter}${letter.toUpperCase()}]`;
}
let result = new RegExp(pattern);
if (aliasAsWord) {
result = alias(result, word);
}
return result;
function kw(word) {
let pattern = Array.from(word).reduce(
(acc, letter) => acc + `[${letter}${letter.toUpperCase()}]`,
""
);
return new RegExp(pattern);
}
function separated(separator, rule) {
@ -132,7 +128,7 @@ module.exports = grammar({
insert_items: ($) =>
choice(
seq(kw("default"), kw("values")),
seq(kw("values"), $.insert_values, repeat(seq(",", $.insert_values))),
seq(kw("values"), commaSep1($.insert_values)),
$.select_statement,
seq("(", $.select_statement, ")")
),
@ -140,6 +136,7 @@ module.exports = grammar({
insert_values: ($) => seq("(", commaSep($.insert_item), ")"),
insert_item: ($) => choice(kw("default"), $._value_expression),
insert_conflict: ($) =>
choice(
seq(
@ -160,11 +157,13 @@ module.exports = grammar({
optional($.where_filter)
)
),
conflict_target: ($) =>
choice(
seq(kw("on"), kw("constraint"), $.identifier),
seq("(", commaSep($._value_expression), ")")
),
update_set: ($) =>
choice(
seq($.identifier, "=", $.update_value),
@ -177,14 +176,16 @@ module.exports = grammar({
")"
)
),
update_value: ($) => choice(kw("default"), $._value_expression),
returning: ($) => seq(kw("returning"), commaSep1($.select_item)),
create_table_statement: ($) =>
seq(
kw("create"),
optional($.temporary),
optional(kw("unlogged")),
optional($.unlogged),
kw("table"),
optional($.if_not_exists),
$.identifier,
@ -228,6 +229,7 @@ module.exports = grammar({
),
index_using: ($) => seq(kw("using"), $.identifier),
index_col: ($) =>
choice(
seq(
@ -243,9 +245,12 @@ module.exports = grammar({
optional($.index_col_nulls)
)
),
index_col_dir: ($) => choice(kw("asc"), kw("desc")),
index_col_nulls: ($) =>
choice(seq(kw("nulls"), kw("first")), seq(kw("nulls"), kw("last"))),
index_includes: ($) => seq(kw("include"), $._list_of_identifiers),
delete_statement: ($) =>
@ -498,13 +503,19 @@ module.exports = grammar({
sequence_increment: ($) =>
seq(kw("increment"), optional(kw("by")), $.number),
sequence_min: ($) =>
choice(seq(kw("no"), kw("minvalue")), seq(kw("minvalue"), $.number)),
sequence_max: ($) =>
choice(seq(kw("no"), kw("maxvalue")), seq(kw("maxvalue"), $.number)),
sequence_start: ($) => seq(kw("start"), optional(kw("with")), $.number),
sequence_cache: ($) => seq(kw("cache"), $.number),
sequence_cycle: ($) => seq(optional(kw("no")), kw("cycle")),
sequence_owned: ($) =>
seq(kw("owned"), kw("by"), choice(kw("none"), $.identifier)),
@ -674,6 +685,7 @@ module.exports = grammar({
),
with_query: ($) => seq(kw("with"), commaSep1($.with_query_item)),
with_query_item: ($) =>
seq(
$.identifier,
@ -686,22 +698,28 @@ module.exports = grammar({
$._with_query_statement,
")"
),
into: ($) =>
seq(kw("into"), optional(kw("strict")), commaSep1($.identifier)),
select_having: ($) => seq(kw("having"), $._value_expression),
_select_limit_offset: ($) =>
choice(
seq($.select_limit, optional($.select_offset)),
seq($.select_offset, optional($.select_limit))
),
select_limit: ($) =>
seq(kw("limit"), choice(kw("all"), $._value_expression)),
select_offset: ($) =>
seq(
kw("offset"),
$._value_expression,
optional(choice(kw("row"), kw("rows")))
),
// TODO(chrde): rollup, cube, grouping sets
select_group_by: ($) =>
prec(
@ -715,15 +733,22 @@ module.exports = grammar({
)
)
),
select_order_by: ($) =>
seq(kw("order"), kw("by"), commaSep1($.order_by_item)),
order_by_item: ($) =>
seq($._value_expression, optional($.order_by_direction)),
order_by_direction: ($) => choice(kw("asc"), kw("desc")),
select_where: ($) => $.where_filter,
select_item: ($) =>
seq($._value_expression, optional(kw("as")), optional($.identifier)),
select_from: ($) => seq(kw("from"), commaSep1($.from_item)),
from_item: ($) =>
prec.left(
seq(
@ -732,10 +757,13 @@ module.exports = grammar({
repeat($.join_item)
)
),
from_select: ($) =>
seq("(", $.select_statement, ")", optional(kw("as")), $.identifier),
from_table: ($) =>
seq($.identifier, optional(kw("as")), optional($.identifier)),
from_function: ($) =>
seq(
$.function_call,
@ -756,11 +784,13 @@ module.exports = grammar({
seq(kw("cross"), kw("join"), $.from_item)
)
),
join_condition: ($) =>
choice(
seq(kw("on"), $._value_expression),
seq(kw("using"), $._list_of_identifiers)
),
join_type: ($) =>
seq(
choice(
@ -792,7 +822,9 @@ module.exports = grammar({
function_return: ($) =>
seq(kw("returns"), choice($._type, $.return_setof, $.return_table)),
return_setof: ($) => seq(kw("setof"), $._type),
return_table: ($) =>
seq(kw("table"), "(", commaSep1($.var_declaration), ")"),
@ -828,15 +860,22 @@ module.exports = grammar({
seq(field("name", $.identifier), field("type", $._type)),
where_filter: ($) => seq(kw("where"), $._value_expression),
or_replace: ($) => seq(kw("or"), kw("replace")),
temporary: ($) => choice(kw("temp"), kw("temporary")),
unlogged: ($) => kw("unlogged"),
if_not_exists: ($) => seq(kw("if"), kw("not"), kw("exists")),
if_exists: ($) => seq(kw("if"), kw("exists")),
as: ($) => seq(kw("as"), $.identifier),
_type: ($) =>
seq(
choice($.predefined_types, $.identifier),
choice($.predefined_type, $.identifier),
optional(choice(repeat1(seq("[", "]")), kw("%rowtype"), kw("%type")))
),
@ -868,10 +907,16 @@ module.exports = grammar({
// | VARCHAR l = type_length? { VarChar(l) }
// (* | schema_qualified_name_nontype (LEFT_PAREN vex (COMMA vex)* RIGHT_PAREN)? *)
// TODO(chrde): moar types!!
predefined_types: ($) => choice(seq(kw("numeric"), optional($.precision))),
predefined_type: ($) =>
choice(
seq(kw("numeric"), optional($.precision)),
seq(kw("varchar"), optional($.type_length))
),
precision: ($) => seq("(", $.number, optional(seq(",", $.number)), ")"),
type_length: ($) => seq("(", $.number, ")"),
string: ($) =>
seq("'", repeat(choice(prec(1, /''/), prec(2, /[^']/))), "'"),
@ -999,29 +1044,47 @@ module.exports = grammar({
// TODO(chrde): https://www.postgresql.org/docs/13/sql-syntax-lexical.html
comparison_op: ($) => choice("<", ">", "=", "<=", ">=", "<>", "!="),
// TODO(chrde): is there a better name other than `contains_op`?
contains_op: ($) =>
choice(kw("between"), kw("in"), kw("like"), kw("ilike")),
comparison_null: ($) =>
choice(kw("is null"), kw("isnull"), kw("is not null"), kw("notnull")),
comparison_kw: ($) =>
choice(kw("is"), kw("is distinct from"), kw("is not distinct from")),
// TODO(chrde): this should be a regex
other_op: ($) =>
choice("||", "<@", "@>", "<<", ">>", "&&", "&<", "&>", "-|-"),
cast: ($) => "::",
minus: ($) => "-",
plus: ($) => "+",
not: ($) => kw("not"),
and: ($) => kw("and"),
or: ($) => kw("or"),
true: ($) => kw("true"),
false: ($) => kw("false"),
null: ($) => kw("null"),
star: ($) => "*",
any: ($) => /.*/,
number: ($) => /-?\d+/,
identifier: ($) => $._identifier,
_identifier: ($) => /[a-zA-Z0-9_]+(\.?[a-zA-Z0-9_]+)*/,
// ^
// |- we dont want to match consecutive dots, e.g: 1..2 consists of 3 tokens

File diff suppressed because it is too large Load Diff

View File

@ -107,7 +107,7 @@
"named": true
},
{
"type": "predefined_types",
"type": "predefined_type",
"named": true
},
{
@ -291,11 +291,6 @@
]
}
},
{
"type": "and",
"named": true,
"fields": {}
},
{
"type": "array_constructor",
"named": true,
@ -985,6 +980,10 @@
{
"type": "temporary",
"named": true
},
{
"type": "unlogged",
"named": true
}
]
}
@ -1164,7 +1163,7 @@
"named": true
},
{
"type": "predefined_types",
"type": "predefined_type",
"named": true
},
{
@ -1342,11 +1341,6 @@
]
}
},
{
"type": "false",
"named": true,
"fields": {}
},
{
"type": "fk_action",
"named": true,
@ -1776,7 +1770,7 @@
"named": true
},
{
"type": "predefined_types",
"type": "predefined_type",
"named": true
},
{
@ -1847,7 +1841,7 @@
"named": true
},
{
"type": "predefined_types",
"type": "predefined_type",
"named": true
}
]
@ -2583,7 +2577,7 @@
"named": true
},
{
"type": "predefined_types",
"type": "predefined_type",
"named": true
},
{
@ -2755,7 +2749,7 @@
}
},
{
"type": "predefined_types",
"type": "predefined_type",
"named": true,
"fields": {},
"children": {
@ -2765,6 +2759,10 @@
{
"type": "precision",
"named": true
},
{
"type": "type_length",
"named": true
}
]
}
@ -2860,7 +2858,7 @@
"named": true
},
{
"type": "predefined_types",
"type": "predefined_type",
"named": true
}
]
@ -3590,7 +3588,7 @@
"named": true
},
{
"type": "predefined_types",
"type": "predefined_type",
"named": true
}
]
@ -3848,9 +3846,19 @@
"fields": {}
},
{
"type": "true",
"type": "type_length",
"named": true,
"fields": {}
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "number",
"named": true
}
]
}
},
{
"type": "update_set",
@ -3987,14 +3995,6 @@
"multiple": true,
"required": true,
"types": [
{
"type": "%rowtype",
"named": false
},
{
"type": "%type",
"named": false
},
{
"type": "[",
"named": false
@ -4008,7 +4008,7 @@
"named": true
},
{
"type": "predefined_types",
"type": "predefined_type",
"named": true
}
]
@ -4203,14 +4203,6 @@
"type": "%",
"named": false
},
{
"type": "%rowtype",
"named": false
},
{
"type": "%type",
"named": false
},
{
"type": "&&",
"named": false
@ -4327,673 +4319,33 @@
"type": "]",
"named": false
},
{
"type": "action",
"named": false
},
{
"type": "add",
"named": false
},
{
"type": "after",
"named": false
},
{
"type": "all",
"named": false
},
{
"type": "alter",
"named": false
},
{
"type": "and",
"named": false
},
{
"type": "array",
"named": false
},
{
"type": "as",
"named": false
},
{
"type": "asc",
"named": false
},
{
"type": "at",
"named": false
},
{
"type": "authorization",
"named": false
},
{
"type": "before",
"named": false
},
{
"type": "begin",
"named": false
},
{
"type": "between",
"named": false
},
{
"type": "by",
"named": false
},
{
"type": "cache",
"named": false
},
{
"type": "cascade",
"named": false
"named": true
},
{
"type": "cast",
"named": true
},
{
"type": "check",
"named": false
},
{
"type": "column",
"named": false
},
{
"type": "comment",
"named": true
},
{
"type": "concurrently",
"named": false
},
{
"type": "conflict",
"named": false
},
{
"type": "constraint",
"named": false
},
{
"type": "create",
"named": false
},
{
"type": "cross",
"named": false
},
{
"type": "current",
"named": false
},
{
"type": "current_user",
"named": false
},
{
"type": "cycle",
"named": false
},
{
"type": "data",
"named": false
},
{
"type": "day",
"named": false
},
{
"type": "declare",
"named": false
},
{
"type": "default",
"named": false
},
{
"type": "deferrable",
"named": false
},
{
"type": "deferred",
"named": false
},
{
"type": "definer",
"named": false
},
{
"type": "delete",
"named": false
},
{
"type": "desc",
"named": false
},
{
"type": "diagnostics",
"named": false
},
{
"type": "do",
"named": false
},
{
"type": "drop",
"named": false
},
{
"type": "each",
"named": false
},
{
"type": "else",
"named": false
},
{
"type": "elseif",
"named": false
},
{
"type": "elsif",
"named": false
},
{
"type": "end",
"named": false
},
{
"type": "enum",
"named": false
},
{
"type": "execute",
"named": false
},
{
"type": "exists",
"named": false
},
{
"type": "false",
"named": false
},
{
"type": "first",
"named": false
},
{
"type": "for",
"named": false
},
{
"type": "foreign",
"named": false
},
{
"type": "from",
"named": false
},
{
"type": "full",
"named": false
},
{
"type": "function",
"named": false
},
{
"type": "functions",
"named": false
},
{
"type": "get",
"named": false
},
{
"type": "grant",
"named": false
},
{
"type": "group",
"named": false
},
{
"type": "having",
"named": false
},
{
"type": "hour",
"named": false
},
{
"type": "if",
"named": false
},
{
"type": "ilike",
"named": false
},
{
"type": "immediate",
"named": false
},
{
"type": "immutable",
"named": false
},
{
"type": "in",
"named": false
},
{
"type": "include",
"named": false
},
{
"type": "increment",
"named": false
},
{
"type": "index",
"named": false
},
{
"type": "initially",
"named": false
},
{
"type": "inner",
"named": false
},
{
"type": "insert",
"named": false
},
{
"type": "instead of",
"named": false
},
{
"type": "interval",
"named": false
},
{
"type": "into",
"named": false
},
{
"type": "invoker",
"named": false
},
{
"type": "is",
"named": false
},
{
"type": "is distinct from",
"named": false
},
{
"type": "is not distinct from",
"named": false
},
{
"type": "is not null",
"named": false
},
{
"type": "is null",
"named": false
},
{
"type": "isnull",
"named": false
},
{
"type": "join",
"named": false
},
{
"type": "key",
"named": false
},
{
"type": "language",
"named": false
},
{
"type": "last",
"named": false
},
{
"type": "left",
"named": false
},
{
"type": "like",
"named": false
},
{
"type": "limit",
"named": false
},
{
"type": "loop",
"named": false
},
{
"type": "materialized",
"named": false
},
{
"type": "maxvalue",
"named": false
},
{
"type": "minute",
"named": false
},
{
"type": "minvalue",
"named": false
},
{
"type": "month",
"named": false
},
{
"type": "natural",
"named": false
},
{
"type": "no",
"named": false
},
{
"type": "none",
"named": false
},
{
"type": "not",
"named": false
},
{
"type": "nothing",
"named": false
},
{
"type": "notnull",
"named": false
},
{
"type": "null",
"named": false
},
{
"type": "nulls",
"named": false
"named": true
},
{
"type": "number",
"named": true
},
{
"type": "numeric",
"named": false
},
{
"type": "offset",
"named": false
},
{
"type": "on",
"named": false
},
{
"type": "open",
"named": false
},
{
"type": "or",
"named": false
},
{
"type": "order",
"named": false
},
{
"type": "outer",
"named": false
},
{
"type": "owned",
"named": false
},
{
"type": "perform",
"named": false
},
{
"type": "primary",
"named": false
},
{
"type": "privileges",
"named": false
},
{
"type": "procedure",
"named": false
},
{
"type": "public",
"named": false
},
{
"type": "query",
"named": false
},
{
"type": "raise",
"named": false
},
{
"type": "references",
"named": false
},
{
"type": "rename",
"named": false
},
{
"type": "replace",
"named": false
},
{
"type": "restrict",
"named": false
},
{
"type": "return",
"named": false
},
{
"type": "returning",
"named": false
},
{
"type": "returns",
"named": false
},
{
"type": "reverse",
"named": false
},
{
"type": "right",
"named": false
},
{
"type": "routine",
"named": false
},
{
"type": "row",
"named": false
},
{
"type": "rows",
"named": false
},
{
"type": "schema",
"named": false
},
{
"type": "second",
"named": false
},
{
"type": "security",
"named": false
},
{
"type": "select",
"named": false
},
{
"type": "sequence",
"named": false
},
{
"type": "sequences",
"named": false
},
{
"type": "session_user",
"named": false
},
{
"type": "set",
"named": false
},
{
"type": "setof",
"named": false
},
{
"type": "stable",
"named": false
},
{
"type": "start",
"named": false
},
{
"type": "statement",
"named": false
},
{
"type": "strict",
"named": false
},
{
"type": "table",
"named": false
},
{
"type": "tables",
"named": false
},
{
"type": "temp",
"named": false
},
{
"type": "temporary",
"named": false
},
{
"type": "then",
"named": false
},
{
"type": "time",
"named": false
},
{
"type": "to",
"named": false
},
{
"type": "trigger",
"named": false
},
{
"type": "true",
"named": false
},
{
"type": "truncate",
"named": false
},
{
"type": "type",
"named": false
},
{
"type": "unique",
"named": false
"named": true
},
{
"type": "unlogged",
"named": false
},
{
"type": "update",
"named": false
},
{
"type": "using",
"named": false
},
{
"type": "values",
"named": false
},
{
"type": "volatile",
"named": false
},
{
"type": "when",
"named": false
},
{
"type": "where",
"named": false
},
{
"type": "with",
"named": false
},
{
"type": "year",
"named": false
},
{
"type": "zone",
"named": false
"named": true
},
{
"type": "||",

138003
src/parser.c

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,36 @@
================================================================================
empty table
create an empty table
================================================================================
create table foo();
--------------------------------------------------------------------------------
(source_file
(create_table_statement
(identifier)))
(identifier)
)
)
================================================================================
temp
create temporary table
================================================================================
create temp table foo();
--------------------------------------------------------------------------------
(source_file
(create_table_statement
(temporary)
(identifier)))
================================================================================
temporary
================================================================================
create temporary table foo();
--------------------------------------------------------------------------------
(source_file
(create_table_statement
(temporary)
(identifier)))
(identifier)
)
(create_table_statement
(temporary)
(identifier)
)
)
================================================================================
if not exists
create table if not exists
================================================================================
create table if not exists foo();
--------------------------------------------------------------------------------
@ -39,17 +38,70 @@ create table if not exists foo();
(source_file
(create_table_statement
(if_not_exists)
(identifier)))
(identifier)
)
)
================================================================================
unlogged
create unlogged table
================================================================================
create unlogged table foo();
--------------------------------------------------------------------------------
(source_file
(create_table_statement
(identifier)))
(unlogged)
(identifier)
)
)
================================================================================
create table with predefined types
================================================================================
create table foo(
col1 numeric,
col2 numeric(2),
col3 numeric(2, 4),
col4 varchar,
col5 varchar(255)
);
--------------------------------------------------------------------------------
(source_file
(create_table_statement
(identifier)
(create_table_item
(table_column_item
(identifier)
(predefined_type)
)
)
(create_table_item
(table_column_item
(identifier)
(predefined_type (precision (number)))
)
)
(create_table_item
(table_column_item
(identifier)
(predefined_type (precision (number) (number)))
)
)
(create_table_item
(table_column_item
(identifier)
(predefined_type)
)
)
(create_table_item
(table_column_item
(identifier)
(predefined_type (type_length (number)))
)
)
)
)
================================================================================
constraints with deferred
@ -81,7 +133,7 @@ create table foo(
(create_table_item
(table_column_item
(identifier)
(predefined_types
(predefined_type
(precision
(number)
(number)))
@ -133,7 +185,7 @@ create table foo(
(create_table_item
(table_column_item
(identifier)
(predefined_types
(predefined_type
(precision
(number)
(number)))

Binary file not shown.