grammar: add column constraints

This commit is contained in:
Dmitriy Pleshevskiy 2023-01-07 02:13:17 +03:00
parent 0f7f6211db
commit 8a50f066ab
Signed by: pleshevskiy
GPG key ID: 1B59187B161C0215
6 changed files with 2994 additions and 1721 deletions

View file

@ -25,19 +25,45 @@ module.exports = grammar({
optional($._if_not_exists),
$.table_reference,
$.column_definitions
// TODO: INHERITS
// TODO: PARTITION BY
// TODO: USING
// TODO: WITH
// TODO: ON COMMIT
// TODO: TABLESPACE
),
column_definitions: ($) =>
seq(
"(",
optional(commaSepRepeat1(choice($.column_definition /*$.constraint*/))),
optional(
commaSepRepeat1(choice($.column_definition /*, $.table_constraint*/))
),
")"
),
column_definition: ($) =>
seq(field("name", $.identifier), field("datatype", $._type)),
seq(
field("name", $.identifier),
field("datatype", $._type),
repeat($.column_constraint)
),
//constraint: $ => seq(),
column_constraint: ($) =>
seq(
optional(seq($.keyword_constraint, field("name", $.identifier))),
choice(
$._not_null,
$.keyword_null,
seq($.keyword_default, $._expression)
// TODO: CHECK
// TODO: GENERATED
// TODO: UNIQUE
// TODO: PRIMARY KEY
// TODO: FOREIGN KEY
)
// TODO: DEFERRABLE
),
table_reference: ($) =>
seq(
@ -45,8 +71,24 @@ module.exports = grammar({
field("name", $.identifier)
),
_expression: ($) =>
choice(
$.literal
// TODO: add more types
),
literal: ($) =>
choice(
$._number,
$._literal_string,
$.keyword_true,
$.keyword_false,
$.keyword_null
),
// keywords
_if_not_exists: ($) => seq($.keyword_if, $.keyword_not, $.keyword_exists),
_not_null: ($) => seq($.keyword_not, $.keyword_null),
keyword_create: (_) => mkKeyword("create"),
keyword_table: (_) => mkKeyword("table"),
@ -55,6 +97,11 @@ module.exports = grammar({
keyword_if: (_) => mkKeyword("if"),
keyword_not: (_) => mkKeyword("not"),
keyword_exists: (_) => mkKeyword("exists"),
keyword_null: (_) => mkKeyword("null"),
keyword_constraint: (_) => mkKeyword("constraint"),
keyword_default: (_) => mkKeyword("default"),
keyword_true: (_) => mkKeyword("true"),
keyword_false: (_) => mkKeyword("false"),
// References: https://www.postgresql.org/docs/15/datatype.html
_type: ($) =>
@ -177,10 +224,8 @@ module.exports = grammar({
seq(mkKeyword("timestamp"), $._with_time_zone)
),
_without_time_zone: ($) => seq($._keyword_without, $._keyword_time_zone),
_with_time_zone: ($) => seq($._keyword_with, $._keyword_time_zone),
_keyword_without: (_) => mkKeyword("without"),
_keyword_with: (_) => mkKeyword("with"),
_without_time_zone: ($) => seq(mkKeyword("without"), $._keyword_time_zone),
_with_time_zone: ($) => seq(mkKeyword("with"), $._keyword_time_zone),
_keyword_time_zone: (_) => seq(mkKeyword("time"), mkKeyword("zone")),
// References: https://www.postgresql.org/docs/15/datatype-uuid.html
@ -198,9 +243,10 @@ module.exports = grammar({
// https://stackoverflow.com/questions/13014947/regex-to-match-a-c-style-multiline-comment
marginalia: (_) => seq("/*", /[^*]*\*+(?:[^/*][^*]*\*+)*/, "/"),
_literal_string: ($) => choice(seq("'", /[^']*/, "'")),
_number: (_) => /\d+/,
identifier: ($) => choice($._identifier, seq('"', $._identifier, '"')),
identifier: ($) => choice($._identifier, seq('"', /[^"]+/, '"')),
_identifier: (_) => /([a-zA-Z_][0-9a-zA-Z_]*)/,
},

View file

@ -181,6 +181,69 @@
"type": "SYMBOL",
"name": "_type"
}
},
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "column_constraint"
}
}
]
},
"column_constraint": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "keyword_constraint"
},
{
"type": "FIELD",
"name": "name",
"content": {
"type": "SYMBOL",
"name": "identifier"
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_not_null"
},
{
"type": "SYMBOL",
"name": "keyword_null"
},
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "keyword_default"
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
}
]
}
]
},
@ -222,6 +285,40 @@
}
]
},
"_expression": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "literal"
}
]
},
"literal": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_number"
},
{
"type": "SYMBOL",
"name": "_literal_string"
},
{
"type": "SYMBOL",
"name": "keyword_true"
},
{
"type": "SYMBOL",
"name": "keyword_false"
},
{
"type": "SYMBOL",
"name": "keyword_null"
}
]
},
"_if_not_exists": {
"type": "SEQ",
"members": [
@ -239,6 +336,19 @@
}
]
},
"_not_null": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "keyword_not"
},
{
"type": "SYMBOL",
"name": "keyword_null"
}
]
},
"keyword_create": {
"type": "PATTERN",
"value": "create|CREATE"
@ -276,6 +386,26 @@
"type": "PATTERN",
"value": "exists|EXISTS"
},
"keyword_null": {
"type": "PATTERN",
"value": "null|NULL"
},
"keyword_constraint": {
"type": "PATTERN",
"value": "constraint|CONSTRAINT"
},
"keyword_default": {
"type": "PATTERN",
"value": "default|DEFAULT"
},
"keyword_true": {
"type": "PATTERN",
"value": "true|TRUE"
},
"keyword_false": {
"type": "PATTERN",
"value": "false|FALSE"
},
"_type": {
"type": "CHOICE",
"members": [
@ -938,8 +1068,8 @@
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_keyword_without"
"type": "PATTERN",
"value": "without|WITHOUT"
},
{
"type": "SYMBOL",
@ -951,8 +1081,8 @@
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_keyword_with"
"type": "PATTERN",
"value": "with|WITH"
},
{
"type": "SYMBOL",
@ -960,14 +1090,6 @@
}
]
},
"_keyword_without": {
"type": "PATTERN",
"value": "without|WITHOUT"
},
"_keyword_with": {
"type": "PATTERN",
"value": "with|WITH"
},
"_keyword_time_zone": {
"type": "SEQ",
"members": [
@ -1027,6 +1149,28 @@
}
]
},
"_literal_string": {
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "'"
},
{
"type": "PATTERN",
"value": "[^']*"
},
{
"type": "STRING",
"value": "'"
}
]
}
]
},
"_number": {
"type": "PATTERN",
"value": "\\d+"
@ -1046,8 +1190,8 @@
"value": "\""
},
{
"type": "SYMBOL",
"name": "_identifier"
"type": "PATTERN",
"value": "[^\"]+"
},
{
"type": "STRING",

View file

@ -25,6 +25,48 @@
]
}
},
{
"type": "column_constraint",
"named": true,
"fields": {
"name": {
"multiple": false,
"required": false,
"types": [
{
"type": "identifier",
"named": true
}
]
}
},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "keyword_constraint",
"named": true
},
{
"type": "keyword_default",
"named": true
},
{
"type": "keyword_not",
"named": true
},
{
"type": "keyword_null",
"named": true
},
{
"type": "literal",
"named": true
}
]
}
},
{
"type": "column_definition",
"named": true,
@ -137,6 +179,16 @@
}
]
}
},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "column_constraint",
"named": true
}
]
}
},
{
@ -282,6 +334,29 @@
"named": true,
"fields": {}
},
{
"type": "literal",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": false,
"types": [
{
"type": "keyword_false",
"named": true
},
{
"type": "keyword_null",
"named": true
},
{
"type": "keyword_true",
"named": true
}
]
}
},
{
"type": "marginalia",
"named": true,
@ -409,6 +484,10 @@
"type": "\"",
"named": false
},
{
"type": "'",
"named": false
},
{
"type": "(",
"named": false
@ -457,6 +536,10 @@
"type": "keyword_bytea",
"named": true
},
{
"type": "keyword_constraint",
"named": true
},
{
"type": "keyword_create",
"named": true
@ -473,10 +556,18 @@
"type": "keyword_decimal",
"named": true
},
{
"type": "keyword_default",
"named": true
},
{
"type": "keyword_exists",
"named": true
},
{
"type": "keyword_false",
"named": true
},
{
"type": "keyword_if",
"named": true
@ -501,6 +592,10 @@
"type": "keyword_not",
"named": true
},
{
"type": "keyword_null",
"named": true
},
{
"type": "keyword_numeric",
"named": true
@ -529,6 +624,10 @@
"type": "keyword_text",
"named": true
},
{
"type": "keyword_true",
"named": true
},
{
"type": "keyword_unlogged",
"named": true
@ -540,9 +639,5 @@
{
"type": "keyword_xml",
"named": true
},
{
"type": "literal",
"named": true
}
]

File diff suppressed because it is too large Load diff

View file

@ -167,3 +167,113 @@ create table foo (
)
)
)
================================================================================
Create a table with column constraints
================================================================================
create table foo (
c1 text not null,
c2 text null,
c2 text not null default 'hello'
);
--------------------------------------------------------------------------------
(source_file
(statement
(create_table
(keyword_create)
(keyword_table)
(table_reference
name: (identifier)
)
(column_definitions
(column_definition
name: (identifier)
datatype: (keyword_text)
(column_constraint
(keyword_not)
(keyword_null)
)
)
(column_definition
name: (identifier)
datatype: (keyword_text)
(column_constraint
(keyword_null)
)
)
(column_definition
name: (identifier)
datatype: (keyword_text)
(column_constraint
(keyword_not)
(keyword_null)
)
(column_constraint
(keyword_default)
(literal)
)
)
)
)
)
)
================================================================================
Create a table with named column constraints
================================================================================
create table foo (
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'
);
--------------------------------------------------------------------------------
(source_file
(statement
(create_table
(keyword_create)
(keyword_table)
(table_reference
name: (identifier)
)
(column_definitions
(column_definition
name: (identifier)
datatype: (keyword_text)
(column_constraint
(keyword_constraint)
name: (identifier)
(keyword_not)
(keyword_null)
)
)
(column_definition
name: (identifier)
datatype: (keyword_text)
(column_constraint
(keyword_constraint)
name: (identifier)
(keyword_null)
)
)
(column_definition
name: (identifier)
datatype: (keyword_text)
(column_constraint
(keyword_constraint)
name: (identifier)
(keyword_not)
(keyword_null)
)
(column_constraint
(keyword_constraint)
name: (identifier)
(keyword_default)
(literal)
)
)
)
)
)
)

Binary file not shown.