rawsql-ts
Version:
High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.
98 lines • 4.49 kB
JavaScript
import { CreateTableQuery, TableColumnDefinition, TableConstraintDefinition } from "../models/CreateTableQuery";
import { AlterTableStatement, AlterTableAddConstraint } from "../models/DDLStatements";
import { QualifiedName } from "../models/ValueComponent";
export class DDLGeneralizer {
/**
* Generalizes DDL statements by moving constraints from CREATE TABLE to ALTER TABLE statements.
* This normalizes the DDL for easier comparison.
*
* @param ast List of SQL components (DDL statements)
* @returns Generalized list of SQL components
*/
static generalize(ast) {
const result = [];
for (const component of ast) {
if (component instanceof CreateTableQuery) {
const { createTable, alterTables } = this.splitCreateTable(component);
result.push(createTable);
result.push(...alterTables);
}
else {
result.push(component);
}
}
return result;
}
static splitCreateTable(query) {
const newColumns = [];
const alterTables = [];
// Construct QualifiedName for the table
const tableQualifiedName = new QualifiedName(query.namespaces || [], query.tableName.name);
// Process columns
for (const col of query.columns) {
const newConstraints = [];
for (const constraint of col.constraints) {
if (['primary-key', 'unique', 'references', 'check'].includes(constraint.kind)) {
// Move to Alter Table
const tableConstraint = this.columnToTableConstraint(col.name, constraint);
alterTables.push(new AlterTableStatement({
table: tableQualifiedName,
actions: [new AlterTableAddConstraint({ constraint: tableConstraint })]
}));
}
else {
// Keep (not-null, default, etc.)
newConstraints.push(constraint);
}
}
newColumns.push(new TableColumnDefinition({
name: col.name,
dataType: col.dataType,
constraints: newConstraints
}));
}
// Process table constraints
if (query.tableConstraints) {
for (const constraint of query.tableConstraints) {
alterTables.push(new AlterTableStatement({
table: tableQualifiedName,
actions: [new AlterTableAddConstraint({ constraint })]
}));
}
}
const newCreateTable = new CreateTableQuery({
tableName: query.tableName.name,
namespaces: query.namespaces,
columns: newColumns,
ifNotExists: query.ifNotExists,
isTemporary: query.isTemporary,
tableOptions: query.tableOptions,
asSelectQuery: query.asSelectQuery,
withDataOption: query.withDataOption,
// tableConstraints is empty
tableConstraints: []
});
return { createTable: newCreateTable, alterTables };
}
static columnToTableConstraint(columnName, constraint) {
var _a, _b;
const baseParams = {
constraintName: constraint.constraintName,
deferrable: (_a = constraint.reference) === null || _a === void 0 ? void 0 : _a.deferrable,
initially: (_b = constraint.reference) === null || _b === void 0 ? void 0 : _b.initially
};
switch (constraint.kind) {
case 'primary-key':
return new TableConstraintDefinition(Object.assign({ kind: 'primary-key', columns: [columnName] }, baseParams));
case 'unique':
return new TableConstraintDefinition(Object.assign({ kind: 'unique', columns: [columnName] }, baseParams));
case 'references':
return new TableConstraintDefinition(Object.assign({ kind: 'foreign-key', columns: [columnName], reference: constraint.reference }, baseParams));
case 'check':
return new TableConstraintDefinition(Object.assign({ kind: 'check', checkExpression: constraint.checkExpression }, baseParams));
default:
throw new Error(`Unsupported constraint kind for generalization: ${constraint.kind}`);
}
}
}
//# sourceMappingURL=DDLGeneralizer.js.map