semanticdb-v2 2.0.0-alpha.6 → 2.0.0-alpha.8

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 (43) hide show
  1. package/README.md +125 -9
  2. package/dist/cache/index.d.ts +2 -1
  3. package/dist/cache/manager.d.ts +5 -0
  4. package/dist/cache/registry.d.ts +14 -0
  5. package/dist/cache/types.d.ts +15 -0
  6. package/dist/close.d.ts +1 -0
  7. package/dist/executor/connection-registry.d.ts +1 -12
  8. package/dist/executor/types.d.ts +8 -4
  9. package/dist/index.d.ts +6 -7
  10. package/dist/logicform-types.d.ts +1 -12
  11. package/dist/normalizer/core.d.ts +9 -0
  12. package/dist/operators/index.d.ts +1 -1
  13. package/dist/operators/registry.d.ts +4 -2
  14. package/dist/operators/types.d.ts +23 -14
  15. package/dist/physical/clickhouse-provider.d.ts +15 -1
  16. package/dist/physical/connection-registry.d.ts +13 -0
  17. package/dist/physical/dameng-provider.d.ts +6 -1
  18. package/dist/physical/databricks-provider.d.ts +6 -1
  19. package/dist/physical/db-connector.d.ts +23 -0
  20. package/dist/physical/index.d.ts +4 -1
  21. package/dist/physical/maxcompute-provider.d.ts +8 -1
  22. package/dist/physical/mysql-protocol-provider.d.ts +4 -1
  23. package/dist/physical/oracle-provider.d.ts +6 -1
  24. package/dist/physical/postgresql-provider.d.ts +6 -1
  25. package/dist/physical/provider.d.ts +45 -0
  26. package/dist/physical/snowflake-provider.d.ts +5 -1
  27. package/dist/physical/sqlserver-provider.d.ts +5 -1
  28. package/dist/physical/table-description.d.ts +5 -0
  29. package/dist/physical/table-discovery.d.ts +10 -0
  30. package/dist/planner/semantics/registry.d.ts +2 -1
  31. package/dist/plugins/observation/operator-policy.d.ts +2 -2
  32. package/dist/semantic-types/types.d.ts +3 -0
  33. package/dist/semanticdb.esm.js +5 -4
  34. package/dist/semanticdb.js +5 -4
  35. package/package.json +1 -1
  36. package/dist/cache/redis-query-cache.esm.js +0 -1
  37. package/dist/cache/redis-query-cache.js +0 -1
  38. package/dist/calendar/constants.d.ts +0 -7
  39. package/dist/calendar/index.d.ts +0 -6
  40. package/dist/calendar/provider-relation-store.d.ts +0 -9
  41. package/dist/calendar/resolver.d.ts +0 -10
  42. package/dist/calendar/system-schemas.d.ts +0 -3
  43. package/dist/calendar/types.d.ts +0 -31
package/README.md CHANGED
@@ -167,6 +167,114 @@ Providers execute only parameterized `sql + parameters`; SemanticDB never execut
167
167
  Because `displaySql` contains literal values and may expose sensitive data, use it only in trusted
168
168
  debugging and observability channels.
169
169
 
170
+ ### Native SQL and table discovery
171
+
172
+ `DBConnector` provides trusted physical database operations independently of LogicForm execution:
173
+
174
+ ```ts
175
+ import { DBConnector, Logicform } from 'semanticdb-v2';
176
+ import type { DatabaseConnection } from 'semanticdb-v2';
177
+
178
+ const connection = {
179
+ id: 'analytics',
180
+ kind: 'mysql',
181
+ host: 'localhost',
182
+ user: 'analytics',
183
+ password: process.env.MYSQL_PASSWORD ?? '',
184
+ database: 'analytics',
185
+ } satisfies DatabaseConnection;
186
+
187
+ const tables = await DBConnector.getTableList({ connection });
188
+ // [{ name: 'orders', database: 'analytics', type: 'table' }, ...]
189
+
190
+ const description = await DBConnector.describeTable({ connection, table: 'orders' });
191
+ // {
192
+ // columns: [{ name: 'id', type: 'int', comment: 'Order ID', primaryKey: true, exampleValue: 42 }, ...],
193
+ // tableInfo: { name: 'orders', database: 'analytics', type: 'table', comment: 'Orders' },
194
+ // }
195
+
196
+ const { rows } = await DBConnector.runSQL({
197
+ connection,
198
+ sql: 'SELECT * FROM orders WHERE status = ?',
199
+ parameters: ['paid'],
200
+ });
201
+
202
+ const updated = await DBConnector.runSQL({
203
+ connection,
204
+ sql: 'UPDATE orders SET status = ? WHERE id = ?',
205
+ parameters: ['shipped', 42],
206
+ });
207
+ // { rows: [], affectedRows: 1 }
208
+
209
+ // The exact same object belongs in Logicform.execute's connections array:
210
+ // await Logicform.execute(logicform, { connections: [connection], schemas, schemaMappings });
211
+
212
+ await Logicform.close(); // DBConnector.close() is the same shutdown operation.
213
+ ```
214
+
215
+ Both APIs share providers and connection pools by connection ID and `providerRegistry`. An ID must
216
+ retain the same configuration until shutdown. Providers and pools are initialized lazily. Either
217
+ `close()` releases **all** SDK-managed connections, including those used by the other API; it does
218
+ not close just the last connector connection.
219
+
220
+ `runSQL` returns `{ rows: DataRow[], affectedRows?: number }`. Commands without a result set return
221
+ an empty array; affected-row counts are included only when the driver reports them. SQL is passed
222
+ through without automatic LIMIT, dialect translation, Schema mapping, hydration, generated `_id`,
223
+ or query caching. It does **not** enforce `ExecuteOptions.permissions`: use trusted callers and
224
+ appropriately restricted database accounts. Supply values through `parameters` using the native
225
+ provider placeholders: `?` for MySQL-compatible databases, Databricks, Dameng, Snowflake and MaxCompute;
226
+ `$1` for PostgreSQL; `@p0` for SQL Server; `:1` for Oracle; typed `{p0:String}`-style
227
+ placeholders for ClickHouse. ClickHouse uses JSONEachRow output; do not override it with another
228
+ FORMAT. Each call is independent, with Oracle/Dameng command execution automatically committed;
229
+ cross-call transactions and multi-statement/multi-result execution are not supported.
230
+
231
+ `getTableList` returns `{ name, database?, schema?, type: 'table' | 'view' }[]` for accessible tables
232
+ and views, retaining namespaces to distinguish same-name tables. Optional `database` and `schema`
233
+ override only this metadata lookup, never the cached connection configuration:
234
+
235
+ - MySQL, Doris, StarRocks, GBase and ClickHouse: `database`; `schema` is rejected.
236
+ - PostgreSQL, Oracle and Dameng: `schema`; cross-database overrides are rejected. Defaults to the
237
+ current schema (or the configured Dameng schema).
238
+ - SQL Server and Snowflake: `database` and `schema`. SQL Server lists all accessible schemas in
239
+ the database by default; Snowflake defaults to the current schema.
240
+ - Databricks: `database` means catalog, and `schema` means schema. Defaults come from the connection's
241
+ `catalog` and `schema` (`connection.database` remains the existing legacy alias for schema).
242
+ - MaxCompute: the existing injected client handles `SHOW TABLES`, returning rows with `table_name`.
243
+ It may implement `getTableList(request)` for project/schema overrides and view metadata, and
244
+ `runSQL(request)` for affected-row counts. Otherwise commands must return `[]` through `execute`.
245
+
246
+ `describeTable({ connection, table, database?, schema?, includeSample? })` inspects one physical
247
+ table or view. `table` is a literal **unqualified** name; provide its namespace separately, using
248
+ the same scope rules as `getTableList`. A dot inside `table` is part of the identifier, not a separator.
249
+ Do not pass a SQL expression or the legacy semantic Schema/`from` object. SQL Server descriptions
250
+ default to the connection's current default schema; pass `schema` explicitly when describing a
251
+ table returned from another schema. Column order follows the database's definition.
252
+
253
+ The result has `columns: { name, type, comment, primaryKey?, exampleValue? }[]` and
254
+ `tableInfo: { name, database?, schema?, type, comment }`. These are physical names/native types,
255
+ not semantic Properties; no `_id` is added. Comments default to an empty string. Primary-key
256
+ membership includes every column of composite keys; unique-only indexes are not primary keys.
257
+ ClickHouse reports its storage primary key, which does not imply relational uniqueness. If the
258
+ adapter cannot determine primary-key membership (Databricks/Snowflake), `primaryKey` is omitted
259
+ rather than guessed. Example values preserve driver types, including `null`.
260
+
261
+ Like the legacy API, descriptions read one example row by default. Set `includeSample: false`
262
+ for metadata-only inspection, avoiding a data read. Empty tables and failed sample queries still
263
+ return metadata without example values; metadata failures, tables not found in the selected namespace, and
264
+ cancellation reject. All SQL uses bound metadata values and quoted identifiers, bypassing
265
+ LogicForm permissions and caching just like `runSQL`.
266
+
267
+ MaxCompute clients may implement `describeTable(request)` to provide project/schema-aware
268
+ metadata. Otherwise the fallback runs `DESC` and expects structured rows with `column_name`,
269
+ `column_type`, optional `column_comment` and `is_primary_key`. Legacy UDBC ASCII `Info` reports
270
+ must be normalized by the client; unparsed reports are rejected rather than producing empty columns.
271
+
272
+ All operations accept `signal` and the same optional `providerRegistry` as `Logicform.execute`.
273
+ Custom providers opt in through `runSQL(request)`, `getTableList(request)` and `describeTable(request)`; missing capabilities
274
+ fail explicitly without changing the existing provider `execute` contract. Unsupported discovery
275
+ scopes are rejected rather than silently ignored. Cancellation does not guarantee rollback of
276
+ commands that have already reached the database.
277
+
170
278
  ### Permissions
171
279
 
172
280
  Pass table, row, and column permissions together through `ExecuteOptions.permissions`:
@@ -475,9 +583,10 @@ comments, or parameter placeholders. Property UDFs do not support the legacy `fu
475
583
  ### Query cache
476
584
 
477
585
  All compiled provider queries, including the internal time-watermark query, can share one
478
- caller-owned query cache. Redis is published from `semanticdb-v2/cache/redis`; cache identity
479
- includes namespace, connection id, provider, SQL, and parameters. Physical expiration belongs to each Schema
480
- mapping's `freshness` policy. See [Query cache and Redis](docs/query-cache.md).
586
+ internally managed Redis query cache. Pass its JSON connection configuration through `cache`;
587
+ cache identity includes namespace, connection id, provider, SQL, and parameters. Physical
588
+ expiration belongs to each Schema mapping's `freshness` policy. See
589
+ [Query cache and Redis](docs/query-cache.md).
481
590
 
482
591
  Schema mappings can also expose same-connection entity feature tables as lazy physical
483
592
  enrichments. A mapped feature property adds a `LEFT JOIN` only when referenced, and a point-in-time
@@ -490,14 +599,21 @@ separate Schema Mapping `dimensions` field. The planner selects a source that co
490
599
  the requested properties and physical time or hierarchy grain. See
491
600
  [Schema Mapping physical granularity](docs/schema-mapping-granularity.md).
492
601
 
493
- When Redis is shared with other applications, pass an application-specific key prefix:
602
+ When Redis is shared with other applications, pass an application-specific key prefix in the
603
+ execution JSON. SemanticDB reuses the connection by `cache.id`:
494
604
 
495
605
  ```ts
496
- import { createRedisQueryCache } from 'semanticdb-v2/cache/redis';
497
-
498
- const cache = await createRedisQueryCache({
499
- url: process.env.REDIS_URL,
500
- keyPrefix: process.env.REDIS_KEY_PREFIX,
606
+ await Logicform.execute(logicform, {
607
+ schemas,
608
+ schemaMappings,
609
+ connections,
610
+ cache: {
611
+ id: 'redis-main',
612
+ kind: 'redis',
613
+ url: process.env.REDIS_URL ?? 'redis://localhost:6379/0',
614
+ keyPrefix: process.env.REDIS_KEY_PREFIX,
615
+ namespace: 'tenant-a:mysql-sales',
616
+ },
501
617
  });
502
618
  ```
503
619
 
@@ -1,3 +1,4 @@
1
1
  export { nextDailyExpiration, resolveQueryExpiration, } from './expiry';
2
2
  export { queryCacheIdentityHash, sourceCacheIndexHash, } from './identity';
3
- export type { QueryCache, QueryCacheExecutionOptions, QueryCacheIdentity, QueryCacheWriteOptions, } from './types';
3
+ export type { InvalidateQueryCacheSourceOptions, QueryCache, QueryCacheConfiguration, QueryCacheExecutionOptions, QueryCacheIdentity, QueryCacheWriteOptions, } from './types';
4
+ export { QueryCacheManager } from './manager';
@@ -0,0 +1,5 @@
1
+ import type { InvalidateQueryCacheSourceOptions } from './types';
2
+ /** Operations for internally managed query-cache connections. */
3
+ export declare const QueryCacheManager: Readonly<{
4
+ invalidateSource: ({ cache, source }: InvalidateQueryCacheSourceOptions) => Promise<void>;
5
+ }>;
@@ -0,0 +1,14 @@
1
+ import type { QueryCache, QueryCacheConfiguration, QueryCacheExecutionOptions } from './types';
2
+ type QueryCacheConnection = Omit<QueryCacheConfiguration, 'namespace'>;
3
+ type QueryCacheFactory = (connection: QueryCacheConnection) => Promise<QueryCache>;
4
+ /** Internally owns and reuses cache connections by stable configuration id. */
5
+ export declare class QueryCacheRegistry {
6
+ #private;
7
+ private readonly create;
8
+ constructor(create?: QueryCacheFactory);
9
+ get(configuration: QueryCacheConfiguration): Promise<QueryCacheExecutionOptions>;
10
+ close(): Promise<void>;
11
+ }
12
+ export declare const resolveQueryCache: (configuration: QueryCacheConfiguration) => Promise<QueryCacheExecutionOptions>;
13
+ export declare const closeQueryCaches: () => Promise<void>;
14
+ export {};
@@ -27,3 +27,18 @@ export interface QueryCacheExecutionOptions {
27
27
  /** Isolates tenants and physical data sources that can produce identical SQL. */
28
28
  readonly namespace: string;
29
29
  }
30
+ /** Redis connection and cache namespace supplied as JSON at the public execution boundary. */
31
+ export interface QueryCacheConfiguration {
32
+ /** Stable identity used to reuse one internally managed Redis connection. */
33
+ readonly id: string;
34
+ readonly kind: 'redis';
35
+ readonly url: string;
36
+ readonly keyPrefix?: string;
37
+ /** Isolates tenants and physical data sources that can produce identical SQL. */
38
+ readonly namespace: string;
39
+ }
40
+ export interface InvalidateQueryCacheSourceOptions {
41
+ readonly cache: QueryCacheConfiguration;
42
+ /** Physical Schema Mapping source to invalidate. */
43
+ readonly source: string;
44
+ }
@@ -0,0 +1 @@
1
+ export declare const closeSemanticDB: () => Promise<void>;
@@ -1,12 +1 @@
1
- import type { CoreComputeProvider, DatabaseConnection, ProviderRegistry } from '../physical/index';
2
- type ProviderFactory = (connection: DatabaseConnection) => CoreComputeProvider;
3
- export declare class ConnectionRegistry {
4
- #private;
5
- private readonly create;
6
- constructor(create?: ProviderFactory);
7
- get(connection: DatabaseConnection): CoreComputeProvider;
8
- close(): Promise<void>;
9
- }
10
- export declare const getConnectionProvider: (connection: DatabaseConnection, providers?: ProviderRegistry) => CoreComputeProvider;
11
- export declare const closeConnections: () => Promise<void>;
12
- export {};
1
+ export { ConnectionRegistry, getConnectionProvider, closeConnections } from '../physical/index';
@@ -1,11 +1,11 @@
1
- import type { OperatorDefinition, OperatorRegistry } from '../operators/index';
1
+ import type { OperatorDefinition, OperatorExecutionContext, OperatorRegistry } from '../operators/index';
2
2
  import type { CoreComputeProvider, DataRow, ProviderRegistry, SqlParameters } from '../physical/index';
3
3
  import type { DatabaseConnection } from '../physical/index';
4
4
  import type { LogicalPlan, QueryLineage } from '../planner/index';
5
5
  import type { SchemaMappingDefinition, SchemaMappingRegistry, SchemaMappingSelection } from '../schema-mappings/index';
6
6
  import type { ResolvedSemanticSchema, SemanticSchemaDraft, SemanticTypeRegistry, TimeWatermarkPolicy } from '../semantic-types/index';
7
7
  import type { LogicformType, PublicLogicformType } from '../logicform-types';
8
- import type { QueryCacheExecutionOptions } from '../cache/index';
8
+ import type { QueryCacheConfiguration, QueryCacheExecutionOptions } from '../cache/index';
9
9
  import type { Permissions } from '../permissions/index';
10
10
  import type { SemanticDBPlugin } from '../plugins/index';
11
11
  import type { LocaleInput, LocaleRegistry } from '../i18n/index';
@@ -69,8 +69,6 @@ interface ExecuteBaseOptions {
69
69
  readonly locales?: LocaleInput;
70
70
  /** Table, row, and column permissions for this execution. */
71
71
  readonly permissions?: Permissions;
72
- /** Optional caller-owned cache shared across executions. */
73
- readonly cache?: QueryCacheExecutionOptions;
74
72
  readonly onProgress?: ProgressCallback;
75
73
  readonly signal?: AbortSignal;
76
74
  /** Default time watermark policy; Schema and Property policies override it. */
@@ -88,12 +86,16 @@ export interface ExecuteOptions extends ExecuteBaseOptions {
88
86
  readonly connections: readonly DatabaseConnection[];
89
87
  /** Provider factories used for built-in or application-defined connection kinds. */
90
88
  readonly providerRegistry?: ProviderRegistry;
89
+ /** JSON configuration for an internally owned and reused query-cache connection. */
90
+ readonly cache?: QueryCacheConfiguration;
91
91
  }
92
92
  /** Internal execution seam used by executor tests after a provider has been resolved. */
93
93
  export interface InternalExecuteOptions extends Omit<ExecuteBaseOptions, 'operators'> {
94
94
  readonly operators?: OperatorRegistry;
95
95
  /** The public execution boundary has already merged built-in, plugin, and explicit Operators. */
96
96
  readonly operatorsResolved?: boolean;
97
+ /** Present for nested executions to reuse or intentionally suppress calendar preloading. */
98
+ readonly executionContext?: OperatorExecutionContext;
97
99
  /** The public execution boundary has already merged plugin SemanticTypes. */
98
100
  readonly semanticTypesResolved?: boolean;
99
101
  readonly localeRegistry?: LocaleRegistry;
@@ -101,6 +103,8 @@ export interface InternalExecuteOptions extends Omit<ExecuteBaseOptions, 'operat
101
103
  /** Resolve providers for additional physical connections in a federated execution. */
102
104
  readonly providerForConnection?: (connectionId: string) => CoreComputeProvider;
103
105
  readonly schemaMappings: SchemaMappingRegistry;
106
+ /** Cache connection already resolved at the public execution boundary. */
107
+ readonly cache?: QueryCacheExecutionOptions;
104
108
  /** Selected connection for public execution; omitted only by internal provider tests. */
105
109
  readonly connectionId?: string;
106
110
  }
package/dist/index.d.ts CHANGED
@@ -9,17 +9,16 @@ export { builtinSemanticTypes, createSemanticTypeRegistry, resolveSchema, Semant
9
9
  export { builtinOperators, createOperatorRegistry, OperatorRegistry, resolveOperator, } from './operators/index';
10
10
  export type { LegacySchemaPluginContext, MappingGranularityContext, MappingGranularityPlugin, OutputHandlerContext, OutputHandlerDefinition, IntervalSemanticProperties, IntervalSemanticsDefinition, PlannerPeriodDefinition, PlannerPeriodEvaluation, RelationSemanticsDefinition, RelationTemporalPlan, TimeWatermarkLogicformContext, PropertyMetadataPlugin, QueryOperatorCompileContext, QueryOperatorAuthorizeContext, QueryOperatorDefinition, QueryOperatorNormalizeContext, QueryOperatorPhysicalSource, QueryOperatorPlanContext, QueryOperatorPlanResult, SchemaMetadataPlugin, SchemaMappingPlugin, SemanticDBPlugin, } from './plugins/index';
11
11
  export { SchemaMappingRegistry, fromYiAskSchemaMapping, } from './schema-mappings/index';
12
- export type { AbsoluteDateValue, CompareOperator, DatePartQueryComparison, DatePartQueryOperand, CalendarDateValue, DateTimeValue, DateValue, EntityIdType, ExpressionItemType, LogicformType, NumericQueryComparison, NumericQueryOperand, PublicLogicformType, PeriodShiftTime, PredItemType, QueryLogicalOperand, QueryExpressionType, RelationQueryType, QueryType, QueryValueType, QueryValueTypeWithCompareOperator, RelativeDateValue, RepresentationType, } from './logicform-types';
12
+ export type { AbsoluteDateValue, CompareOperator, DatePartQueryComparison, DatePartQueryOperand, DateTimeValue, DateValue, EntityIdType, ExpressionItemType, LogicformType, NumericQueryComparison, NumericQueryOperand, PublicLogicformType, PeriodShiftTime, PredItemType, QueryLogicalOperand, QueryExpressionType, RelationQueryType, QueryType, QueryValueType, QueryValueTypeWithCompareOperator, RelativeDateValue, RepresentationType, } from './logicform-types';
13
13
  export type { RecursiveQueryType } from './plugins/index';
14
- export { CALENDAR_DATES_TABLE, CALENDAR_RELATIONS_TABLE, CALENDAR_SYSTEM_SCHEMA_IDS, calendarSystemSchemas, ProviderCalendarRelationStore, resolveCalendarPeriod, resolveCalendarPeriodFromStore, selectCalendarDates, } from './calendar/index';
15
- export type { CalendarAlignment, CalendarComparison, CalendarDateRow, CalendarRelation, CalendarRelationRow, ResolvedCalendarPeriod, } from './calendar/index';
16
- export type { CalendarRelationStore } from './calendar/index';
17
14
  export type { PrimalType, PropertyHierarchyDefinition, PropertySqlDefinition, ResolvedSemanticProperty, ResolvedSemanticSchema, SemanticTypeNormalizeContext, SemanticPropertyDraft, SemanticSchemaDraft, SemanticTypeDefinition, SemanticTypeResultContext, SemanticTypeResultProperty, TimeGranularity, TimeWatermarkPolicy, } from './semantic-types/index';
18
15
  export type { DataRow, SqlParameters, BuiltinDatabaseConnection, DatabaseConnection, DatabaseConnectionBase, DatabaseConnectionExtensions, ProviderDefinition, ProviderKind, ProviderKindExtensions, } from './physical/index';
19
- export { ProviderRegistry } from './physical/index';
20
- export type { OperatorDefinition, OperatorDefaultNameContext, OperatorComponentContext, OperatorComponentCalculation, OperatorComponentQuery, OperatorExecutionComponent, OperatorPlanInputContext, OperatorPlannedInput, OperatorGroupKeyShift, OperatorJavaScriptCalculation, OperatorQueryComponent, OperatorEvaluateContext, OperatorOutputPropertyContext, OperatorSqlCapabilities, OperatorSqlContext, ResultProperty, ResultPropertyTemporalMetadata, ResultPropertyTemporalMetadataExtensions, } from './operators/index';
16
+ export { DBConnector, ProviderRegistry } from './physical/index';
17
+ export type { DBConnectorOptions, RunSQLOptions, GetTableListOptions, DescribeTableOptions, DescribeTableRequest, DatabaseColumn, TableDescription, DatabaseTable, SQLResult, TableListRequest, } from './physical/index';
18
+ export type { OperatorDefinition, OperatorDefaultNameContext, OperatorExecutionContext, OperatorComponentContext, OperatorComponentCalculation, OperatorComponentQuery, OperatorExecutionComponent, OperatorPlanInputContext, OperatorPlannedInput, OperatorGroupKeyShift, OperatorJavaScriptCalculation, OperatorQueryComponent, OperatorEvaluateContext, OperatorOutputPropertyContext, OperatorSqlCapabilities, OperatorSqlContext, ResultProperty, ResultPropertyTemporalMetadata, ResultPropertyTemporalMetadataExtensions, } from './operators/index';
21
19
  export type { SchemaMappingDefinition, SchemaMappingEnrichmentDefinition, SchemaMappingEnrichmentKey, SchemaMappingItem, SchemaMappingGranularity, SchemaMappingGranularityExtensions, SchemaMappingPointTemporalDefinition, SchemaMappingPredDefinition, SchemaMappingPredMatch, SchemaMappingSelection, RejectedSchemaMapping, SourceFreshnessPolicy, YiAskSchemaMappingItem, YiAskSchemaMappingRecord, } from './schema-mappings/index';
22
- export type { QueryCache, QueryCacheExecutionOptions, QueryCacheIdentity, QueryCacheWriteOptions, } from './cache/index';
20
+ export { QueryCacheManager } from './cache/index';
21
+ export type { InvalidateQueryCacheSourceOptions, QueryCacheConfiguration, } from './cache/index';
23
22
  export type { ExecuteOptions, ExecuteFailureResult, ExecuteProgressEvent, ExecuteResult, ExecuteSuccessResult, ExecutedSql, ExecutedSqlType, PartialExecuteResult, ProgressCallback, } from './executor/index';
24
23
  export type { ColumnPermissions, Permissions, SchemaPermissions, } from './permissions/index';
25
24
  export type { CreateLogicalPlanOptions, LogicalPlan, QueryLineage, } from './planner/index';
@@ -19,21 +19,10 @@ export interface AbsoluteDateValue {
19
19
  readonly second?: number;
20
20
  readonly period?: 'am' | 'pm';
21
21
  }
22
- /** A business-calendar period resolved to natural days before planning. */
23
- export interface CalendarDateValue {
24
- readonly calendar: string;
25
- readonly key?: string;
26
- readonly year?: number;
27
- readonly quarter?: number;
28
- readonly month?: number;
29
- readonly week?: number;
30
- readonly day?: number;
31
- readonly relativeDay?: number | readonly number[];
32
- }
33
22
  /** Period reference used by operators such as `$periodShift`. */
34
23
  export type PeriodShiftTime = RelativeDateValue | AbsoluteDateValue;
35
24
  /** A date value before semantic-type normalization. */
36
- export type DateValue = string | RelativeDateValue | AbsoluteDateValue | CalendarDateValue;
25
+ export type DateValue = string | RelativeDateValue | AbsoluteDateValue;
37
26
  /** Stable entity identity. Numeric IDs must be safe integers. */
38
27
  export type EntityIdType = string | number;
39
28
  export type CompareOperator = '$eq' | '$gt' | '$gte' | '$lt' | '$lte' | '$ne' | '$in' | '$nin' | '$exists' | '$regex' | '$contains' | '$startsWith' | '$length' | '$and' | '$or' | '$second' | '$minute' | '$hour' | '$weekday' | '$day' | '$week' | '$month' | '$quarter' | '$year' | Extract<keyof QueryOperatorExtensions, string>;
@@ -16,6 +16,15 @@ export interface NormalizeLogicformOptions {
16
16
  readonly now?: Date;
17
17
  readonly resolveSchema?: (schemaId: string) => ResolvedSemanticSchema;
18
18
  readonly requestTimeWatermark?: (schema: ResolvedSemanticSchema, property: ResolvedSemanticProperty, requestedUpperBound: Date) => Promise<Date | undefined>;
19
+ readonly requestAutoCaseBounds?: (schema: ResolvedSemanticSchema, reference: string, query: LogicformType['query']) => Promise<{
20
+ readonly min: number;
21
+ readonly max: number;
22
+ readonly count: number;
23
+ } | {
24
+ readonly empty: true;
25
+ }>;
26
+ /** Internal root query used to resolve automatic `$case` boundaries. */
27
+ readonly autoCaseQuery?: LogicformType['query'];
19
28
  readonly resolveFromSchema?: (normalizedFrom: LogicformType, outerSchema: ResolvedSemanticSchema) => ResolvedSemanticSchema;
20
29
  readonly canProjectProperty?: (schema: ResolvedSemanticSchema, property: ResolvedSemanticProperty) => boolean;
21
30
  /** Internal recursion hook installed by normalizeLogicform. */
@@ -3,6 +3,6 @@ import { OperatorRegistry } from './registry';
3
3
  export { OperatorRegistry } from './registry';
4
4
  export { resolveOperator } from './resolve';
5
5
  export { bindTrustedSqlExpression } from './sql-expression';
6
- export type { OperatorDefinition, OperatorDefaultNameContext, OperatorComponentContext, OperatorComponentCalculation, OperatorComponentQuery, OperatorExecutionComponent, OperatorGroupKeyShift, OperatorJavaScriptCalculation, OperatorQueryComponent, OperatorEvaluateContext, OperatorOutputPropertyContext, OperatorPeriodBoundaryPolicy, OperatorPeriodBoundaryPolicyContext, OperatorNormalizePredContext, OperatorPlanExpressionContext, OperatorPeriodEvaluationContext, OperatorPlanInputContext, OperatorPlannedInput, OperatorRewriteLogicformContext, OperatorValidatePlanContext, OperatorSqlCapabilities, OperatorSqlContext, ResultProperty, ResultPropertyTemporalMetadata, ResultPropertyTemporalMetadataExtensions, } from './types';
6
+ export type { OperatorDefinition, OperatorDefaultNameContext, OperatorExecutionContext, OperatorComponentContext, OperatorComponentCalculation, OperatorComponentQuery, OperatorExecutionComponent, OperatorGroupKeyShift, OperatorJavaScriptCalculation, OperatorQueryComponent, OperatorEvaluateContext, OperatorOutputPropertyContext, OperatorPeriodBoundaryPolicy, OperatorPeriodBoundaryPolicyContext, OperatorNormalizePredContext, OperatorPlanExpressionContext, OperatorPeriodEvaluationContext, OperatorPlanInputContext, OperatorPlannedInput, OperatorRewriteLogicformContext, OperatorValidatePlanContext, OperatorSqlCapabilities, OperatorSqlContext, ResultProperty, ResultPropertyTemporalMetadata, ResultPropertyTemporalMetadataExtensions, } from './types';
7
7
  export declare const builtinOperators: readonly import("./types").OperatorDefinition[];
8
8
  export declare const createOperatorRegistry: (plugins?: readonly SemanticDBPlugin[]) => OperatorRegistry;
@@ -1,7 +1,9 @@
1
- import type { OperatorDefinition, OperatorPeriodEvaluationContext } from './types';
1
+ import type { OperatorDefinition, OperatorExecutionContext, OperatorPeriodEvaluationContext } from './types';
2
2
  export declare class OperatorRegistry {
3
3
  #private;
4
- constructor(definitions?: readonly OperatorDefinition[]);
4
+ readonly executionContext: OperatorExecutionContext;
5
+ constructor(definitions?: readonly OperatorDefinition[], executionContext?: OperatorExecutionContext);
6
+ withExecutionContext(executionContext: OperatorExecutionContext): OperatorRegistry;
5
7
  register(input: OperatorDefinition): this;
6
8
  get(name: string): OperatorDefinition;
7
9
  requiresPerPeriodEvaluation(name: string, context: OperatorPeriodEvaluationContext): boolean;
@@ -3,6 +3,15 @@ import type { LogicformType, PredItemType } from '../logicform-types';
3
3
  import type { DataRow } from '../physical/index';
4
4
  import type { Expression, LogicalPlan } from '../planner/index';
5
5
  import type { LocaleTranslate } from '../i18n/index';
6
+ /** Immutable data shared by all Operator hooks during one LogicForm execution. */
7
+ export interface OperatorExecutionContext {
8
+ /** Complete rows from the unique Schema marked with `is_calendar`. */
9
+ readonly calendar?: readonly Readonly<DataRow>[];
10
+ }
11
+ interface OperatorHookContext {
12
+ /** Always supplied by the executor; optional for direct unit-level hook invocation. */
13
+ readonly executionContext?: OperatorExecutionContext;
14
+ }
6
15
  export interface OperatorSqlCapabilities {
7
16
  /** Produce a dialect-specific aggregate function around an expression. */
8
17
  aggregateFunction(name: string, expression?: string): string;
@@ -24,7 +33,7 @@ export interface OperatorSqlCapabilities {
24
33
  condition(expression: string, condition: unknown): string;
25
34
  }
26
35
  /** Context passed to an operator that pushes its computation into SQL. */
27
- export interface OperatorSqlContext {
36
+ export interface OperatorSqlContext extends OperatorHookContext {
28
37
  readonly sql: OperatorSqlCapabilities;
29
38
  /** SQL for the nested input expression, when this operator has one. */
30
39
  readonly expression?: string;
@@ -36,7 +45,7 @@ export interface OperatorSqlContext {
36
45
  readonly args: Readonly<Record<string, unknown>>;
37
46
  }
38
47
  /** Context passed to an operator evaluated after the provider returns rows. */
39
- export interface OperatorEvaluateContext {
48
+ export interface OperatorEvaluateContext extends OperatorHookContext {
40
49
  /** Value produced by the nested expression, or undefined for a propertyless operator. */
41
50
  readonly input: unknown;
42
51
  /** Operator-specific LogicForm arguments. */
@@ -82,7 +91,7 @@ export type ResultPropertyTemporalMetadata = {
82
91
  readonly date: string;
83
92
  }[];
84
93
  } | ResultPropertyTemporalMetadataExtensions[keyof ResultPropertyTemporalMetadataExtensions];
85
- export interface OperatorOutputPropertyContext {
94
+ export interface OperatorOutputPropertyContext extends OperatorHookContext {
86
95
  /** Final alias assigned to this operator's single output column. */
87
96
  readonly name: string;
88
97
  /** Original Schema property when the operator starts from a physical property. */
@@ -95,13 +104,13 @@ export interface OperatorOutputPropertyContext {
95
104
  readonly args: Readonly<Record<string, unknown>>;
96
105
  }
97
106
  /** Context used by operators whose value must be evaluated per time bucket. */
98
- export interface OperatorPeriodEvaluationContext {
107
+ export interface OperatorPeriodEvaluationContext extends OperatorHookContext {
99
108
  readonly logicform: LogicformType;
100
109
  readonly pred: PredItemType;
101
110
  readonly schema: ResolvedSemanticSchema;
102
111
  readonly inputProperty?: ResolvedSemanticProperty;
103
112
  }
104
- export interface OperatorDefaultNameContext {
113
+ export interface OperatorDefaultNameContext extends OperatorHookContext {
105
114
  /** Name produced by the direct pred inputs or localized row label. */
106
115
  readonly operandName: string;
107
116
  /** Name of a direct or nested pred input. */
@@ -115,7 +124,7 @@ export interface OperatorDefaultNameContext {
115
124
  /** Translate a stable message key using the requested locale. */
116
125
  readonly t?: LocaleTranslate;
117
126
  }
118
- export interface OperatorPlanInputContext {
127
+ export interface OperatorPlanInputContext extends OperatorHookContext {
119
128
  /** Canonical property or relation reference supplied as this operator's direct pred. */
120
129
  readonly reference: string;
121
130
  readonly args: Readonly<Record<string, unknown>>;
@@ -128,11 +137,11 @@ export interface OperatorPlannedInput {
128
137
  /** Provider-independent arguments resolved from semantic metadata. */
129
138
  readonly args: Readonly<Record<string, unknown>>;
130
139
  }
131
- export interface OperatorNormalizePredContext {
140
+ export interface OperatorNormalizePredContext extends OperatorHookContext {
132
141
  readonly pred: PredItemType;
133
142
  readonly schema: ResolvedSemanticSchema;
134
143
  }
135
- export interface OperatorPlanExpressionContext {
144
+ export interface OperatorPlanExpressionContext extends OperatorHookContext {
136
145
  readonly pred: PredItemType;
137
146
  readonly input?: Expression;
138
147
  readonly inputProperty?: ResultProperty;
@@ -142,29 +151,29 @@ export interface OperatorPlanExpressionContext {
142
151
  readonly getOperator: (name: string) => OperatorDefinition;
143
152
  readonly planQuery: (query: Readonly<Record<string, unknown>>) => Readonly<Record<string, unknown>>;
144
153
  }
145
- export interface OperatorPeriodBoundaryPolicyContext {
154
+ export interface OperatorPeriodBoundaryPolicyContext extends OperatorHookContext {
146
155
  readonly pred: PredItemType;
147
156
  }
148
157
  export interface OperatorPeriodBoundaryPolicy {
149
158
  readonly boundary: 'start' | 'end';
150
159
  readonly implicit: boolean;
151
160
  }
152
- export interface OperatorValidatePlanContext {
161
+ export interface OperatorValidatePlanContext extends OperatorHookContext {
153
162
  readonly pred: PredItemType;
154
163
  readonly groupByNames: readonly string[];
155
164
  readonly resolveGroupName: (reference: string) => string | undefined;
156
165
  readonly getOperator: (name: string) => OperatorDefinition;
157
166
  }
158
- export interface OperatorValidateGroupbyContext {
167
+ export interface OperatorValidateGroupbyContext extends OperatorHookContext {
159
168
  readonly pred: PredItemType;
160
169
  }
161
- export interface OperatorRewriteLogicformContext {
170
+ export interface OperatorRewriteLogicformContext extends OperatorHookContext {
162
171
  readonly logicform: LogicformType;
163
172
  readonly schema: ResolvedSemanticSchema;
164
173
  /** Resolve operator metadata while rewriting nested expressions. */
165
174
  readonly getOperator?: (name: string) => OperatorDefinition;
166
175
  }
167
- export interface OperatorComponentContext {
176
+ export interface OperatorComponentContext extends OperatorHookContext {
168
177
  /** Fully normalized LogicForm containing this top-level operator projection. */
169
178
  readonly logicform: LogicformType;
170
179
  /** Caller-authored normalized LogicForm before executor row policies were added. */
@@ -268,7 +277,7 @@ interface OperatorDefinitionBase {
268
277
  /** Validate semantics that apply only when this Operator is used as a group key. */
269
278
  readonly validateGroupby?: (context: OperatorValidateGroupbyContext) => void;
270
279
  /** The logical planner may fully lower a component, so no executor child query is needed. */
271
- readonly skipComponentExecution?: (context: {
280
+ readonly skipComponentExecution?: (context: OperatorHookContext & {
272
281
  readonly plan: LogicalPlan;
273
282
  }) => boolean;
274
283
  /** Expand high-level operator semantics into ordinary nested LogicForm objects before planning. */
@@ -1,4 +1,4 @@
1
- import type { CoreComputeProvider, DatePart, DataRow, ProviderExecutionRequest } from './provider';
1
+ import type { CoreComputeProvider, DatePart, DataRow, ProviderExecutionRequest, SQLResult, DatabaseTable, TableListRequest, DescribeTableRequest, TableDescription } from './provider';
2
2
  interface ClickHouseResultLike {
3
3
  json<T>(): Promise<T>;
4
4
  }
@@ -9,6 +9,17 @@ export interface ClickHouseClientLike {
9
9
  query_params: Readonly<Record<string, unknown>>;
10
10
  abort_signal?: AbortSignal;
11
11
  }): Promise<ClickHouseResultLike>;
12
+ /** Native SDK exec does not append a FORMAT clause to commands. */
13
+ exec?(options: {
14
+ query: string;
15
+ query_params: Readonly<Record<string, unknown>>;
16
+ clickhouse_settings: {
17
+ readonly default_format: 'JSONEachRow';
18
+ };
19
+ abort_signal?: AbortSignal;
20
+ }): Promise<{
21
+ readonly stream: AsyncIterable<string | Buffer>;
22
+ }>;
12
23
  close(): Promise<void>;
13
24
  }
14
25
  export interface ClickHouseProviderOptions {
@@ -52,6 +63,9 @@ export declare class ClickHouseProvider implements CoreComputeProvider {
52
63
  valueExpression: string;
53
64
  };
54
65
  execute(request: ProviderExecutionRequest): Promise<DataRow[]>;
66
+ getTableList(request: TableListRequest): Promise<DatabaseTable[]>;
67
+ describeTable(request: DescribeTableRequest): Promise<TableDescription>;
68
+ runSQL(request: ProviderExecutionRequest): Promise<SQLResult>;
55
69
  close(): Promise<void>;
56
70
  }
57
71
  export {};
@@ -0,0 +1,13 @@
1
+ import type { DatabaseConnection, ProviderRegistry } from './connection';
2
+ import type { CoreComputeProvider } from './provider';
3
+ type ProviderFactory = (connection: DatabaseConnection) => CoreComputeProvider;
4
+ export declare class ConnectionRegistry {
5
+ #private;
6
+ private readonly create;
7
+ constructor(create?: ProviderFactory);
8
+ get(connection: DatabaseConnection): CoreComputeProvider;
9
+ close(): Promise<void>;
10
+ }
11
+ export declare const getConnectionProvider: (connection: DatabaseConnection, providers?: ProviderRegistry) => CoreComputeProvider;
12
+ export declare const closeConnections: () => Promise<void>;
13
+ export {};
@@ -1,4 +1,4 @@
1
- import type { CoreComputeProvider, DatePart, DataRow, ProviderExecutionRequest } from './provider';
1
+ import type { CoreComputeProvider, DatePart, DataRow, ProviderExecutionRequest, SQLResult, DatabaseTable, TableListRequest, DescribeTableRequest, TableDescription } from './provider';
2
2
  type DamengBind = string | number | Date | Buffer | null;
3
3
  export interface DamengConnectionOptions {
4
4
  readonly connectString?: string;
@@ -15,8 +15,10 @@ export interface DamengConnectionOptions {
15
15
  export interface DamengConnectionLike {
16
16
  execute(sql: string, binds: DamengBind[], options: {
17
17
  readonly outFormat: number;
18
+ readonly autoCommit?: boolean;
18
19
  }): Promise<{
19
20
  readonly rows?: unknown[];
21
+ readonly rowsAffected?: number;
20
22
  }>;
21
23
  close(): Promise<void>;
22
24
  }
@@ -56,6 +58,9 @@ export declare class DamengProvider implements CoreComputeProvider {
56
58
  stringLength(expression: string): string;
57
59
  regex(expression: string, pattern: string, options?: string): string;
58
60
  execute(request: ProviderExecutionRequest): Promise<DataRow[]>;
61
+ runSQL(request: ProviderExecutionRequest): Promise<SQLResult>;
62
+ getTableList(request: TableListRequest): Promise<DatabaseTable[]>;
63
+ describeTable(request: DescribeTableRequest): Promise<TableDescription>;
59
64
  close(): Promise<void>;
60
65
  }
61
66
  export {};
@@ -1,4 +1,4 @@
1
- import type { CoreComputeProvider, DatePart, DataRow, ProviderExecutionRequest } from './provider';
1
+ import type { CoreComputeProvider, DatePart, DataRow, ProviderExecutionRequest, SQLResult, DatabaseTable, TableListRequest, DescribeTableRequest, TableDescription } from './provider';
2
2
  type DatabricksBind = string | number | boolean | bigint | Date | null;
3
3
  export interface DatabricksConnectionBase {
4
4
  readonly host: string;
@@ -29,6 +29,8 @@ export interface DatabricksOAuthAuth {
29
29
  export type DatabricksConnectionOptions = DatabricksConnectionBase & (DatabricksAccessTokenAuth | DatabricksOAuthAuth);
30
30
  export interface DatabricksOperationLike {
31
31
  fetchAll(): Promise<unknown>;
32
+ /** The native SDK can finish commands that have no result set to fetch. */
33
+ finished?(): Promise<void>;
32
34
  cancel(): Promise<unknown>;
33
35
  close(): Promise<unknown>;
34
36
  }
@@ -78,6 +80,9 @@ export declare class DatabricksProvider implements CoreComputeProvider {
78
80
  valueExpression: string;
79
81
  };
80
82
  execute(request: ProviderExecutionRequest): Promise<DataRow[]>;
83
+ runSQL(request: ProviderExecutionRequest): Promise<SQLResult>;
84
+ describeTable(request: DescribeTableRequest): Promise<TableDescription>;
85
+ getTableList(request: TableListRequest): Promise<DatabaseTable[]>;
81
86
  close(): Promise<void>;
82
87
  }
83
88
  export {};
@@ -0,0 +1,23 @@
1
+ import type { DatabaseConnection, ProviderRegistry } from './connection';
2
+ import type { DatabaseTable, SQLResult, SqlParameters, TableListRequest, DescribeTableRequest, TableDescription } from './provider';
3
+ export interface DBConnectorOptions {
4
+ /** Exactly the same connection object accepted by Logicform.execute.connections. */
5
+ readonly connection: DatabaseConnection;
6
+ readonly providerRegistry?: ProviderRegistry;
7
+ readonly signal?: AbortSignal;
8
+ }
9
+ export interface RunSQLOptions extends DBConnectorOptions {
10
+ readonly sql: string;
11
+ readonly parameters?: SqlParameters;
12
+ }
13
+ export interface GetTableListOptions extends DBConnectorOptions, TableListRequest {
14
+ }
15
+ export interface DescribeTableOptions extends DBConnectorOptions, DescribeTableRequest {
16
+ }
17
+ /** Trusted physical operations; no LogicForm permissions, rewriting, or caching. */
18
+ export declare const DBConnector: Readonly<{
19
+ runSQL: (options: RunSQLOptions) => Promise<SQLResult>;
20
+ getTableList: (options: GetTableListOptions) => Promise<DatabaseTable[]>;
21
+ describeTable: (options: DescribeTableOptions) => Promise<TableDescription>;
22
+ close: () => Promise<void>;
23
+ }>;
@@ -1,5 +1,8 @@
1
1
  /** Internal physical adapters selected from the public database connection configuration. */
2
- export type { CoreComputeProvider, DatePart, DataRow, ProviderExecutionRequest, ProviderKind, ProviderKindExtensions, SqlRenderCapabilities, SqlParameters, } from './provider';
2
+ export type { CoreComputeProvider, DatePart, DataRow, DatabaseTable, SQLResult, TableListRequest, DescribeTableRequest, DatabaseColumn, TableDescription, ProviderExecutionRequest, ProviderKind, ProviderKindExtensions, SqlRenderCapabilities, SqlParameters, } from './provider';
3
+ export { ConnectionRegistry, getConnectionProvider, closeConnections } from './connection-registry';
4
+ export { DBConnector } from './db-connector';
5
+ export type { DBConnectorOptions, RunSQLOptions, GetTableListOptions, DescribeTableOptions } from './db-connector';
3
6
  export { builtinProviderDefinitions, createProvider, defaultProviderRegistry, ProviderRegistry, } from './connection';
4
7
  export type { BuiltinDatabaseConnection, DatabaseConnection, DatabaseConnectionBase, DatabaseConnectionExtensions, ProviderDefinition, } from './connection';
5
8
  export { DuckDBCoordinatorProvider } from './duckdb-coordinator-provider';