rawsql-ts
Version:
High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
738 lines • 31.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CreateTableParser = void 0;
const SqlTokenizer_1 = require("./SqlTokenizer");
const SelectQueryParser_1 = require("./SelectQueryParser");
const CreateTableQuery_1 = require("../models/CreateTableQuery");
const Lexeme_1 = require("../models/Lexeme");
const FullNameParser_1 = require("./FullNameParser");
const FunctionExpressionParser_1 = require("./FunctionExpressionParser");
const ValueParser_1 = require("./ValueParser");
const ValueComponent_1 = require("../models/ValueComponent");
const ParserStringUtils_1 = require("../utils/ParserStringUtils");
/**
* Parses CREATE TABLE statements (DDL or AS SELECT) into CreateTableQuery models.
*/
class CreateTableParser {
/**
* Parse SQL string to CreateTableQuery AST.
*/
static parse(query) {
const tokenizer = new SqlTokenizer_1.SqlTokenizer(query);
const lexemes = tokenizer.readLexemes();
const result = this.parseFromLexeme(lexemes, 0);
if (result.newIndex < lexemes.length) {
throw new Error(`Syntax error: Unexpected token "${lexemes[result.newIndex].value}" at position ${result.newIndex}. The CREATE TABLE statement is complete but there are additional tokens.`);
}
return result.value;
}
/**
* Parse from lexeme array (for internal use and tests).
*/
static parseFromLexeme(lexemes, index) {
var _a;
let idx = index;
// Guard against unexpected end of input before parsing begins.
if (idx >= lexemes.length) {
throw new Error(`[CreateTableParser] Unexpected end of input at position ${idx}.`);
}
const commandLexeme = lexemes[idx];
// Capture comments that precede the CREATE TABLE keyword so they can be re-applied later.
const leadingCreateComments = this.popLexemeComments(commandLexeme, 'before');
const commandToken = commandLexeme.value.toLowerCase();
const isTemporary = commandToken === "create temporary table";
if (commandToken !== "create table" && !isTemporary) {
throw new Error(`[CreateTableParser] Syntax error at position ${idx}: expected 'CREATE TABLE' but found '${lexemes[idx].value}'.`);
}
idx++;
// Handle optional IF NOT EXISTS clause.
const tokenAt = (offset) => { var _a; return (_a = lexemes[idx + offset]) === null || _a === void 0 ? void 0 : _a.value.toLowerCase(); };
let ifNotExists = false;
if (tokenAt(0) === "if not exists") {
idx++;
ifNotExists = true;
}
// Parse qualified table name.
const tableNameResult = this.parseQualifiedName(lexemes, idx);
idx = tableNameResult.newIndex;
const tableName = tableNameResult.name;
const tableNamespaces = tableNameResult.namespaces;
// Place captured comments from the identifier on the CreateTableQuery after instantiation.
const positionedComments = tableName.positionedComments ? [...tableName.positionedComments] : null;
const legacyComments = tableName.comments ? [...tableName.comments] : null;
let columns = [];
let tableConstraints = [];
let tableOptions = null;
let asSelectQuery;
let withDataOption = null;
// Parse DDL column definitions when present.
if (((_a = lexemes[idx]) === null || _a === void 0 ? void 0 : _a.type) === Lexeme_1.TokenType.OpenParen) {
({ columns, tableConstraints, newIndex: idx } = this.parseDefinitionList(lexemes, idx));
}
// Capture trailing table options that appear before an AS SELECT clause.
if (idx < lexemes.length) {
const nextValue = tokenAt(0);
if (!this.isSelectKeyword(nextValue, lexemes[idx + 1])) {
const optionsEnd = this.findClauseBoundary(lexemes, idx);
if (optionsEnd > idx) {
tableOptions = new ValueComponent_1.RawString((0, ParserStringUtils_1.joinLexemeValues)(lexemes, idx, optionsEnd));
idx = optionsEnd;
}
}
}
// Parse optional AS SELECT / SELECT clause.
const nextToken = tokenAt(0);
if (nextToken === "as") {
idx++;
const selectResult = SelectQueryParser_1.SelectQueryParser.parseFromLexeme(lexemes, idx);
asSelectQuery = selectResult.value;
idx = selectResult.newIndex;
}
else if (nextToken === "select" || nextToken === "with" || nextToken === "values") {
const selectResult = SelectQueryParser_1.SelectQueryParser.parseFromLexeme(lexemes, idx);
asSelectQuery = selectResult.value;
idx = selectResult.newIndex;
}
if (asSelectQuery) {
// Allow optional PostgreSQL-style WITH [NO] DATA clause after AS SELECT bodies.
const withResult = this.parseWithDataOption(lexemes, idx);
if (withResult) {
withDataOption = withResult.value;
idx = withResult.newIndex;
}
}
const query = new CreateTableQuery_1.CreateTableQuery({
tableName: tableName.name,
namespaces: tableNamespaces,
isTemporary,
ifNotExists,
columns,
tableConstraints,
tableOptions,
asSelectQuery,
withDataOption
});
// Re-attach positioned comments captured on the identifier.
if (positionedComments) {
query.tableName.positionedComments = positionedComments.map(pc => ({
position: pc.position,
comments: [...pc.comments]
}));
}
if (legacyComments) {
query.tableName.comments = [...legacyComments];
}
if (leadingCreateComments.length > 0) {
// Keep top-level comments aligned with the CREATE TABLE statement.
query.addPositionedComments('before', leadingCreateComments);
}
return { value: query, newIndex: idx };
}
static parseQualifiedName(lexemes, index) {
const { namespaces, name, newIndex } = FullNameParser_1.FullNameParser.parseFromLexeme(lexemes, index);
return {
namespaces: namespaces ? [...namespaces] : null,
name,
newIndex
};
}
static parseDefinitionList(lexemes, index) {
var _a, _b;
let idx = index;
const columns = [];
const constraints = [];
const openParenLexeme = lexemes[idx];
// Convert comments placed immediately after '(' into leading comments for the first entry.
let pendingLeading = this.toOptionalComments(this.popLexemeComments(openParenLexeme, 'after'));
// Skip opening parenthesis.
idx++;
// Parse individual column or constraint entries until closing parenthesis.
while (idx < lexemes.length) {
const lexeme = lexemes[idx];
if (lexeme.type === Lexeme_1.TokenType.CloseParen) {
// When comments sit right before ')', keep them with the preceding entry.
const closingLeading = this.popLexemeComments(lexeme, 'before');
if (closingLeading.length > 0) {
const target = (_a = (constraints.length > 0 ? constraints[constraints.length - 1] : columns[columns.length - 1])) !== null && _a !== void 0 ? _a : null;
if (target) {
target.addPositionedComments('after', closingLeading);
}
}
idx++;
break;
}
const tokenValue = lexeme.value.toLowerCase();
const isConstraint = this.TABLE_CONSTRAINT_STARTERS.has(tokenValue);
const entryResult = isConstraint
? this.parseTableConstraint(lexemes, idx)
: this.parseColumnDefinition(lexemes, idx);
let entry = entryResult.value;
if (pendingLeading && pendingLeading.length > 0) {
// Reattach comments that belonged between comma/parenthesis and the entry itself.
entry.addPositionedComments('before', pendingLeading);
pendingLeading = null;
}
const trailingComments = this.popLexemeComments(lexemes[Math.max(entryResult.newIndex - 1, idx)], 'after');
if (trailingComments.length > 0) {
// Preserve inline comments that appeared after the entry tokens.
entry.addPositionedComments('after', trailingComments);
}
if (isConstraint) {
constraints.push(entry);
}
else {
columns.push(entry);
}
idx = entryResult.newIndex;
// Consume delimiter comma between definitions.
if (idx < lexemes.length && (lexemes[idx].type & Lexeme_1.TokenType.Comma)) {
const commaLexeme = lexemes[idx];
const commaTrailing = this.popLexemeComments(commaLexeme, 'after');
pendingLeading = this.toOptionalComments(commaTrailing);
idx++;
continue;
}
// Break when encountering the closing parenthesis.
if (idx < lexemes.length && lexemes[idx].type === Lexeme_1.TokenType.CloseParen) {
const closingLexeme = lexemes[idx];
const closingLeading = this.popLexemeComments(closingLexeme, 'before');
if (closingLeading.length > 0) {
const target = (_b = (constraints.length > 0 ? constraints[constraints.length - 1] : columns[columns.length - 1])) !== null && _b !== void 0 ? _b : null;
if (target) {
target.addPositionedComments('after', closingLeading);
}
}
idx++;
break;
}
pendingLeading = null;
}
return { columns, tableConstraints: constraints, newIndex: idx };
}
static parseColumnDefinition(lexemes, index) {
let idx = index;
// Parse the column name as a qualified identifier.
const columnNameResult = this.parseQualifiedName(lexemes, idx);
idx = columnNameResult.newIndex;
if (columnNameResult.namespaces && columnNameResult.namespaces.length > 0) {
const qualified = [...columnNameResult.namespaces, columnNameResult.name.name].join(".");
throw new Error(`[CreateTableParser] Column name '${qualified}' must not include a schema or namespace qualifier.`);
}
const columnName = columnNameResult.name;
// Parse optional data type immediately following the column name.
let dataType;
if (idx < lexemes.length && !this.isColumnConstraintStart(lexemes[idx]) && !this.isColumnTerminator(lexemes[idx])) {
const typeResult = this.parseColumnType(lexemes, idx);
dataType = typeResult.value;
idx = typeResult.newIndex;
}
// Collect column constraints until termination.
const constraints = [];
while (idx < lexemes.length && !this.isColumnTerminator(lexemes[idx])) {
const constraintResult = this.parseColumnConstraint(lexemes, idx);
constraints.push(constraintResult.value);
idx = constraintResult.newIndex;
}
const columnDef = new CreateTableQuery_1.TableColumnDefinition({
name: columnName,
dataType,
constraints
});
return { value: columnDef, newIndex: idx };
}
static parseColumnType(lexemes, index) {
try {
const result = FunctionExpressionParser_1.FunctionExpressionParser.parseTypeValue(lexemes, index);
return { value: result.value, newIndex: result.newIndex };
}
catch {
const typeEnd = this.findFirstConstraintIndex(lexemes, index);
const rawText = (0, ParserStringUtils_1.joinLexemeValues)(lexemes, index, typeEnd);
return { value: new ValueComponent_1.RawString(rawText), newIndex: typeEnd };
}
}
static parseColumnConstraint(lexemes, index) {
var _a;
let idx = index;
let constraintName;
// Handle optional CONSTRAINT <name> prefix.
if (((_a = lexemes[idx]) === null || _a === void 0 ? void 0 : _a.value.toLowerCase()) === "constraint") {
idx++;
const nameResult = this.parseQualifiedName(lexemes, idx);
constraintName = nameResult.name;
idx = nameResult.newIndex;
}
const token = lexemes[idx];
if (!token) {
throw new Error(`[CreateTableParser] Expected constraint definition at index ${idx}.`);
}
const value = token.value.toLowerCase();
// Parse NOT NULL / NULL constraints.
if (value === "not null" || value === "null") {
idx++;
return {
value: new CreateTableQuery_1.ColumnConstraintDefinition({
kind: value === "not null" ? "not-null" : "null",
constraintName
}),
newIndex: idx
};
}
// Parse DEFAULT constraint with arbitrary expressions.
if (value === "default") {
idx++;
const exprResult = ValueParser_1.ValueParser.parseFromLexeme(lexemes, idx);
idx = exprResult.newIndex;
return {
value: new CreateTableQuery_1.ColumnConstraintDefinition({
kind: "default",
constraintName,
defaultValue: exprResult.value
}),
newIndex: idx
};
}
// Parse PRIMARY KEY constraint.
if (value === "primary key") {
idx++;
return {
value: new CreateTableQuery_1.ColumnConstraintDefinition({
kind: "primary-key",
constraintName
}),
newIndex: idx
};
}
// Parse UNIQUE / UNIQUE KEY constraint.
if (value === "unique" || value === "unique key") {
idx++;
return {
value: new CreateTableQuery_1.ColumnConstraintDefinition({
kind: "unique",
constraintName
}),
newIndex: idx
};
}
// Parse REFERENCES clause.
if (value === "references") {
const referenceResult = this.parseReferenceDefinition(lexemes, idx);
idx = referenceResult.newIndex;
return {
value: new CreateTableQuery_1.ColumnConstraintDefinition({
kind: "references",
constraintName,
reference: referenceResult.value
}),
newIndex: idx
};
}
// Parse CHECK constraint.
if (value === "check") {
idx++;
const checkExpression = this.parseParenExpression(lexemes, idx);
idx = checkExpression.newIndex;
return {
value: new CreateTableQuery_1.ColumnConstraintDefinition({
kind: "check",
constraintName,
checkExpression: checkExpression.value
}),
newIndex: idx
};
}
// Parse identity-style generated clauses.
if (value.startsWith("generated")) {
const clauseEnd = this.findFirstConstraintIndex(lexemes, idx + 1);
const text = (0, ParserStringUtils_1.joinLexemeValues)(lexemes, idx, clauseEnd);
idx = clauseEnd;
const kind = value.startsWith("generated always")
? "generated-always-identity"
: "generated-by-default-identity";
return {
value: new CreateTableQuery_1.ColumnConstraintDefinition({
kind,
constraintName,
rawClause: new ValueComponent_1.RawString(text)
}),
newIndex: idx
};
}
// Fallback to raw clause capture for unsupported constraints.
const rawEnd = this.findFirstConstraintIndex(lexemes, idx + 1);
const rawText = (0, ParserStringUtils_1.joinLexemeValues)(lexemes, idx, rawEnd);
return {
value: new CreateTableQuery_1.ColumnConstraintDefinition({
kind: "raw",
constraintName,
rawClause: new ValueComponent_1.RawString(rawText)
}),
newIndex: rawEnd
};
}
static parseTableConstraint(lexemes, index) {
var _a;
let idx = index;
let constraintName;
// Capture optional CONSTRAINT <name> prefix.
if (((_a = lexemes[idx]) === null || _a === void 0 ? void 0 : _a.value.toLowerCase()) === "constraint") {
idx++;
const nameResult = this.parseQualifiedName(lexemes, idx);
constraintName = nameResult.name;
idx = nameResult.newIndex;
}
const token = lexemes[idx];
if (!token) {
throw new Error(`[CreateTableParser] Expected table constraint at index ${idx}.`);
}
const value = token.value.toLowerCase();
if (value === "primary key") {
idx++;
const { identifiers, newIndex } = this.parseIdentifierList(lexemes, idx);
idx = newIndex;
return {
value: new CreateTableQuery_1.TableConstraintDefinition({
kind: "primary-key",
constraintName,
columns: identifiers
}),
newIndex: idx
};
}
if (value === "unique" || value === "unique key") {
idx++;
let inlineKeyName;
if (idx < lexemes.length &&
lexemes[idx].value !== "(" &&
!(lexemes[idx].type & Lexeme_1.TokenType.Command)) {
const inlineNameResult = this.parseQualifiedName(lexemes, idx);
inlineKeyName = inlineNameResult.name;
idx = inlineNameResult.newIndex;
}
const { identifiers, newIndex } = this.parseIdentifierList(lexemes, idx);
idx = newIndex;
return {
value: new CreateTableQuery_1.TableConstraintDefinition({
kind: "unique",
constraintName: constraintName !== null && constraintName !== void 0 ? constraintName : inlineKeyName,
columns: identifiers
}),
newIndex: idx
};
}
if (value === "foreign key") {
idx++;
let inlineKeyName;
if (idx < lexemes.length &&
lexemes[idx].value !== "(" &&
!(lexemes[idx].type & Lexeme_1.TokenType.Command)) {
const inlineNameResult = this.parseQualifiedName(lexemes, idx);
inlineKeyName = inlineNameResult.name;
idx = inlineNameResult.newIndex;
}
const { identifiers, newIndex } = this.parseIdentifierList(lexemes, idx);
idx = newIndex;
const referenceResult = this.parseReferenceDefinition(lexemes, idx);
idx = referenceResult.newIndex;
return {
value: new CreateTableQuery_1.TableConstraintDefinition({
kind: "foreign-key",
constraintName: constraintName !== null && constraintName !== void 0 ? constraintName : inlineKeyName,
columns: identifiers,
reference: referenceResult.value,
deferrable: referenceResult.value.deferrable,
initially: referenceResult.value.initially
}),
newIndex: idx
};
}
if (value === "check") {
idx++;
const checkExpression = this.parseParenExpression(lexemes, idx);
idx = checkExpression.newIndex;
return {
value: new CreateTableQuery_1.TableConstraintDefinition({
kind: "check",
constraintName,
checkExpression: checkExpression.value
}),
newIndex: idx
};
}
// Fallback to capturing the raw text when the constraint is not recognized.
const rawEnd = this.findFirstConstraintIndex(lexemes, idx + 1);
const rawText = (0, ParserStringUtils_1.joinLexemeValues)(lexemes, idx, rawEnd);
return {
value: new CreateTableQuery_1.TableConstraintDefinition({
kind: "raw",
constraintName,
rawClause: new ValueComponent_1.RawString(rawText)
}),
newIndex: rawEnd
};
}
static parseIdentifierList(lexemes, index) {
var _a, _b, _c;
let idx = index;
const identifiers = [];
if (((_a = lexemes[idx]) === null || _a === void 0 ? void 0 : _a.type) !== Lexeme_1.TokenType.OpenParen) {
throw new Error(`[CreateTableParser] Expected '(' to start identifier list at index ${idx}.`);
}
idx++;
while (idx < lexemes.length) {
const nameResult = this.parseQualifiedName(lexemes, idx);
identifiers.push(nameResult.name);
idx = nameResult.newIndex;
if (((_b = lexemes[idx]) === null || _b === void 0 ? void 0 : _b.type) === Lexeme_1.TokenType.Comma) {
idx++;
continue;
}
if (((_c = lexemes[idx]) === null || _c === void 0 ? void 0 : _c.type) === Lexeme_1.TokenType.CloseParen) {
idx++;
break;
}
}
return { identifiers, newIndex: idx };
}
static parseReferenceDefinition(lexemes, index) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
let idx = index;
if (((_a = lexemes[idx]) === null || _a === void 0 ? void 0 : _a.value.toLowerCase()) !== "references") {
throw new Error(`[CreateTableParser] Expected REFERENCES clause at index ${idx}.`);
}
idx++;
const tableNameResult = this.parseQualifiedName(lexemes, idx);
idx = tableNameResult.newIndex;
const targetTable = new ValueComponent_1.QualifiedName(tableNameResult.namespaces, tableNameResult.name);
// Parse optional column list in the REFERENCES clause.
let columns = null;
if (((_b = lexemes[idx]) === null || _b === void 0 ? void 0 : _b.type) === Lexeme_1.TokenType.OpenParen) {
const listResult = this.parseIdentifierList(lexemes, idx);
columns = listResult.identifiers;
idx = listResult.newIndex;
}
let matchType = null;
let onDelete = null;
let onUpdate = null;
let deferrable = null;
let initially = null;
// Parse optional trailing reference options.
while (idx < lexemes.length) {
const current = lexemes[idx].value.toLowerCase();
if (this.MATCH_KEYWORDS.has(current)) {
matchType = this.MATCH_KEYWORDS.get(current);
idx++;
continue;
}
if (current === "match") {
idx++;
const descriptor = (_d = (_c = lexemes[idx]) === null || _c === void 0 ? void 0 : _c.value.toLowerCase()) !== null && _d !== void 0 ? _d : "";
matchType = descriptor;
idx++;
continue;
}
if (current === "on delete") {
idx++;
const action = (_f = (_e = lexemes[idx]) === null || _e === void 0 ? void 0 : _e.value.toLowerCase()) !== null && _f !== void 0 ? _f : "";
onDelete = (_g = this.REFERENTIAL_ACTIONS.get(action)) !== null && _g !== void 0 ? _g : null;
idx++;
continue;
}
if (current === "on update") {
idx++;
const action = (_j = (_h = lexemes[idx]) === null || _h === void 0 ? void 0 : _h.value.toLowerCase()) !== null && _j !== void 0 ? _j : "";
onUpdate = (_k = this.REFERENTIAL_ACTIONS.get(action)) !== null && _k !== void 0 ? _k : null;
idx++;
continue;
}
if (this.DEFERRABILITY_KEYWORDS.has(current)) {
deferrable = this.DEFERRABILITY_KEYWORDS.get(current);
idx++;
continue;
}
if (this.INITIALLY_KEYWORDS.has(current)) {
initially = this.INITIALLY_KEYWORDS.get(current);
idx++;
continue;
}
break;
}
return {
value: new CreateTableQuery_1.ReferenceDefinition({
targetTable,
columns,
matchType,
onDelete,
onUpdate,
deferrable,
initially
}),
newIndex: idx
};
}
static parseParenExpression(lexemes, index) {
var _a, _b;
let idx = index;
if (((_a = lexemes[idx]) === null || _a === void 0 ? void 0 : _a.type) !== Lexeme_1.TokenType.OpenParen) {
throw new Error(`[CreateTableParser] Expected '(' introducing expression at index ${idx}.`);
}
idx++;
const expressionResult = ValueParser_1.ValueParser.parseFromLexeme(lexemes, idx);
idx = expressionResult.newIndex;
if (((_b = lexemes[idx]) === null || _b === void 0 ? void 0 : _b.type) !== Lexeme_1.TokenType.CloseParen) {
throw new Error(`[CreateTableParser] Expected ')' terminating expression at index ${idx}.`);
}
idx++;
return { value: expressionResult.value, newIndex: idx };
}
static isColumnConstraintStart(lexeme) {
if (!lexeme) {
return false;
}
const lower = lexeme.value.toLowerCase();
return this.COLUMN_CONSTRAINT_STARTERS.has(lower);
}
static isColumnTerminator(lexeme) {
if (!lexeme) {
return true;
}
if (lexeme.type & (Lexeme_1.TokenType.Comma | Lexeme_1.TokenType.CloseParen)) {
return true;
}
return false;
}
static isSelectKeyword(value, nextLexeme) {
if (!value) {
return false;
}
if (value === 'with' && (nextLexeme === null || nextLexeme === void 0 ? void 0 : nextLexeme.type) === Lexeme_1.TokenType.OpenParen) {
return false;
}
return value === "as" || value === "select" || value === "with" || value === "values";
}
static findClauseBoundary(lexemes, index) {
let idx = index;
while (idx < lexemes.length) {
const lower = lexemes[idx].value.toLowerCase();
if (this.isSelectKeyword(lower, lexemes[idx + 1])) {
break;
}
idx++;
}
return idx;
}
static findFirstConstraintIndex(lexemes, index) {
let idx = index;
while (idx < lexemes.length && !this.isColumnConstraintStart(lexemes[idx]) && !this.isColumnTerminator(lexemes[idx])) {
idx++;
}
return idx;
}
static parseWithDataOption(lexemes, index) {
// Detect PostgreSQL-style WITH [NO] DATA phrases that follow CREATE TABLE ... AS SELECT.
const current = lexemes[index];
if (!current) {
return null;
}
const value = current.value.toLowerCase();
if (value === "with data") {
return { value: "with-data", newIndex: index + 1 };
}
if (value === "with no data") {
return { value: "with-no-data", newIndex: index + 1 };
}
if (value !== "with") {
return null;
}
const next = lexemes[index + 1];
const nextValue = next === null || next === void 0 ? void 0 : next.value.toLowerCase();
if (nextValue === "data") {
return { value: "with-data", newIndex: index + 2 };
}
if (nextValue === "data") {
return { value: "with-data", newIndex: index + 2 };
}
if (nextValue === "no data") {
return { value: "with-no-data", newIndex: index + 2 };
}
if (nextValue === "no") {
const following = lexemes[index + 2];
if (following && following.value.toLowerCase() === "data") {
return { value: "with-no-data", newIndex: index + 3 };
}
}
return null;
}
static popLexemeComments(lexeme, position) {
if (!lexeme) {
return [];
}
let collected = [];
// Extract positioned comments first so they are not reused downstream.
if (lexeme.positionedComments && lexeme.positionedComments.length > 0) {
const matchIndex = lexeme.positionedComments.findIndex(pc => pc.position === position);
if (matchIndex >= 0) {
collected = [...lexeme.positionedComments[matchIndex].comments];
const remaining = lexeme.positionedComments.filter((_, idx) => idx !== matchIndex);
lexeme.positionedComments = remaining.length > 0 ? remaining : undefined;
}
}
if (collected.length > 0) {
return collected;
}
if (lexeme.comments && lexeme.comments.length > 0) {
const legacy = [...lexeme.comments];
lexeme.comments = null;
return legacy;
}
return [];
}
static toOptionalComments(comments) {
return comments.length > 0 ? comments : null;
}
}
exports.CreateTableParser = CreateTableParser;
CreateTableParser.TABLE_CONSTRAINT_STARTERS = new Set([
"constraint",
"primary key",
"unique",
"unique key",
"foreign key",
"check"
]);
CreateTableParser.COLUMN_CONSTRAINT_STARTERS = new Set([
"constraint",
"not null",
"null",
"default",
"primary key",
"unique",
"unique key",
"references",
"check",
"generated always",
"generated always as identity",
"generated by default",
"generated by default as identity"
]);
CreateTableParser.MATCH_KEYWORDS = new Map([
["match full", "full"],
["match partial", "partial"],
["match simple", "simple"]
]);
CreateTableParser.REFERENTIAL_ACTIONS = new Map([
["cascade", "cascade"],
["restrict", "restrict"],
["no action", "no action"],
["set null", "set null"],
["set default", "set default"]
]);
CreateTableParser.DEFERRABILITY_KEYWORDS = new Map([
["deferrable", "deferrable"],
["not deferrable", "not deferrable"]
]);
CreateTableParser.INITIALLY_KEYWORDS = new Map([
["initially immediate", "immediate"],
["initially deferred", "deferred"]
]);
//# sourceMappingURL=CreateTableParser.js.map