@quereus/quereus 0.4.6 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/README.md +2 -2
  2. package/dist/src/config/loader.d.ts +41 -0
  3. package/dist/src/config/loader.d.ts.map +1 -0
  4. package/dist/src/config/loader.js +102 -0
  5. package/dist/src/config/loader.js.map +1 -0
  6. package/dist/src/core/database.d.ts +1 -1
  7. package/dist/src/core/database.js +2 -2
  8. package/dist/src/core/database.js.map +1 -1
  9. package/dist/src/index.d.ts +2 -0
  10. package/dist/src/index.d.ts.map +1 -1
  11. package/dist/src/index.js +2 -0
  12. package/dist/src/index.js.map +1 -1
  13. package/dist/src/planner/building/create-view.d.ts.map +1 -1
  14. package/dist/src/planner/building/create-view.js +3 -25
  15. package/dist/src/planner/building/create-view.js.map +1 -1
  16. package/dist/src/planner/building/select.d.ts.map +1 -1
  17. package/dist/src/planner/building/select.js +20 -1
  18. package/dist/src/planner/building/select.js.map +1 -1
  19. package/dist/src/planner/nodes/dml-executor-node.d.ts +1 -1
  20. package/dist/src/planner/nodes/dml-executor-node.js +1 -1
  21. package/dist/src/runtime/emit/dml-executor.js +3 -3
  22. package/dist/src/runtime/emit/dml-executor.js.map +1 -1
  23. package/dist/src/runtime/emit/remote-query.d.ts +1 -1
  24. package/dist/src/runtime/emit/remote-query.js +5 -5
  25. package/dist/src/runtime/emit/remote-query.js.map +1 -1
  26. package/dist/src/runtime/emit/scan.js +10 -10
  27. package/dist/src/runtime/emit/scan.js.map +1 -1
  28. package/dist/src/runtime/emit/update.js +1 -1
  29. package/dist/src/runtime/emit/update.js.map +1 -1
  30. package/dist/src/runtime/utils.js +6 -6
  31. package/dist/src/runtime/utils.js.map +1 -1
  32. package/dist/src/schema/catalog.d.ts.map +1 -1
  33. package/dist/src/schema/catalog.js +18 -3
  34. package/dist/src/schema/catalog.js.map +1 -1
  35. package/dist/src/schema/manager.d.ts +4 -4
  36. package/dist/src/schema/manager.js +20 -20
  37. package/dist/src/schema/manager.js.map +1 -1
  38. package/dist/src/schema/schema-differ.js +3 -3
  39. package/dist/src/schema/schema-differ.js.map +1 -1
  40. package/dist/src/util/ast-stringify.d.ts +1 -0
  41. package/dist/src/util/ast-stringify.d.ts.map +1 -1
  42. package/dist/src/util/ast-stringify.js +1 -1
  43. package/dist/src/util/ast-stringify.js.map +1 -1
  44. package/dist/src/vtab/best-access-plan.d.ts +0 -6
  45. package/dist/src/vtab/best-access-plan.d.ts.map +1 -1
  46. package/dist/src/vtab/best-access-plan.js +0 -27
  47. package/dist/src/vtab/best-access-plan.js.map +1 -1
  48. package/dist/src/vtab/memory/module.d.ts +4 -10
  49. package/dist/src/vtab/memory/module.d.ts.map +1 -1
  50. package/dist/src/vtab/memory/module.js +4 -16
  51. package/dist/src/vtab/memory/module.js.map +1 -1
  52. package/dist/src/vtab/memory/table.d.ts +14 -14
  53. package/dist/src/vtab/memory/table.d.ts.map +1 -1
  54. package/dist/src/vtab/memory/table.js +21 -21
  55. package/dist/src/vtab/memory/table.js.map +1 -1
  56. package/dist/src/vtab/module.d.ts +6 -18
  57. package/dist/src/vtab/module.d.ts.map +1 -1
  58. package/dist/src/vtab/table.d.ts +17 -17
  59. package/dist/src/vtab/table.d.ts.map +1 -1
  60. package/package.json +1 -1
  61. package/src/config/loader.ts +140 -0
  62. package/src/core/database.ts +2 -2
  63. package/src/index.ts +9 -0
  64. package/src/planner/building/create-view.ts +3 -30
  65. package/src/planner/building/select.ts +29 -1
  66. package/src/planner/nodes/dml-executor-node.ts +1 -1
  67. package/src/runtime/emit/dml-executor.ts +3 -3
  68. package/src/runtime/emit/remote-query.ts +5 -5
  69. package/src/runtime/emit/scan.ts +10 -10
  70. package/src/runtime/emit/update.ts +1 -1
  71. package/src/runtime/utils.ts +6 -6
  72. package/src/schema/catalog.ts +17 -3
  73. package/src/schema/manager.ts +20 -20
  74. package/src/schema/schema-differ.ts +3 -3
  75. package/src/util/ast-stringify.ts +1 -1
  76. package/src/vtab/best-access-plan.ts +0 -30
  77. package/src/vtab/memory/module.ts +4 -17
  78. package/src/vtab/memory/table.ts +21 -21
  79. package/src/vtab/module.ts +7 -17
  80. package/src/vtab/table.ts +17 -17
@@ -22,7 +22,7 @@ export function emitDmlExecutor(plan: DmlExecutorNode, ctx: EmissionContext): In
22
22
  try {
23
23
  for await (const flatRow of rows) {
24
24
  const newRow = extractNewRowFromFlat(flatRow, tableSchema.columns.length);
25
- await vtab.xUpdate!('insert', newRow, undefined, plan.onConflict ?? ConflictResolution.ABORT);
25
+ await vtab.update!('insert', newRow, undefined, plan.onConflict ?? ConflictResolution.ABORT);
26
26
  // Track change (INSERT): record NEW primary key
27
27
  const pkValues = tableSchema.primaryKeyDefinition.map(def => newRow[def.index]);
28
28
  ctx.db._recordInsert(`${tableSchema.schemaName}.${tableSchema.name}`, pkValues);
@@ -48,7 +48,7 @@ export function emitDmlExecutor(plan: DmlExecutorNode, ctx: EmissionContext): In
48
48
  }
49
49
  return oldRow[pkColIdx];
50
50
  });
51
- await vtab.xUpdate!('update', newRow, keyValues, ConflictResolution.ABORT);
51
+ await vtab.update!('update', newRow, keyValues, ConflictResolution.ABORT);
52
52
  // Track change (UPDATE): record OLD and NEW primary keys
53
53
  const newKeyValues: SqlValue[] = tableSchema.primaryKeyDefinition.map(pkColDef => newRow[pkColDef.index]);
54
54
  ctx.db._recordUpdate(`${tableSchema.schemaName}.${tableSchema.name}`, keyValues, newKeyValues);
@@ -72,7 +72,7 @@ export function emitDmlExecutor(plan: DmlExecutorNode, ctx: EmissionContext): In
72
72
  }
73
73
  return oldRow[pkColIdx];
74
74
  });
75
- await vtab.xUpdate!('delete', undefined, keyValues, ConflictResolution.ABORT);
75
+ await vtab.update!('delete', undefined, keyValues, ConflictResolution.ABORT);
76
76
  // Track change (DELETE): record OLD primary key
77
77
  ctx.db._recordDelete(`${tableSchema.schemaName}.${tableSchema.name}`, keyValues);
78
78
  yield flatRow;
@@ -8,7 +8,7 @@ import type { AnyVirtualTableModule } from '../../vtab/module.js';
8
8
 
9
9
  /**
10
10
  * Emitter for RemoteQueryNode.
11
- * Calls the virtual table's xExecutePlan() method to execute the pushed-down pipeline.
11
+ * Calls the virtual table's executePlan() method to execute the pushed-down pipeline.
12
12
  */
13
13
  export function emitRemoteQuery(plan: RemoteQueryNode, _ctx: EmissionContext): Instruction {
14
14
  async function* run(rctx: RuntimeContext): AsyncIterable<Row> {
@@ -19,7 +19,7 @@ export function emitRemoteQuery(plan: RemoteQueryNode, _ctx: EmissionContext): I
19
19
  const vtabModule = (moduleCtx as { vtabModule?: AnyVirtualTableModule } | undefined)?.vtabModule ?? tableRef.vtabModule;
20
20
 
21
21
  // Connect to the table to get the instance
22
- const table = vtabModule.xConnect(
22
+ const table = vtabModule.connect(
23
23
  rctx.db,
24
24
  undefined, // pAux
25
25
  tableSchema.vtabModuleName,
@@ -28,15 +28,15 @@ export function emitRemoteQuery(plan: RemoteQueryNode, _ctx: EmissionContext): I
28
28
  {} // empty config for now
29
29
  );
30
30
 
31
- if (!table.xExecutePlan) {
31
+ if (!table.executePlan) {
32
32
  throw new QuereusError(
33
- `Virtual table module for '${tableSchema.name}' does not implement xExecutePlan() ` +
33
+ `Virtual table module for '${tableSchema.name}' does not implement executePlan() ` +
34
34
  `despite indicating support via supports() method.`,
35
35
  StatusCode.INTERNAL
36
36
  );
37
37
  }
38
38
 
39
- yield* table.xExecutePlan(rctx.db, plan.source, plan.moduleCtx);
39
+ yield* table.executePlan(rctx.db, plan.source, plan.moduleCtx);
40
40
  }
41
41
 
42
42
  return {
@@ -38,14 +38,14 @@ export function emitSeqScan(plan: SeqScanNode | IndexScanNode | IndexSeekNode, c
38
38
  }
39
39
 
40
40
  const module = capturedModuleInfo.module;
41
- if (typeof module.xConnect !== 'function') {
42
- throw new QuereusError(`Virtual table module '${schema.vtabModuleName}' does not implement xConnect`, StatusCode.MISUSE);
41
+ if (typeof module.connect !== 'function') {
42
+ throw new QuereusError(`Virtual table module '${schema.vtabModuleName}' does not implement connect`, StatusCode.MISUSE);
43
43
  }
44
44
 
45
45
  let vtabInstance: VirtualTable;
46
46
  try {
47
47
  const options: BaseModuleConfig = (schema.vtabArgs ?? {}) as BaseModuleConfig;
48
- vtabInstance = module.xConnect(
48
+ vtabInstance = module.connect(
49
49
  runtimeCtx.db,
50
50
  capturedModuleInfo.auxData,
51
51
  schema.vtabModuleName,
@@ -55,13 +55,13 @@ export function emitSeqScan(plan: SeqScanNode | IndexScanNode | IndexSeekNode, c
55
55
  );
56
56
  } catch (e: any) {
57
57
  const message = e instanceof Error ? e.message : String(e);
58
- throw new QuereusError(`Module '${schema.vtabModuleName}' xConnect failed for table '${schema.name}': ${message}`, e instanceof QuereusError ? e.code : StatusCode.ERROR, e instanceof Error ? e : undefined);
58
+ throw new QuereusError(`Module '${schema.vtabModuleName}' connect failed for table '${schema.name}': ${message}`, e instanceof QuereusError ? e.code : StatusCode.ERROR, e instanceof Error ? e : undefined);
59
59
  }
60
60
 
61
- if (typeof vtabInstance.xQuery !== 'function') {
62
- // Fallback or error if xQuery is not available. For now, throwing an error.
63
- // Later, we could implement the xOpen/xFilter/xNext loop here as a fallback.
64
- throw new QuereusError(`Virtual table '${schema.name}' does not support xQuery.`, StatusCode.UNSUPPORTED);
61
+ if (typeof vtabInstance.query !== 'function') {
62
+ // Fallback or error if query is not available. For now, throwing an error.
63
+ // Later, we could implement the open/filter/next loop here as a fallback.
64
+ throw new QuereusError(`Virtual table '${schema.name}' does not support query.`, StatusCode.UNSUPPORTED);
65
65
  }
66
66
 
67
67
  const rowSlot = createRowSlot(runtimeCtx, rowDescriptor);
@@ -74,14 +74,14 @@ export function emitSeqScan(plan: SeqScanNode | IndexScanNode | IndexSeekNode, c
74
74
  return plan.filterInfo;
75
75
  })();
76
76
 
77
- const asyncRowIterable = vtabInstance.xQuery(effectiveFilterInfo);
77
+ const asyncRowIterable = vtabInstance.query(effectiveFilterInfo);
78
78
  for await (const row of asyncRowIterable) {
79
79
  rowSlot.set(row);
80
80
  yield row;
81
81
  }
82
82
  } catch (e: any) {
83
83
  const message = e instanceof Error ? e.message : String(e);
84
- throw new QuereusError(`Error during xQuery on table '${schema.name}': ${message}`, e instanceof QuereusError ? e.code : StatusCode.ERROR, e instanceof Error ? e : undefined);
84
+ throw new QuereusError(`Error during query on table '${schema.name}': ${message}`, e instanceof QuereusError ? e.code : StatusCode.ERROR, e instanceof Error ? e : undefined);
85
85
  } finally {
86
86
  rowSlot.close();
87
87
  // Properly disconnect the VirtualTable instance
@@ -51,7 +51,7 @@ export function emitUpdate(plan: UpdateNode, ctx: EmissionContext): Instruction
51
51
 
52
52
  // Yield the flat row for constraint checking
53
53
  // NOTE: UpdateNode only transforms rows - it does NOT execute the actual update
54
- // The UpdateExecutorNode is responsible for calling vtab.xUpdate
54
+ // The UpdateExecutorNode is responsible for calling vtab.update
55
55
  yield flatRow;
56
56
  });
57
57
  }
@@ -86,11 +86,11 @@ export async function getVTable(ctx: RuntimeContext, tableSchema: TableSchema):
86
86
  throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' not found for table '${tableSchema.name}'`, StatusCode.ERROR);
87
87
  }
88
88
  const module = moduleInfo.module;
89
- if (typeof module.xConnect !== 'function') {
90
- throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' does not implement xConnect`, StatusCode.MISUSE);
89
+ if (typeof module.connect !== 'function') {
90
+ throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' does not implement connect`, StatusCode.MISUSE);
91
91
  }
92
92
  const vtabArgs = tableSchema.vtabArgs || {};
93
- const vtabInstance = module.xConnect(ctx.db, moduleInfo.auxData, tableSchema.vtabModuleName, tableSchema.schemaName, tableSchema.name, vtabArgs);
93
+ const vtabInstance = module.connect(ctx.db, moduleInfo.auxData, tableSchema.vtabModuleName, tableSchema.schemaName, tableSchema.name, vtabArgs);
94
94
 
95
95
  // If we have an active connection for this table, inject it into the VirtualTable
96
96
  const tableName = tableSchema.name;
@@ -112,9 +112,9 @@ export async function getVTable(ctx: RuntimeContext, tableSchema: TableSchema):
112
112
  */
113
113
  export async function disconnectVTable(ctx: RuntimeContext, vtab: VirtualTable): Promise<void> {
114
114
  // Disconnect the VirtualTable instance
115
- if (typeof vtab.xDisconnect === 'function') {
116
- await vtab.xDisconnect().catch((e: any) => {
117
- errorLog(`Error during xDisconnect for table '${vtab.tableName}': ${e}`);
115
+ if (typeof vtab.disconnect === 'function') {
116
+ await vtab.disconnect().catch((e: any) => {
117
+ errorLog(`Error during disconnect for table '${vtab.tableName}': ${e}`);
118
118
  });
119
119
  }
120
120
  }
@@ -2,7 +2,7 @@ import type { Database } from '../core/database.js';
2
2
  import type { TableSchema } from './table.js';
3
3
  import type { ViewSchema } from './view.js';
4
4
  import type { IntegrityAssertionSchema } from './assertion.js';
5
- import { createTableToString } from '../util/ast-stringify.js';
5
+ import { createTableToString, createViewToString } from '../util/ast-stringify.js';
6
6
  import type * as AST from '../parser/ast.js';
7
7
 
8
8
  /**
@@ -196,9 +196,23 @@ export function generateDeclaredDDL(declaredSchema: AST.DeclareSchemaStmt, targe
196
196
  case 'declaredIndex':
197
197
  // TODO: Implement index DDL generation
198
198
  break;
199
- case 'declaredView':
200
- // TODO: Implement view DDL generation
199
+ case 'declaredView': {
200
+ // Qualify view name with schema if specified
201
+ const viewStmt = item.viewStmt;
202
+ if (targetSchema && targetSchema !== 'main' && !viewStmt.view.schema) {
203
+ const qualifiedStmt: AST.CreateViewStmt = {
204
+ ...viewStmt,
205
+ view: {
206
+ ...viewStmt.view,
207
+ schema: targetSchema
208
+ }
209
+ };
210
+ ddlStatements.push(createViewToString(qualifiedStmt));
211
+ } else {
212
+ ddlStatements.push(createViewToString(viewStmt));
213
+ }
201
214
  break;
215
+ }
202
216
  }
203
217
  }
204
218
 
@@ -368,23 +368,23 @@ export class SchemaManager {
368
368
 
369
369
  let destroyPromise: Promise<void> | null = null;
370
370
 
371
- // Call xDestroy on the module, providing table details
371
+ // Call destroy on the module, providing table details
372
372
  if (tableSchema.vtabModuleName) { // tableSchema is guaranteed to be defined here
373
373
  const moduleRegistration = this.getModule(tableSchema.vtabModuleName);
374
- if (moduleRegistration && moduleRegistration.module && moduleRegistration.module.xDestroy) {
375
- log(`Calling xDestroy for VTab %s.%s via module %s`, schemaName, tableName, tableSchema.vtabModuleName);
376
- destroyPromise = moduleRegistration.module.xDestroy(
374
+ if (moduleRegistration && moduleRegistration.module && moduleRegistration.module.destroy) {
375
+ log(`Calling destroy for VTab %s.%s via module %s`, schemaName, tableName, tableSchema.vtabModuleName);
376
+ destroyPromise = moduleRegistration.module.destroy(
377
377
  this.db,
378
378
  moduleRegistration.auxData,
379
379
  tableSchema.vtabModuleName,
380
380
  schemaName,
381
381
  tableName
382
382
  ).catch(err => {
383
- errorLog(`Error during VTab module xDestroy for %s.%s: %O`, schemaName, tableName, err);
384
- // Potentially re-throw or handle as a critical error if xDestroy failure is problematic
383
+ errorLog(`Error during VTab module destroy for %s.%s: %O`, schemaName, tableName, err);
384
+ // Potentially re-throw or handle as a critical error if destroy failure is problematic
385
385
  });
386
386
  } else {
387
- warnLog(`VTab module %s (for table %s.%s) or its xDestroy method not found during dropTable.`, tableSchema.vtabModuleName, schemaName, tableName);
387
+ warnLog(`VTab module %s (for table %s.%s) or its destroy method not found during dropTable.`, tableSchema.vtabModuleName, schemaName, tableName);
388
388
  }
389
389
  }
390
390
 
@@ -408,7 +408,7 @@ export class SchemaManager {
408
408
 
409
409
  // Process destruction asynchronously
410
410
  if (destroyPromise) {
411
- void destroyPromise.then(() => log(`xDestroy completed for VTab %s.%s`, schemaName, tableName));
411
+ void destroyPromise.then(() => log(`destroy completed for VTab %s.%s`, schemaName, tableName));
412
412
  }
413
413
 
414
414
  return removed; // True if removed from schema, false if not found and ifExists was true.
@@ -469,11 +469,11 @@ export class SchemaManager {
469
469
 
470
470
  /**
471
471
  * Creates a new index on an existing table based on an AST.CreateIndexStmt.
472
- * This method validates the index definition and calls the virtual table's xCreateIndex method.
472
+ * This method validates the index definition and calls the virtual table's createIndex method.
473
473
  *
474
474
  * @param stmt The AST node for the CREATE INDEX statement.
475
475
  * @returns A Promise that resolves when the index is created.
476
- * @throws QuereusError on errors (e.g., table not found, column not found, xCreateIndex fails).
476
+ * @throws QuereusError on errors (e.g., table not found, column not found, createIndex fails).
477
477
  */
478
478
  async createIndex(stmt: AST.CreateIndexStmt): Promise<void> {
479
479
  const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
@@ -486,8 +486,8 @@ export class SchemaManager {
486
486
  throw new QuereusError(`no such table: ${tableName}`, StatusCode.ERROR, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
487
487
  }
488
488
 
489
- // Check if the virtual table module supports xCreateIndex
490
- if (!tableSchema.vtabModule.xCreateIndex) {
489
+ // Check if the virtual table module supports createIndex
490
+ if (!tableSchema.vtabModule.createIndex) {
491
491
  throw new QuereusError(`Virtual table module '${tableSchema.vtabModuleName}' for table '${tableName}' does not support CREATE INDEX.`, StatusCode.ERROR, undefined, stmt.table.loc?.start.line, stmt.table.loc?.start.column);
492
492
  }
493
493
 
@@ -531,8 +531,8 @@ export class SchemaManager {
531
531
  };
532
532
 
533
533
  try {
534
- // Call xCreateIndex on the virtual table module
535
- await tableSchema.vtabModule.xCreateIndex(
534
+ // Call createIndex on the virtual table module
535
+ await tableSchema.vtabModule.createIndex(
536
536
  this.db,
537
537
  targetSchemaName,
538
538
  tableName,
@@ -563,18 +563,18 @@ export class SchemaManager {
563
563
  } catch (e: unknown) {
564
564
  const message = e instanceof Error ? e.message : String(e);
565
565
  const code = e instanceof QuereusError ? e.code : StatusCode.ERROR;
566
- throw new QuereusError(`xCreateIndex failed for index '${indexName}' on table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
566
+ throw new QuereusError(`createIndex failed for index '${indexName}' on table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
567
567
  }
568
568
  }
569
569
 
570
570
  /**
571
571
  * Defines a new table in the schema based on an AST.CreateTableStmt.
572
- * This method encapsulates the logic for interacting with VTab modules (xCreate)
572
+ * This method encapsulates the logic for interacting with VTab modules (create)
573
573
  * and registering the new table schema.
574
574
  *
575
575
  * @param stmt The AST node for the CREATE TABLE statement.
576
576
  * @returns A Promise that resolves to the created TableSchema.
577
- * @throws QuereusError on errors (e.g., module not found, xCreate fails, table exists).
577
+ * @throws QuereusError on errors (e.g., module not found, create fails, table exists).
578
578
  */
579
579
  async createTable(stmt: AST.CreateTableStmt): Promise<TableSchema> {
580
580
  const targetSchemaName = stmt.table.schema || this.getCurrentSchemaName();
@@ -670,14 +670,14 @@ export class SchemaManager {
670
670
 
671
671
  let tableInstance: VirtualTable;
672
672
  try {
673
- tableInstance = moduleInfo.module.xCreate(
673
+ tableInstance = moduleInfo.module.create(
674
674
  this.db,
675
675
  baseTableSchema
676
676
  );
677
677
  } catch (e: unknown) {
678
678
  const message = e instanceof Error ? e.message : String(e);
679
679
  const code = e instanceof QuereusError ? e.code : StatusCode.ERROR;
680
- throw new QuereusError(`Module '${moduleName}' xCreate failed for table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
680
+ throw new QuereusError(`Module '${moduleName}' create failed for table '${tableName}': ${message}`, code, e instanceof Error ? e : undefined, stmt.loc?.start.line, stmt.loc?.start.column);
681
681
  }
682
682
 
683
683
  const schema = this.getSchema(targetSchemaName);
@@ -687,7 +687,7 @@ export class SchemaManager {
687
687
 
688
688
  const finalRegisteredSchema = tableInstance.tableSchema;
689
689
  if (!finalRegisteredSchema) {
690
- throw new QuereusError(`Module '${moduleName}' xCreate did not provide a tableSchema for '${tableName}'.`, StatusCode.INTERNAL);
690
+ throw new QuereusError(`Module '${moduleName}' create did not provide a tableSchema for '${tableName}'.`, StatusCode.INTERNAL);
691
691
  }
692
692
 
693
693
  // Create a properly typed schema object instead of mutating properties
@@ -1,6 +1,6 @@
1
1
  import type { SchemaCatalog } from './catalog.js';
2
2
  import type * as AST from '../parser/ast.js';
3
- import { createTableToString } from '../util/ast-stringify.js';
3
+ import { createTableToString, createViewToString } from '../util/ast-stringify.js';
4
4
 
5
5
  /**
6
6
  * Represents the difference between a declared schema and actual database state
@@ -104,8 +104,8 @@ export function computeSchemaDiff(
104
104
  // Find views to create/drop
105
105
  for (const [name, declaredView] of declaredViews) {
106
106
  if (!actualViews.has(name)) {
107
- // TODO: Generate view DDL
108
- diff.viewsToCreate.push(`CREATE VIEW "${declaredView.viewStmt.view.name}" AS SELECT 1`);
107
+ // Generate proper view DDL using AST stringifier
108
+ diff.viewsToCreate.push(createViewToString(declaredView.viewStmt));
109
109
  }
110
110
  }
111
111
 
@@ -629,7 +629,7 @@ function createIndexToString(stmt: AST.CreateIndexStmt): string {
629
629
  return parts.join(' ');
630
630
  }
631
631
 
632
- function createViewToString(stmt: AST.CreateViewStmt): string {
632
+ export function createViewToString(stmt: AST.CreateViewStmt): string {
633
633
  const parts: string[] = ['create'];
634
634
  if (stmt.isTemporary) parts.push('temp');
635
635
  parts.push('view');
@@ -238,34 +238,4 @@ export function validateAccessPlan(
238
238
  }
239
239
  }
240
240
 
241
- /**
242
- * Helper to convert old IndexConstraint to new PredicateConstraint
243
- * @deprecated Use direct PredicateConstraint construction instead
244
- */
245
- export function convertIndexConstraint(
246
- constraint: any, // Old IndexConstraint type
247
- value?: SqlValue
248
- ): PredicateConstraint {
249
- // Map old constraint operators to new ones
250
- const opMap: Record<string, ConstraintOp> = {
251
- 'EQ': '=',
252
- 'GT': '>',
253
- 'GE': '>=',
254
- 'LT': '<',
255
- 'LE': '<=',
256
- 'MATCH': 'MATCH',
257
- 'LIKE': 'LIKE',
258
- 'GLOB': 'GLOB',
259
- 'ISNULL': 'IS NULL',
260
- 'ISNOTNULL': 'IS NOT NULL'
261
- };
262
241
 
263
- const op = opMap[constraint.op] || '=';
264
-
265
- return {
266
- columnIndex: constraint.iColumn,
267
- op,
268
- value,
269
- usable: constraint.usable
270
- };
271
- }
@@ -27,7 +27,7 @@ export class MemoryTableModule implements VirtualTableModule<MemoryTable, Memory
27
27
  /**
28
28
  * Creates a new memory table definition
29
29
  */
30
- xCreate(db: Database, tableSchema: TableSchema): MemoryTable {
30
+ create(db: Database, tableSchema: TableSchema): MemoryTable {
31
31
  // Ensure table doesn't already exist
32
32
  const tableKey = `${tableSchema.schemaName}.${tableSchema.name}`.toLowerCase();
33
33
  if (this.tables.has(tableKey)) {
@@ -58,7 +58,7 @@ export class MemoryTableModule implements VirtualTableModule<MemoryTable, Memory
58
58
  /**
59
59
  * Connects to an existing memory table definition
60
60
  */
61
- xConnect(db: Database, pAux: unknown, moduleName: string, schemaName: string, tableName: string, _options: MemoryTableConfig): MemoryTable {
61
+ connect(db: Database, pAux: unknown, moduleName: string, schemaName: string, tableName: string, _options: MemoryTableConfig): MemoryTable {
62
62
  const tableKey = `${schemaName}.${tableName}`.toLowerCase();
63
63
  const existingManager = this.tables.get(tableKey);
64
64
 
@@ -305,20 +305,7 @@ export class MemoryTableModule implements VirtualTableModule<MemoryTable, Memory
305
305
  return true;
306
306
  }
307
307
 
308
- /**
309
- * Determines the best query plan for executing a query against a memory table
310
- * @deprecated Use getBestAccessPlan instead for better type safety and extensibility
311
- */
312
- xBestIndex(db: Database, tableInfo: TableSchema, indexInfo: IndexInfo): number {
313
- const planningContext = this.createPlanningContext(tableInfo, indexInfo);
314
- const availableIndexes = this.gatherAvailableIndexes(tableInfo);
315
- const bestPlan = this.findBestPlan(planningContext, availableIndexes, indexInfo);
316
- this.populateIndexInfoOutput(indexInfo, bestPlan, availableIndexes);
317
308
 
318
- logger.debugLog(`[xBestIndex] Selected plan for ${tableInfo.name}: ${bestPlan.planType} on index ${bestPlan.indexId} (cost: ${bestPlan.cost})`);
319
-
320
- return StatusCode.OK;
321
- }
322
309
 
323
310
  private createPlanningContext(_tableInfo: TableSchema, _indexInfo: IndexInfo) {
324
311
  return {
@@ -644,7 +631,7 @@ export class MemoryTableModule implements VirtualTableModule<MemoryTable, Memory
644
631
  /**
645
632
  * Destroys a memory table and frees associated resources
646
633
  */
647
- async xDestroy(db: Database, pAux: unknown, moduleName: string, schemaName: string, tableName: string): Promise<void> {
634
+ async destroy(db: Database, pAux: unknown, moduleName: string, schemaName: string, tableName: string): Promise<void> {
648
635
  const tableKey = `${schemaName}.${tableName}`.toLowerCase();
649
636
  const manager = this.tables.get(tableKey);
650
637
 
@@ -659,7 +646,7 @@ export class MemoryTableModule implements VirtualTableModule<MemoryTable, Memory
659
646
  /**
660
647
  * Creates an index on a memory table
661
648
  */
662
- async xCreateIndex(db: Database, schemaName: string, tableName: string, indexSchema: IndexSchema): Promise<void> {
649
+ async createIndex(db: Database, schemaName: string, tableName: string, indexSchema: IndexSchema): Promise<void> {
663
650
  const tableKey = `${schemaName}.${tableName}`.toLowerCase();
664
651
  const manager = this.tables.get(tableKey);
665
652
 
@@ -30,7 +30,7 @@ export class MemoryTable extends VirtualTable {
30
30
  private connection: MemoryTableConnection | null = null;
31
31
 
32
32
  /**
33
- * @internal - Use MemoryTableModule.xConnect or xCreate
33
+ * @internal - Use MemoryTableModule.connect or create
34
34
  * Creates a connection-specific instance linked to a manager.
35
35
  */
36
36
  constructor(
@@ -101,29 +101,29 @@ export class MemoryTable extends VirtualTable {
101
101
  return new MemoryVirtualTableConnection(this.tableName, this.connection);
102
102
  }
103
103
 
104
- // New xQuery method for direct async iteration
105
- async* xQuery(filterInfo: FilterInfo): AsyncIterable<Row> {
104
+ // Direct async iteration for query execution
105
+ async* query(filterInfo: FilterInfo): AsyncIterable<Row> {
106
106
  const conn = await this.ensureConnection();
107
- logger.debugLog(`xQuery using connection ${conn.connectionId} (pending: ${conn.pendingTransactionLayer?.getLayerId()}, read: ${conn.readLayer.getLayerId()})`);
107
+ logger.debugLog(`query using connection ${conn.connectionId} (pending: ${conn.pendingTransactionLayer?.getLayerId()}, read: ${conn.readLayer.getLayerId()})`);
108
108
  const currentSchema = this.manager.tableSchema;
109
109
  if (!currentSchema) {
110
- logger.error('xQuery', this.tableName, 'Table schema is undefined');
110
+ logger.error('query', this.tableName, 'Table schema is undefined');
111
111
  return;
112
112
  }
113
113
  const plan = buildScanPlanFromFilterInfo(filterInfo, currentSchema);
114
- logger.debugLog(`xQuery invoked for ${this.tableName} with plan: ${safeJsonStringify(plan)}`);
114
+ logger.debugLog(`query invoked for ${this.tableName} with plan: ${safeJsonStringify(plan)}`);
115
115
 
116
116
  const startLayer = conn.pendingTransactionLayer ?? conn.readLayer;
117
- logger.debugLog(`xQuery reading from layer ${startLayer.getLayerId()}`);
117
+ logger.debugLog(`query reading from layer ${startLayer.getLayerId()}`);
118
118
 
119
119
  // Delegate scanning to the manager, which handles layer recursion
120
120
  yield* this.manager.scanLayer(startLayer, plan);
121
121
  }
122
122
 
123
- // Note: xBestIndex is handled by the MemoryTableModule, not the table instance.
123
+ // Note: getBestAccessPlan is handled by the MemoryTableModule, not the table instance.
124
124
 
125
125
  /** Performs mutation through the connection's transaction layer */
126
- async xUpdate(
126
+ async update(
127
127
  operation: 'insert' | 'update' | 'delete',
128
128
  values: Row | undefined,
129
129
  oldKeyValues?: Row,
@@ -136,12 +136,12 @@ export class MemoryTable extends VirtualTable {
136
136
  }
137
137
 
138
138
  /** Begins a transaction for this connection */
139
- async xBegin(): Promise<void> {
139
+ async begin(): Promise<void> {
140
140
  (await this.ensureConnection()).begin();
141
141
  }
142
142
 
143
143
  /** Commits this connection's transaction */
144
- async xCommit(): Promise<void> {
144
+ async commit(): Promise<void> {
145
145
  // Only commit if a connection has actually been established
146
146
  if (this.connection) {
147
147
  await this.connection.commit();
@@ -149,7 +149,7 @@ export class MemoryTable extends VirtualTable {
149
149
  }
150
150
 
151
151
  /** Rolls back this connection's transaction */
152
- async xRollback(): Promise<void> {
152
+ async rollback(): Promise<void> {
153
153
  // Only rollback if a connection has actually been established
154
154
  if (this.connection) {
155
155
  this.connection.rollback();
@@ -157,14 +157,14 @@ export class MemoryTable extends VirtualTable {
157
157
  }
158
158
 
159
159
  /** Sync operation (currently no-op for memory table layers) */
160
- async xSync(): Promise<void> {
160
+ async sync(): Promise<void> {
161
161
  // This might trigger background collapse in the manager in the future
162
162
  // await this.manager.tryCollapseLayers(); // Optional: trigger collapse on sync?
163
163
  return Promise.resolve();
164
164
  }
165
165
 
166
166
  /** Renames the underlying table via the manager */
167
- async xRename(newName: string): Promise<void> {
167
+ async rename(newName: string): Promise<void> {
168
168
  logger.operation('Rename', this.tableName, { newName });
169
169
  await this.manager.renameTable(newName);
170
170
  // Update this instance's schema reference after rename
@@ -172,17 +172,17 @@ export class MemoryTable extends VirtualTable {
172
172
  }
173
173
 
174
174
  // --- Savepoint operations ---
175
- async xSavepoint(savepointIndex: number): Promise<void> {
175
+ async savepoint(savepointIndex: number): Promise<void> {
176
176
  const conn = await this.ensureConnection();
177
177
  conn.createSavepoint(savepointIndex);
178
178
  }
179
179
 
180
- async xRelease(savepointIndex: number): Promise<void> {
180
+ async release(savepointIndex: number): Promise<void> {
181
181
  if (!this.connection) return; // No connection, no savepoints to release
182
182
  this.connection.releaseSavepoint(savepointIndex);
183
183
  }
184
184
 
185
- async xRollbackTo(savepointIndex: number): Promise<void> {
185
+ async rollbackTo(savepointIndex: number): Promise<void> {
186
186
  if (!this.connection) return; // No connection, no savepoints to rollback to
187
187
  this.connection.rollbackToSavepoint(savepointIndex);
188
188
  }
@@ -190,7 +190,7 @@ export class MemoryTable extends VirtualTable {
190
190
 
191
191
 
192
192
  /** Handles schema changes via the manager */
193
- async xAlterSchema(changeInfo: SchemaChangeInfo): Promise<void> {
193
+ async alterSchema(changeInfo: SchemaChangeInfo): Promise<void> {
194
194
  const originalManagerSchema = this.manager.tableSchema; // For potential error recovery
195
195
  try {
196
196
  switch (changeInfo.type) {
@@ -226,7 +226,7 @@ export class MemoryTable extends VirtualTable {
226
226
  }
227
227
 
228
228
  /** Disconnects this connection instance from the manager */
229
- async xDisconnect(): Promise<void> {
229
+ async disconnect(): Promise<void> {
230
230
  if (this.connection) {
231
231
  // Manager handles cleanup and potential layer collapse trigger
232
232
  await this.manager.disconnect(this.connection.connectionId);
@@ -235,13 +235,13 @@ export class MemoryTable extends VirtualTable {
235
235
  }
236
236
 
237
237
  // --- Index DDL methods delegate to the manager ---
238
- async xCreateIndex(indexSchema: IndexSchema): Promise<void> {
238
+ async createIndex(indexSchema: IndexSchema): Promise<void> {
239
239
  logger.operation('Create Index', this.tableName, { indexName: indexSchema.name });
240
240
  await this.manager.createIndex(indexSchema);
241
241
  this.tableSchema = this.manager.tableSchema; // Refresh local schema ref
242
242
  }
243
243
 
244
- async xDropIndex(indexName: string): Promise<void> {
244
+ async dropIndex(indexName: string): Promise<void> {
245
245
  logger.operation('Drop Index', this.tableName, { indexName });
246
246
  await this.manager.dropIndex(indexName);
247
247
  // Update schema reference
@@ -7,7 +7,7 @@ import type { BestAccessPlanRequest, BestAccessPlanResult } from './best-access-
7
7
  import type { PlanNode } from '../planner/nodes/plan-node.js';
8
8
 
9
9
  /**
10
- * Base interface for module-specific configuration passed to xCreate/xConnect.
10
+ * Base interface for module-specific configuration passed to create/connect.
11
11
  * Modules should define their own interface extending this if they need options.
12
12
  */
13
13
  // eslint-disable-next-line @typescript-eslint/no-empty-object-type
@@ -45,7 +45,7 @@ export interface VirtualTableModule<
45
45
  * @returns The new VirtualTable instance
46
46
  * @throws QuereusError on failure
47
47
  */
48
- xCreate(
48
+ create(
49
49
  db: Database,
50
50
  tableSchema: TableSchema,
51
51
  ): TTable;
@@ -63,7 +63,7 @@ export interface VirtualTableModule<
63
63
  * @returns The connection-specific VirtualTable instance
64
64
  * @throws QuereusError on failure
65
65
  */
66
- xConnect(
66
+ connect(
67
67
  db: Database,
68
68
  pAux: unknown,
69
69
  moduleName: string,
@@ -98,17 +98,7 @@ export interface VirtualTableModule<
98
98
  request: BestAccessPlanRequest
99
99
  ): BestAccessPlanResult;
100
100
 
101
- /**
102
- * Determines the best query plan for a given set of constraints and orderings.
103
- * This method MUST be synchronous for performance. It modifies the passed IndexInfo object.
104
- *
105
- * @deprecated Use getBestAccessPlan instead for better type safety and extensibility
106
- * @param db The database connection
107
- * @param tableInfo The schema information for the table being planned
108
- * @param indexInfo Input constraints/orderings and output plan details
109
- * @returns StatusCode.OK on success, or an error code
110
- */
111
- xBestIndex(db: Database, tableInfo: TableSchema, indexInfo: IndexInfo): number;
101
+
112
102
 
113
103
  /**
114
104
  * Destroys the underlying persistent representation of the virtual table.
@@ -121,7 +111,7 @@ export interface VirtualTableModule<
121
111
  * @param tableName The name of the virtual table being destroyed
122
112
  * @throws QuereusError on failure
123
113
  */
124
- xDestroy(
114
+ destroy(
125
115
  db: Database,
126
116
  pAux: unknown,
127
117
  moduleName: string,
@@ -139,7 +129,7 @@ export interface VirtualTableModule<
139
129
  * @param indexSchema The schema definition for the index being created
140
130
  * @throws QuereusError on failure
141
131
  */
142
- xCreateIndex?(
132
+ createIndex?(
143
133
  db: Database,
144
134
  schemaName: string,
145
135
  tableName: string,
@@ -151,7 +141,7 @@ export interface VirtualTableModule<
151
141
  * @param name The name to check
152
142
  * @returns true if the name would conflict
153
143
  */
154
- xShadowName?(name: string): boolean;
144
+ shadowName?(name: string): boolean;
155
145
  }
156
146
 
157
147
  /**