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: ($) => column_definitions: ($) =>
seq( parens(
"(", optional(commaSep1(choice($.column_definition, $.table_constraint)))
optional(
commaSepRepeat1(choice($.column_definition, $.table_constraint))
),
")"
), ),
column_definition: ($) => column_definition: ($) =>
@ -55,28 +51,53 @@ module.exports = grammar({
// TODO: add index_parameters in UNIQUE, PRIMARY KEY // TODO: add index_parameters in UNIQUE, PRIMARY KEY
$._unique_constraint, $._unique_constraint,
$._primary_key, $._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: CHECK
// TODO: GENERATED // TODO: GENERATED
) )
// TODO: DEFERRABLE // TODO: DEFERRABLE
), ),
ref_column: ($) => parens(field("name", $.identifier)),
table_constraint: ($) => table_constraint: ($) =>
seq( seq(
optional(seq($.keyword_constraint, field("name", $.identifier))), optional(seq($.keyword_constraint, field("name", $.identifier))),
choice( choice(
seq($._unique_constraint, $.column_list), seq($._unique_constraint, $.column_list),
seq($._primary_key, $.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: CHECK
// TODO: EXCLUDE // TODO: EXCLUDE
) )
// TODO: DEFERRABLE // TODO: DEFERRABLE
), ),
column_list: ($) => column_list: ($) => parens(commaSep1(field("name", $.identifier))),
seq("(", commaSepRepeat1(field("name", $.identifier)), ")"),
_unique_constraint: ($) => _unique_constraint: ($) =>
seq( 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: ($) => _foreign_key_match: ($) =>
seq( seq(
$.keyword_match, $.keyword_match,
@ -117,7 +125,7 @@ module.exports = grammar({
seq( seq(
$.keyword_set, $.keyword_set,
choice($.keyword_null, $.keyword_default), 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()); return new RegExp(word + "|" + word.toUpperCase());
} }
function commaSepRepeat1(field) { function commaSep1(rule) {
return seq(field, repeat(seq(",", field))); 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"]) { function parametricType($, type, params = ["size"]) {

View file

@ -256,13 +256,106 @@
"name": "_primary_key" "name": "_primary_key"
}, },
{ {
"type": "SYMBOL", "type": "SEQ",
"name": "_foreign_key_references" "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": { "table_constraint": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [
@ -333,7 +426,79 @@
}, },
{ {
"type": "SYMBOL", "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": { "_foreign_key_match": {
"type": "SEQ", "type": "SEQ",
"members": [ "members": [

View file

@ -43,16 +43,6 @@
"named": true "named": true
} }
] ]
},
"refcolumn": {
"multiple": false,
"required": false,
"types": [
{
"type": "identifier",
"named": true
}
]
} }
}, },
"children": { "children": {
@ -131,6 +121,10 @@
"type": "literal", "type": "literal",
"named": true "named": true
}, },
{
"type": "ref_column",
"named": true
},
{ {
"type": "referencial_action", "type": "referencial_action",
"named": true "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", "type": "referencial_action",
"named": true, "named": true,
@ -493,16 +519,6 @@
"named": true "named": true
} }
] ]
},
"refcolumn": {
"multiple": false,
"required": false,
"types": [
{
"type": "identifier",
"named": true
}
]
} }
}, },
"children": { "children": {
@ -577,6 +593,10 @@
"type": "keyword_update", "type": "keyword_update",
"named": true "named": true
}, },
{
"type": "ref_column_list",
"named": true
},
{ {
"type": "referencial_action", "type": "referencial_action",
"named": true "named": true

File diff suppressed because it is too large Load diff

View file

@ -267,7 +267,9 @@ create table foo (
(table_reference (table_reference
name: (identifier) name: (identifier)
) )
refcolumn: (identifier) (ref_column
name: (identifier)
)
(keyword_on) (keyword_on)
(keyword_update) (keyword_update)
(referencial_action (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.