You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
224 lines
6.7 KiB
224 lines
6.7 KiB
# encoding: utf-8
|
|
#
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
#
|
|
# Contact: Kyle Lahnakoski (kyle@lahnakoski.com)
|
|
# Bill Sun 2022 - 2023
|
|
|
|
|
|
# KNOWN TYPES
|
|
from mo_parsing import Forward, Group, Optional, MatchFirst, Literal, ZeroOrMore, export
|
|
from mo_parsing.infix import delimited_list, RIGHT_ASSOC, LEFT_ASSOC
|
|
|
|
from aquery_parser.keywords import (
|
|
RB,
|
|
LB,
|
|
NEG,
|
|
NOT,
|
|
BINARY_NOT,
|
|
NULL,
|
|
EQ,
|
|
KNOWN_OPS,
|
|
LT,
|
|
GT,
|
|
)
|
|
from aquery_parser.utils import (
|
|
keyword,
|
|
to_json_call,
|
|
int_num,
|
|
ansi_string,
|
|
ansi_ident,
|
|
assign,
|
|
flag,
|
|
)
|
|
|
|
_size = Optional(LB + int_num("params") + RB)
|
|
_sizes = Optional(LB + delimited_list(int_num("params")) + RB)
|
|
|
|
simple_types = Forward()
|
|
|
|
BIGINT = Group(keyword("bigint")("op") + Optional(_size)+Optional(flag("unsigned"))) / to_json_call
|
|
BOOL = Group(keyword("bool")("op")) / to_json_call
|
|
BOOLEAN = Group(keyword("boolean")("op")) / to_json_call
|
|
DOUBLE = Group(keyword("double")("op")) / to_json_call
|
|
FLOAT64 = Group(keyword("float64")("op")) / to_json_call
|
|
FLOAT = Group(keyword("float")("op")) / to_json_call
|
|
GEOMETRY = Group(keyword("geometry")("op")) / to_json_call
|
|
INTEGER = Group(keyword("integer")("op")) / to_json_call
|
|
INT = (keyword("int")("op") + _size) / to_json_call
|
|
INT32 = Group(keyword("int32")("op")) / to_json_call
|
|
INT64 = Group(keyword("int64")("op")) / to_json_call
|
|
REAL = Group(keyword("real")("op")) / to_json_call
|
|
TEXT = Group(keyword("text")("op")) / to_json_call
|
|
SMALLINT = Group(keyword("smallint")("op")) / to_json_call
|
|
STRING = Group(keyword("string")("op")) / to_json_call
|
|
|
|
BLOB = (keyword("blob")("op") + _size) / to_json_call
|
|
BYTES = (keyword("bytes")("op") + _size) / to_json_call
|
|
CHAR = (keyword("char")("op") + _size) / to_json_call
|
|
NCHAR = (keyword("nchar")("op") + _size) / to_json_call
|
|
VARCHAR = (keyword("varchar")("op") + _size) / to_json_call
|
|
VARCHAR2 = (keyword("varchar2")("op") + _size) / to_json_call
|
|
VARBINARY = (keyword("varbinary")("op") + _size) / to_json_call
|
|
TINYINT = (keyword("tinyint")("op") + _size) / to_json_call
|
|
UUID = Group(keyword("uuid")("op")) / to_json_call
|
|
|
|
DECIMAL = (keyword("decimal")("op") + _sizes) / to_json_call
|
|
DOUBLE_PRECISION = (
|
|
Group((keyword("double precision") / (lambda: "double_precision"))("op"))
|
|
/ to_json_call
|
|
)
|
|
NUMERIC = (keyword("numeric")("op") + _sizes) / to_json_call
|
|
NUMBER = (keyword("number")("op") + _sizes) / to_json_call
|
|
|
|
MAP_TYPE = (
|
|
keyword("map")("op") + LB + delimited_list(simple_types("params")) + RB
|
|
) / to_json_call
|
|
ARRAY_TYPE = (keyword("array")("op") + LB + simple_types("params") + RB) / to_json_call
|
|
|
|
DATE = keyword("date")
|
|
DATETIME = keyword("datetime")
|
|
DATETIME_W_TIMEZONE = keyword("datetime with time zone")
|
|
TIME = keyword("time")
|
|
TIMESTAMP = keyword("timestamp")
|
|
TIMESTAMP_W_TIMEZONE = keyword("timestamp with time zone")
|
|
TIMESTAMPTZ = keyword("timestamptz")
|
|
TIMETZ = keyword("timetz")
|
|
|
|
time_functions = DATE | DATETIME | TIME | TIMESTAMP | TIMESTAMPTZ | TIMETZ
|
|
|
|
# KNOWNN TIME TYPES
|
|
_format = Optional((ansi_string | ansi_ident)("params"))
|
|
|
|
DATE_TYPE = (DATE("op") + _format) / to_json_call
|
|
DATETIME_TYPE = (DATETIME("op") + _format) / to_json_call
|
|
DATETIME_W_TIMEZONE_TYPE = (DATETIME_W_TIMEZONE("op") + _format) / to_json_call
|
|
TIME_TYPE = (TIME("op") + _format) / to_json_call
|
|
TIMESTAMP_TYPE = (TIMESTAMP("op") + _format) / to_json_call
|
|
TIMESTAMP_W_TIMEZONE_TYPE = (TIMESTAMP_W_TIMEZONE("op") + _format) / to_json_call
|
|
TIMESTAMPTZ_TYPE = (TIMESTAMPTZ("op") + _format) / to_json_call
|
|
TIMETZ_TYPE = (TIMETZ("op") + _format) / to_json_call
|
|
|
|
simple_types << MatchFirst([
|
|
ARRAY_TYPE,
|
|
BIGINT,
|
|
BOOL,
|
|
BOOLEAN,
|
|
BLOB,
|
|
BYTES,
|
|
CHAR,
|
|
DATE_TYPE,
|
|
DATETIME_W_TIMEZONE_TYPE,
|
|
DATETIME_TYPE,
|
|
DECIMAL,
|
|
DOUBLE_PRECISION,
|
|
DOUBLE,
|
|
FLOAT64,
|
|
FLOAT,
|
|
GEOMETRY,
|
|
MAP_TYPE,
|
|
INTEGER,
|
|
INT,
|
|
INT32,
|
|
INT64,
|
|
NCHAR,
|
|
NUMBER,
|
|
NUMERIC,
|
|
REAL,
|
|
TEXT,
|
|
SMALLINT,
|
|
STRING,
|
|
TIME_TYPE,
|
|
TIMESTAMP_W_TIMEZONE_TYPE,
|
|
TIMESTAMP_TYPE,
|
|
TIMESTAMPTZ_TYPE,
|
|
TIMETZ_TYPE,
|
|
TINYINT,
|
|
UUID,
|
|
VARCHAR,
|
|
VARCHAR2,
|
|
VARBINARY,
|
|
])
|
|
|
|
CASTING = (Literal("::").suppress() + simple_types("params")).set_parser_name("cast")
|
|
KNOWN_OPS.insert(0, CASTING)
|
|
|
|
unary_ops = {
|
|
NEG: RIGHT_ASSOC,
|
|
NOT: RIGHT_ASSOC,
|
|
BINARY_NOT: RIGHT_ASSOC,
|
|
CASTING: LEFT_ASSOC,
|
|
}
|
|
|
|
|
|
def get_column_type(expr, var_name, literal_string):
|
|
column_definition = Forward()
|
|
column_type = Forward().set_parser_name("column type")
|
|
|
|
struct_type = (
|
|
keyword("struct")("op")
|
|
+ LT.suppress()
|
|
+ Group(delimited_list(column_definition))("params")
|
|
+ GT.suppress()
|
|
) / to_json_call
|
|
|
|
row_type = (
|
|
keyword("row")("op")
|
|
+ LB
|
|
+ Group(delimited_list(column_definition))("params")
|
|
+ RB
|
|
) / to_json_call
|
|
|
|
array_type = (
|
|
keyword("array")("op")
|
|
+ (
|
|
(
|
|
LT.suppress()
|
|
+ Group(delimited_list(column_type))("params")
|
|
+ GT.suppress()
|
|
)
|
|
| (LB + Group(delimited_list(column_type))("params") + RB)
|
|
)
|
|
) / to_json_call
|
|
|
|
column_type << (struct_type | row_type | array_type | simple_types)
|
|
|
|
column_def_identity = (
|
|
assign(
|
|
"generated",
|
|
(keyword("always") | keyword("by default") / (lambda: "by_default")),
|
|
)
|
|
+ keyword("as identity").suppress()
|
|
+ Optional(assign("start with", int_num))
|
|
+ Optional(assign("increment by", int_num))
|
|
)
|
|
|
|
column_def_references = assign(
|
|
"references", var_name("table") + LB + delimited_list(var_name)("columns") + RB,
|
|
)
|
|
|
|
column_options = ZeroOrMore(
|
|
((NOT + NULL) / (lambda: False))("nullable")
|
|
| (NULL / (lambda t: True))("nullable")
|
|
| flag("unique")
|
|
| flag("auto_increment")
|
|
| assign("comment", literal_string)
|
|
| assign("collate", Optional(EQ) + var_name)
|
|
| flag("primary key")
|
|
| column_def_identity("identity")
|
|
| column_def_references
|
|
| assign("check", LB + expr + RB)
|
|
| assign("default", expr)
|
|
).set_parser_name("column_options")
|
|
|
|
column_definition << Group(
|
|
var_name("name") + (column_type | var_name)("type") + column_options
|
|
).set_parser_name("column_definition")
|
|
|
|
return column_type, column_definition, column_def_references
|
|
|
|
|
|
export("aquery_parser.utils", unary_ops)
|