grammar: add column constraints
This commit is contained in:
parent
0f7f6211db
commit
8a50f066ab
6 changed files with 2994 additions and 1721 deletions
62
grammar.js
62
grammar.js
|
@ -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_]*)/,
|
||||
},
|
||||
|
|
172
src/grammar.json
172
src/grammar.json
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
}
|
||||
]
|
4268
src/parser.c
4268
src/parser.c
File diff suppressed because it is too large
Load diff
|
@ -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.
Loading…
Reference in a new issue