grammar: fix foreign key

This commit is contained in:
Dmitriy Pleshevskiy 2023-01-08 23:54:06 +03:00
parent de04a49b20
commit 09f0ec4c3f
Signed by: pleshevskiy
GPG key ID: 1B59187B161C0215
7 changed files with 3147 additions and 1954 deletions

View file

@ -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"]) {

View file

@ -255,11 +255,104 @@
"type": "SYMBOL",
"name": "_primary_key"
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_foreign_key_references"
"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": ")"
}
]
},
@ -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": [

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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.