import { ResolverAdapter } from "../resolver/types.mjs"; import { PlannerCapabilities } from "gscdump/query/plan"; import { TableName } from "@gscdump/contracts"; import { BuilderState } from "gscdump/query"; type QueryRow = Record; interface FileSet { table: TableName; partitions: string[]; } interface ExecuteSqlOptions { fileSets?: Record; } /** * Flat capability bag: planner-side flags (`regex`, `comparisonJoin`, ...) * mixed with storage-side flags. SQL execution is not a capability flag — * callers probe `typeof source.executeSql === 'function'`. */ interface SourceCapabilities extends PlannerCapabilities { attachedTables?: boolean; fileSets?: boolean; /** * true iff the source provides a `ResolverAdapter` for analyzers that * compose SQL from a typed `BuilderState` at plan-build time. */ adapter?: boolean; } type AnalysisSourceKind = 'local' | 'browser' | 'live' | 'in-memory' | 'composite' | 'attached-table'; interface AnalysisQuerySource { name?: string; /** Telemetry tag stamped onto analyzer result meta; not used for routing. */ kind?: AnalysisSourceKind; capabilities: SourceCapabilities; /** * Dialect adapter surfaced for analyzers that compose SQL from a * `BuilderState` at plan-build time. Optional for pure row sources. */ adapter?: ResolverAdapter; /** Tenant scope; multi-tenant dialects (sqlite/D1) require it, parquet omits it. */ siteId?: string | number; queryRows: (state: BuilderState) => Promise; /** * Optional raw-SQL escape hatch. Receives the compiled SQL plan with * `{{FILES}}` placeholders; sources that advertise `capabilities.fileSets` * consume `opts.fileSets`, others ignore them. Implementations MUST coerce * BigInts to numbers before returning (see Source invariant above). */ executeSql?: (sql: string, params?: unknown[], opts?: ExecuteSqlOptions) => Promise; } export { AnalysisQuerySource, AnalysisSourceKind, ExecuteSqlOptions, FileSet, QueryRow, SourceCapabilities };