grammar: fix foreign key
This commit is contained in:
parent
de04a49b20
commit
09f0ec4c3f
7 changed files with 3147 additions and 1954 deletions
68
grammar.js
68
grammar.js
|
@ -34,12 +34,8 @@ module.exports = grammar({
|
|||
),
|
||||
|
||||
column_definitions: ($) =>
|
||||
seq(
|
||||
"(",
|
||||
optional(
|
||||
commaSepRepeat1(choice($.column_definition, $.table_constraint))
|
||||
),
|
||||
")"
|
||||
parens(
|
||||
optional(commaSep1(choice($.column_definition, $.table_constraint)))
|
||||
),
|
||||
|
||||
column_definition: ($) =>
|
||||
|
@ -55,28 +51,53 @@ module.exports = grammar({
|
|||
// TODO: add index_parameters in UNIQUE, PRIMARY KEY
|
||||
$._unique_constraint,
|
||||
$._primary_key,
|
||||
$._foreign_key_references
|
||||
seq(
|
||||
$.keyword_references,
|
||||
$.table_reference,
|
||||
optional($.ref_column),
|
||||
optional($._foreign_key_match),
|
||||
optional(
|
||||
choice(
|
||||
seq($._foreign_key_on_delete, $._foreign_key_on_update),
|
||||
seq($._foreign_key_on_update, $._foreign_key_on_delete)
|
||||
)
|
||||
)
|
||||
)
|
||||
// TODO: CHECK
|
||||
// TODO: GENERATED
|
||||
)
|
||||
// TODO: DEFERRABLE
|
||||
),
|
||||
|
||||
ref_column: ($) => parens(field("name", $.identifier)),
|
||||
|
||||
table_constraint: ($) =>
|
||||
seq(
|
||||
optional(seq($.keyword_constraint, field("name", $.identifier))),
|
||||
choice(
|
||||
seq($._unique_constraint, $.column_list),
|
||||
seq($._primary_key, $.column_list),
|
||||
seq($._foreign_key, $.column_list, $._foreign_key_references)
|
||||
seq(
|
||||
$._foreign_key,
|
||||
$.column_list,
|
||||
$.keyword_references,
|
||||
$.table_reference,
|
||||
optional(alias($.column_list, $.ref_column_list)),
|
||||
optional($._foreign_key_match),
|
||||
optional(
|
||||
choice(
|
||||
seq($._foreign_key_on_delete, $._foreign_key_on_update),
|
||||
seq($._foreign_key_on_update, $._foreign_key_on_delete)
|
||||
)
|
||||
)
|
||||
)
|
||||
// TODO: CHECK
|
||||
// TODO: EXCLUDE
|
||||
)
|
||||
// TODO: DEFERRABLE
|
||||
),
|
||||
|
||||
column_list: ($) =>
|
||||
seq("(", commaSepRepeat1(field("name", $.identifier)), ")"),
|
||||
column_list: ($) => parens(commaSep1(field("name", $.identifier))),
|
||||
|
||||
_unique_constraint: ($) =>
|
||||
seq(
|
||||
|
@ -86,19 +107,6 @@ module.exports = grammar({
|
|||
)
|
||||
),
|
||||
|
||||
_foreign_key_references: ($) =>
|
||||
seq(
|
||||
$.keyword_references,
|
||||
$.table_reference,
|
||||
optional(seq("(", field("refcolumn", $.identifier), ")")),
|
||||
optional($._foreign_key_match),
|
||||
optional(
|
||||
choice(
|
||||
seq($._foreign_key_on_delete, $._foreign_key_on_update),
|
||||
seq($._foreign_key_on_update, $._foreign_key_on_delete)
|
||||
)
|
||||
)
|
||||
),
|
||||
_foreign_key_match: ($) =>
|
||||
seq(
|
||||
$.keyword_match,
|
||||
|
@ -117,7 +125,7 @@ module.exports = grammar({
|
|||
seq(
|
||||
$.keyword_set,
|
||||
choice($.keyword_null, $.keyword_default),
|
||||
optional(seq("(", commaSepRepeat1($.identifier), ")"))
|
||||
optional(parens(commaSep1($.identifier)))
|
||||
)
|
||||
),
|
||||
|
||||
|
@ -324,8 +332,16 @@ function mkKeyword(word) {
|
|||
return new RegExp(word + "|" + word.toUpperCase());
|
||||
}
|
||||
|
||||
function commaSepRepeat1(field) {
|
||||
return seq(field, repeat(seq(",", field)));
|
||||
function commaSep1(rule) {
|
||||
return sep1(",", rule);
|
||||
}
|
||||
|
||||
function sep1(separator, rule) {
|
||||
return seq(rule, repeat(seq(separator, rule)));
|
||||
}
|
||||
|
||||
function parens(rule) {
|
||||
return seq("(", rule, ")");
|
||||
}
|
||||
|
||||
function parametricType($, type, params = ["size"]) {
|
||||
|
|
264
src/grammar.json
264
src/grammar.json
|
@ -256,13 +256,106 @@
|
|||
"name": "_primary_key"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_references"
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "keyword_references"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "table_reference"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "ref_column"
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_match"
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_delete"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_update"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_update"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_delete"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"ref_column": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "("
|
||||
},
|
||||
{
|
||||
"type": "FIELD",
|
||||
"name": "name",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "identifier"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ")"
|
||||
}
|
||||
]
|
||||
},
|
||||
"table_constraint": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
|
@ -333,7 +426,79 @@
|
|||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_references"
|
||||
"name": "keyword_references"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "table_reference"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "ALIAS",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "column_list"
|
||||
},
|
||||
"named": true,
|
||||
"value": "ref_column_list"
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_match"
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_delete"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_update"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_update"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_delete"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -429,99 +594,6 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"_foreign_key_references": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "keyword_references"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "table_reference"
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": "("
|
||||
},
|
||||
{
|
||||
"type": "FIELD",
|
||||
"name": "refcolumn",
|
||||
"content": {
|
||||
"type": "SYMBOL",
|
||||
"name": "identifier"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "STRING",
|
||||
"value": ")"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_match"
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "CHOICE",
|
||||
"members": [
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_delete"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_update"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_update"
|
||||
},
|
||||
{
|
||||
"type": "SYMBOL",
|
||||
"name": "_foreign_key_on_delete"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "BLANK"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"_foreign_key_match": {
|
||||
"type": "SEQ",
|
||||
"members": [
|
||||
|
|
|
@ -43,16 +43,6 @@
|
|||
"named": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"refcolumn": {
|
||||
"multiple": false,
|
||||
"required": false,
|
||||
"types": [
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"children": {
|
||||
|
@ -131,6 +121,10 @@
|
|||
"type": "literal",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "ref_column",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "referencial_action",
|
||||
"named": true
|
||||
|
@ -407,6 +401,38 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ref_column",
|
||||
"named": true,
|
||||
"fields": {
|
||||
"name": {
|
||||
"multiple": false,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "ref_column_list",
|
||||
"named": true,
|
||||
"fields": {
|
||||
"name": {
|
||||
"multiple": true,
|
||||
"required": true,
|
||||
"types": [
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "referencial_action",
|
||||
"named": true,
|
||||
|
@ -493,16 +519,6 @@
|
|||
"named": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"refcolumn": {
|
||||
"multiple": false,
|
||||
"required": false,
|
||||
"types": [
|
||||
{
|
||||
"type": "identifier",
|
||||
"named": true
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"children": {
|
||||
|
@ -577,6 +593,10 @@
|
|||
"type": "keyword_update",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "ref_column_list",
|
||||
"named": true
|
||||
},
|
||||
{
|
||||
"type": "referencial_action",
|
||||
"named": true
|
||||
|
|
4398
src/parser.c
4398
src/parser.c
File diff suppressed because it is too large
Load diff
|
@ -267,7 +267,9 @@ create table foo (
|
|||
(table_reference
|
||||
name: (identifier)
|
||||
)
|
||||
refcolumn: (identifier)
|
||||
(ref_column
|
||||
name: (identifier)
|
||||
)
|
||||
(keyword_on)
|
||||
(keyword_update)
|
||||
(referencial_action
|
||||
|
@ -370,3 +372,310 @@ create table foo (
|
|||
)
|
||||
)
|
||||
)
|
||||
|
||||
================================================================================
|
||||
Create a table with table constraints
|
||||
================================================================================
|
||||
create table foo (
|
||||
id uuid,
|
||||
primary key (id),
|
||||
c1 text not null,
|
||||
c2 text null,
|
||||
c3 text not null default 'hello',
|
||||
unique (c1, c3)
|
||||
);
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(statement
|
||||
(create_table
|
||||
(keyword_create)
|
||||
(keyword_table)
|
||||
(table_reference
|
||||
name: (identifier)
|
||||
)
|
||||
(column_definitions
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_uuid))
|
||||
)
|
||||
(table_constraint
|
||||
(keyword_primary)
|
||||
(keyword_key)
|
||||
(column_list
|
||||
name: (identifier)
|
||||
)
|
||||
)
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_text))
|
||||
(column_constraint
|
||||
(keyword_not)
|
||||
(keyword_null)
|
||||
)
|
||||
)
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_text))
|
||||
(column_constraint
|
||||
(keyword_null)
|
||||
)
|
||||
)
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_text))
|
||||
(column_constraint
|
||||
(keyword_not)
|
||||
(keyword_null)
|
||||
)
|
||||
(column_constraint
|
||||
(keyword_default)
|
||||
(literal
|
||||
(literal_string)
|
||||
)
|
||||
)
|
||||
)
|
||||
(table_constraint
|
||||
(keyword_unique)
|
||||
(column_list
|
||||
name: (identifier)
|
||||
name: (identifier)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
================================================================================
|
||||
Create a table with primary key and foreign key
|
||||
================================================================================
|
||||
create table foo (
|
||||
id uuid primary key,
|
||||
bar_id uuid null references bar (id) on update set null on delete cascade
|
||||
);
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(statement
|
||||
(create_table
|
||||
(keyword_create)
|
||||
(keyword_table)
|
||||
(table_reference
|
||||
name: (identifier)
|
||||
)
|
||||
(column_definitions
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_uuid))
|
||||
(column_constraint
|
||||
(keyword_primary)
|
||||
(keyword_key)
|
||||
)
|
||||
)
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_uuid))
|
||||
(column_constraint
|
||||
(keyword_null)
|
||||
)
|
||||
(column_constraint
|
||||
(keyword_references)
|
||||
(table_reference
|
||||
name: (identifier)
|
||||
)
|
||||
(ref_column
|
||||
name: (identifier)
|
||||
)
|
||||
(keyword_on)
|
||||
(keyword_update)
|
||||
(referencial_action
|
||||
(keyword_set)
|
||||
(keyword_null)
|
||||
)
|
||||
(keyword_on)
|
||||
(keyword_delete)
|
||||
(referencial_action
|
||||
(keyword_cascade)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
================================================================================
|
||||
Create a table with named column constraints
|
||||
================================================================================
|
||||
create table foo (
|
||||
id uuid constraint foo_pkey primary key,
|
||||
c1 text constraint strong_c1 not null,
|
||||
c2 text constraint weak_c2 null,
|
||||
c3 text constraint "c3 with power" not null constraint "c2 set default hello" default 'hello',
|
||||
c4 text constraint "c4 unique" unique nulls not distinct
|
||||
);
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(statement
|
||||
(create_table
|
||||
(keyword_create)
|
||||
(keyword_table)
|
||||
(table_reference
|
||||
name: (identifier)
|
||||
)
|
||||
(column_definitions
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_uuid))
|
||||
(column_constraint
|
||||
(keyword_constraint)
|
||||
name: (identifier)
|
||||
(keyword_primary)
|
||||
(keyword_key)
|
||||
)
|
||||
)
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_text))
|
||||
(column_constraint
|
||||
(keyword_constraint)
|
||||
name: (identifier)
|
||||
(keyword_not)
|
||||
(keyword_null)
|
||||
)
|
||||
)
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_text))
|
||||
(column_constraint
|
||||
(keyword_constraint)
|
||||
name: (identifier)
|
||||
(keyword_null)
|
||||
)
|
||||
)
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_text))
|
||||
(column_constraint
|
||||
(keyword_constraint)
|
||||
name: (identifier)
|
||||
(keyword_not)
|
||||
(keyword_null)
|
||||
)
|
||||
(column_constraint
|
||||
(keyword_constraint)
|
||||
name: (identifier)
|
||||
(keyword_default)
|
||||
(literal
|
||||
(literal_string)
|
||||
)
|
||||
)
|
||||
)
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_text))
|
||||
(column_constraint
|
||||
(keyword_constraint)
|
||||
name: (identifier)
|
||||
(keyword_unique)
|
||||
(keyword_nulls)
|
||||
(keyword_not)
|
||||
(keyword_distinct)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
================================================================================
|
||||
Create a table with named table constraints
|
||||
================================================================================
|
||||
create table foo (
|
||||
id uuid,
|
||||
constraint foo_pkey primary key (id),
|
||||
c3 uuid not null,
|
||||
constraint foo_c3_fkey foreign key (c3) references bar (id) on update set null on delete cascade,
|
||||
c4 text,
|
||||
constraint "c4 unique" unique nulls not distinct (c4)
|
||||
);
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
(source_file
|
||||
(statement
|
||||
(create_table
|
||||
(keyword_create)
|
||||
(keyword_table)
|
||||
(table_reference
|
||||
name: (identifier)
|
||||
)
|
||||
(column_definitions
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_uuid))
|
||||
)
|
||||
(table_constraint
|
||||
(keyword_constraint)
|
||||
name: (identifier)
|
||||
(keyword_primary)
|
||||
(keyword_key)
|
||||
(column_list
|
||||
name: (identifier)
|
||||
)
|
||||
)
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_uuid))
|
||||
(column_constraint
|
||||
(keyword_not)
|
||||
(keyword_null)
|
||||
)
|
||||
)
|
||||
(table_constraint
|
||||
(keyword_constraint)
|
||||
name: (identifier)
|
||||
(keyword_foreign)
|
||||
(keyword_key)
|
||||
(column_list
|
||||
name: (identifier)
|
||||
)
|
||||
(keyword_references)
|
||||
(table_reference
|
||||
name: (identifier)
|
||||
)
|
||||
(ref_column_list
|
||||
name: (identifier)
|
||||
)
|
||||
(keyword_on)
|
||||
(keyword_update)
|
||||
(referencial_action
|
||||
(keyword_set)
|
||||
(keyword_null)
|
||||
)
|
||||
(keyword_on)
|
||||
(keyword_delete)
|
||||
(referencial_action
|
||||
(keyword_cascade)
|
||||
)
|
||||
)
|
||||
(column_definition
|
||||
name: (identifier)
|
||||
(type (keyword_text))
|
||||
)
|
||||
(table_constraint
|
||||
(keyword_constraint)
|
||||
name: (identifier)
|
||||
(keyword_unique)
|
||||
(keyword_nulls)
|
||||
(keyword_not)
|
||||
(keyword_distinct)
|
||||
(column_list
|
||||
name: (identifier)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in a new issue