mirror of
https://github.com/chartdb/chartdb.git
synced 2025-10-24 00:23:40 +00:00
273 lines
8.0 KiB
TypeScript
273 lines
8.0 KiB
TypeScript
export const parserOpts = { database: 'postgresql' };
|
|
|
|
// Define interfaces for AST nodes - Fixed no-explicit-any issues
|
|
export interface SQLAstNode {
|
|
type: string;
|
|
keyword?: string;
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
[key: string]: any; // Need to keep any here for compatibility with Parser's AST
|
|
}
|
|
|
|
// Define a minimal interface for table objects used in helper functions
|
|
export interface TableLike {
|
|
id: string;
|
|
name: string;
|
|
schema?: string;
|
|
columns: unknown[];
|
|
indexes: unknown[];
|
|
}
|
|
|
|
export interface TableReference {
|
|
table?: string;
|
|
schema?: string;
|
|
db?: string; // Support for PostgreSQL AST compatibility
|
|
}
|
|
|
|
export interface ColumnReference {
|
|
column?:
|
|
| string
|
|
| { value?: string; expr?: { value?: string; type?: string } };
|
|
expr?: { value?: string; type?: string };
|
|
value?: string;
|
|
type?: string;
|
|
}
|
|
|
|
export interface ColumnDefinition {
|
|
resource: string;
|
|
column: string | ColumnReference;
|
|
definition?: {
|
|
dataType?: string;
|
|
constraint?: string;
|
|
length?: number;
|
|
precision?: number;
|
|
scale?: number;
|
|
};
|
|
primary_key?: string;
|
|
nullable?: { type?: string };
|
|
unique?: string;
|
|
default_val?: SQLAstNode;
|
|
auto_increment?: string;
|
|
}
|
|
|
|
export interface ConstraintDefinition {
|
|
resource: string;
|
|
constraint_type: string;
|
|
constraint_name?: string;
|
|
definition?: Array<ColumnReference> | { columns?: string[] };
|
|
columns?: string[];
|
|
reference_definition?: ReferenceDefinition;
|
|
reference?: ReferenceDefinition;
|
|
}
|
|
|
|
export interface ReferenceDefinition {
|
|
table?: string | TableReference | TableReference[];
|
|
columns?: Array<ColumnReference | string> | string[];
|
|
definition?: Array<ColumnReference>;
|
|
on_update?: string;
|
|
on_delete?: string;
|
|
}
|
|
|
|
export interface CreateTableStatement extends SQLAstNode {
|
|
table: TableReference | TableReference[];
|
|
create_definitions?: Array<ColumnDefinition | ConstraintDefinition>;
|
|
comment?: string;
|
|
}
|
|
|
|
export interface CreateIndexStatement extends SQLAstNode {
|
|
table: TableReference | TableReference[] | string;
|
|
index?: string;
|
|
index_name?: string;
|
|
index_type?: string;
|
|
unique?: boolean;
|
|
columns?: Array<ColumnReference>;
|
|
index_columns?: Array<{ column?: ColumnReference } | ColumnReference>;
|
|
}
|
|
|
|
export interface AlterTableConstraintDefinition extends ConstraintDefinition {
|
|
constraint?: string;
|
|
}
|
|
|
|
export interface AlterTableExprItem {
|
|
action: string;
|
|
resource?: string;
|
|
type?: string;
|
|
keyword?: string;
|
|
constraint?: { constraint_type?: string };
|
|
// Properties for ADD COLUMN
|
|
column?:
|
|
| {
|
|
column?:
|
|
| {
|
|
expr?: {
|
|
value?: string;
|
|
};
|
|
}
|
|
| string;
|
|
}
|
|
| string
|
|
| ColumnReference;
|
|
definition?: {
|
|
dataType?: string;
|
|
length?: number;
|
|
precision?: number;
|
|
scale?: number;
|
|
suffix?: unknown[];
|
|
nullable?: { type: string };
|
|
unique?: string;
|
|
primary_key?: string;
|
|
constraint?: string;
|
|
default_val?: unknown;
|
|
auto_increment?: string;
|
|
};
|
|
nullable?: { type: string; value?: string };
|
|
unique?: string;
|
|
default_val?: unknown;
|
|
// Properties for constraints
|
|
create_definitions?:
|
|
| AlterTableConstraintDefinition
|
|
| {
|
|
constraint_type?: string;
|
|
definition?: Array<ColumnReference>;
|
|
constraint?: string;
|
|
reference_definition?: ReferenceDefinition;
|
|
resource?: string;
|
|
};
|
|
}
|
|
|
|
export interface AlterTableStatement extends SQLAstNode {
|
|
table: TableReference[] | TableReference | string;
|
|
expr: AlterTableExprItem[];
|
|
}
|
|
|
|
// Define type for column type arguments
|
|
export interface TypeArgs {
|
|
length?: number;
|
|
precision?: number;
|
|
scale?: number;
|
|
}
|
|
|
|
// Helper to extract column name from different AST formats
|
|
export function extractColumnName(
|
|
columnObj: string | ColumnReference | undefined
|
|
): string {
|
|
if (!columnObj) return '';
|
|
|
|
// Handle different formats based on actual AST structure
|
|
if (typeof columnObj === 'string') return columnObj;
|
|
|
|
if (typeof columnObj === 'object') {
|
|
// Direct column property
|
|
if (columnObj.column) {
|
|
if (typeof columnObj.column === 'string') return columnObj.column;
|
|
if (typeof columnObj.column === 'object') {
|
|
// Handle nested value property
|
|
if (columnObj.column.value) return columnObj.column.value;
|
|
// Handle expression property with value
|
|
if (columnObj.column.expr?.value)
|
|
return columnObj.column.expr.value;
|
|
// Handle double_quote_string type which is common in PostgreSQL
|
|
if (columnObj.column.expr?.type === 'double_quote_string')
|
|
return columnObj.column.expr.value || '';
|
|
// Direct access to expr
|
|
if (columnObj.column.expr?.type === 'default')
|
|
return columnObj.column.expr.value || '';
|
|
}
|
|
}
|
|
|
|
// Direct expr property
|
|
if (columnObj.expr) {
|
|
if (columnObj.expr.type === 'default')
|
|
return columnObj.expr.value || '';
|
|
if (columnObj.expr.type === 'double_quote_string')
|
|
return columnObj.expr.value || '';
|
|
if (columnObj.expr.value) return columnObj.expr.value;
|
|
}
|
|
|
|
// Direct value property
|
|
if (columnObj.value) return columnObj.value;
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
// Helper function to extract type arguments from column definition
|
|
export function getTypeArgs(
|
|
definition: ColumnDefinition['definition'] | undefined
|
|
): TypeArgs {
|
|
const typeArgs: TypeArgs = {};
|
|
|
|
if (!definition) return typeArgs;
|
|
|
|
if (definition.length !== undefined) {
|
|
typeArgs.length = definition.length;
|
|
}
|
|
|
|
if (definition.scale !== undefined && definition.precision !== undefined) {
|
|
typeArgs.precision = definition.precision;
|
|
typeArgs.scale = definition.scale;
|
|
}
|
|
|
|
return typeArgs;
|
|
}
|
|
|
|
// Helper function to find a table with consistent schema handling
|
|
export function findTableWithSchemaSupport(
|
|
tables: TableLike[],
|
|
tableName: string,
|
|
schemaName?: string
|
|
): TableLike | undefined {
|
|
// Default to public schema if none provided
|
|
const effectiveSchema = schemaName || 'public';
|
|
|
|
// First try with exact schema match
|
|
let table = tables.find(
|
|
(t) => t.name === tableName && t.schema === effectiveSchema
|
|
);
|
|
|
|
// If not found with schema, try with the legacy schema match
|
|
if (!table && schemaName) {
|
|
table = tables.find(
|
|
(t) => t.name === tableName && t.schema === schemaName
|
|
);
|
|
}
|
|
|
|
// If still not found with schema, try any match on the table name
|
|
if (!table) {
|
|
table = tables.find((t) => t.name === tableName);
|
|
}
|
|
|
|
return table;
|
|
}
|
|
|
|
// Helper function to find table ID with schema support
|
|
export function getTableIdWithSchemaSupport(
|
|
tableMap: Record<string, string>,
|
|
tableName: string,
|
|
schemaName?: string
|
|
): string | undefined {
|
|
// Default to public schema if none provided
|
|
const effectiveSchema = schemaName || 'public';
|
|
|
|
// First try with schema
|
|
const tableKey = `${effectiveSchema}.${tableName}`;
|
|
let tableId = tableMap[tableKey];
|
|
|
|
// If not found with the effective schema, try with the original schema if different
|
|
if (!tableId && schemaName && schemaName !== effectiveSchema) {
|
|
const originalSchemaKey = `${schemaName}.${tableName}`;
|
|
tableId = tableMap[originalSchemaKey];
|
|
}
|
|
|
|
// If still not found with schema, try without schema
|
|
if (!tableId) {
|
|
tableId = tableMap[tableName];
|
|
if (!tableId) {
|
|
console.warn(
|
|
`No table ID found for ${tableName} with schema ${effectiveSchema}`
|
|
);
|
|
}
|
|
}
|
|
|
|
return tableId;
|
|
}
|