@deepagents/text2sql 7.3.0 → 7.4.0
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.
- package/README.md +80 -28
- package/dist/bin/sql.js +15 -7
- package/dist/index.js +28 -22
- package/dist/index.js.map +2 -2
- package/dist/lib/adapters/adapter.d.ts.map +1 -1
- package/dist/lib/adapters/bigquery/index.js +2 -6
- package/dist/lib/adapters/bigquery/index.js.map +2 -2
- package/dist/lib/adapters/clickhouse/index.js +4 -8
- package/dist/lib/adapters/clickhouse/index.js.map +3 -3
- package/dist/lib/adapters/duckdb/index.js +6 -10
- package/dist/lib/adapters/duckdb/index.js.map +3 -3
- package/dist/lib/adapters/mysql/index.js +2 -6
- package/dist/lib/adapters/mysql/index.js.map +2 -2
- package/dist/lib/adapters/postgres/index.js +4 -8
- package/dist/lib/adapters/postgres/index.js.map +3 -3
- package/dist/lib/adapters/posthog/index.js +2 -6
- package/dist/lib/adapters/posthog/index.js.map +2 -2
- package/dist/lib/adapters/spreadsheet/index.js +7 -13
- package/dist/lib/adapters/spreadsheet/index.js.map +3 -3
- package/dist/lib/adapters/spreadsheet/spreadsheet.d.ts.map +1 -1
- package/dist/lib/adapters/sqlite/index.js +5 -11
- package/dist/lib/adapters/sqlite/index.js.map +3 -3
- package/dist/lib/adapters/sqlite/table.sqlite.grounding.d.ts.map +1 -1
- package/dist/lib/adapters/sqlserver/index.js +2 -6
- package/dist/lib/adapters/sqlserver/index.js.map +2 -2
- package/dist/lib/checkpoint.d.ts +3 -0
- package/dist/lib/checkpoint.d.ts.map +1 -1
- package/dist/lib/file-cache.d.ts +12 -2
- package/dist/lib/file-cache.d.ts.map +1 -1
- package/dist/lib/fs/sqlite/ddl.sqlite-fs.d.ts +1 -1
- package/dist/lib/fs/sqlite/ddl.sqlite-fs.d.ts.map +1 -1
- package/dist/lib/fs/sqlite/sqlite-fs.d.ts.map +1 -1
- package/dist/lib/index-cache.d.ts +4 -1
- package/dist/lib/index-cache.d.ts.map +1 -1
- package/package.json +10 -8
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/adapters/adapter.ts", "../../../../src/lib/agents/exceptions.ts", "../../../../src/lib/fragments/schema.ts", "../../../../src/lib/adapters/groundings/context.ts", "../../../../src/lib/adapters/groundings/abstract.grounding.ts", "../../../../src/lib/adapters/groundings/column-stats.grounding.ts", "../../../../src/lib/adapters/groundings/column-values.grounding.ts", "../../../../src/lib/adapters/groundings/constraint.grounding.ts", "../../../../src/lib/adapters/groundings/indexes.grounding.ts", "../../../../src/lib/adapters/groundings/info.grounding.ts", "../../../../src/lib/adapters/groundings/row-count.grounding.ts", "../../../../src/lib/adapters/groundings/table.grounding.ts", "../../../../src/lib/adapters/postgres/column-stats.postgres.grounding.ts", "../../../../src/lib/adapters/groundings/rows.ts", "../../../../src/lib/adapters/postgres/column-values.postgres.grounding.ts", "../../../../src/lib/adapters/postgres/constraint.postgres.grounding.ts", "../../../../src/lib/adapters/postgres/indexes.postgres.grounding.ts", "../../../../src/lib/adapters/postgres/info.postgres.grounding.ts", "../../../../src/lib/adapters/parser-sql-policy.ts", "../../../../src/lib/sql-scope-error.ts", "../../../../src/lib/adapters/postgres/postgres-parser-workaround.ts", "../../../../src/lib/adapters/postgres/postgres.sql-policy.ts", "../../../../src/lib/adapters/postgres/postgres.ts", "../../../../src/lib/adapters/postgres/row-count.postgres.grounding.ts", "../../../../src/lib/adapters/postgres/table.postgres.grounding.ts", "../../../../src/lib/adapters/postgres/postgres-rows.ts", "../../../../src/lib/adapters/groundings/view.grounding.ts", "../../../../src/lib/adapters/postgres/view.postgres.grounding.ts", "../../../../src/lib/adapters/postgres/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { type SqlLanguage, format as formatSql } from 'sql-formatter';\nimport { z } from 'zod';\n\nimport type { ContextFragment, FragmentObject } from '@deepagents/context';\n\nimport { SQLReadOnlyError, SQLScopeError } from '../agents/exceptions.ts';\nimport {\n column,\n constraint,\n dialectInfo,\n index,\n relationship,\n table,\n view,\n} from '../fragments/schema.ts';\nimport type { AbstractGrounding } from './groundings/abstract.grounding.ts';\nimport {\n type GroundingContext,\n createGroundingContext,\n} from './groundings/context.ts';\nimport type { View } from './groundings/view.grounding.ts';\nimport {\n type SqlPolicyAnalyzer,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\nexport {\n type SqlPolicyAnalyzer,\n type SqlPolicyContext,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\n/**\n * Filter type for view/table names.\n * - string[]: explicit list of view names\n * - RegExp: pattern to match view names\n * - function: predicate to filter view names\n */\nexport type Filter = string[] | RegExp | ((viewName: string) => boolean);\n\nexport interface Table {\n name: string;\n schema?: string;\n rawName?: string;\n columns: {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n isIndexed?: boolean;\n stats?: ColumnStats;\n }[];\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n indexes?: TableIndex[];\n constraints?: TableConstraint[];\n}\n\nexport interface TableIndex {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}\n\nexport interface TableConstraint {\n name: string;\n type:\n 'CHECK' | 'UNIQUE' | 'NOT_NULL' | 'DEFAULT' | 'PRIMARY_KEY' | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}\n\nexport interface ColumnStats {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n}\n\nexport type Relationship = {\n table: string;\n from: string[];\n referenced_table: string;\n to: string[];\n};\n\nexport type TablesFilter = string[] | RegExp;\n\nexport interface Introspection {\n tables: Table[];\n relationships: Relationship[];\n}\n\nexport interface AdapterInfo {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}\n\nexport type AdapterInfoProvider =\n AdapterInfo | (() => Promise<AdapterInfo> | AdapterInfo);\n\nexport type IntrospectionPhase =\n | 'info'\n | 'tables'\n | 'views'\n | 'row_counts'\n | 'constraints'\n | 'indexes'\n | 'column_stats'\n | 'column_values'\n | 'low_cardinality'\n | 'relationships'\n | 'definitions';\n\nexport type IntrospectionProgressType =\n 'phase:start' | 'phase:progress' | 'phase:end';\n\nexport interface IntrospectionProgress {\n type: IntrospectionProgressType;\n phase: IntrospectionPhase;\n message: string;\n table?: string;\n current?: number;\n total?: number;\n timestampMs?: number;\n}\n\nexport type OnProgress = (progress: IntrospectionProgress) => void;\n\nexport type GroundingFn = (adapter: Adapter) => AbstractGrounding;\n\n/**\n * Builds a grounding factory for a grounding that needs a concrete adapter's\n * API (BigQuery datasets, DuckDB namespaces, ...). Given any other adapter,\n * the factory throws.\n */\nexport function groundingFor<A extends Adapter>(\n adapterType: abstract new (...args: never[]) => A,\n create: (adapter: A) => AbstractGrounding,\n): GroundingFn {\n return (adapter) => {\n if (!(adapter instanceof adapterType)) {\n throw new Error(\n `A ${adapterType.name} grounding needs a ${adapterType.name} adapter, not ${adapter.constructor.name}.`,\n );\n }\n return create(adapter);\n };\n}\n\nexport type ExecuteFunction = (sql: string) => Promise<any> | any;\nexport type ValidateFunction = (\n sql: string,\n) => Promise<string | void> | string | void;\n\nexport abstract class Adapter {\n readonly #policyAnalyzer: SqlPolicyAnalyzer;\n\n /**\n * Injects the strategy that guards validate() and execute().\n */\n protected constructor(policyAnalyzer: SqlPolicyAnalyzer) {\n this.#policyAnalyzer = policyAnalyzer;\n }\n\n abstract grounding: GroundingFn[];\n\n abstract readonly formatterLanguage: SqlLanguage;\n\n /**\n * Default schema name for this database.\n * PostgreSQL: 'public', SQL Server: 'dbo', SQLite: undefined\n */\n abstract readonly defaultSchema: string | undefined;\n\n /**\n * System schemas to exclude from introspection by default.\n */\n abstract readonly systemSchemas: string[];\n\n /**\n * Introspect the database schema and return context fragments.\n *\n * Executes all configured groundings to populate the context, then\n * generates fragments from the complete context data.\n *\n * @param ctx - Optional grounding context for sharing state between groundings\n * @returns Array of context fragments representing the database schema\n */\n async introspect(ctx = createGroundingContext()): Promise<ContextFragment[]> {\n // Phase 1: All groundings populate ctx\n for (const fn of this.grounding) {\n const grounding = fn(this);\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:start',\n phase: grounding.phase,\n message: `Starting ${grounding.name} introspection...`,\n });\n }\n try {\n await grounding.execute(ctx);\n } finally {\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:end',\n phase: grounding.phase,\n message: `Finished ${grounding.name} introspection.`,\n });\n }\n }\n }\n\n // Phase 2: Generate fragments from complete ctx\n return this.#toSchemaFragments(ctx);\n }\n\n /**\n * Resolve the allowed entity names (tables + views) from grounding config.\n * Asks each grounding to contribute its entities; annotators contribute\n * nothing, so their metadata scans are skipped.\n * Results are NOT cached \u2014 call once and store the result.\n */\n async resolveAllowedEntities(): Promise<string[]> {\n const ctx = createGroundingContext();\n for (const fn of this.grounding) {\n await fn(this).contributeEntities(ctx);\n }\n return [...ctx.tables.map((t) => t.name), ...ctx.views.map((v) => v.name)];\n }\n\n /**\n * Convert complete grounding context to schema fragments.\n * Called after all groundings have populated ctx with data.\n */\n #toSchemaFragments(ctx: GroundingContext): ContextFragment[] {\n const fragments: ContextFragment[] = [];\n\n // Dialect info\n if (ctx.info) {\n fragments.push(\n dialectInfo({\n dialect: ctx.info.dialect,\n version: ctx.info.version,\n database: ctx.info.database,\n details: ctx.info.details,\n }),\n );\n }\n\n // Tables (with all annotations now included)\n for (const t of ctx.tables) {\n fragments.push(this.#tableToFragment(t));\n }\n\n // Views\n for (const v of ctx.views) {\n fragments.push(this.#viewToFragment(v));\n }\n\n // Relationships \u2014 filter out FK columns that were removed by column restriction\n const tableMap = new Map(ctx.tables.map((t) => [t.name, t]));\n const tableColumnSets = new Map(\n ctx.tables.map((t) => [t.name, new Set(t.columns.map((c) => c.name))]),\n );\n for (const rel of ctx.relationships) {\n const sourceColumns = tableColumnSets.get(rel.table);\n const targetColumns = tableColumnSets.get(rel.referenced_table);\n if (\n sourceColumns &&\n rel.from.some((column) => !sourceColumns.has(column))\n ) {\n continue;\n }\n if (\n targetColumns &&\n rel.to.some((column) => !targetColumns.has(column))\n ) {\n continue;\n }\n\n const sourceTable = tableMap.get(rel.table);\n const targetTable = tableMap.get(rel.referenced_table);\n fragments.push(\n this.#relationshipToFragment(rel, sourceTable, targetTable),\n );\n }\n\n fragments.push(...(ctx.fragments ?? []));\n\n return fragments;\n }\n\n /**\n * Convert a Table to a table fragment with nested column, index, and constraint fragments.\n */\n #tableToFragment(t: Table): ContextFragment {\n // Build constraint lookup maps for column-level annotations\n const pkConstraint = t.constraints?.find((c) => c.type === 'PRIMARY_KEY');\n const pkColumns = new Set(pkConstraint?.columns ?? []);\n\n const notNullColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'NOT_NULL')\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n const defaultByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'DEFAULT') ?? []) {\n for (const col of c.columns ?? []) {\n if (c.defaultValue != null) {\n defaultByColumn.set(col, c.defaultValue);\n }\n }\n }\n\n // Single-column UNIQUE constraints\n const uniqueColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'UNIQUE' && c.columns?.length === 1)\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n // Foreign key lookup: column -> referenced table.column\n const fkByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'FOREIGN_KEY') ??\n []) {\n const cols = c.columns ?? [];\n const refCols = c.referencedColumns ?? [];\n for (let i = 0; i < cols.length; i++) {\n const refCol = refCols[i] ?? refCols[0] ?? cols[i];\n fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);\n }\n }\n\n // Build column fragments\n const columnFragments = t.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n pk: pkColumns.has(col.name) || undefined,\n fk: fkByColumn.get(col.name),\n unique: uniqueColumns.has(col.name) || undefined,\n notNull: notNullColumns.has(col.name) || undefined,\n default: defaultByColumn.get(col.name),\n indexed: col.isIndexed || undefined,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n // Set of present column names for cascade-cleaning indexes/constraints\n const presentColumns = new Set(t.columns.map((c) => c.name));\n\n // Build index fragments\n const indexFragments = (t.indexes ?? [])\n .filter((idx) =>\n idx.columns.every((column) => presentColumns.has(column)),\n )\n .map((idx) =>\n index({\n name: idx.name,\n columns: idx.columns,\n unique: idx.unique,\n type: idx.type,\n }),\n );\n\n // Build constraint fragments for multi-column UNIQUE and CHECK constraints\n const constraintFragments = (t.constraints ?? [])\n .filter(\n (c) =>\n c.type === 'CHECK' ||\n (c.type === 'UNIQUE' && (c.columns?.length ?? 0) > 1),\n )\n .filter(\n (c) =>\n !c.columns?.length ||\n c.columns.every((column) => presentColumns.has(column)),\n )\n .map((c) =>\n constraint({\n name: c.name,\n type: c.type,\n columns: c.columns,\n definition: c.definition,\n }),\n );\n\n return table({\n name: t.name,\n schema: t.schema,\n rowCount: t.rowCount,\n sizeHint: t.sizeHint,\n columns: columnFragments,\n indexes: indexFragments.length > 0 ? indexFragments : undefined,\n constraints:\n constraintFragments.length > 0 ? constraintFragments : undefined,\n });\n }\n\n /**\n * Convert a View to a view fragment with nested column fragments.\n */\n #viewToFragment(v: View): ContextFragment {\n const columnFragments = v.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n return view({\n name: v.name,\n schema: v.schema,\n columns: columnFragments,\n definition: v.definition,\n });\n }\n\n /**\n * Convert a Relationship to a relationship fragment.\n * Infers cardinality from row counts if available.\n */\n #relationshipToFragment(\n rel: Relationship,\n sourceTable?: Table,\n targetTable?: Table,\n ): ContextFragment {\n const sourceCount = sourceTable?.rowCount;\n const targetCount = targetTable?.rowCount;\n\n let cardinality:\n 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many' | undefined;\n\n if (sourceCount != null && targetCount != null && targetCount > 0) {\n const ratio = sourceCount / targetCount;\n if (ratio > 5) {\n cardinality = 'many-to-one';\n } else if (ratio < 1.2 && ratio > 0.8) {\n cardinality = 'one-to-one';\n } else if (ratio < 0.2) {\n cardinality = 'one-to-many';\n }\n }\n\n return relationship({\n from: { table: rel.table, columns: rel.from },\n to: { table: rel.referenced_table, columns: rel.to },\n cardinality,\n });\n }\n format(sql: string): string {\n const decoded = this.#decodeShellEscapes(sql);\n try {\n return formatSql(decoded, { language: this.formatterLanguage });\n } catch {\n return decoded;\n }\n }\n\n #decodeShellEscapes(sql: string): string {\n return sql\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\([().*$])/g, '$1')\n .replace(/\\\\(?=$)/gm, '');\n }\n\n #cachedAllowedEntities: string[] | null = null;\n\n async #resolveScope(): Promise<string[]> {\n if (this.#cachedAllowedEntities) return this.#cachedAllowedEntities;\n this.#cachedAllowedEntities = await this.resolveAllowedEntities();\n return this.#cachedAllowedEntities;\n }\n\n async #analyzePolicy(sql: string): Promise<SqlPolicyViolation | null> {\n return this.#policyAnalyzer.analyze(sql, {\n resolveAllowedEntities: () => this.#resolveScope(),\n });\n }\n\n async validate(sql: string): Promise<string | void> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') return violation.message;\n if (violation?.kind === 'scope') return JSON.stringify(violation.payload);\n return this.validateImpl(decoded);\n }\n\n async execute(sql: string): Promise<any[]> {\n return this.executeImpl(await this.enforceExecutionPolicy(sql));\n }\n\n protected async enforceExecutionPolicy(sql: string): Promise<string> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') {\n throw new SQLReadOnlyError(violation.message);\n }\n if (violation?.kind === 'scope') {\n throw new SQLScopeError(violation.payload);\n }\n return decoded;\n }\n\n abstract executeImpl(sql: string): Promise<any[]> | any[];\n abstract validateImpl(sql: string): Promise<string | void> | string | void;\n\n /**\n * Run an introspection query and check every row against `row`, the shape\n * the driver returns for that query. A row of any other shape throws.\n */\n async runQuery<RowSchema extends z.ZodType>(\n sql: string,\n row: RowSchema,\n ): Promise<z.output<RowSchema>[]> {\n const rows = z.array(row).safeParse(await this.queryRows(sql));\n if (!rows.success) {\n throw new Error(\n `${this.constructor.name} introspection query returned rows of an unexpected shape:\\n${z.prettifyError(rows.error)}\\nSQL: ${sql.trim()}`,\n { cause: rows.error },\n );\n }\n return rows.data;\n }\n\n /**\n * Run an introspection query through the driver and return its rows as the\n * driver produced them.\n */\n protected abstract queryRows(sql: string): Promise<unknown[]> | unknown[];\n\n /**\n * The rows in a driver's execute() result: the result itself when it is an\n * array, otherwise the first array found at one of `paths` (dot-separated,\n * so `recordsets.0` reads `result.recordsets[0]`).\n */\n protected rowsFrom(result: unknown, paths: readonly string[]): unknown[] {\n if (Array.isArray(result)) return result;\n for (const path of paths) {\n const rows = path\n .split('.')\n .reduce<unknown>(\n (value, key) =>\n typeof value === 'object' && value !== null\n ? Reflect.get(value, key)\n : undefined,\n result,\n );\n if (Array.isArray(rows)) return rows;\n }\n throw new Error(\n `${this.constructor.name} execute() must return an array of rows or an object holding one at ${paths.map((path) => `result.${path}`).join(', ')}.`,\n );\n }\n\n /**\n * Quote an identifier (table/column name) for safe use in SQL.\n * Each database uses different quoting styles.\n */\n abstract quoteIdentifier(name: string): string;\n\n /**\n * Escape a string value for safe use in SQL.\n * Each database escapes different characters.\n */\n abstract escape(value: string): string;\n\n /**\n * Build a SELECT query to sample rows from a table.\n * Each database uses different syntax for limiting rows (LIMIT vs TOP).\n */\n abstract buildSampleRowsQuery(\n tableName: string,\n columns: string[] | undefined,\n limit: number,\n ): string;\n\n /**\n * Convert unknown database value to number.\n * Handles number, bigint, and string types.\n */\n toNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'bigint') {\n return Number(value);\n }\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n }\n\n /**\n * Parse a potentially qualified table name into schema and table parts.\n */\n parseTableName(name: string): { schema: string; table: string } {\n if (name.includes('.')) {\n const [schema, ...rest] = name.split('.');\n return { schema, table: rest.join('.') };\n }\n return { schema: this.defaultSchema ?? '', table: name };\n }\n\n /**\n * Escape a string value for use in SQL string literals (single quotes).\n * Used in WHERE clauses like: WHERE name = '${escapeString(value)}'\n */\n escapeString(value: string): string {\n return value.replace(/'/g, \"''\");\n }\n\n /**\n * Build a SQL filter clause to include/exclude schemas.\n * @param columnName - The schema column name (e.g., 'TABLE_SCHEMA')\n * @param allowedSchemas - If provided, filter to these schemas only\n */\n buildSchemaFilter(columnName: string, allowedSchemas?: string[]): string {\n if (allowedSchemas && allowedSchemas.length > 0) {\n const values = allowedSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} IN (${values})`;\n }\n if (this.systemSchemas.length > 0) {\n const values = this.systemSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} NOT IN (${values})`;\n }\n return '';\n }\n}\n\nexport function filterTablesByName<T extends { name: string }>(\n tables: T[],\n filter: TablesFilter | undefined,\n): T[] {\n if (!filter) return tables;\n return tables.filter((table) => matchesFilter(table.name, filter));\n}\n\nexport function filterRelationshipsByTables(\n relationships: Relationship[],\n tableNames: Set<string> | undefined,\n): Relationship[] {\n if (tableNames === undefined) {\n return relationships;\n }\n if (tableNames.size === 0) {\n return [];\n }\n return relationships.filter(\n (it) => tableNames.has(it.table) || tableNames.has(it.referenced_table),\n );\n}\n\nexport function applyTablesFilter(\n tables: Table[],\n relationships: Relationship[],\n filter: TablesFilter | undefined,\n): { tables: Table[]; relationships: Relationship[] } {\n if (!filter) {\n return { tables, relationships };\n }\n\n const allowedNames = new Set(\n getTablesWithRelated(tables, relationships, filter),\n );\n\n return {\n tables: tables.filter((table) => allowedNames.has(table.name)),\n relationships: filterRelationshipsByTables(relationships, allowedNames),\n };\n}\n\nexport function matchesFilter(\n tableName: string,\n filter: TablesFilter,\n): boolean {\n if (Array.isArray(filter)) {\n return filter.includes(tableName);\n }\n return filter.test(tableName);\n}\n\nexport function getTablesWithRelated(\n allTables: Table[],\n relationships: Relationship[],\n filter: TablesFilter,\n): string[] {\n const matchedTables = filterTablesByName(allTables, filter).map(\n (it) => it.name,\n );\n\n if (matchedTables.length === 0) {\n return [];\n }\n\n const adjacency = new Map<string, Set<string>>();\n\n for (const rel of relationships) {\n if (!adjacency.has(rel.table)) {\n adjacency.set(rel.table, new Set());\n }\n if (!adjacency.has(rel.referenced_table)) {\n adjacency.set(rel.referenced_table, new Set());\n }\n adjacency.get(rel.table)!.add(rel.referenced_table);\n adjacency.get(rel.referenced_table)!.add(rel.table);\n }\n\n const result = new Set<string>(matchedTables);\n const queue = [...matchedTables];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const neighbors = adjacency.get(current);\n\n if (!neighbors) {\n continue;\n }\n\n for (const neighbor of neighbors) {\n if (!result.has(neighbor)) {\n result.add(neighbor);\n queue.push(neighbor);\n }\n }\n }\n\n return Array.from(result);\n}\n", "const sqlValidationMarker = Symbol('SQLValidationError');\nconst unanswerableSqlMarker = Symbol('UnanswerableSQLError');\nconst sqlScopeMarker = Symbol('SQLScopeError');\nconst sqlReadOnlyMarker = Symbol('SQLReadOnlyError');\n\nexport type SQLScopeErrorType = 'OUT_OF_SCOPE' | 'SQL_SCOPE_PARSE_ERROR';\n\nexport interface SQLScopeErrorPayload {\n error: string;\n error_type: SQLScopeErrorType;\n suggestion: string;\n sql_attempted: string;\n referenced_entities?: string[];\n allowed_entities?: string[];\n parser_dialect?: string;\n parser_error?: string;\n}\n\n/**\n * Error thrown when SQL validation fails.\n */\nexport class SQLValidationError extends Error {\n [sqlValidationMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLValidationError';\n this[sqlValidationMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLValidationError {\n return (\n error instanceof SQLValidationError && error[sqlValidationMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when the question cannot be answered with the given schema.\n */\nexport class UnanswerableSQLError extends Error {\n [unanswerableSqlMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'UnanswerableSQLError';\n this[unanswerableSqlMarker] = true;\n }\n\n static isInstance(error: unknown): error is UnanswerableSQLError {\n return (\n error instanceof UnanswerableSQLError &&\n error[unanswerableSqlMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when a query falls outside the grounded SQL scope.\n */\nexport class SQLScopeError extends Error {\n [sqlScopeMarker]: true;\n readonly payload: SQLScopeErrorPayload;\n readonly errorType: SQLScopeErrorType;\n\n constructor(payload: SQLScopeErrorPayload) {\n super(JSON.stringify(payload));\n this.name = 'SQLScopeError';\n this.payload = payload;\n this.errorType = payload.error_type;\n this[sqlScopeMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLScopeError {\n return error instanceof SQLScopeError && error[sqlScopeMarker] === true;\n }\n}\n\n/**\n * Error thrown when a query is not read-only (does not start with SELECT or WITH).\n */\nexport class SQLReadOnlyError extends Error {\n [sqlReadOnlyMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLReadOnlyError';\n this[sqlReadOnlyMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLReadOnlyError {\n return (\n error instanceof SQLReadOnlyError && error[sqlReadOnlyMarker] === true\n );\n }\n}\n", "import type { ContextFragment, FragmentObject } from '@deepagents/context';\n\n/**\n * Schema fragment builders.\n *\n * These fragments represent database schema metadata that can be injected\n * into AI prompts. Use with renderers (XML, Markdown, TOML, TOON) to format.\n *\n * @example\n * ```ts\n * import { dialectInfo, table, column, relationship } from '@deepagents/text2sql';\n *\n * const schemaFragments = [\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5' }),\n * table({\n * name: 'users',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true }),\n * ],\n * }),\n * ];\n * ```\n */\n\n/**\n * Database dialect and version information.\n *\n * @param input.dialect - Database type (PostgreSQL, SQLite, SQL Server, etc.)\n * @param input.version - Database version string\n * @param input.database - Database name\n *\n * @example\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5', database: 'myapp' })\n */\nexport function dialectInfo(input: {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}): ContextFragment {\n return {\n name: 'dialectInfo',\n data: {\n dialect: input.dialect,\n ...(input.version && { version: input.version }),\n ...(input.database && { database: input.database }),\n ...(input.details && { details: input.details }),\n },\n };\n}\n\n/**\n * Database table with columns and optional metadata.\n *\n * @param input.name - Table name\n * @param input.schema - Schema name (e.g., 'public' for PostgreSQL)\n * @param input.rowCount - Approximate row count\n * @param input.sizeHint - Size category for query optimization hints\n * @param input.columns - Array of column() fragments\n * @param input.indexes - Array of index() fragments\n * @param input.constraints - Array of constraint() fragments\n *\n * @example\n * table({\n * name: 'users',\n * rowCount: 1500,\n * sizeHint: 'medium',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true, indexed: true }),\n * ],\n * indexes: [\n * index({ name: 'idx_email', columns: ['email'], unique: true }),\n * ],\n * })\n */\nexport function table(input: {\n name: string;\n schema?: string;\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n columns: ContextFragment[];\n indexes?: ContextFragment[];\n constraints?: ContextFragment[];\n}): ContextFragment {\n return {\n name: 'table',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n ...(input.rowCount != null && { rowCount: input.rowCount }),\n ...(input.sizeHint && { sizeHint: input.sizeHint }),\n columns: input.columns,\n ...(input.indexes?.length && { indexes: input.indexes }),\n ...(input.constraints?.length && { constraints: input.constraints }),\n },\n };\n}\n\n/**\n * Table column with type and annotations.\n *\n * @param input.name - Column name\n * @param input.type - Column data type (e.g., 'integer', 'varchar(255)')\n * @param input.pk - Is primary key\n * @param input.fk - Foreign key reference in \"table.column\" format\n * @param input.unique - Has unique constraint\n * @param input.notNull - Has NOT NULL constraint\n * @param input.default - Default value expression\n * @param input.indexed - Has index on this column\n * @param input.values - Enum or low cardinality values\n * @param input.stats - Column statistics (min, max, null fraction)\n *\n * @example\n * column({\n * name: 'status',\n * type: 'varchar',\n * notNull: true,\n * indexed: true,\n * values: ['active', 'inactive', 'suspended'],\n * })\n */\nexport function column(input: {\n name: string;\n type: string;\n pk?: boolean;\n fk?: string;\n unique?: boolean;\n notNull?: boolean;\n default?: string;\n indexed?: boolean;\n values?: string[];\n stats?: {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n };\n}): ContextFragment {\n return {\n name: 'column',\n data: {\n name: input.name,\n type: input.type,\n ...(input.pk && { pk: true }),\n ...(input.fk && { fk: input.fk }),\n ...(input.unique && { unique: true }),\n ...(input.notNull && { notNull: true }),\n ...(input.default && { default: input.default }),\n ...(input.indexed && { indexed: true }),\n ...(input.values?.length && { values: input.values }),\n ...(input.stats && { stats: input.stats }),\n },\n };\n}\n\n/**\n * Table index.\n *\n * @param input.name - Index name\n * @param input.columns - Columns included in the index\n * @param input.unique - Is unique index\n * @param input.type - Index type (BTREE, HASH, GIN, etc.)\n *\n * @example\n * index({ name: 'idx_user_email', columns: ['email'], unique: true, type: 'BTREE' })\n */\nexport function index(input: {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}): ContextFragment {\n return {\n name: 'index',\n data: {\n name: input.name,\n columns: input.columns,\n ...(input.unique && { unique: true }),\n ...(input.type && { type: input.type }),\n },\n };\n}\n\n/**\n * Table constraint (CHECK, UNIQUE, PRIMARY_KEY, FOREIGN_KEY, etc).\n *\n * @param input.name - Constraint name\n * @param input.type - Constraint type\n * @param input.columns - Columns involved in the constraint\n * @param input.definition - CHECK constraint SQL definition\n * @param input.defaultValue - DEFAULT constraint value\n * @param input.referencedTable - For FK: referenced table name\n * @param input.referencedColumns - For FK: referenced column names\n *\n * @example\n * constraint({\n * name: 'chk_amount_positive',\n * type: 'CHECK',\n * definition: 'amount > 0',\n * })\n *\n * @example\n * constraint({\n * name: 'fk_order_user',\n * type: 'FOREIGN_KEY',\n * columns: ['user_id'],\n * referencedTable: 'users',\n * referencedColumns: ['id'],\n * })\n */\nexport function constraint(input: {\n name: string;\n type:\n | 'CHECK'\n | 'UNIQUE'\n | 'NOT_NULL'\n | 'DEFAULT'\n | 'PRIMARY_KEY'\n | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}): ContextFragment {\n return {\n name: 'constraint',\n data: {\n name: input.name,\n type: input.type,\n ...(input.columns?.length && { columns: input.columns }),\n ...(input.definition && { definition: input.definition }),\n ...(input.defaultValue && { defaultValue: input.defaultValue }),\n ...(input.referencedTable && { referencedTable: input.referencedTable }),\n ...(input.referencedColumns?.length && {\n referencedColumns: input.referencedColumns,\n }),\n },\n };\n}\n\n/**\n * Database view.\n *\n * @param input.name - View name\n * @param input.schema - Schema name\n * @param input.columns - Array of column() fragments\n * @param input.definition - View SQL definition\n *\n * @example\n * view({\n * name: 'active_users',\n * columns: [\n * column({ name: 'id', type: 'integer' }),\n * column({ name: 'email', type: 'varchar' }),\n * ],\n * definition: \"SELECT id, email FROM users WHERE status = 'active'\",\n * })\n */\nexport function view(input: {\n name: string;\n schema?: string;\n columns: ContextFragment[];\n definition?: string;\n}): ContextFragment {\n return {\n name: 'view',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n columns: input.columns,\n ...(input.definition && { definition: input.definition }),\n },\n };\n}\n\n/**\n * Relationship between tables (foreign key connection).\n *\n * @param input.from - Source table and columns\n * @param input.to - Referenced table and columns\n * @param input.cardinality - Relationship cardinality\n *\n * @example\n * relationship({\n * from: { table: 'orders', columns: ['user_id'] },\n * to: { table: 'users', columns: ['id'] },\n * cardinality: 'many-to-one',\n * })\n */\nexport function relationship(input: {\n from: { table: string; columns: string[] };\n to: { table: string; columns: string[] };\n cardinality?: 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';\n}): ContextFragment {\n return {\n name: 'relationship',\n data: {\n from: input.from,\n to: input.to,\n ...(input.cardinality && { cardinality: input.cardinality }),\n },\n };\n}\n", "import type { ContextFragment } from '@deepagents/context';\n\nimport type {\n AdapterInfo,\n ColumnStats,\n OnProgress,\n Relationship,\n Table,\n} from '../adapter.ts';\nimport type { View } from './view.grounding.ts';\n\n/**\n * Column type for grounding operations.\n * Common interface between Table.columns and View.columns.\n */\nexport interface Column {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n stats?: ColumnStats;\n}\n\n/**\n * Entity with columns (Table or View).\n */\nexport interface ColumnContainer {\n name: string;\n columns: Column[];\n}\n\n/**\n * Shared context object passed to all groundings.\n * Groundings read from and write to this context.\n */\nexport interface GroundingContext {\n /** Tables discovered by TableGrounding */\n tables: Table[];\n\n /** Views discovered by ViewGrounding */\n views: View[];\n\n /** Relationships discovered by TableGrounding */\n relationships: Relationship[];\n\n /** Database info collected by InfoGrounding */\n info?: AdapterInfo;\n\n /** Adapter-specific fragments contributed during grounding. */\n fragments?: ContextFragment[];\n\n /** Shared cache for cross-grounding deduplication. Keyed by `type:key`. */\n cache: Map<string, unknown>;\n\n /** Progress sink for long-running introspection work. */\n onProgress: OnProgress;\n}\n\nconst noopProgress: OnProgress = () => {};\n\nfunction timestampProgress(onProgress?: OnProgress): OnProgress {\n if (!onProgress) return noopProgress;\n return (progress) => {\n onProgress({\n ...progress,\n timestampMs: progress.timestampMs ?? Date.now(),\n });\n };\n}\n\n/**\n * Create a new empty grounding context.\n */\nexport function createGroundingContext(\n options: { onProgress?: OnProgress } = {},\n): GroundingContext {\n return {\n tables: [],\n views: [],\n relationships: [],\n info: undefined,\n fragments: [],\n cache: new Map(),\n onProgress: timestampProgress(options.onProgress),\n };\n}\n", "import type { Filter, IntrospectionPhase } from '../adapter.ts';\nimport type { GroundingContext } from './context.ts';\n\nexport type { AdapterInfo, AdapterInfoProvider, Filter } from '../adapter.ts';\n\n/**\n * Per-entity column filter.\n * Maps entity name (table or view) to a Filter that selects which columns to keep.\n * Entities not listed in the record keep all their columns.\n */\nexport type ColumnsFilter = Record<string, Filter>;\n\n/**\n * Filter a columns array using a Filter.\n * Keeps columns whose name matches the filter.\n */\nexport function filterColumns<T extends { name: string }>(\n columns: T[],\n filter: Filter,\n): T[] {\n if (Array.isArray(filter)) {\n return columns.filter((col) => filter.includes(col.name));\n }\n if (filter instanceof RegExp) {\n return columns.filter((col) => filter.test(col.name));\n }\n return columns.filter((col) => filter(col.name));\n}\n\n/**\n * Apply per-entity column filtering.\n * Returns the entity unchanged if no filter matches its name.\n */\nexport function applyColumnFilter<\n T extends { name: string; columns: { name: string }[] },\n>(entity: T, columnsConfig?: ColumnsFilter): T {\n if (!columnsConfig) return entity;\n const filter = columnsConfig[entity.name];\n if (!filter) return entity;\n return { ...entity, columns: filterColumns(entity.columns, filter) };\n}\n\n/**\n * Abstract base class for database schema groundings.\n *\n * Groundings collect schema metadata into the shared GroundingContext.\n * Fragment generation is centralized in Adapter.introspect().\n */\nexport abstract class AbstractGrounding {\n /**\n * Grounding identifier for debugging/logging.\n */\n name: string;\n phase?: IntrospectionPhase;\n\n constructor(name: string, phase?: IntrospectionPhase) {\n this.name = name;\n this.phase = phase;\n }\n\n /**\n * Execute grounding to populate the shared context.\n * Groundings mutate ctx to add their collected data (tables, views, indexes, etc).\n * Fragment generation happens centrally in Adapter after all groundings complete.\n *\n * @param ctx - Shared context for accumulating schema data\n */\n abstract execute(ctx: GroundingContext): Promise<void>;\n\n /**\n * Populate ctx with the tables/views this grounding makes available for scope\n * resolution. Annotators decorate entities other groundings produced and add\n * no membership, so the default is a no-op; entity-producing groundings\n * override it. This lets scope resolution skip the annotators' metadata scans.\n *\n * @param _ctx - Shared context for accumulating entity membership\n */\n async contributeEntities(_ctx: GroundingContext): Promise<void> {}\n}\n", "import type { ColumnStats } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { Column, ColumnContainer, GroundingContext } from './context.ts';\n\n/**\n * Configuration for ColumnStatsGrounding.\n */\nexport interface ColumnStatsGroundingConfig {\n // Future: filter which tables/columns to collect stats for\n}\n\n/**\n * Abstract base class for column statistics grounding.\n *\n * Reads tables and views from the context and annotates their columns\n * with statistics (min, max, nullFraction).\n *\n * Subclasses implement database-specific hooks:\n * - `collectStats()` - collect min/max/nullFraction for a column\n */\nexport abstract class ColumnStatsGrounding extends AbstractGrounding {\n constructor(config: ColumnStatsGroundingConfig = {}) {\n super('columnStats', 'column_stats');\n }\n\n /**\n * Collect min/max/nullFraction statistics for a column.\n * Return undefined to skip this column.\n */\n protected abstract collectStats(\n tableName: string,\n column: Column,\n ): Promise<ColumnStats | undefined>;\n\n /**\n * Execute the grounding process.\n * Annotates columns in ctx.tables and ctx.views with statistics.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n // Process both tables and views\n const allContainers: ColumnContainer[] = [...ctx.tables, ...ctx.views];\n const total = allContainers.length;\n for (let i = 0; i < allContainers.length; i++) {\n const container = allContainers[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'column_stats',\n table: container.name,\n message: `Collecting stats for ${container.name}...`,\n current: i + 1,\n total,\n });\n for (const column of container.columns) {\n // Collect min/max/nullFraction\n try {\n const stats = await this.collectStats(container.name, column);\n if (stats) {\n column.stats = stats;\n }\n } catch (error) {\n // Skip on error\n console.warn(\n 'Error collecting stats for',\n container.name,\n column.name,\n error,\n );\n }\n }\n }\n }\n}\n", "import type { Table, TableConstraint } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { Column, ColumnContainer, GroundingContext } from './context.ts';\n\nexport type { Column, ColumnContainer };\n\n/**\n * Result of column value detection.\n */\nexport type ColumnValuesResult = {\n kind: 'Enum' | 'LowCardinality';\n values: string[];\n};\n\n/**\n * Configuration for ColumnValuesGrounding.\n */\nexport interface ColumnValuesGroundingConfig {\n /** Maximum number of distinct values to consider low cardinality (default: 20) */\n lowCardinalityLimit?: number;\n /** Maximum character length for individual values. Columns with any value exceeding this are skipped entirely (default: 100) */\n maxValueLength?: number;\n}\n\n/**\n * Abstract base class for column values grounding.\n *\n * Discovers possible values for columns from three sources (in priority order):\n * 1. Native ENUM types (PostgreSQL, MySQL) \u2192 kind: 'Enum'\n * 2. CHECK constraints with IN clauses \u2192 kind: 'Enum'\n * 3. Low cardinality data scan \u2192 kind: 'LowCardinality'\n *\n * Subclasses implement database-specific hooks:\n * - `collectEnumValues()` - get values for native ENUM columns\n * - `collectLowCardinality()` - collect distinct values via data scan\n */\nexport abstract class ColumnValuesGrounding extends AbstractGrounding {\n protected lowCardinalityLimit: number;\n protected maxValueLength: number;\n\n constructor(config: ColumnValuesGroundingConfig = {}) {\n super('columnValues', 'column_values');\n this.lowCardinalityLimit = config.lowCardinalityLimit ?? 20;\n this.maxValueLength = config.maxValueLength ?? 100;\n }\n\n /**\n * Get values for native ENUM type columns.\n * Return undefined if column is not an ENUM type.\n * Default implementation returns undefined (no native ENUM support).\n */\n protected async collectEnumValues(\n _tableName: string,\n _column: Column,\n ): Promise<string[] | undefined> {\n return undefined;\n }\n\n /**\n * Collect distinct values for low cardinality columns via data scan.\n * Return undefined if column has too many distinct values.\n */\n protected abstract collectLowCardinality(\n tableName: string,\n column: Column,\n ): Promise<string[] | undefined>;\n\n /**\n * Parse CHECK constraint for enum-like IN clause.\n * Extracts values from patterns like:\n * - CHECK (status IN ('active', 'inactive'))\n * - CHECK ((status)::text = ANY (ARRAY['a'::text, 'b'::text]))\n * - CHECK (status = 'active' OR status = 'inactive')\n */\n protected parseCheckConstraint(\n constraint: TableConstraint,\n columnName: string,\n ): string[] | undefined {\n if (constraint.type !== 'CHECK' || !constraint.definition) {\n return undefined;\n }\n\n // Check if constraint applies to this column\n if (constraint.columns && !constraint.columns.includes(columnName)) {\n return undefined;\n }\n\n const def = constraint.definition;\n const escapedCol = this.escapeRegex(columnName);\n\n // Column pattern: matches column name with optional parens and type cast\n // e.g., \"status\", \"(status)\", \"((status)::text)\"\n const colPattern = `(?:\\\\(?\\\\(?${escapedCol}\\\\)?(?:::(?:text|varchar|character varying))?\\\\)?)`;\n\n // Pattern 1: column IN ('val1', 'val2', ...)\n const inMatch = def.match(\n new RegExp(`${colPattern}\\\\s+IN\\\\s*\\\\(([^)]+)\\\\)`, 'i'),\n );\n if (inMatch) {\n return this.extractStringValues(inMatch[1]);\n }\n\n // Pattern 2: PostgreSQL ANY(ARRAY[...])\n const anyMatch = def.match(\n new RegExp(\n `${colPattern}\\\\s*=\\\\s*ANY\\\\s*\\\\(\\\\s*(?:ARRAY)?\\\\s*\\\\[([^\\\\]]+)\\\\]`,\n 'i',\n ),\n );\n if (anyMatch) {\n return this.extractStringValues(anyMatch[1]);\n }\n\n // Pattern 3: column = 'val1' OR column = 'val2' ...\n const orPattern = new RegExp(\n `\\\\b${this.escapeRegex(columnName)}\\\\b\\\\s*=\\\\s*'([^']*)'`,\n 'gi',\n );\n const orMatches = [...def.matchAll(orPattern)];\n if (orMatches.length >= 2) {\n return orMatches.map((m) => m[1]);\n }\n\n return undefined;\n }\n\n /**\n * Extract string values from a comma-separated list.\n */\n private extractStringValues(input: string): string[] | undefined {\n const values: string[] = [];\n // Match quoted strings: 'value' or 'value'::type\n const matches = input.matchAll(/'([^']*)'/g);\n for (const match of matches) {\n values.push(match[1]);\n }\n return values.length > 0 ? values : undefined;\n }\n\n /**\n * Escape special regex characters in a string.\n */\n private escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n\n /**\n * Get the table from context by name.\n */\n private getTable(ctx: GroundingContext, name: string): Table | undefined {\n return ctx.tables.find((t) => t.name === name);\n }\n\n /**\n * Execute the grounding process.\n * Annotates columns in ctx.tables and ctx.views with values.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n // Process both tables and views\n const allContainers: ColumnContainer[] = [...ctx.tables, ...ctx.views];\n\n const total = allContainers.length;\n for (let i = 0; i < allContainers.length; i++) {\n const container = allContainers[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'column_values',\n table: container.name,\n message: `Collecting column values for ${container.name}...`,\n current: i + 1,\n total,\n });\n const table = this.getTable(ctx, container.name);\n\n for (const column of container.columns) {\n try {\n const result = await this.resolveColumnValues(\n container.name,\n column,\n table?.constraints,\n );\n if (result) {\n column.kind = result.kind;\n column.values = result.values;\n }\n } catch (error) {\n console.warn(\n 'Error collecting column values for',\n container.name,\n column.name,\n error,\n );\n }\n }\n }\n }\n\n private exceedsMaxValueLength(values: string[]): boolean {\n return values.some((v) => v.length > this.maxValueLength);\n }\n\n /**\n * Resolve column values from all sources in priority order.\n */\n private async resolveColumnValues(\n tableName: string,\n column: Column,\n constraints?: TableConstraint[],\n ): Promise<ColumnValuesResult | undefined> {\n // Priority 1: Native ENUM type\n const enumValues = await this.collectEnumValues(tableName, column);\n if (enumValues?.length && !this.exceedsMaxValueLength(enumValues)) {\n return { kind: 'Enum', values: enumValues };\n }\n\n // Priority 2: CHECK constraint with IN clause\n if (constraints) {\n for (const constraint of constraints) {\n const checkValues = this.parseCheckConstraint(constraint, column.name);\n if (checkValues?.length && !this.exceedsMaxValueLength(checkValues)) {\n return { kind: 'Enum', values: checkValues };\n }\n }\n }\n\n // Priority 3: Low cardinality data scan\n const lowCardValues = await this.collectLowCardinality(tableName, column);\n if (lowCardValues?.length && !this.exceedsMaxValueLength(lowCardValues)) {\n return { kind: 'LowCardinality', values: lowCardValues };\n }\n\n return undefined;\n }\n}\n", "import type { TableConstraint } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for ConstraintGrounding.\n */\nexport interface ConstraintGroundingConfig {\n // Future: filter which tables/constraint types to collect\n}\n\n/**\n * Abstract base class for constraint grounding.\n *\n * Reads tables from the context and annotates them with constraints\n * (CHECK, UNIQUE, NOT_NULL, DEFAULT).\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getConstraints()` - fetch constraints for a table\n */\nexport abstract class ConstraintGrounding extends AbstractGrounding {\n constructor(config: ConstraintGroundingConfig = {}) {\n super('constraint', 'constraints');\n }\n\n /**\n * Fetch constraints for a specific table.\n */\n protected abstract getConstraints(\n tableName: string,\n ): Promise<TableConstraint[]>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with their constraints.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'constraints',\n table: table.name,\n message: `Loading constraints for ${table.name}...`,\n current: i + 1,\n total,\n });\n try {\n table.constraints = await this.getConstraints(table.name);\n } catch (error) {\n // Skip on error - table might not exist or be inaccessible\n console.warn('Error collecting constraints for', table.name, error);\n }\n }\n }\n}\n", "import type { TableIndex } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for IndexesGrounding.\n */\nexport interface IndexesGroundingConfig {\n // Future: filter which tables to collect indexes for\n}\n\n/**\n * Abstract base class for indexes grounding.\n *\n * Reads tables from the context and annotates them with index metadata.\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getIndexes()` - fetch indexes for a table\n */\nexport abstract class IndexesGrounding extends AbstractGrounding {\n constructor(config: IndexesGroundingConfig = {}) {\n super('index', 'indexes');\n }\n\n /**\n * Fetch indexes for a specific table.\n */\n protected abstract getIndexes(tableName: string): Promise<TableIndex[]>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with their indexes and marks indexed columns.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'indexes',\n table: table.name,\n message: `Loading indexes for ${table.name}...`,\n current: i + 1,\n total,\n });\n table.indexes = await this.getIndexes(table.name);\n // Mark columns that are part of indexes\n for (const index of table.indexes ?? []) {\n for (const colName of index.columns) {\n const column = table.columns.find((c) => c.name === colName);\n if (column) {\n column.isIndexed = true;\n }\n }\n }\n }\n }\n}\n", "import type { AdapterInfo } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for InfoGrounding.\n */\nexport interface InfoGroundingConfig {\n // Future: options to control what info to collect\n}\n\n/**\n * Abstract base class for database info grounding.\n *\n * Collects database dialect, version, and connection info.\n *\n * Subclasses implement the database-specific hook:\n * - `collectInfo()` - collect database info\n */\nexport abstract class InfoGrounding extends AbstractGrounding {\n constructor(config: InfoGroundingConfig = {}) {\n super('dialectInfo', 'info');\n }\n\n /**\n * Collect database dialect, version, and other info.\n */\n protected abstract collectInfo(): Promise<AdapterInfo>;\n\n /**\n * Execute the grounding process.\n * Writes database info to ctx.info.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n ctx.info = await this.collectInfo();\n }\n}\n", "import type { Table } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for RowCountGrounding.\n */\nexport interface RowCountGroundingConfig {\n // Future: filter which tables to count\n}\n\n/**\n * Abstract base class for row count grounding.\n *\n * Reads tables from the context and annotates them with row counts and size hints.\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getRowCount()` - get row count for a table\n */\nexport abstract class RowCountGrounding extends AbstractGrounding {\n constructor(config: RowCountGroundingConfig = {}) {\n super('rowCount', 'row_counts');\n }\n\n /**\n * Get row count for a specific table.\n */\n protected abstract getRowCount(\n tableName: string,\n ): Promise<number | undefined>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with row counts and size hints.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'row_counts',\n table: table.name,\n message: `Counting rows in ${table.name}...`,\n current: i + 1,\n total,\n });\n const count = await this.getRowCount(table.name);\n if (count != null) {\n table.rowCount = count;\n table.sizeHint = this.#classifyRowCount(count);\n }\n }\n }\n\n /**\n * Classify row count into a size hint category.\n */\n #classifyRowCount(count: number): Table['sizeHint'] {\n if (count < 100) return 'tiny';\n if (count < 1000) return 'small';\n if (count < 10000) return 'medium';\n if (count < 100000) return 'large';\n return 'huge';\n }\n}\n", "import type { Filter, Relationship, Table } from '../adapter.ts';\nimport {\n AbstractGrounding,\n type ColumnsFilter,\n applyColumnFilter,\n filterColumns,\n} from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for TableGrounding.\n */\nexport interface TableGroundingConfig {\n /** Filter to select seed tables */\n filter?: Filter;\n /**\n * Per-table column filter.\n * Maps table name to a Filter that selects which columns to keep.\n * Tables not listed keep all their columns.\n */\n columns?: ColumnsFilter;\n /**\n * Traverse forward (child\u2192parent) following FK direction.\n * - true: unlimited depth\n * - number: maximum depth\n * - false/undefined: no forward traversal\n */\n forward?: boolean | number;\n /**\n * Traverse backward (parent\u2192child) finding tables that reference us.\n * - true: unlimited depth\n * - number: maximum depth\n * - false/undefined: no backward traversal\n */\n backward?: boolean | number;\n}\n\n/**\n * Abstract base class for table grounding.\n *\n * The `execute()` method implements a BFS traversal algorithm that discovers\n * tables and relationships. Subclasses implement the database-specific hooks:\n * - `getAllTableNames()` - list all tables\n * - `getTable()` - get table metadata\n * - `findOutgoingRelations()` - find FKs FROM a table\n * - `findIncomingRelations()` - find FKs TO a table\n */\nexport abstract class TableGrounding extends AbstractGrounding {\n #filter?: Filter;\n #columns?: ColumnsFilter;\n #forward?: boolean | number;\n #backward?: boolean | number;\n\n constructor(config: TableGroundingConfig = {}) {\n super('table', 'tables');\n this.#filter = config.filter;\n this.#columns = config.columns;\n this.#forward = config.forward;\n this.#backward = config.backward;\n }\n\n /** Get all table names in the database */\n protected abstract getAllTableNames(): Promise<string[]>;\n\n /** Get full table metadata for a single table */\n protected abstract getTable(tableName: string): Promise<Table>;\n\n /** Find FKs FROM this table (outgoing relationships) */\n protected abstract findOutgoingRelations(\n tableName: string,\n ctx: GroundingContext,\n ): Promise<Relationship[]>;\n\n /** Find FKs TO this table (incoming relationships) */\n protected abstract findIncomingRelations(\n tableName: string,\n ctx: GroundingContext,\n ): Promise<Relationship[]>;\n\n override async contributeEntities(ctx: GroundingContext): Promise<void> {\n await this.execute(ctx);\n }\n\n /**\n * Execute the grounding process.\n * Writes discovered tables and relationships to the context.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const seedTables = await this.applyFilter();\n const forward = this.#forward;\n const backward = this.#backward;\n\n // No traversal at all - just add the seed tables\n if (!forward && !backward) {\n const tables = await Promise.all(\n seedTables.map(async (name, index) => {\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: index + 1,\n total: seedTables.length,\n });\n return applyColumnFilter(await this.getTable(name), this.#columns);\n }),\n );\n ctx.tables.push(...tables);\n return;\n }\n\n const tables: Record<string, Table> = {};\n const allRelationships: Relationship[] = [];\n const seenRelationships = new Set<string>();\n\n // Track depth separately for forward/backward using BFS\n const forwardQueue: Array<{ name: string; depth: number }> = [];\n const backwardQueue: Array<{ name: string; depth: number }> = [];\n const forwardVisited = new Set<string>();\n const backwardVisited = new Set<string>();\n let loadedCount = 0;\n\n // Initialize queues with seed tables at depth 0\n for (const name of seedTables) {\n if (forward) forwardQueue.push({ name, depth: 0 });\n if (backward) backwardQueue.push({ name, depth: 0 });\n }\n\n // Process forward (child\u2192parent)\n const forwardLimit = forward === true ? Infinity : forward || 0;\n while (forwardQueue.length > 0) {\n const item = forwardQueue.shift();\n if (!item) break;\n const { name, depth } = item;\n\n if (forwardVisited.has(name)) continue;\n forwardVisited.add(name);\n\n if (!tables[name]) {\n loadedCount++;\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: loadedCount,\n });\n tables[name] = applyColumnFilter(\n await this.getTable(name),\n this.#columns,\n );\n }\n\n if (depth < forwardLimit) {\n const rels = await this.findOutgoingRelations(name, ctx);\n for (const rel of rels) {\n if (!this.isRelationshipVisible(rel)) continue;\n this.addRelationship(rel, allRelationships, seenRelationships);\n if (!forwardVisited.has(rel.referenced_table)) {\n forwardQueue.push({ name: rel.referenced_table, depth: depth + 1 });\n }\n }\n }\n }\n\n // Process backward (parent\u2192child)\n const backwardLimit = backward === true ? Infinity : backward || 0;\n while (backwardQueue.length > 0) {\n const item = backwardQueue.shift();\n if (!item) break;\n const { name, depth } = item;\n\n if (backwardVisited.has(name)) continue;\n backwardVisited.add(name);\n\n if (!tables[name]) {\n loadedCount++;\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: loadedCount,\n });\n tables[name] = applyColumnFilter(\n await this.getTable(name),\n this.#columns,\n );\n }\n\n if (depth < backwardLimit) {\n const rels = await this.findIncomingRelations(name, ctx);\n for (const rel of rels) {\n if (!this.isRelationshipVisible(rel)) continue;\n this.addRelationship(rel, allRelationships, seenRelationships);\n if (!backwardVisited.has(rel.table)) {\n backwardQueue.push({ name: rel.table, depth: depth + 1 });\n }\n }\n }\n }\n\n // Write to context\n const tablesList = Object.values(tables);\n ctx.tables.push(...tablesList);\n ctx.relationships.push(...allRelationships);\n }\n\n /**\n * Apply the filter to get seed table names.\n * If filter is an explicit array, skip querying all table names.\n */\n protected async applyFilter(): Promise<string[]> {\n const filter = this.#filter;\n if (Array.isArray(filter)) {\n return filter;\n }\n const names = await this.getAllTableNames();\n if (!filter) {\n return names;\n }\n if (filter instanceof RegExp) {\n return names.filter((name) => filter.test(name));\n }\n return names.filter(filter);\n }\n\n /**\n * Add a relationship to the collection, deduplicating by key.\n */\n protected addRelationship(\n rel: Relationship,\n all: Relationship[],\n seen: Set<string>,\n ): void {\n const key = `${rel.table}:${rel.from.join(',')}:${rel.referenced_table}:${rel.to.join(',')}`;\n if (!seen.has(key)) {\n seen.add(key);\n all.push(rel);\n }\n }\n\n protected isRelationshipVisible(rel: Relationship): boolean {\n return (\n this.areColumnsVisible(rel.from, this.#columns?.[rel.table]) &&\n this.areColumnsVisible(rel.to, this.#columns?.[rel.referenced_table])\n );\n }\n\n protected areColumnsVisible(names: string[], filter?: Filter): boolean {\n if (!filter) return true;\n return (\n filterColumns(\n names.map((name) => ({ name })),\n filter,\n ).length === names.length\n );\n }\n}\n", "import { z } from 'zod';\n\nimport type { Adapter, ColumnStats } from '../adapter.ts';\nimport {\n ColumnStatsGrounding,\n type ColumnStatsGroundingConfig,\n} from '../groundings/column-stats.grounding.ts';\nimport type { Column, GroundingContext } from '../groundings/context.ts';\nimport { numericValue } from '../groundings/rows.ts';\n\n/**\n * A pg_stats row. null_frac, n_distinct and correlation are float4, which pg\n * reads as numbers; histogram_bounds is cast to its text form '{a,b}'.\n * correlation and histogram_bounds are null when ANALYZE did not compute them.\n */\nconst pgStatsRow = z.object({\n schemaname: z.string(),\n tablename: z.string(),\n attname: z.string(),\n null_frac: z.number().nullable(),\n n_distinct: z.number().nullable(),\n histogram_bounds: z.string().nullable(),\n correlation: z.number().nullable(),\n});\n\ntype PgStatsRow = z.output<typeof pgStatsRow>;\n\n/**\n * MIN/MAX cast to text; AVG of a numeric expression is numeric, which pg\n * returns as a decimal string. All three are null for an empty table.\n */\nconst liveStatsRow = z.object({\n min_value: z.string().nullable(),\n max_value: z.string().nullable(),\n null_fraction: numericValue.nullable(),\n});\n\nexport class PostgresColumnStatsGrounding extends ColumnStatsGrounding {\n #adapter: Adapter;\n #pgStatsCache = new Map<string, Map<string, PgStatsRow>>();\n\n constructor(adapter: Adapter, config: ColumnStatsGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n override async execute(ctx: GroundingContext): Promise<void> {\n await this.#fetchAllPgStats(ctx);\n await super.execute(ctx);\n }\n\n async #fetchAllPgStats(ctx: GroundingContext): Promise<void> {\n const allContainers = [...ctx.tables, ...ctx.views];\n if (allContainers.length === 0) return;\n\n const conditions = allContainers.map((container) => {\n const { schema, table } = this.#adapter.parseTableName(container.name);\n return `(schemaname = '${this.#adapter.escapeString(schema)}' AND tablename = '${this.#adapter.escapeString(table)}')`;\n });\n\n const rows = await this.#adapter.runQuery(\n `\n SELECT\n schemaname,\n tablename,\n attname,\n null_frac,\n n_distinct,\n histogram_bounds::text,\n correlation\n FROM pg_stats\n WHERE ${conditions.join(' OR ')}\n `,\n pgStatsRow,\n );\n\n for (const row of rows) {\n const tableName = allContainers.find((c) => {\n const { schema, table } = this.#adapter.parseTableName(c.name);\n return schema === row.schemaname && table === row.tablename;\n })?.name;\n if (!tableName) continue;\n\n let map = this.#pgStatsCache.get(tableName);\n if (!map) {\n map = new Map();\n this.#pgStatsCache.set(tableName, map);\n }\n map.set(row.attname, row);\n }\n }\n\n protected override async collectStats(\n tableName: string,\n column: Column,\n ): Promise<ColumnStats | undefined> {\n const cached = this.#pgStatsCache.get(tableName)?.get(column.name);\n if (cached) {\n return this.#fromPgStats(cached);\n }\n\n return this.#collectStatsLive(tableName, column);\n }\n\n #fromPgStats(row: PgStatsRow): ColumnStats | undefined {\n const bounds = row.histogram_bounds\n ? this.#parsePgArray(row.histogram_bounds)\n : undefined;\n\n const nullFraction = this.#adapter.toNumber(row.null_frac);\n const nDistinct = this.#adapter.toNumber(row.n_distinct);\n const correlation = this.#adapter.toNumber(row.correlation);\n\n const result: ColumnStats = {\n ...(bounds?.length && { min: bounds[0] }),\n ...(bounds?.length && { max: bounds[bounds.length - 1] }),\n ...(nullFraction != null && {\n nullFraction: Math.max(0, Math.min(1, nullFraction)),\n }),\n ...(nDistinct != null && { nDistinct }),\n ...(correlation != null && {\n correlation: Math.max(-1, Math.min(1, correlation)),\n }),\n };\n\n return Object.keys(result).length > 0 ? result : undefined;\n }\n\n async #collectStatsLive(\n tableName: string,\n column: Column,\n ): Promise<ColumnStats | undefined> {\n if (!this.#shouldCollectStats(column.type)) {\n return undefined;\n }\n\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const tableIdentifier = `${this.#adapter.quoteIdentifier(schema)}.${this.#adapter.quoteIdentifier(table)}`;\n const columnIdentifier = this.#adapter.quoteIdentifier(column.name);\n\n const rows = await this.#adapter.runQuery(\n `\n SELECT\n MIN(${columnIdentifier})::text AS min_value,\n MAX(${columnIdentifier})::text AS max_value,\n AVG(CASE WHEN ${columnIdentifier} IS NULL THEN 1.0 ELSE 0.0 END) AS null_fraction\n FROM ${tableIdentifier}\n `,\n liveStatsRow,\n );\n\n if (!rows.length) {\n return undefined;\n }\n\n const min = rows[0]?.min_value;\n const max = rows[0]?.max_value;\n const nullFraction = this.#adapter.toNumber(rows[0]?.null_fraction);\n\n if (min == null && max == null && nullFraction == null) {\n return undefined;\n }\n\n return {\n min: min ?? undefined,\n max: max ?? undefined,\n nullFraction:\n nullFraction != null && Number.isFinite(nullFraction)\n ? Math.max(0, Math.min(1, nullFraction))\n : undefined,\n };\n }\n\n #shouldCollectStats(type: string | undefined): boolean {\n if (!type) {\n return false;\n }\n const normalized = type.toLowerCase();\n return /int|real|numeric|double|float|decimal|date|time|serial/.test(\n normalized,\n );\n }\n\n #parsePgArray(text: string): string[] {\n const inner =\n text.startsWith('{') && text.endsWith('}') ? text.slice(1, -1) : text;\n\n if (!inner) {\n return [];\n }\n\n const values: string[] = [];\n let current = '';\n let inQuote = false;\n\n for (let i = 0; i < inner.length; i++) {\n const ch = inner[i];\n\n if (inQuote) {\n if (ch === '\"' && inner[i + 1] === '\"') {\n current += '\"';\n i++;\n } else if (ch === '\"') {\n inQuote = false;\n } else {\n current += ch;\n }\n } else if (ch === '\"') {\n inQuote = true;\n } else if (ch === ',') {\n values.push(current);\n current = '';\n } else {\n current += ch;\n }\n }\n\n values.push(current);\n return values;\n }\n}\n", "import { z } from 'zod';\n\n// Row shapes shared by every adapter because no driver changes them.\n\n/** A text column aliased `name`, such as a table or view name. */\nexport const nameRow = z.object({ name: z.string() });\n\n/** `SELECT <engine version function> AS version`. */\nexport const versionRow = z.object({ version: z.string() });\n\n/** The current database's name, aliased `db`. */\nexport const databaseRow = z.object({ db: z.string() });\n\n/** A view's stored definition, aliased `definition`; NULL where the engine hides it. */\nexport const viewDefinitionRow = z.object({\n definition: z.string().nullable(),\n});\n\n/** `SELECT DISTINCT <column> AS value`: whatever the column stores. */\nexport const distinctValueRow = z.object({ value: z.unknown() });\n\n/** A distinct value the query casts to text after filtering out NULLs. */\nexport const textValueRow = z.object({ value: z.string() });\n\n/**\n * A number as drivers return it: a JS number, a bigint (DuckDB BIGINT, the\n * mariadb connector, node:sqlite readBigInts) or a decimal string (pg and\n * tedious BIGINT, NUMERIC and DECIMAL). Read it with Adapter.toNumber().\n */\nexport const numericValue = z.union([z.number(), z.bigint(), z.string()]);\n", "import pMemoize from 'p-memoize';\nimport { z } from 'zod';\n\nimport type { Adapter } from '../adapter.ts';\nimport {\n type Column,\n ColumnValuesGrounding,\n type ColumnValuesGroundingConfig,\n} from '../groundings/column-values.grounding.ts';\n\n/** An ENUM label with its type; typname, nspname and enumlabel are names. */\nconst enumValueRow = z.object({\n type_name: z.string(),\n type_schema: z.string(),\n enum_value: z.string(),\n});\n\n/** The type a column was declared with, from information_schema.columns. */\nconst columnTypeRow = z.object({\n udt_name: z.string(),\n udt_schema: z.string(),\n});\n\n/** `SELECT DISTINCT <column>::text AS value`. */\nconst textValueRow = z.object({ value: z.string().nullable() });\n\nexport class PostgresColumnValuesGrounding extends ColumnValuesGrounding {\n #adapter: Adapter;\n /** Every ENUM type's values, loaded once on first use; a failed load runs again. */\n readonly #enumValues: () => Promise<Map<string, string[]>>;\n\n constructor(adapter: Adapter, config: ColumnValuesGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n this.#enumValues = pMemoize(() => this.#loadEnumValues());\n }\n\n /**\n * Load all ENUM types and their values, keyed by schema-qualified and by\n * bare type name. One query is more efficient than one per column.\n */\n async #loadEnumValues(): Promise<Map<string, string[]>> {\n const enumValues = new Map<string, string[]>();\n const rows = await this.#adapter.runQuery(\n `\n SELECT\n t.typname AS type_name,\n n.nspname AS type_schema,\n e.enumlabel AS enum_value\n FROM pg_type t\n JOIN pg_enum e ON t.oid = e.enumtypid\n JOIN pg_namespace n ON n.oid = t.typnamespace\n ORDER BY t.typname, e.enumsortorder\n `,\n enumValueRow,\n );\n\n for (const row of rows) {\n const key = `${row.type_schema}.${row.type_name}`;\n const existing = enumValues.get(key) ?? [];\n existing.push(row.enum_value);\n enumValues.set(key, existing);\n\n // Also key it without schema for convenience\n const simpleKey = row.type_name;\n const simpleExisting = enumValues.get(simpleKey) ?? [];\n simpleExisting.push(row.enum_value);\n enumValues.set(simpleKey, simpleExisting);\n }\n\n return enumValues;\n }\n\n protected override async collectEnumValues(\n tableName: string,\n column: Column,\n ): Promise<string[] | undefined> {\n // USER-DEFINED type in PostgreSQL could be ENUM\n if (column.type.toLowerCase() !== 'user-defined') {\n return undefined;\n }\n\n const enumValues = await this.#enumValues();\n\n // Get the actual type name for this column\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const rows = await this.#adapter.runQuery(\n `\n SELECT udt_name, udt_schema\n FROM information_schema.columns\n WHERE table_schema = '${this.#adapter.escapeString(schema)}'\n AND table_name = '${this.#adapter.escapeString(table)}'\n AND column_name = '${this.#adapter.escapeString(column.name)}'\n `,\n columnTypeRow,\n );\n\n if (!rows.length) {\n return undefined;\n }\n\n const { udt_name, udt_schema } = rows[0];\n\n // Look up in cache\n const fullKey = `${udt_schema}.${udt_name}`;\n const values = enumValues.get(fullKey) ?? enumValues.get(udt_name);\n\n return values?.length ? values : undefined;\n }\n\n protected override async collectLowCardinality(\n tableName: string,\n column: Column,\n ): Promise<string[] | undefined> {\n if (this.#isHighCardinality(column)) {\n return undefined;\n }\n\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const tableIdentifier = `${this.#adapter.quoteIdentifier(schema)}.${this.#adapter.quoteIdentifier(table)}`;\n const columnIdentifier = this.#adapter.quoteIdentifier(column.name);\n const limit = this.lowCardinalityLimit + 1;\n\n const sql = `\n SELECT DISTINCT ${columnIdentifier}::text AS value\n FROM ${tableIdentifier}\n WHERE ${columnIdentifier} IS NOT NULL\n LIMIT ${limit}\n `;\n\n const rows = await this.#adapter.runQuery(sql, textValueRow);\n\n if (!rows.length || rows.length > this.lowCardinalityLimit) {\n return undefined;\n }\n\n const values: string[] = [];\n for (const row of rows) {\n if (row.value == null) {\n return undefined;\n }\n values.push(row.value);\n }\n\n return values.length ? values : undefined;\n }\n\n #isHighCardinality(column: Column): boolean {\n const nDistinct = column.stats?.nDistinct;\n if (nDistinct == null) return false;\n if (nDistinct > 0) return nDistinct > this.lowCardinalityLimit;\n return true;\n }\n}\n", "import { z } from 'zod';\n\nimport type { Adapter, TableConstraint } from '../adapter.ts';\nimport {\n ConstraintGrounding,\n type ConstraintGroundingConfig,\n} from '../groundings/constraint.grounding.ts';\n\n/**\n * One key column of a pg_constraint row. contype is a \"char\", which pg reads\n * as a one-letter string; the column and referenced-table members come from\n * LEFT JOINs, so they are null for a CHECK without columns or a non-foreign key.\n */\nconst constraintRow = z.object({\n constraint_name: z.string(),\n constraint_type: z.string(),\n definition: z.string().nullable(),\n column_name: z.string().nullable(),\n ref_schema: z.string().nullable(),\n ref_table: z.string().nullable(),\n ref_column: z.string().nullable(),\n});\n\n/** information_schema.columns: is_nullable is 'YES' or 'NO'. */\nconst columnDefaultRow = z.object({\n column_name: z.string(),\n column_default: z.string().nullable(),\n is_nullable: z.string(),\n});\n\n/**\n * PostgreSQL implementation of ConstraintGrounding.\n */\nexport class PostgresConstraintGrounding extends ConstraintGrounding {\n #adapter: Adapter;\n\n constructor(adapter: Adapter, config: ConstraintGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getConstraints(\n tableName: string,\n ): Promise<TableConstraint[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const constraints: TableConstraint[] = [];\n\n // Get PRIMARY KEY, FOREIGN KEY, CHECK, and UNIQUE constraints from pg_constraint\n // contype: p=primary key, f=foreign key, c=check, u=unique\n const constraintRows = await this.#adapter.runQuery(\n `\n SELECT\n con.conname AS constraint_name,\n con.contype AS constraint_type,\n pg_get_constraintdef(con.oid) AS definition,\n a.attname AS column_name,\n ref_nsp.nspname AS ref_schema,\n ref_rel.relname AS ref_table,\n ref_a.attname AS ref_column\n FROM pg_constraint con\n JOIN pg_class rel ON rel.oid = con.conrelid\n JOIN pg_namespace nsp ON nsp.oid = rel.relnamespace\n LEFT JOIN LATERAL unnest(con.conkey) WITH ORDINALITY AS key(attnum, ord) ON TRUE\n LEFT JOIN pg_attribute a ON a.attrelid = rel.oid AND a.attnum = key.attnum\n LEFT JOIN pg_class ref_rel ON ref_rel.oid = con.confrelid\n LEFT JOIN pg_namespace ref_nsp ON ref_nsp.oid = ref_rel.relnamespace\n LEFT JOIN LATERAL unnest(con.confkey) WITH ORDINALITY AS ref_key(attnum, ord) ON key.ord = ref_key.ord\n LEFT JOIN pg_attribute ref_a ON ref_a.attrelid = ref_rel.oid AND ref_a.attnum = ref_key.attnum\n WHERE nsp.nspname = '${this.#adapter.escapeString(schema)}'\n AND rel.relname = '${this.#adapter.escapeString(table)}'\n AND con.contype IN ('p', 'f', 'c', 'u')\n ORDER BY con.conname, key.ord\n `,\n constraintRow,\n );\n\n // Group by constraint name\n const constraintMap = new Map<\n string,\n {\n type: string;\n definition: string | null;\n columns: string[];\n refSchema: string | null;\n refTable: string | null;\n refColumns: string[];\n }\n >();\n\n for (const row of constraintRows) {\n const existing = constraintMap.get(row.constraint_name);\n if (existing) {\n if (row.column_name && !existing.columns.includes(row.column_name)) {\n existing.columns.push(row.column_name);\n }\n if (row.ref_column && !existing.refColumns.includes(row.ref_column)) {\n existing.refColumns.push(row.ref_column);\n }\n } else {\n constraintMap.set(row.constraint_name, {\n type: row.constraint_type,\n definition: row.definition,\n columns: row.column_name ? [row.column_name] : [],\n refSchema: row.ref_schema,\n refTable: row.ref_table,\n refColumns: row.ref_column ? [row.ref_column] : [],\n });\n }\n }\n\n for (const [name, data] of constraintMap) {\n if (data.type === 'p') {\n // PRIMARY KEY constraint\n constraints.push({\n name,\n type: 'PRIMARY_KEY',\n columns: data.columns,\n });\n } else if (data.type === 'f') {\n // FOREIGN KEY constraint\n const referencedTable =\n data.refSchema && data.refTable\n ? `${data.refSchema}.${data.refTable}`\n : (data.refTable ?? undefined);\n constraints.push({\n name,\n type: 'FOREIGN_KEY',\n columns: data.columns,\n referencedTable,\n referencedColumns: data.refColumns,\n });\n } else if (data.type === 'c') {\n // CHECK constraint\n constraints.push({\n name,\n type: 'CHECK',\n definition:\n data.definition?.replace(/^CHECK\\s*\\(/i, '').replace(/\\)$/, '') ||\n undefined,\n columns: data.columns.length > 0 ? data.columns : undefined,\n });\n } else if (data.type === 'u') {\n // UNIQUE constraint\n constraints.push({\n name,\n type: 'UNIQUE',\n columns: data.columns,\n });\n }\n }\n\n // Get NOT NULL and DEFAULT from information_schema\n const columnRows = await this.#adapter.runQuery(\n `\n SELECT\n column_name,\n column_default,\n is_nullable\n FROM information_schema.columns\n WHERE table_schema = '${this.#adapter.escapeString(schema)}'\n AND table_name = '${this.#adapter.escapeString(table)}'\n `,\n columnDefaultRow,\n );\n\n for (const col of columnRows) {\n // NOT NULL constraint (exclude primary key columns which are implicitly NOT NULL)\n const pkConstraint = constraints.find((c) => c.type === 'PRIMARY_KEY');\n const isPkColumn = pkConstraint?.columns?.includes(col.column_name);\n if (col.is_nullable === 'NO' && !isPkColumn) {\n constraints.push({\n name: `${table}_${col.column_name}_notnull`,\n type: 'NOT_NULL',\n columns: [col.column_name],\n });\n }\n\n // DEFAULT constraint\n if (col.column_default != null) {\n constraints.push({\n name: `${table}_${col.column_name}_default`,\n type: 'DEFAULT',\n columns: [col.column_name],\n defaultValue: col.column_default,\n });\n }\n }\n\n return constraints;\n }\n}\n", "import { z } from 'zod';\n\nimport type { Adapter, TableIndex } from '../adapter.ts';\nimport {\n IndexesGrounding,\n type IndexesGroundingConfig,\n} from '../groundings/indexes.grounding.ts';\n\n/**\n * One indexed column. relname, attname and amname are name columns (strings),\n * indisunique a bool, and array_position() an int4 (a number).\n */\nconst indexRow = z.object({\n index_name: z.string(),\n column_name: z.string(),\n is_unique: z.boolean(),\n index_type: z.string(),\n column_position: z.number(),\n});\n\n/**\n * PostgreSQL implementation of IndexesGrounding.\n */\nexport class PostgresIndexesGrounding extends IndexesGrounding {\n #adapter: Adapter;\n\n constructor(adapter: Adapter, config: IndexesGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getIndexes(\n tableName: string,\n ): Promise<TableIndex[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n\n const rows = await this.#adapter.runQuery(\n `\n SELECT\n i.relname AS index_name,\n a.attname AS column_name,\n ix.indisunique AS is_unique,\n am.amname AS index_type,\n array_position(ix.indkey, a.attnum) AS column_position\n FROM pg_index ix\n JOIN pg_class i ON i.oid = ix.indexrelid\n JOIN pg_class t ON t.oid = ix.indrelid\n JOIN pg_namespace n ON n.oid = t.relnamespace\n JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)\n JOIN pg_am am ON am.oid = i.relam\n WHERE n.nspname = '${this.#adapter.escapeString(schema)}'\n AND t.relname = '${this.#adapter.escapeString(table)}'\n ORDER BY i.relname, array_position(ix.indkey, a.attnum)\n `,\n indexRow,\n );\n\n return this.#groupIndexes(rows);\n }\n\n #groupIndexes(rows: z.output<typeof indexRow>[]): TableIndex[] {\n const indexes = new Map<string, TableIndex>();\n\n for (const row of rows) {\n if (!row.index_name || !row.column_name) continue;\n\n const existing = indexes.get(row.index_name);\n if (existing) {\n existing.columns.push(row.column_name);\n } else {\n indexes.set(row.index_name, {\n name: row.index_name,\n columns: [row.column_name],\n unique: row.is_unique,\n type: row.index_type?.toUpperCase(),\n });\n }\n }\n\n return Array.from(indexes.values());\n }\n}\n", "import type { Adapter, AdapterInfo } from '../adapter.ts';\nimport {\n InfoGrounding,\n type InfoGroundingConfig,\n} from '../groundings/info.grounding.ts';\nimport { databaseRow, versionRow } from '../groundings/rows.ts';\n\n/**\n * PostgreSQL implementation of InfoGrounding.\n */\nexport class PostgresInfoGrounding extends InfoGrounding {\n #adapter: Adapter;\n\n constructor(adapter: Adapter, config: InfoGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async collectInfo(): Promise<AdapterInfo> {\n const [versionRows, dbRows] = await Promise.all([\n this.#adapter.runQuery('SELECT version() AS version', versionRow),\n this.#adapter.runQuery('SELECT current_database() AS db', databaseRow),\n ]);\n\n return {\n dialect: 'postgresql',\n version: versionRows[0]?.version,\n database: dbRows[0]?.db,\n details: {\n parameterPlaceholder: '$1, $2, $3, ...',\n identifierQuoting:\n 'PostgreSQL lowercases unquoted identifiers. To preserve mixed-case names, wrap table and column names in double quotes: SELECT \"columnName\" FROM \"TableName\"',\n },\n };\n }\n}\n", "import nodeSqlParser from 'node-sql-parser';\n\nimport type { SQLScopeErrorPayload } from '../agents/exceptions.ts';\nimport { buildScopeParseErrorPayload } from '../sql-scope-error.ts';\nimport { recoverPostgresTypedLiteralParserGap } from './postgres/postgres-parser-workaround.ts';\nimport type {\n SqlPolicyAnalyzer,\n SqlPolicyContext,\n SqlPolicyViolation,\n} from './sql-policy.ts';\n\nexport type ParserDialect =\n 'bigquery' | 'mysql' | 'postgresql' | 'sqlite' | 'transactsql';\n\ninterface SqlEntityReference {\n db?: string | null;\n table: string;\n}\n\ntype AstLike = Record<string, unknown>;\n\nexport type ParserReadOnlyPolicy = {\n blockedFunctions?: readonly string[];\n blockedFunctionPrefixes?: readonly string[];\n blockAssignments?: boolean;\n blockQualifiedFunctions?: boolean;\n blockLockingReads?: boolean;\n blockSelectInto?: boolean;\n blockServerQualifiedRelations?: boolean;\n blockTableHints?: boolean;\n};\n\ntype ScopeVisitState = {\n cteNames: Set<string>;\n references: Map<string, SqlEntityReference>;\n};\n\nconst READ_ONLY_MESSAGE = 'only SELECT or WITH queries allowed';\nconst { Parser } = nodeSqlParser;\nconst parser = new Parser();\n\n/**\n * Internal base for dialect analyzers backed by node-sql-parser.\n * Server-backed analyzers implement SqlPolicyAnalyzer directly.\n */\nexport abstract class ParserSqlPolicyAnalyzer implements SqlPolicyAnalyzer {\n protected abstract readonly dialects: readonly ParserDialect[];\n protected readonly readOnlyPolicy: ParserReadOnlyPolicy = {};\n\n async analyze(\n sql: string,\n context: SqlPolicyContext,\n ): Promise<SqlPolicyViolation | null> {\n if (!this.#isReadOnly(sql)) {\n return { kind: 'read-only', message: READ_ONLY_MESSAGE };\n }\n\n const scopeError = await this.#checkScope(sql, context);\n return scopeError ? { kind: 'scope', payload: scopeError } : null;\n }\n\n #isReadOnly(sql: string): boolean {\n const statements = this.#readParsedStatements(sql);\n if (statements) {\n return (\n statements.length === 1 &&\n statements[0]?.type === 'select' &&\n !containsBlockedOperation(statements[0], this.readOnlyPolicy)\n );\n }\n\n const keyword = firstStatementKeyword(sql);\n return keyword === 'SELECT' || keyword === 'WITH';\n }\n\n #readParsedStatements(sql: string): AstLike[] | null {\n for (const dialect of this.dialects) {\n try {\n return this.#parseStatements(sql, dialect);\n } catch {\n // Parser coverage failures are handled by scope/adapter validation later.\n }\n }\n return null;\n }\n\n async #checkScope(\n sql: string,\n context: SqlPolicyContext,\n ): Promise<SQLScopeErrorPayload | null> {\n let references: SqlEntityReference[] | null = null;\n let lastError: unknown;\n let lastDialect = this.dialects[0]!;\n\n for (const dialect of this.dialects) {\n try {\n references = extractBaseEntityReferences(this.#parseAst(sql, dialect));\n break;\n } catch (error) {\n lastDialect = dialect;\n lastError = error;\n }\n }\n\n if (references === null) {\n return buildScopeParseErrorPayload(sql, lastDialect, lastError);\n }\n if (references.length === 0) return null;\n\n const allowedEntities = await context.resolveAllowedEntities();\n const allowedQualified = new Set(\n allowedEntities.map((entity) => entity.toLowerCase()),\n );\n const allowedUnqualified = new Set<string>();\n for (const entity of allowedEntities) {\n const dot = entity.lastIndexOf('.');\n allowedUnqualified.add(\n (dot === -1 ? entity : entity.slice(dot + 1)).toLowerCase(),\n );\n }\n\n const outOfScope = references\n .map((reference) =>\n reference.db ? `${reference.db}.${reference.table}` : reference.table,\n )\n .filter((name) => {\n const lower = name.toLowerCase();\n if (!name.includes('.')) {\n return !allowedQualified.has(lower) && !allowedUnqualified.has(lower);\n }\n if (allowedQualified.has(lower)) return false;\n\n const parts = lower.split('.');\n return (\n parts.length < 3 || !allowedQualified.has(parts.slice(-2).join('.'))\n );\n });\n\n return outOfScope.length === 0\n ? null\n : buildOutOfScopePayload(sql, outOfScope, [...allowedEntities]);\n }\n\n #parseStatements(sql: string, dialect: ParserDialect): AstLike[] {\n return parseStatements(this.#parseAst(sql, dialect));\n }\n\n #parseAst(sql: string, dialect: ParserDialect): unknown {\n let parserSql = sql;\n const attempted = new Set([sql]);\n\n while (true) {\n try {\n return parser.astify(parserSql, { database: dialect });\n } catch (error) {\n const recovered =\n dialect === 'postgresql'\n ? recoverPostgresTypedLiteralParserGap(parserSql, error)\n : null;\n if (!recovered || attempted.has(recovered)) throw error;\n attempted.add(recovered);\n parserSql = recovered;\n }\n }\n }\n}\n\nfunction parseStatements(ast: unknown): AstLike[] {\n const statements: unknown[] = Array.isArray(ast) ? ast : [ast];\n return statements.filter(isAstLike);\n}\n\nfunction containsBlockedOperation(\n node: unknown,\n policy: ParserReadOnlyPolicy,\n): boolean {\n if (Array.isArray(node)) {\n return node.some((item) => containsBlockedOperation(item, policy));\n }\n if (!isAstLike(node)) return false;\n\n if (\n policy.blockSelectInto &&\n node.type === 'select' &&\n isAstLike(node.into) &&\n node.into.type === 'into'\n ) {\n return true;\n }\n if (policy.blockLockingReads && node.locking_read != null) return true;\n if (policy.blockAssignments && node.type === 'assign') return true;\n if (\n policy.blockServerQualifiedRelations &&\n isTableReferenceNode(node) &&\n typeof node.server === 'string'\n ) {\n return true;\n }\n if (policy.blockTableHints && node.table_hint != null) return true;\n\n if (node.type === 'function') {\n const functionIdentifier = readFunctionIdentifier(node);\n if (\n functionIdentifier &&\n policy.blockQualifiedFunctions &&\n functionIdentifier.parts.length > 1\n ) {\n return true;\n }\n if (\n functionIdentifier &&\n policy.blockedFunctions?.some(\n (blocked) => blocked.toLowerCase() === functionIdentifier.parts.at(-1),\n )\n ) {\n return true;\n }\n if (\n functionIdentifier &&\n policy.blockedFunctionPrefixes?.some((prefix) =>\n functionIdentifier.parts.at(-1)?.startsWith(prefix.toLowerCase()),\n )\n ) {\n return true;\n }\n }\n\n return Object.values(node).some((value) =>\n containsBlockedOperation(value, policy),\n );\n}\n\nfunction readFunctionIdentifier(node: AstLike): { parts: string[] } | null {\n if (!isAstLike(node.name)) return null;\n const parts: string[] = [];\n\n if (\n isAstLike(node.name.schema) &&\n typeof node.name.schema.value === 'string'\n ) {\n appendIdentifierParts(parts, node.name.schema.value);\n }\n\n const names = Array.isArray(node.name.name) ? node.name.name : [];\n for (const name of names) {\n if (isAstLike(name) && typeof name.value === 'string') {\n appendIdentifierParts(parts, name.value);\n }\n }\n\n return parts.length > 0 ? { parts } : null;\n}\n\nfunction appendIdentifierParts(parts: string[], value: string): void {\n parts.push(\n ...value\n .toLowerCase()\n .split('.')\n .filter((part) => part.length > 0),\n );\n}\n\nfunction extractBaseEntityReferences(ast: unknown): SqlEntityReference[] {\n const state: ScopeVisitState = {\n cteNames: new Set<string>(),\n references: new Map<string, SqlEntityReference>(),\n };\n\n visitNode(ast, state);\n return Array.from(state.references.values());\n}\n\nfunction firstStatementKeyword(sql: string): string | null {\n let offset = 0;\n\n while (offset < sql.length) {\n if (/\\s/.test(sql[offset])) {\n offset++;\n continue;\n }\n\n if (sql.startsWith('--', offset)) {\n offset += 2;\n while (\n offset < sql.length &&\n sql[offset] !== '\\n' &&\n sql[offset] !== '\\r'\n ) {\n offset++;\n }\n continue;\n }\n\n if (sql.startsWith('/*', offset)) {\n const commentEnd = sql.indexOf('*/', offset + 2);\n if (commentEnd === -1) return null;\n offset = commentEnd + 2;\n continue;\n }\n\n const keyword = /^[A-Za-z]+/.exec(sql.slice(offset));\n return keyword ? keyword[0].toUpperCase() : null;\n }\n\n return null;\n}\n\nfunction buildOutOfScopePayload(\n sql: string,\n referencedEntities: string[],\n allowedEntities: string[],\n): SQLScopeErrorPayload {\n return {\n error: `Query references entities outside grounded scope: ${referencedEntities.join(', ')}`,\n error_type: 'OUT_OF_SCOPE',\n suggestion:\n 'Restrict the query to grounded tables/views or expand grounding to include the referenced entities.',\n sql_attempted: sql,\n referenced_entities: referencedEntities,\n allowed_entities: allowedEntities,\n };\n}\n\nfunction visitNode(node: unknown, state: ScopeVisitState): void {\n if (Array.isArray(node)) {\n for (const item of node) visitNode(item, state);\n return;\n }\n if (!isAstLike(node)) return;\n\n if (isStatementNode(node)) {\n visitStatement(node, state);\n return;\n }\n\n if (isTableReferenceNode(node)) addReference(node, state);\n for (const value of Object.values(node)) visitNode(value, state);\n}\n\nfunction visitStatement(node: AstLike, parentState: ScopeVisitState): void {\n const localState: ScopeVisitState = {\n cteNames: new Set(parentState.cteNames),\n references: parentState.references,\n };\n const withItems = Array.isArray(node.with) ? node.with : [];\n\n for (const item of withItems) {\n if (!isAstLike(item)) continue;\n const cteName = readCteName(item);\n if (cteName) localState.cteNames.add(caseFold(cteName));\n }\n\n for (const item of withItems) {\n if (isAstLike(item)) visitNode(item.stmt, localState);\n }\n\n for (const [key, value] of Object.entries(node)) {\n if (key !== 'with') visitNode(value, localState);\n }\n}\n\nfunction addReference(node: AstLike, state: ScopeVisitState): void {\n const table = typeof node.table === 'string' ? node.table : null;\n if (!table || state.cteNames.has(caseFold(table))) return;\n\n const db = typeof node.db === 'string' ? node.db : null;\n const key = db ? `${db}.${table}` : table;\n if (!state.references.has(key)) state.references.set(key, { db, table });\n}\n\nfunction readCteName(node: AstLike): string | undefined {\n const name = node.name;\n if (typeof name === 'string') return name;\n if (!isAstLike(name)) return undefined;\n return typeof name.value === 'string' ? name.value : undefined;\n}\n\nfunction isStatementNode(node: AstLike): boolean {\n return (\n typeof node.type === 'string' &&\n ['delete', 'insert', 'replace', 'select', 'update'].includes(node.type)\n );\n}\n\nfunction isTableReferenceNode(node: AstLike): boolean {\n if (node.type === 'column_ref' || typeof node.table !== 'string')\n return false;\n\n return (\n 'addition' in node ||\n 'as' in node ||\n 'db' in node ||\n 'join' in node ||\n 'operator' in node ||\n 'surround' in node ||\n 'table_hint' in node ||\n 'temporal_table' in node\n );\n}\n\nfunction isAstLike(value: unknown): value is AstLike {\n return typeof value === 'object' && value !== null;\n}\n\nfunction caseFold(value: string): string {\n return value.toLowerCase();\n}\n", "import type { SQLScopeErrorPayload } from './agents/exceptions.ts';\n\nexport function buildScopeParseErrorPayload(\n sql: string,\n parserDialect: string,\n error: unknown,\n): SQLScopeErrorPayload {\n const parserError =\n error instanceof Error ? error.message : String(error ?? 'Unknown error');\n\n return {\n error: `SQL scope analysis failed before validation/execution: ${parserError}`,\n error_type: 'SQL_SCOPE_PARSE_ERROR',\n suggestion:\n 'Rewrite the query into simpler SQL that can be analyzed safely, or extend parser coverage for this dialect feature.',\n sql_attempted: sql,\n parser_dialect: parserDialect,\n parser_error: parserError,\n };\n}\n", "/**\n * Temporary workaround for a node-sql-parser 5.4.0 PostgreSQL grammar\n * shortcoming: it rejects valid typed string constants such as\n * `TIMESTAMPTZ 'epoch'`. Remove this module and its parser retry once\n * node-sql-parser supports PostgreSQL typed string constants natively.\n */\n\nconst TYPE_BEFORE_LITERAL =\n /(?<type>(?:pg_catalog\\.)?[A-Za-z_][A-Za-z0-9_$]*(?:\\s+(?:varying|precision))?(?:\\s*\\(\\s*\\d+(?:\\s*,\\s*\\d+)?\\s*\\))?(?:\\s+(?:with|without)\\s+time\\s+zone)?)\\s*$/i;\nconst TIME_ZONE_SUFFIX = /^\\s+time\\s+zone\\s+/i;\nconst TIME_BEFORE_SUFFIX =\n /(?<type>time(?:stamp)?(?:\\s*\\(\\s*\\d+\\s*\\))?)\\s+(?<qualifier>with|without)$/i;\n\nexport function recoverPostgresTypedLiteralParserGap(\n sql: string,\n error: unknown,\n): string | null {\n const errorOffset = parserErrorOffset(error);\n if (errorOffset === null) return null;\n\n const prefix = sql.slice(0, errorOffset);\n let literalStart = errorOffset;\n let literalEnd = findLiteralEnd(sql, literalStart);\n let typeMatch = TYPE_BEFORE_LITERAL.exec(prefix);\n let type = typeMatch?.groups?.type;\n\n if (literalEnd === null) {\n const suffixMatch = TIME_ZONE_SUFFIX.exec(sql.slice(errorOffset));\n typeMatch = TIME_BEFORE_SUFFIX.exec(prefix);\n type =\n typeMatch?.groups?.type && typeMatch.groups.qualifier && suffixMatch\n ? `${typeMatch.groups.type} ${typeMatch.groups.qualifier} TIME ZONE`\n : undefined;\n literalStart = errorOffset + (suffixMatch?.[0].length ?? 0);\n literalEnd = findLiteralEnd(sql, literalStart);\n }\n if (!type || typeMatch?.index === undefined || literalEnd === null)\n return null;\n\n // PostgreSQL defines type 'value' and CAST('value' AS type) as equivalent.\n return (\n prefix.slice(0, typeMatch.index) +\n `CAST(${sql.slice(literalStart, literalEnd)} AS ${parserType(type)})` +\n sql.slice(literalEnd)\n );\n}\n\nfunction parserErrorOffset(error: unknown): number | null {\n if (typeof error !== 'object' || error === null) return null;\n const location = Reflect.get(error, 'location');\n if (typeof location !== 'object' || location === null) return null;\n const start = Reflect.get(location, 'start');\n if (typeof start !== 'object' || start === null) return null;\n const offset = Reflect.get(start, 'offset');\n return typeof offset === 'number' ? offset : null;\n}\n\nfunction findLiteralEnd(sql: string, start: number): number | null {\n if (sql[start] !== \"'\") {\n const delimiter = /^\\$(?:[A-Za-z_][A-Za-z0-9_]*)?\\$/.exec(\n sql.slice(start),\n )?.[0];\n if (!delimiter) return null;\n const end = sql.indexOf(delimiter, start + delimiter.length);\n return end === -1 ? null : end + delimiter.length;\n }\n\n let offset = start + 1;\n while (offset < sql.length) {\n if (sql[offset] === '\\\\') {\n offset += 2;\n continue;\n }\n if (sql[offset] !== \"'\") {\n offset++;\n continue;\n }\n if (sql[offset + 1] === \"'\") {\n offset += 2;\n continue;\n }\n return offset + 1;\n }\n return null;\n}\n\nfunction parserType(type: string): string {\n const unqualified = type.replace(/^pg_catalog\\./i, '');\n const timetz = /^timetz(\\s*\\([^)]*\\))?$/i.exec(unqualified);\n return timetz ? `TIME${timetz[1] ?? ''} WITH TIME ZONE` : unqualified;\n}\n", "import { ParserSqlPolicyAnalyzer } from '../parser-sql-policy.ts';\n\nexport class PostgresSqlPolicyAnalyzer extends ParserSqlPolicyAnalyzer {\n protected readonly dialects = ['postgresql'] as const;\n protected override readonly readOnlyPolicy = {\n blockSelectInto: true,\n blockedFunctionPrefixes: [\n 'DBLINK_',\n 'LO_',\n 'PG_ADVISORY_',\n 'PG_LS_',\n 'PG_TRY_ADVISORY_',\n ],\n blockedFunctions: [\n 'NEXTVAL',\n 'PG_CANCEL_BACKEND',\n 'PG_READ_BINARY_FILE',\n 'PG_READ_FILE',\n 'PG_RELOAD_CONF',\n 'PG_NOTIFY',\n 'PG_ROTATE_LOGFILE',\n 'PG_SLEEP',\n 'PG_STAT_FILE',\n 'PG_TERMINATE_BACKEND',\n 'SET_CONFIG',\n 'SETVAL',\n ],\n } as const;\n}\n", "import {\n Adapter,\n type ExecuteFunction,\n type GroundingFn,\n type ValidateFunction,\n} from '../adapter.ts';\nimport { PostgresSqlPolicyAnalyzer } from './postgres.sql-policy.ts';\n\nexport type PostgresAdapterOptions = {\n execute: ExecuteFunction;\n validate?: ValidateFunction;\n grounding: GroundingFn[];\n schemas?: string[];\n};\n\nconst POSTGRES_ERROR_MAP: Record<string, { type: string; hint: string }> = {\n '42P01': {\n type: 'MISSING_TABLE',\n hint: 'Check the database schema for the correct table name. Include the schema prefix if necessary.',\n },\n '42703': {\n type: 'INVALID_COLUMN',\n hint: 'Verify the column exists on the referenced table and use table aliases to disambiguate.',\n },\n '42601': {\n type: 'SYNTAX_ERROR',\n hint: 'There is a SQL syntax error. Review keywords, punctuation, and the overall query shape.',\n },\n '42P10': {\n type: 'INVALID_COLUMN',\n hint: 'Columns referenced in GROUP BY/SELECT must exist. Double-check the column names and aliases.',\n },\n '42883': {\n type: 'INVALID_FUNCTION',\n hint: 'The function or operator you used is not recognized. Confirm its name and argument types.',\n },\n};\n\nfunction isPostgresError(\n error: unknown,\n): error is { code?: string; message?: string } {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n typeof error.code === 'string'\n );\n}\n\nexport function formatPostgresError(sql: string, error: unknown) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : 'Unknown error occurred';\n\n if (isPostgresError(error)) {\n const metadata = POSTGRES_ERROR_MAP[error.code ?? ''];\n if (metadata) {\n return {\n error: errorMessage,\n error_type: metadata.type,\n suggestion: metadata.hint,\n sql_attempted: sql,\n };\n }\n }\n\n return {\n error: errorMessage,\n error_type: 'UNKNOWN_ERROR',\n suggestion: 'Review the query and try again',\n sql_attempted: sql,\n };\n}\n\nexport class Postgres extends Adapter {\n #options: PostgresAdapterOptions;\n override readonly grounding: GroundingFn[];\n override readonly defaultSchema = 'public';\n override readonly systemSchemas = ['pg_catalog', 'information_schema'];\n override readonly formatterLanguage = 'postgresql';\n\n constructor(options: PostgresAdapterOptions) {\n super(new PostgresSqlPolicyAnalyzer());\n if (!options || typeof options.execute !== 'function') {\n throw new Error('Postgres adapter requires an execute function.');\n }\n this.#options = {\n ...options,\n schemas: options.schemas?.length ? options.schemas : undefined,\n };\n this.grounding = options.grounding;\n }\n\n override async executeImpl(sql: string) {\n return this.#options.execute(sql);\n }\n\n override async validateImpl(sql: string) {\n const validator: ValidateFunction =\n this.#options.validate ??\n (async (text: string) => {\n await this.#options.execute(`EXPLAIN ${text}`);\n });\n\n try {\n return await validator(sql);\n } catch (error) {\n return JSON.stringify(formatPostgresError(sql, error));\n }\n }\n\n override quoteIdentifier(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n }\n\n override escape(value: string): string {\n return value.replace(/\"/g, '\"\"');\n }\n\n override buildSampleRowsQuery(\n tableName: string,\n columns: string[] | undefined,\n limit: number,\n ): string {\n const { schema, table } = this.parseTableName(tableName);\n const tableIdentifier = schema\n ? `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(table)}`\n : this.quoteIdentifier(table);\n const columnList = columns?.length\n ? columns.map((c) => this.quoteIdentifier(c)).join(', ')\n : '*';\n return `SELECT ${columnList} FROM ${tableIdentifier} LIMIT ${limit}`;\n }\n\n /**\n * The schemas introspection is limited to; table and view discovery use\n * them unless a grounding lists its own.\n */\n get schemas(): string[] | undefined {\n return this.#options.schemas;\n }\n\n protected override async queryRows(sql: string): Promise<unknown[]> {\n return this.rowsFrom(await this.#options.execute(sql), ['rows']);\n }\n}\n", "import { z } from 'zod';\n\nimport type { Adapter } from '../adapter.ts';\nimport {\n RowCountGrounding,\n type RowCountGroundingConfig,\n} from '../groundings/row-count.grounding.ts';\nimport { numericValue } from '../groundings/rows.ts';\n\n// Both counts are bigint (int8), which pg returns as a decimal string unless\n// the pool installs its own int8 parser.\n\nconst estimateRow = z.object({ estimate: numericValue.nullable() });\n\nconst countRow = z.object({ count: numericValue.nullable() });\n\nexport class PostgresRowCountGrounding extends RowCountGrounding {\n #adapter: Adapter;\n\n constructor(adapter: Adapter, config: RowCountGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getRowCount(\n tableName: string,\n ): Promise<number | undefined> {\n const estimate = await this.#getEstimatedRowCount(tableName);\n if (estimate != null && estimate > 0) {\n return Math.round(estimate);\n }\n\n return this.#getLiveRowCount(tableName);\n }\n\n async #getEstimatedRowCount(tableName: string): Promise<number | undefined> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const rows = await this.#adapter.runQuery(\n `\n SELECT c.reltuples::bigint AS estimate\n FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE n.nspname = '${this.#adapter.escapeString(schema)}'\n AND c.relname = '${this.#adapter.escapeString(table)}'\n `,\n estimateRow,\n );\n\n return this.#adapter.toNumber(rows[0]?.estimate);\n }\n\n async #getLiveRowCount(tableName: string): Promise<number | undefined> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const tableIdentifier = `${this.#adapter.quoteIdentifier(schema)}.${this.#adapter.quoteIdentifier(table)}`;\n\n const rows = await this.#adapter.runQuery(\n `SELECT COUNT(*) as count FROM ${tableIdentifier}`,\n countRow,\n );\n\n return this.#adapter.toNumber(rows[0]?.count);\n }\n}\n", "import { z } from 'zod';\n\nimport type { Relationship, Table } from '../adapter.ts';\nimport { nameRow } from '../groundings/rows.ts';\nimport {\n TableGrounding,\n type TableGroundingConfig,\n} from '../groundings/table.grounding.ts';\nimport { columnRow } from './postgres-rows.ts';\nimport type { Postgres } from './postgres.ts';\n\n/** One column pair of a foreign key, read from pg_constraint. */\nconst relationshipRow = z.object({\n constraint_name: z.string(),\n table_schema: z.string(),\n table_name: z.string(),\n column_name: z.string(),\n foreign_table_schema: z.string(),\n foreign_table_name: z.string(),\n foreign_column_name: z.string(),\n});\n\nexport interface PostgresTableGroundingConfig extends TableGroundingConfig {\n /** Schemas to include (defaults to the adapter's schemas option) */\n schemas?: string[];\n}\n\n/**\n * PostgreSQL implementation of TableGrounding.\n *\n * PostgreSQL can query incoming relationships directly via pg_constraint,\n * so no caching is needed like SQLite.\n */\nexport class PostgresTableGrounding extends TableGrounding {\n #adapter: Postgres;\n #schemas?: string[];\n\n constructor(adapter: Postgres, config: PostgresTableGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n this.#schemas = config.schemas ?? adapter.schemas;\n }\n\n protected override async getAllTableNames(): Promise<string[]> {\n const rows = await this.#adapter.runQuery(\n `\n SELECT DISTINCT table_schema || '.' || table_name AS name\n FROM information_schema.tables\n WHERE table_type = 'BASE TABLE'\n ${this.#adapter.buildSchemaFilter('table_schema', this.#schemas)}\n ORDER BY name\n `,\n nameRow,\n );\n return rows.map((r) => r.name);\n }\n\n protected override async getTable(tableName: string): Promise<Table> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n\n const columns = await this.#adapter.runQuery(\n `\n SELECT column_name, data_type\n FROM information_schema.columns\n WHERE table_schema = '${this.#adapter.escapeString(schema)}'\n AND table_name = '${this.#adapter.escapeString(table)}'\n ORDER BY ordinal_position\n `,\n columnRow,\n );\n\n return {\n name: tableName,\n schema,\n rawName: table,\n columns: columns.map((col) => ({\n name: col.column_name ?? 'unknown',\n type: col.data_type ?? 'unknown',\n })),\n };\n }\n\n protected override async findOutgoingRelations(\n tableName: string,\n ): Promise<Relationship[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n return this.#foreignKeys(\n `nsp.nspname = '${this.#adapter.escapeString(schema)}'\n AND rel.relname = '${this.#adapter.escapeString(table)}'`,\n );\n }\n\n protected override async findIncomingRelations(\n tableName: string,\n ): Promise<Relationship[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n return this.#foreignKeys(\n `ref_nsp.nspname = '${this.#adapter.escapeString(schema)}'\n AND ref_rel.relname = '${this.#adapter.escapeString(table)}'`,\n );\n }\n\n /**\n * The foreign keys matching `where`. unnest(conkey, confkey) WITH\n * ORDINALITY pairs each column with the column it references by position,\n * and each side carries its own schema, so composite and cross-schema keys\n * come back whole.\n */\n async #foreignKeys(where: string): Promise<Relationship[]> {\n const rows = await this.#adapter.runQuery(\n `\n SELECT\n con.conname AS constraint_name,\n nsp.nspname AS table_schema,\n rel.relname AS table_name,\n att.attname AS column_name,\n ref_nsp.nspname AS foreign_table_schema,\n ref_rel.relname AS foreign_table_name,\n ref_att.attname AS foreign_column_name\n FROM pg_constraint AS con\n JOIN pg_class AS rel ON rel.oid = con.conrelid\n JOIN pg_namespace AS nsp ON nsp.oid = rel.relnamespace\n JOIN pg_class AS ref_rel ON ref_rel.oid = con.confrelid\n JOIN pg_namespace AS ref_nsp ON ref_nsp.oid = ref_rel.relnamespace\n CROSS JOIN LATERAL unnest(con.conkey, con.confkey)\n WITH ORDINALITY AS key(attnum, ref_attnum, ord)\n JOIN pg_attribute AS att\n ON att.attrelid = con.conrelid AND att.attnum = key.attnum\n JOIN pg_attribute AS ref_att\n ON ref_att.attrelid = con.confrelid AND ref_att.attnum = key.ref_attnum\n WHERE con.contype = 'f'\n AND ${where}\n ORDER BY nsp.nspname, rel.relname, con.conname, key.ord\n `,\n relationshipRow,\n );\n\n const relationships = new Map<string, Relationship>();\n for (const row of rows) {\n const table = `${row.table_schema}.${row.table_name}`;\n const key = `${table}:${row.constraint_name}`;\n const relationship = relationships.get(key) ?? {\n table,\n from: [],\n referenced_table: `${row.foreign_table_schema}.${row.foreign_table_name}`,\n to: [],\n };\n relationship.from.push(row.column_name);\n relationship.to.push(row.foreign_column_name);\n relationships.set(key, relationship);\n }\n return Array.from(relationships.values());\n }\n}\n", "import { z } from 'zod';\n\n// Rows of PostgreSQL catalog queries, as node-postgres returns them with its\n// default type parsers: name, text and information_schema identifier columns\n// are strings.\n\n/** `SELECT column_name, data_type FROM information_schema.columns`. */\nexport const columnRow = z.object({\n column_name: z.string().nullable(),\n data_type: z.string().nullable(),\n});\n", "import type { ColumnStats, Filter } from '../adapter.ts';\nimport {\n AbstractGrounding,\n type ColumnsFilter,\n applyColumnFilter,\n} from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Represents a database view with its metadata.\n */\nexport interface View {\n name: string;\n schema?: string;\n rawName?: string;\n /** The SQL definition of the view (CREATE VIEW statement or query) */\n definition?: string;\n columns: {\n name: string;\n type: string;\n /** Low cardinality marker */\n kind?: 'LowCardinality';\n /** Distinct values for low cardinality columns */\n values?: string[];\n /** Column statistics (min, max, nullFraction) */\n stats?: ColumnStats;\n }[];\n}\n\n/**\n * Configuration for ViewGrounding.\n */\nexport interface ViewGroundingConfig {\n /** Filter to select views */\n filter?: Filter;\n /**\n * Per-view column filter.\n * Maps view name to a Filter that selects which columns to keep.\n * Views not listed keep all their columns.\n */\n columns?: ColumnsFilter;\n /** Whether to fetch the SQL definition of each view (default: true) */\n includeDefinition?: boolean;\n}\n\n/**\n * Abstract base class for view grounding\n *\n * The `execute()` method implements the algorithm that discovers views.\n * Subclasses implement the database-specific hooks:\n * - `getAllViewNames()` - list all views\n * - `getView()` - get view metadata\n */\nexport abstract class ViewGrounding extends AbstractGrounding {\n #filter?: Filter;\n #columns?: ColumnsFilter;\n protected includeDefinition: boolean;\n\n constructor(config: ViewGroundingConfig = {}) {\n super('view', 'views');\n this.#filter = config.filter;\n this.#columns = config.columns;\n this.includeDefinition = config.includeDefinition ?? true;\n }\n\n /** Get all view names in the database */\n protected abstract getAllViewNames(): Promise<string[]>;\n\n /** Get full view metadata for a single view */\n protected abstract getView(viewName: string): Promise<View>;\n\n override async contributeEntities(ctx: GroundingContext): Promise<void> {\n await this.execute(ctx);\n }\n\n /**\n * Execute the grounding process.\n * Writes discovered views to the context.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const viewNames = await this.applyFilter();\n const views = await Promise.all(\n viewNames.map(async (name, index) => {\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'views',\n table: name,\n message: `Loading view ${name}...`,\n current: index + 1,\n total: viewNames.length,\n });\n return applyColumnFilter(await this.getView(name), this.#columns);\n }),\n );\n ctx.views.push(...views);\n }\n\n /**\n * Apply the filter to get view names.\n * If filter is an explicit array, skip querying all view names.\n */\n protected async applyFilter(): Promise<string[]> {\n const filter = this.#filter;\n if (Array.isArray(filter)) {\n return filter;\n }\n const names = await this.getAllViewNames();\n if (!filter) {\n return names;\n }\n if (filter instanceof RegExp) {\n return names.filter((name) => filter.test(name));\n }\n return names.filter(filter);\n }\n}\n", "import { nameRow, viewDefinitionRow } from '../groundings/rows.ts';\nimport {\n type View,\n ViewGrounding,\n type ViewGroundingConfig,\n} from '../groundings/view.grounding.ts';\nimport { columnRow } from './postgres-rows.ts';\nimport type { Postgres } from './postgres.ts';\n\nexport interface PostgresViewGroundingConfig extends ViewGroundingConfig {\n /** Schemas to include (defaults to the adapter's schemas option) */\n schemas?: string[];\n}\n\n/**\n * PostgreSQL implementation of ViewGrounding.\n */\nexport class PostgresViewGrounding extends ViewGrounding {\n #adapter: Postgres;\n #schemas?: string[];\n\n constructor(adapter: Postgres, config: PostgresViewGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n this.#schemas = config.schemas ?? adapter.schemas;\n }\n\n protected override async getAllViewNames(): Promise<string[]> {\n const rows = await this.#adapter.runQuery(\n `\n SELECT table_schema || '.' || table_name AS name\n FROM information_schema.views\n WHERE 1=1\n ${this.#adapter.buildSchemaFilter('table_schema', this.#schemas)}\n ORDER BY name\n `,\n nameRow,\n );\n return rows.map((r) => r.name);\n }\n\n protected override async getView(viewName: string): Promise<View> {\n const { schema, table: view } = this.#adapter.parseTableName(viewName);\n\n let definition: string | undefined;\n if (this.includeDefinition) {\n const defRows = await this.#adapter.runQuery(\n `\n SELECT definition\n FROM pg_views\n WHERE schemaname = '${this.#adapter.escapeString(schema)}'\n AND viewname = '${this.#adapter.escapeString(view)}'\n `,\n viewDefinitionRow,\n );\n definition = defRows[0]?.definition ?? undefined;\n }\n\n const columns = await this.#adapter.runQuery(\n `\n SELECT column_name, data_type\n FROM information_schema.columns\n WHERE table_schema = '${this.#adapter.escapeString(schema)}'\n AND table_name = '${this.#adapter.escapeString(view)}'\n ORDER BY ordinal_position\n `,\n columnRow,\n );\n\n return {\n name: viewName,\n schema,\n rawName: view,\n definition,\n columns: columns.map((col) => ({\n name: col.column_name ?? 'unknown',\n type: col.data_type ?? 'unknown',\n })),\n };\n }\n}\n", "import { type Adapter, groundingFor } from '../adapter.ts';\nimport { type ColumnStatsGroundingConfig } from '../groundings/column-stats.grounding.ts';\nimport { type ColumnValuesGroundingConfig } from '../groundings/column-values.grounding.ts';\nimport { type ConstraintGroundingConfig } from '../groundings/constraint.grounding.ts';\nimport { type IndexesGroundingConfig } from '../groundings/indexes.grounding.ts';\nimport { type InfoGroundingConfig } from '../groundings/info.grounding.ts';\nimport { type RowCountGroundingConfig } from '../groundings/row-count.grounding.ts';\nimport { type TableGroundingConfig } from '../groundings/table.grounding.ts';\nimport type { ViewGroundingConfig } from '../groundings/view.grounding.ts';\nimport { PostgresColumnStatsGrounding } from './column-stats.postgres.grounding.ts';\nimport { PostgresColumnValuesGrounding } from './column-values.postgres.grounding.ts';\nimport { PostgresConstraintGrounding } from './constraint.postgres.grounding.ts';\nimport { PostgresIndexesGrounding } from './indexes.postgres.grounding.ts';\nimport { PostgresInfoGrounding } from './info.postgres.grounding.ts';\nimport { Postgres } from './postgres.ts';\nimport { PostgresRowCountGrounding } from './row-count.postgres.grounding.ts';\nimport { PostgresTableGrounding } from './table.postgres.grounding.ts';\nimport { PostgresViewGrounding } from './view.postgres.grounding.ts';\n\nexport * from './postgres.ts';\nexport { PostgresSqlPolicyAnalyzer } from './postgres.sql-policy.ts';\n\nexport function tables(config: TableGroundingConfig = {}) {\n return groundingFor(\n Postgres,\n (adapter) => new PostgresTableGrounding(adapter, config),\n );\n}\n\nexport function info(config: InfoGroundingConfig = {}) {\n return (adapter: Adapter) => new PostgresInfoGrounding(adapter, config);\n}\n\nexport function views(config: ViewGroundingConfig = {}) {\n return groundingFor(\n Postgres,\n (adapter) => new PostgresViewGrounding(adapter, config),\n );\n}\n\nexport function columnStats(config: ColumnStatsGroundingConfig = {}) {\n return (adapter: Adapter) => {\n return new PostgresColumnStatsGrounding(adapter, config);\n };\n}\n\nexport function columnValues(config: ColumnValuesGroundingConfig = {}) {\n return (adapter: Adapter) => {\n return new PostgresColumnValuesGrounding(adapter, config);\n };\n}\n\nexport function indexes(config: IndexesGroundingConfig = {}) {\n return (adapter: Adapter) => {\n return new PostgresIndexesGrounding(adapter, config);\n };\n}\n\nexport function rowCount(config: RowCountGroundingConfig = {}) {\n return (adapter: Adapter) => {\n return new PostgresRowCountGrounding(adapter, config);\n };\n}\n\nexport function constraints(config: ConstraintGroundingConfig = {}) {\n return (adapter: Adapter) => {\n return new PostgresConstraintGrounding(adapter, config);\n };\n}\n\nexport default {\n tables,\n info,\n views,\n columnStats,\n columnValues,\n indexes,\n rowCount,\n constraints,\n Postgres,\n};\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["column", "c", "column", "constraint", "table", "column", "constraints", "table", "table", "index", "column", "table", "tables", "index", "z", "z", "z", "table", "column", "z", "z", "textValueRow", "column", "table", "z", "z", "table", "constraints", "z", "z", "table", "indexes", "table", "table", "z", "z", "table", "z", "z", "z", "table", "relationship", "views", "index", "view"]
|
|
4
|
+
"sourcesContent": ["import pMemoize from 'p-memoize';\nimport { type SqlLanguage, format as formatSql } from 'sql-formatter';\nimport { z } from 'zod';\n\nimport type { ContextFragment, FragmentObject } from '@deepagents/context';\n\nimport { SQLReadOnlyError, SQLScopeError } from '../agents/exceptions.ts';\nimport {\n column,\n constraint,\n dialectInfo,\n index,\n relationship,\n table,\n view,\n} from '../fragments/schema.ts';\nimport type { AbstractGrounding } from './groundings/abstract.grounding.ts';\nimport {\n type GroundingContext,\n createGroundingContext,\n} from './groundings/context.ts';\nimport type { View } from './groundings/view.grounding.ts';\nimport {\n type SqlPolicyAnalyzer,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\nexport {\n type SqlPolicyAnalyzer,\n type SqlPolicyContext,\n type SqlPolicyViolation,\n} from './sql-policy.ts';\n\n/**\n * Filter type for view/table names.\n * - string[]: explicit list of view names\n * - RegExp: pattern to match view names\n * - function: predicate to filter view names\n */\nexport type Filter = string[] | RegExp | ((viewName: string) => boolean);\n\nexport interface Table {\n name: string;\n schema?: string;\n rawName?: string;\n columns: {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n isIndexed?: boolean;\n stats?: ColumnStats;\n }[];\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n indexes?: TableIndex[];\n constraints?: TableConstraint[];\n}\n\nexport interface TableIndex {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}\n\nexport interface TableConstraint {\n name: string;\n type:\n 'CHECK' | 'UNIQUE' | 'NOT_NULL' | 'DEFAULT' | 'PRIMARY_KEY' | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}\n\nexport interface ColumnStats {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n}\n\nexport type Relationship = {\n table: string;\n from: string[];\n referenced_table: string;\n to: string[];\n};\n\nexport type TablesFilter = string[] | RegExp;\n\nexport interface Introspection {\n tables: Table[];\n relationships: Relationship[];\n}\n\nexport interface AdapterInfo {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}\n\nexport type AdapterInfoProvider =\n AdapterInfo | (() => Promise<AdapterInfo> | AdapterInfo);\n\nexport type IntrospectionPhase =\n | 'info'\n | 'tables'\n | 'views'\n | 'row_counts'\n | 'constraints'\n | 'indexes'\n | 'column_stats'\n | 'column_values'\n | 'low_cardinality'\n | 'relationships'\n | 'definitions';\n\nexport type IntrospectionProgressType =\n 'phase:start' | 'phase:progress' | 'phase:end';\n\nexport interface IntrospectionProgress {\n type: IntrospectionProgressType;\n phase: IntrospectionPhase;\n message: string;\n table?: string;\n current?: number;\n total?: number;\n timestampMs?: number;\n}\n\nexport type OnProgress = (progress: IntrospectionProgress) => void;\n\nexport type GroundingFn = (adapter: Adapter) => AbstractGrounding;\n\n/**\n * Builds a grounding factory for a grounding that needs a concrete adapter's\n * API (BigQuery datasets, DuckDB namespaces, ...). Given any other adapter,\n * the factory throws.\n */\nexport function groundingFor<A extends Adapter>(\n adapterType: abstract new (...args: never[]) => A,\n create: (adapter: A) => AbstractGrounding,\n): GroundingFn {\n return (adapter) => {\n if (!(adapter instanceof adapterType)) {\n throw new Error(\n `A ${adapterType.name} grounding needs a ${adapterType.name} adapter, not ${adapter.constructor.name}.`,\n );\n }\n return create(adapter);\n };\n}\n\nexport type ExecuteFunction = (sql: string) => Promise<any> | any;\nexport type ValidateFunction = (\n sql: string,\n) => Promise<string | void> | string | void;\n\nexport abstract class Adapter {\n readonly #policyAnalyzer: SqlPolicyAnalyzer;\n\n /**\n * Injects the strategy that guards validate() and execute().\n */\n protected constructor(policyAnalyzer: SqlPolicyAnalyzer) {\n this.#policyAnalyzer = policyAnalyzer;\n }\n\n abstract grounding: GroundingFn[];\n\n abstract readonly formatterLanguage: SqlLanguage;\n\n /**\n * Default schema name for this database.\n * PostgreSQL: 'public', SQL Server: 'dbo', SQLite: undefined\n */\n abstract readonly defaultSchema: string | undefined;\n\n /**\n * System schemas to exclude from introspection by default.\n */\n abstract readonly systemSchemas: string[];\n\n /**\n * Introspect the database schema and return context fragments.\n *\n * Executes all configured groundings to populate the context, then\n * generates fragments from the complete context data.\n *\n * @param ctx - Optional grounding context for sharing state between groundings\n * @returns Array of context fragments representing the database schema\n */\n async introspect(ctx = createGroundingContext()): Promise<ContextFragment[]> {\n // Phase 1: All groundings populate ctx\n for (const fn of this.grounding) {\n const grounding = fn(this);\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:start',\n phase: grounding.phase,\n message: `Starting ${grounding.name} introspection...`,\n });\n }\n try {\n await grounding.execute(ctx);\n } finally {\n if (grounding.phase) {\n ctx.onProgress({\n type: 'phase:end',\n phase: grounding.phase,\n message: `Finished ${grounding.name} introspection.`,\n });\n }\n }\n }\n\n // Phase 2: Generate fragments from complete ctx\n return this.#toSchemaFragments(ctx);\n }\n\n /**\n * Resolve the allowed entity names (tables + views) from grounding config.\n * Asks each grounding to contribute its entities; annotators contribute\n * nothing, so their metadata scans are skipped.\n * Results are NOT cached \u2014 call once and store the result.\n */\n async resolveAllowedEntities(): Promise<string[]> {\n const ctx = createGroundingContext();\n for (const fn of this.grounding) {\n await fn(this).contributeEntities(ctx);\n }\n return [...ctx.tables.map((t) => t.name), ...ctx.views.map((v) => v.name)];\n }\n\n /**\n * Convert complete grounding context to schema fragments.\n * Called after all groundings have populated ctx with data.\n */\n #toSchemaFragments(ctx: GroundingContext): ContextFragment[] {\n const fragments: ContextFragment[] = [];\n\n // Dialect info\n if (ctx.info) {\n fragments.push(\n dialectInfo({\n dialect: ctx.info.dialect,\n version: ctx.info.version,\n database: ctx.info.database,\n details: ctx.info.details,\n }),\n );\n }\n\n // Tables (with all annotations now included)\n for (const t of ctx.tables) {\n fragments.push(this.#tableToFragment(t));\n }\n\n // Views\n for (const v of ctx.views) {\n fragments.push(this.#viewToFragment(v));\n }\n\n // Relationships \u2014 filter out FK columns that were removed by column restriction\n const tableMap = new Map(ctx.tables.map((t) => [t.name, t]));\n const tableColumnSets = new Map(\n ctx.tables.map((t) => [t.name, new Set(t.columns.map((c) => c.name))]),\n );\n for (const rel of ctx.relationships) {\n const sourceColumns = tableColumnSets.get(rel.table);\n const targetColumns = tableColumnSets.get(rel.referenced_table);\n if (\n sourceColumns &&\n rel.from.some((column) => !sourceColumns.has(column))\n ) {\n continue;\n }\n if (\n targetColumns &&\n rel.to.some((column) => !targetColumns.has(column))\n ) {\n continue;\n }\n\n const sourceTable = tableMap.get(rel.table);\n const targetTable = tableMap.get(rel.referenced_table);\n fragments.push(\n this.#relationshipToFragment(rel, sourceTable, targetTable),\n );\n }\n\n fragments.push(...(ctx.fragments ?? []));\n\n return fragments;\n }\n\n /**\n * Convert a Table to a table fragment with nested column, index, and constraint fragments.\n */\n #tableToFragment(t: Table): ContextFragment {\n // Build constraint lookup maps for column-level annotations\n const pkConstraint = t.constraints?.find((c) => c.type === 'PRIMARY_KEY');\n const pkColumns = new Set(pkConstraint?.columns ?? []);\n\n const notNullColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'NOT_NULL')\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n const defaultByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'DEFAULT') ?? []) {\n for (const col of c.columns ?? []) {\n if (c.defaultValue != null) {\n defaultByColumn.set(col, c.defaultValue);\n }\n }\n }\n\n // Single-column UNIQUE constraints\n const uniqueColumns = new Set(\n t.constraints\n ?.filter((c) => c.type === 'UNIQUE' && c.columns?.length === 1)\n .flatMap((c) => c.columns ?? []) ?? [],\n );\n\n // Foreign key lookup: column -> referenced table.column\n const fkByColumn = new Map<string, string>();\n for (const c of t.constraints?.filter((c) => c.type === 'FOREIGN_KEY') ??\n []) {\n const cols = c.columns ?? [];\n const refCols = c.referencedColumns ?? [];\n for (let i = 0; i < cols.length; i++) {\n const refCol = refCols[i] ?? refCols[0] ?? cols[i];\n fkByColumn.set(cols[i], `${c.referencedTable}.${refCol}`);\n }\n }\n\n // Build column fragments\n const columnFragments = t.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n pk: pkColumns.has(col.name) || undefined,\n fk: fkByColumn.get(col.name),\n unique: uniqueColumns.has(col.name) || undefined,\n notNull: notNullColumns.has(col.name) || undefined,\n default: defaultByColumn.get(col.name),\n indexed: col.isIndexed || undefined,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n // Set of present column names for cascade-cleaning indexes/constraints\n const presentColumns = new Set(t.columns.map((c) => c.name));\n\n // Build index fragments\n const indexFragments = (t.indexes ?? [])\n .filter((idx) =>\n idx.columns.every((column) => presentColumns.has(column)),\n )\n .map((idx) =>\n index({\n name: idx.name,\n columns: idx.columns,\n unique: idx.unique,\n type: idx.type,\n }),\n );\n\n // Build constraint fragments for multi-column UNIQUE and CHECK constraints\n const constraintFragments = (t.constraints ?? [])\n .filter(\n (c) =>\n c.type === 'CHECK' ||\n (c.type === 'UNIQUE' && (c.columns?.length ?? 0) > 1),\n )\n .filter(\n (c) =>\n !c.columns?.length ||\n c.columns.every((column) => presentColumns.has(column)),\n )\n .map((c) =>\n constraint({\n name: c.name,\n type: c.type,\n columns: c.columns,\n definition: c.definition,\n }),\n );\n\n return table({\n name: t.name,\n schema: t.schema,\n rowCount: t.rowCount,\n sizeHint: t.sizeHint,\n columns: columnFragments,\n indexes: indexFragments.length > 0 ? indexFragments : undefined,\n constraints:\n constraintFragments.length > 0 ? constraintFragments : undefined,\n });\n }\n\n /**\n * Convert a View to a view fragment with nested column fragments.\n */\n #viewToFragment(v: View): ContextFragment {\n const columnFragments = v.columns.map((col) =>\n column({\n name: col.name,\n type: col.type,\n values: col.values,\n stats: col.stats,\n }),\n );\n\n return view({\n name: v.name,\n schema: v.schema,\n columns: columnFragments,\n definition: v.definition,\n });\n }\n\n /**\n * Convert a Relationship to a relationship fragment.\n * Infers cardinality from row counts if available.\n */\n #relationshipToFragment(\n rel: Relationship,\n sourceTable?: Table,\n targetTable?: Table,\n ): ContextFragment {\n const sourceCount = sourceTable?.rowCount;\n const targetCount = targetTable?.rowCount;\n\n let cardinality:\n 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many' | undefined;\n\n if (sourceCount != null && targetCount != null && targetCount > 0) {\n const ratio = sourceCount / targetCount;\n if (ratio > 5) {\n cardinality = 'many-to-one';\n } else if (ratio < 1.2 && ratio > 0.8) {\n cardinality = 'one-to-one';\n } else if (ratio < 0.2) {\n cardinality = 'one-to-many';\n }\n }\n\n return relationship({\n from: { table: rel.table, columns: rel.from },\n to: { table: rel.referenced_table, columns: rel.to },\n cardinality,\n });\n }\n format(sql: string): string {\n const decoded = this.#decodeShellEscapes(sql);\n try {\n return formatSql(decoded, { language: this.formatterLanguage });\n } catch {\n return decoded;\n }\n }\n\n #decodeShellEscapes(sql: string): string {\n return sql\n .replace(/\\\\n/g, '\\n')\n .replace(/\\\\t/g, '\\t')\n .replace(/\\\\([().*$])/g, '$1')\n .replace(/\\\\(?=$)/gm, '');\n }\n\n readonly #resolveScope = pMemoize(() => this.resolveAllowedEntities());\n\n async #analyzePolicy(sql: string): Promise<SqlPolicyViolation | null> {\n return this.#policyAnalyzer.analyze(sql, {\n resolveAllowedEntities: () => this.#resolveScope(),\n });\n }\n\n async validate(sql: string): Promise<string | void> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') return violation.message;\n if (violation?.kind === 'scope') return JSON.stringify(violation.payload);\n return this.validateImpl(decoded);\n }\n\n async execute(sql: string): Promise<any[]> {\n return this.executeImpl(await this.enforceExecutionPolicy(sql));\n }\n\n protected async enforceExecutionPolicy(sql: string): Promise<string> {\n const decoded = this.#decodeShellEscapes(sql);\n const violation = await this.#analyzePolicy(decoded);\n if (violation?.kind === 'read-only') {\n throw new SQLReadOnlyError(violation.message);\n }\n if (violation?.kind === 'scope') {\n throw new SQLScopeError(violation.payload);\n }\n return decoded;\n }\n\n abstract executeImpl(sql: string): Promise<any[]> | any[];\n abstract validateImpl(sql: string): Promise<string | void> | string | void;\n\n /**\n * Run an introspection query and check every row against `row`, the shape\n * the driver returns for that query. A row of any other shape throws.\n */\n async runQuery<RowSchema extends z.ZodType>(\n sql: string,\n row: RowSchema,\n ): Promise<z.output<RowSchema>[]> {\n const rows = z.array(row).safeParse(await this.queryRows(sql));\n if (!rows.success) {\n throw new Error(\n `${this.constructor.name} introspection query returned rows of an unexpected shape:\\n${z.prettifyError(rows.error)}\\nSQL: ${sql.trim()}`,\n { cause: rows.error },\n );\n }\n return rows.data;\n }\n\n /**\n * Run an introspection query through the driver and return its rows as the\n * driver produced them.\n */\n protected abstract queryRows(sql: string): Promise<unknown[]> | unknown[];\n\n /**\n * The rows in a driver's execute() result: the result itself when it is an\n * array, otherwise the first array found at one of `paths` (dot-separated,\n * so `recordsets.0` reads `result.recordsets[0]`).\n */\n protected rowsFrom(result: unknown, paths: readonly string[]): unknown[] {\n if (Array.isArray(result)) return result;\n for (const path of paths) {\n const rows = path\n .split('.')\n .reduce<unknown>(\n (value, key) =>\n typeof value === 'object' && value !== null\n ? Reflect.get(value, key)\n : undefined,\n result,\n );\n if (Array.isArray(rows)) return rows;\n }\n throw new Error(\n `${this.constructor.name} execute() must return an array of rows or an object holding one at ${paths.map((path) => `result.${path}`).join(', ')}.`,\n );\n }\n\n /**\n * Quote an identifier (table/column name) for safe use in SQL.\n * Each database uses different quoting styles.\n */\n abstract quoteIdentifier(name: string): string;\n\n /**\n * Escape a string value for safe use in SQL.\n * Each database escapes different characters.\n */\n abstract escape(value: string): string;\n\n /**\n * Build a SELECT query to sample rows from a table.\n * Each database uses different syntax for limiting rows (LIMIT vs TOP).\n */\n abstract buildSampleRowsQuery(\n tableName: string,\n columns: string[] | undefined,\n limit: number,\n ): string;\n\n /**\n * Convert unknown database value to number.\n * Handles number, bigint, and string types.\n */\n toNumber(value: unknown): number | undefined {\n if (typeof value === 'number' && Number.isFinite(value)) {\n return value;\n }\n if (typeof value === 'bigint') {\n return Number(value);\n }\n if (typeof value === 'string' && value.trim() !== '') {\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : undefined;\n }\n return undefined;\n }\n\n /**\n * Parse a potentially qualified table name into schema and table parts.\n */\n parseTableName(name: string): { schema: string; table: string } {\n if (name.includes('.')) {\n const [schema, ...rest] = name.split('.');\n return { schema, table: rest.join('.') };\n }\n return { schema: this.defaultSchema ?? '', table: name };\n }\n\n /**\n * Escape a string value for use in SQL string literals (single quotes).\n * Used in WHERE clauses like: WHERE name = '${escapeString(value)}'\n */\n escapeString(value: string): string {\n return value.replace(/'/g, \"''\");\n }\n\n /**\n * Build a SQL filter clause to include/exclude schemas.\n * @param columnName - The schema column name (e.g., 'TABLE_SCHEMA')\n * @param allowedSchemas - If provided, filter to these schemas only\n */\n buildSchemaFilter(columnName: string, allowedSchemas?: string[]): string {\n if (allowedSchemas && allowedSchemas.length > 0) {\n const values = allowedSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} IN (${values})`;\n }\n if (this.systemSchemas.length > 0) {\n const values = this.systemSchemas\n .map((s) => `'${this.escapeString(s)}'`)\n .join(', ');\n return `AND ${columnName} NOT IN (${values})`;\n }\n return '';\n }\n}\n\nexport function filterTablesByName<T extends { name: string }>(\n tables: T[],\n filter: TablesFilter | undefined,\n): T[] {\n if (!filter) return tables;\n return tables.filter((table) => matchesFilter(table.name, filter));\n}\n\nexport function filterRelationshipsByTables(\n relationships: Relationship[],\n tableNames: Set<string> | undefined,\n): Relationship[] {\n if (tableNames === undefined) {\n return relationships;\n }\n if (tableNames.size === 0) {\n return [];\n }\n return relationships.filter(\n (it) => tableNames.has(it.table) || tableNames.has(it.referenced_table),\n );\n}\n\nexport function applyTablesFilter(\n tables: Table[],\n relationships: Relationship[],\n filter: TablesFilter | undefined,\n): { tables: Table[]; relationships: Relationship[] } {\n if (!filter) {\n return { tables, relationships };\n }\n\n const allowedNames = new Set(\n getTablesWithRelated(tables, relationships, filter),\n );\n\n return {\n tables: tables.filter((table) => allowedNames.has(table.name)),\n relationships: filterRelationshipsByTables(relationships, allowedNames),\n };\n}\n\nexport function matchesFilter(\n tableName: string,\n filter: TablesFilter,\n): boolean {\n if (Array.isArray(filter)) {\n return filter.includes(tableName);\n }\n return filter.test(tableName);\n}\n\nexport function getTablesWithRelated(\n allTables: Table[],\n relationships: Relationship[],\n filter: TablesFilter,\n): string[] {\n const matchedTables = filterTablesByName(allTables, filter).map(\n (it) => it.name,\n );\n\n if (matchedTables.length === 0) {\n return [];\n }\n\n const adjacency = new Map<string, Set<string>>();\n\n for (const rel of relationships) {\n if (!adjacency.has(rel.table)) {\n adjacency.set(rel.table, new Set());\n }\n if (!adjacency.has(rel.referenced_table)) {\n adjacency.set(rel.referenced_table, new Set());\n }\n adjacency.get(rel.table)!.add(rel.referenced_table);\n adjacency.get(rel.referenced_table)!.add(rel.table);\n }\n\n const result = new Set<string>(matchedTables);\n const queue = [...matchedTables];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const neighbors = adjacency.get(current);\n\n if (!neighbors) {\n continue;\n }\n\n for (const neighbor of neighbors) {\n if (!result.has(neighbor)) {\n result.add(neighbor);\n queue.push(neighbor);\n }\n }\n }\n\n return Array.from(result);\n}\n", "const sqlValidationMarker = Symbol('SQLValidationError');\nconst unanswerableSqlMarker = Symbol('UnanswerableSQLError');\nconst sqlScopeMarker = Symbol('SQLScopeError');\nconst sqlReadOnlyMarker = Symbol('SQLReadOnlyError');\n\nexport type SQLScopeErrorType = 'OUT_OF_SCOPE' | 'SQL_SCOPE_PARSE_ERROR';\n\nexport interface SQLScopeErrorPayload {\n error: string;\n error_type: SQLScopeErrorType;\n suggestion: string;\n sql_attempted: string;\n referenced_entities?: string[];\n allowed_entities?: string[];\n parser_dialect?: string;\n parser_error?: string;\n}\n\n/**\n * Error thrown when SQL validation fails.\n */\nexport class SQLValidationError extends Error {\n [sqlValidationMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLValidationError';\n this[sqlValidationMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLValidationError {\n return (\n error instanceof SQLValidationError && error[sqlValidationMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when the question cannot be answered with the given schema.\n */\nexport class UnanswerableSQLError extends Error {\n [unanswerableSqlMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'UnanswerableSQLError';\n this[unanswerableSqlMarker] = true;\n }\n\n static isInstance(error: unknown): error is UnanswerableSQLError {\n return (\n error instanceof UnanswerableSQLError &&\n error[unanswerableSqlMarker] === true\n );\n }\n}\n\n/**\n * Error thrown when a query falls outside the grounded SQL scope.\n */\nexport class SQLScopeError extends Error {\n [sqlScopeMarker]: true;\n readonly payload: SQLScopeErrorPayload;\n readonly errorType: SQLScopeErrorType;\n\n constructor(payload: SQLScopeErrorPayload) {\n super(JSON.stringify(payload));\n this.name = 'SQLScopeError';\n this.payload = payload;\n this.errorType = payload.error_type;\n this[sqlScopeMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLScopeError {\n return error instanceof SQLScopeError && error[sqlScopeMarker] === true;\n }\n}\n\n/**\n * Error thrown when a query is not read-only (does not start with SELECT or WITH).\n */\nexport class SQLReadOnlyError extends Error {\n [sqlReadOnlyMarker]: true;\n\n constructor(message: string) {\n super(message);\n this.name = 'SQLReadOnlyError';\n this[sqlReadOnlyMarker] = true;\n }\n\n static isInstance(error: unknown): error is SQLReadOnlyError {\n return (\n error instanceof SQLReadOnlyError && error[sqlReadOnlyMarker] === true\n );\n }\n}\n", "import type { ContextFragment, FragmentObject } from '@deepagents/context';\n\n/**\n * Schema fragment builders.\n *\n * These fragments represent database schema metadata that can be injected\n * into AI prompts. Use with renderers (XML, Markdown, TOML, TOON) to format.\n *\n * @example\n * ```ts\n * import { dialectInfo, table, column, relationship } from '@deepagents/text2sql';\n *\n * const schemaFragments = [\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5' }),\n * table({\n * name: 'users',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true }),\n * ],\n * }),\n * ];\n * ```\n */\n\n/**\n * Database dialect and version information.\n *\n * @param input.dialect - Database type (PostgreSQL, SQLite, SQL Server, etc.)\n * @param input.version - Database version string\n * @param input.database - Database name\n *\n * @example\n * dialectInfo({ dialect: 'PostgreSQL', version: '14.5', database: 'myapp' })\n */\nexport function dialectInfo(input: {\n dialect: string;\n version?: string;\n database?: string;\n details?: FragmentObject;\n}): ContextFragment {\n return {\n name: 'dialectInfo',\n data: {\n dialect: input.dialect,\n ...(input.version && { version: input.version }),\n ...(input.database && { database: input.database }),\n ...(input.details && { details: input.details }),\n },\n };\n}\n\n/**\n * Database table with columns and optional metadata.\n *\n * @param input.name - Table name\n * @param input.schema - Schema name (e.g., 'public' for PostgreSQL)\n * @param input.rowCount - Approximate row count\n * @param input.sizeHint - Size category for query optimization hints\n * @param input.columns - Array of column() fragments\n * @param input.indexes - Array of index() fragments\n * @param input.constraints - Array of constraint() fragments\n *\n * @example\n * table({\n * name: 'users',\n * rowCount: 1500,\n * sizeHint: 'medium',\n * columns: [\n * column({ name: 'id', type: 'integer', pk: true }),\n * column({ name: 'email', type: 'varchar', unique: true, indexed: true }),\n * ],\n * indexes: [\n * index({ name: 'idx_email', columns: ['email'], unique: true }),\n * ],\n * })\n */\nexport function table(input: {\n name: string;\n schema?: string;\n rowCount?: number;\n sizeHint?: 'tiny' | 'small' | 'medium' | 'large' | 'huge';\n columns: ContextFragment[];\n indexes?: ContextFragment[];\n constraints?: ContextFragment[];\n}): ContextFragment {\n return {\n name: 'table',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n ...(input.rowCount != null && { rowCount: input.rowCount }),\n ...(input.sizeHint && { sizeHint: input.sizeHint }),\n columns: input.columns,\n ...(input.indexes?.length && { indexes: input.indexes }),\n ...(input.constraints?.length && { constraints: input.constraints }),\n },\n };\n}\n\n/**\n * Table column with type and annotations.\n *\n * @param input.name - Column name\n * @param input.type - Column data type (e.g., 'integer', 'varchar(255)')\n * @param input.pk - Is primary key\n * @param input.fk - Foreign key reference in \"table.column\" format\n * @param input.unique - Has unique constraint\n * @param input.notNull - Has NOT NULL constraint\n * @param input.default - Default value expression\n * @param input.indexed - Has index on this column\n * @param input.values - Enum or low cardinality values\n * @param input.stats - Column statistics (min, max, null fraction)\n *\n * @example\n * column({\n * name: 'status',\n * type: 'varchar',\n * notNull: true,\n * indexed: true,\n * values: ['active', 'inactive', 'suspended'],\n * })\n */\nexport function column(input: {\n name: string;\n type: string;\n pk?: boolean;\n fk?: string;\n unique?: boolean;\n notNull?: boolean;\n default?: string;\n indexed?: boolean;\n values?: string[];\n stats?: {\n min?: string;\n max?: string;\n nullFraction?: number;\n nDistinct?: number;\n correlation?: number;\n };\n}): ContextFragment {\n return {\n name: 'column',\n data: {\n name: input.name,\n type: input.type,\n ...(input.pk && { pk: true }),\n ...(input.fk && { fk: input.fk }),\n ...(input.unique && { unique: true }),\n ...(input.notNull && { notNull: true }),\n ...(input.default && { default: input.default }),\n ...(input.indexed && { indexed: true }),\n ...(input.values?.length && { values: input.values }),\n ...(input.stats && { stats: input.stats }),\n },\n };\n}\n\n/**\n * Table index.\n *\n * @param input.name - Index name\n * @param input.columns - Columns included in the index\n * @param input.unique - Is unique index\n * @param input.type - Index type (BTREE, HASH, GIN, etc.)\n *\n * @example\n * index({ name: 'idx_user_email', columns: ['email'], unique: true, type: 'BTREE' })\n */\nexport function index(input: {\n name: string;\n columns: string[];\n unique?: boolean;\n type?: string;\n}): ContextFragment {\n return {\n name: 'index',\n data: {\n name: input.name,\n columns: input.columns,\n ...(input.unique && { unique: true }),\n ...(input.type && { type: input.type }),\n },\n };\n}\n\n/**\n * Table constraint (CHECK, UNIQUE, PRIMARY_KEY, FOREIGN_KEY, etc).\n *\n * @param input.name - Constraint name\n * @param input.type - Constraint type\n * @param input.columns - Columns involved in the constraint\n * @param input.definition - CHECK constraint SQL definition\n * @param input.defaultValue - DEFAULT constraint value\n * @param input.referencedTable - For FK: referenced table name\n * @param input.referencedColumns - For FK: referenced column names\n *\n * @example\n * constraint({\n * name: 'chk_amount_positive',\n * type: 'CHECK',\n * definition: 'amount > 0',\n * })\n *\n * @example\n * constraint({\n * name: 'fk_order_user',\n * type: 'FOREIGN_KEY',\n * columns: ['user_id'],\n * referencedTable: 'users',\n * referencedColumns: ['id'],\n * })\n */\nexport function constraint(input: {\n name: string;\n type:\n | 'CHECK'\n | 'UNIQUE'\n | 'NOT_NULL'\n | 'DEFAULT'\n | 'PRIMARY_KEY'\n | 'FOREIGN_KEY';\n columns?: string[];\n definition?: string;\n defaultValue?: string;\n referencedTable?: string;\n referencedColumns?: string[];\n}): ContextFragment {\n return {\n name: 'constraint',\n data: {\n name: input.name,\n type: input.type,\n ...(input.columns?.length && { columns: input.columns }),\n ...(input.definition && { definition: input.definition }),\n ...(input.defaultValue && { defaultValue: input.defaultValue }),\n ...(input.referencedTable && { referencedTable: input.referencedTable }),\n ...(input.referencedColumns?.length && {\n referencedColumns: input.referencedColumns,\n }),\n },\n };\n}\n\n/**\n * Database view.\n *\n * @param input.name - View name\n * @param input.schema - Schema name\n * @param input.columns - Array of column() fragments\n * @param input.definition - View SQL definition\n *\n * @example\n * view({\n * name: 'active_users',\n * columns: [\n * column({ name: 'id', type: 'integer' }),\n * column({ name: 'email', type: 'varchar' }),\n * ],\n * definition: \"SELECT id, email FROM users WHERE status = 'active'\",\n * })\n */\nexport function view(input: {\n name: string;\n schema?: string;\n columns: ContextFragment[];\n definition?: string;\n}): ContextFragment {\n return {\n name: 'view',\n data: {\n name: input.name,\n ...(input.schema && { schema: input.schema }),\n columns: input.columns,\n ...(input.definition && { definition: input.definition }),\n },\n };\n}\n\n/**\n * Relationship between tables (foreign key connection).\n *\n * @param input.from - Source table and columns\n * @param input.to - Referenced table and columns\n * @param input.cardinality - Relationship cardinality\n *\n * @example\n * relationship({\n * from: { table: 'orders', columns: ['user_id'] },\n * to: { table: 'users', columns: ['id'] },\n * cardinality: 'many-to-one',\n * })\n */\nexport function relationship(input: {\n from: { table: string; columns: string[] };\n to: { table: string; columns: string[] };\n cardinality?: 'one-to-one' | 'one-to-many' | 'many-to-one' | 'many-to-many';\n}): ContextFragment {\n return {\n name: 'relationship',\n data: {\n from: input.from,\n to: input.to,\n ...(input.cardinality && { cardinality: input.cardinality }),\n },\n };\n}\n", "import type { ContextFragment } from '@deepagents/context';\n\nimport type {\n AdapterInfo,\n ColumnStats,\n OnProgress,\n Relationship,\n Table,\n} from '../adapter.ts';\nimport type { View } from './view.grounding.ts';\n\n/**\n * Column type for grounding operations.\n * Common interface between Table.columns and View.columns.\n */\nexport interface Column {\n name: string;\n type: string;\n kind?: 'LowCardinality' | 'Enum';\n values?: string[];\n stats?: ColumnStats;\n}\n\n/**\n * Entity with columns (Table or View).\n */\nexport interface ColumnContainer {\n name: string;\n columns: Column[];\n}\n\n/**\n * Shared context object passed to all groundings.\n * Groundings read from and write to this context.\n */\nexport interface GroundingContext {\n /** Tables discovered by TableGrounding */\n tables: Table[];\n\n /** Views discovered by ViewGrounding */\n views: View[];\n\n /** Relationships discovered by TableGrounding */\n relationships: Relationship[];\n\n /** Database info collected by InfoGrounding */\n info?: AdapterInfo;\n\n /** Adapter-specific fragments contributed during grounding. */\n fragments?: ContextFragment[];\n\n /** Shared cache for cross-grounding deduplication. Keyed by `type:key`. */\n cache: Map<string, unknown>;\n\n /** Progress sink for long-running introspection work. */\n onProgress: OnProgress;\n}\n\nconst noopProgress: OnProgress = () => {};\n\nfunction timestampProgress(onProgress?: OnProgress): OnProgress {\n if (!onProgress) return noopProgress;\n return (progress) => {\n onProgress({\n ...progress,\n timestampMs: progress.timestampMs ?? Date.now(),\n });\n };\n}\n\n/**\n * Create a new empty grounding context.\n */\nexport function createGroundingContext(\n options: { onProgress?: OnProgress } = {},\n): GroundingContext {\n return {\n tables: [],\n views: [],\n relationships: [],\n info: undefined,\n fragments: [],\n cache: new Map(),\n onProgress: timestampProgress(options.onProgress),\n };\n}\n", "import type { Filter, IntrospectionPhase } from '../adapter.ts';\nimport type { GroundingContext } from './context.ts';\n\nexport type { AdapterInfo, AdapterInfoProvider, Filter } from '../adapter.ts';\n\n/**\n * Per-entity column filter.\n * Maps entity name (table or view) to a Filter that selects which columns to keep.\n * Entities not listed in the record keep all their columns.\n */\nexport type ColumnsFilter = Record<string, Filter>;\n\n/**\n * Filter a columns array using a Filter.\n * Keeps columns whose name matches the filter.\n */\nexport function filterColumns<T extends { name: string }>(\n columns: T[],\n filter: Filter,\n): T[] {\n if (Array.isArray(filter)) {\n return columns.filter((col) => filter.includes(col.name));\n }\n if (filter instanceof RegExp) {\n return columns.filter((col) => filter.test(col.name));\n }\n return columns.filter((col) => filter(col.name));\n}\n\n/**\n * Apply per-entity column filtering.\n * Returns the entity unchanged if no filter matches its name.\n */\nexport function applyColumnFilter<\n T extends { name: string; columns: { name: string }[] },\n>(entity: T, columnsConfig?: ColumnsFilter): T {\n if (!columnsConfig) return entity;\n const filter = columnsConfig[entity.name];\n if (!filter) return entity;\n return { ...entity, columns: filterColumns(entity.columns, filter) };\n}\n\n/**\n * Abstract base class for database schema groundings.\n *\n * Groundings collect schema metadata into the shared GroundingContext.\n * Fragment generation is centralized in Adapter.introspect().\n */\nexport abstract class AbstractGrounding {\n /**\n * Grounding identifier for debugging/logging.\n */\n name: string;\n phase?: IntrospectionPhase;\n\n constructor(name: string, phase?: IntrospectionPhase) {\n this.name = name;\n this.phase = phase;\n }\n\n /**\n * Execute grounding to populate the shared context.\n * Groundings mutate ctx to add their collected data (tables, views, indexes, etc).\n * Fragment generation happens centrally in Adapter after all groundings complete.\n *\n * @param ctx - Shared context for accumulating schema data\n */\n abstract execute(ctx: GroundingContext): Promise<void>;\n\n /**\n * Populate ctx with the tables/views this grounding makes available for scope\n * resolution. Annotators decorate entities other groundings produced and add\n * no membership, so the default is a no-op; entity-producing groundings\n * override it. This lets scope resolution skip the annotators' metadata scans.\n *\n * @param _ctx - Shared context for accumulating entity membership\n */\n async contributeEntities(_ctx: GroundingContext): Promise<void> {}\n}\n", "import type { ColumnStats } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { Column, ColumnContainer, GroundingContext } from './context.ts';\n\n/**\n * Configuration for ColumnStatsGrounding.\n */\nexport interface ColumnStatsGroundingConfig {\n // Future: filter which tables/columns to collect stats for\n}\n\n/**\n * Abstract base class for column statistics grounding.\n *\n * Reads tables and views from the context and annotates their columns\n * with statistics (min, max, nullFraction).\n *\n * Subclasses implement database-specific hooks:\n * - `collectStats()` - collect min/max/nullFraction for a column\n */\nexport abstract class ColumnStatsGrounding extends AbstractGrounding {\n constructor(config: ColumnStatsGroundingConfig = {}) {\n super('columnStats', 'column_stats');\n }\n\n /**\n * Collect min/max/nullFraction statistics for a column.\n * Return undefined to skip this column.\n */\n protected abstract collectStats(\n tableName: string,\n column: Column,\n ): Promise<ColumnStats | undefined>;\n\n /**\n * Execute the grounding process.\n * Annotates columns in ctx.tables and ctx.views with statistics.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n // Process both tables and views\n const allContainers: ColumnContainer[] = [...ctx.tables, ...ctx.views];\n const total = allContainers.length;\n for (let i = 0; i < allContainers.length; i++) {\n const container = allContainers[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'column_stats',\n table: container.name,\n message: `Collecting stats for ${container.name}...`,\n current: i + 1,\n total,\n });\n for (const column of container.columns) {\n // Collect min/max/nullFraction\n try {\n const stats = await this.collectStats(container.name, column);\n if (stats) {\n column.stats = stats;\n }\n } catch (error) {\n // Skip on error\n console.warn(\n 'Error collecting stats for',\n container.name,\n column.name,\n error,\n );\n }\n }\n }\n }\n}\n", "import type { Table, TableConstraint } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { Column, ColumnContainer, GroundingContext } from './context.ts';\n\nexport type { Column, ColumnContainer };\n\n/**\n * Result of column value detection.\n */\nexport type ColumnValuesResult = {\n kind: 'Enum' | 'LowCardinality';\n values: string[];\n};\n\n/**\n * Configuration for ColumnValuesGrounding.\n */\nexport interface ColumnValuesGroundingConfig {\n /** Maximum number of distinct values to consider low cardinality (default: 20) */\n lowCardinalityLimit?: number;\n /** Maximum character length for individual values. Columns with any value exceeding this are skipped entirely (default: 100) */\n maxValueLength?: number;\n}\n\n/**\n * Abstract base class for column values grounding.\n *\n * Discovers possible values for columns from three sources (in priority order):\n * 1. Native ENUM types (PostgreSQL, MySQL) \u2192 kind: 'Enum'\n * 2. CHECK constraints with IN clauses \u2192 kind: 'Enum'\n * 3. Low cardinality data scan \u2192 kind: 'LowCardinality'\n *\n * Subclasses implement database-specific hooks:\n * - `collectEnumValues()` - get values for native ENUM columns\n * - `collectLowCardinality()` - collect distinct values via data scan\n */\nexport abstract class ColumnValuesGrounding extends AbstractGrounding {\n protected lowCardinalityLimit: number;\n protected maxValueLength: number;\n\n constructor(config: ColumnValuesGroundingConfig = {}) {\n super('columnValues', 'column_values');\n this.lowCardinalityLimit = config.lowCardinalityLimit ?? 20;\n this.maxValueLength = config.maxValueLength ?? 100;\n }\n\n /**\n * Get values for native ENUM type columns.\n * Return undefined if column is not an ENUM type.\n * Default implementation returns undefined (no native ENUM support).\n */\n protected async collectEnumValues(\n _tableName: string,\n _column: Column,\n ): Promise<string[] | undefined> {\n return undefined;\n }\n\n /**\n * Collect distinct values for low cardinality columns via data scan.\n * Return undefined if column has too many distinct values.\n */\n protected abstract collectLowCardinality(\n tableName: string,\n column: Column,\n ): Promise<string[] | undefined>;\n\n /**\n * Parse CHECK constraint for enum-like IN clause.\n * Extracts values from patterns like:\n * - CHECK (status IN ('active', 'inactive'))\n * - CHECK ((status)::text = ANY (ARRAY['a'::text, 'b'::text]))\n * - CHECK (status = 'active' OR status = 'inactive')\n */\n protected parseCheckConstraint(\n constraint: TableConstraint,\n columnName: string,\n ): string[] | undefined {\n if (constraint.type !== 'CHECK' || !constraint.definition) {\n return undefined;\n }\n\n // Check if constraint applies to this column\n if (constraint.columns && !constraint.columns.includes(columnName)) {\n return undefined;\n }\n\n const def = constraint.definition;\n const escapedCol = this.escapeRegex(columnName);\n\n // Column pattern: matches column name with optional parens and type cast\n // e.g., \"status\", \"(status)\", \"((status)::text)\"\n const colPattern = `(?:\\\\(?\\\\(?${escapedCol}\\\\)?(?:::(?:text|varchar|character varying))?\\\\)?)`;\n\n // Pattern 1: column IN ('val1', 'val2', ...)\n const inMatch = def.match(\n new RegExp(`${colPattern}\\\\s+IN\\\\s*\\\\(([^)]+)\\\\)`, 'i'),\n );\n if (inMatch) {\n return this.extractStringValues(inMatch[1]);\n }\n\n // Pattern 2: PostgreSQL ANY(ARRAY[...])\n const anyMatch = def.match(\n new RegExp(\n `${colPattern}\\\\s*=\\\\s*ANY\\\\s*\\\\(\\\\s*(?:ARRAY)?\\\\s*\\\\[([^\\\\]]+)\\\\]`,\n 'i',\n ),\n );\n if (anyMatch) {\n return this.extractStringValues(anyMatch[1]);\n }\n\n // Pattern 3: column = 'val1' OR column = 'val2' ...\n const orPattern = new RegExp(\n `\\\\b${this.escapeRegex(columnName)}\\\\b\\\\s*=\\\\s*'([^']*)'`,\n 'gi',\n );\n const orMatches = [...def.matchAll(orPattern)];\n if (orMatches.length >= 2) {\n return orMatches.map((m) => m[1]);\n }\n\n return undefined;\n }\n\n /**\n * Extract string values from a comma-separated list.\n */\n private extractStringValues(input: string): string[] | undefined {\n const values: string[] = [];\n // Match quoted strings: 'value' or 'value'::type\n const matches = input.matchAll(/'([^']*)'/g);\n for (const match of matches) {\n values.push(match[1]);\n }\n return values.length > 0 ? values : undefined;\n }\n\n /**\n * Escape special regex characters in a string.\n */\n private escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n }\n\n /**\n * Get the table from context by name.\n */\n private getTable(ctx: GroundingContext, name: string): Table | undefined {\n return ctx.tables.find((t) => t.name === name);\n }\n\n /**\n * Execute the grounding process.\n * Annotates columns in ctx.tables and ctx.views with values.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n // Process both tables and views\n const allContainers: ColumnContainer[] = [...ctx.tables, ...ctx.views];\n\n const total = allContainers.length;\n for (let i = 0; i < allContainers.length; i++) {\n const container = allContainers[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'column_values',\n table: container.name,\n message: `Collecting column values for ${container.name}...`,\n current: i + 1,\n total,\n });\n const table = this.getTable(ctx, container.name);\n\n for (const column of container.columns) {\n try {\n const result = await this.resolveColumnValues(\n container.name,\n column,\n table?.constraints,\n );\n if (result) {\n column.kind = result.kind;\n column.values = result.values;\n }\n } catch (error) {\n console.warn(\n 'Error collecting column values for',\n container.name,\n column.name,\n error,\n );\n }\n }\n }\n }\n\n private exceedsMaxValueLength(values: string[]): boolean {\n return values.some((v) => v.length > this.maxValueLength);\n }\n\n /**\n * Resolve column values from all sources in priority order.\n */\n private async resolveColumnValues(\n tableName: string,\n column: Column,\n constraints?: TableConstraint[],\n ): Promise<ColumnValuesResult | undefined> {\n // Priority 1: Native ENUM type\n const enumValues = await this.collectEnumValues(tableName, column);\n if (enumValues?.length && !this.exceedsMaxValueLength(enumValues)) {\n return { kind: 'Enum', values: enumValues };\n }\n\n // Priority 2: CHECK constraint with IN clause\n if (constraints) {\n for (const constraint of constraints) {\n const checkValues = this.parseCheckConstraint(constraint, column.name);\n if (checkValues?.length && !this.exceedsMaxValueLength(checkValues)) {\n return { kind: 'Enum', values: checkValues };\n }\n }\n }\n\n // Priority 3: Low cardinality data scan\n const lowCardValues = await this.collectLowCardinality(tableName, column);\n if (lowCardValues?.length && !this.exceedsMaxValueLength(lowCardValues)) {\n return { kind: 'LowCardinality', values: lowCardValues };\n }\n\n return undefined;\n }\n}\n", "import type { TableConstraint } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for ConstraintGrounding.\n */\nexport interface ConstraintGroundingConfig {\n // Future: filter which tables/constraint types to collect\n}\n\n/**\n * Abstract base class for constraint grounding.\n *\n * Reads tables from the context and annotates them with constraints\n * (CHECK, UNIQUE, NOT_NULL, DEFAULT).\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getConstraints()` - fetch constraints for a table\n */\nexport abstract class ConstraintGrounding extends AbstractGrounding {\n constructor(config: ConstraintGroundingConfig = {}) {\n super('constraint', 'constraints');\n }\n\n /**\n * Fetch constraints for a specific table.\n */\n protected abstract getConstraints(\n tableName: string,\n ): Promise<TableConstraint[]>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with their constraints.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'constraints',\n table: table.name,\n message: `Loading constraints for ${table.name}...`,\n current: i + 1,\n total,\n });\n try {\n table.constraints = await this.getConstraints(table.name);\n } catch (error) {\n // Skip on error - table might not exist or be inaccessible\n console.warn('Error collecting constraints for', table.name, error);\n }\n }\n }\n}\n", "import type { TableIndex } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for IndexesGrounding.\n */\nexport interface IndexesGroundingConfig {\n // Future: filter which tables to collect indexes for\n}\n\n/**\n * Abstract base class for indexes grounding.\n *\n * Reads tables from the context and annotates them with index metadata.\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getIndexes()` - fetch indexes for a table\n */\nexport abstract class IndexesGrounding extends AbstractGrounding {\n constructor(config: IndexesGroundingConfig = {}) {\n super('index', 'indexes');\n }\n\n /**\n * Fetch indexes for a specific table.\n */\n protected abstract getIndexes(tableName: string): Promise<TableIndex[]>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with their indexes and marks indexed columns.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'indexes',\n table: table.name,\n message: `Loading indexes for ${table.name}...`,\n current: i + 1,\n total,\n });\n table.indexes = await this.getIndexes(table.name);\n // Mark columns that are part of indexes\n for (const index of table.indexes ?? []) {\n for (const colName of index.columns) {\n const column = table.columns.find((c) => c.name === colName);\n if (column) {\n column.isIndexed = true;\n }\n }\n }\n }\n }\n}\n", "import type { AdapterInfo } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for InfoGrounding.\n */\nexport interface InfoGroundingConfig {\n // Future: options to control what info to collect\n}\n\n/**\n * Abstract base class for database info grounding.\n *\n * Collects database dialect, version, and connection info.\n *\n * Subclasses implement the database-specific hook:\n * - `collectInfo()` - collect database info\n */\nexport abstract class InfoGrounding extends AbstractGrounding {\n constructor(config: InfoGroundingConfig = {}) {\n super('dialectInfo', 'info');\n }\n\n /**\n * Collect database dialect, version, and other info.\n */\n protected abstract collectInfo(): Promise<AdapterInfo>;\n\n /**\n * Execute the grounding process.\n * Writes database info to ctx.info.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n ctx.info = await this.collectInfo();\n }\n}\n", "import type { Table } from '../adapter.ts';\nimport { AbstractGrounding } from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for RowCountGrounding.\n */\nexport interface RowCountGroundingConfig {\n // Future: filter which tables to count\n}\n\n/**\n * Abstract base class for row count grounding.\n *\n * Reads tables from the context and annotates them with row counts and size hints.\n * This grounding must run AFTER TableGrounding since it reads from ctx.tables.\n *\n * Subclasses implement the database-specific hook:\n * - `getRowCount()` - get row count for a table\n */\nexport abstract class RowCountGrounding extends AbstractGrounding {\n constructor(config: RowCountGroundingConfig = {}) {\n super('rowCount', 'row_counts');\n }\n\n /**\n * Get row count for a specific table.\n */\n protected abstract getRowCount(\n tableName: string,\n ): Promise<number | undefined>;\n\n /**\n * Execute the grounding process.\n * Annotates tables in ctx.tables with row counts and size hints.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const total = ctx.tables.length;\n for (let i = 0; i < ctx.tables.length; i++) {\n const table = ctx.tables[i];\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'row_counts',\n table: table.name,\n message: `Counting rows in ${table.name}...`,\n current: i + 1,\n total,\n });\n const count = await this.getRowCount(table.name);\n if (count != null) {\n table.rowCount = count;\n table.sizeHint = this.#classifyRowCount(count);\n }\n }\n }\n\n /**\n * Classify row count into a size hint category.\n */\n #classifyRowCount(count: number): Table['sizeHint'] {\n if (count < 100) return 'tiny';\n if (count < 1000) return 'small';\n if (count < 10000) return 'medium';\n if (count < 100000) return 'large';\n return 'huge';\n }\n}\n", "import type { Filter, Relationship, Table } from '../adapter.ts';\nimport {\n AbstractGrounding,\n type ColumnsFilter,\n applyColumnFilter,\n filterColumns,\n} from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Configuration for TableGrounding.\n */\nexport interface TableGroundingConfig {\n /** Filter to select seed tables */\n filter?: Filter;\n /**\n * Per-table column filter.\n * Maps table name to a Filter that selects which columns to keep.\n * Tables not listed keep all their columns.\n */\n columns?: ColumnsFilter;\n /**\n * Traverse forward (child\u2192parent) following FK direction.\n * - true: unlimited depth\n * - number: maximum depth\n * - false/undefined: no forward traversal\n */\n forward?: boolean | number;\n /**\n * Traverse backward (parent\u2192child) finding tables that reference us.\n * - true: unlimited depth\n * - number: maximum depth\n * - false/undefined: no backward traversal\n */\n backward?: boolean | number;\n}\n\n/**\n * Abstract base class for table grounding.\n *\n * The `execute()` method implements a BFS traversal algorithm that discovers\n * tables and relationships. Subclasses implement the database-specific hooks:\n * - `getAllTableNames()` - list all tables\n * - `getTable()` - get table metadata\n * - `findOutgoingRelations()` - find FKs FROM a table\n * - `findIncomingRelations()` - find FKs TO a table\n */\nexport abstract class TableGrounding extends AbstractGrounding {\n #filter?: Filter;\n #columns?: ColumnsFilter;\n #forward?: boolean | number;\n #backward?: boolean | number;\n\n constructor(config: TableGroundingConfig = {}) {\n super('table', 'tables');\n this.#filter = config.filter;\n this.#columns = config.columns;\n this.#forward = config.forward;\n this.#backward = config.backward;\n }\n\n /** Get all table names in the database */\n protected abstract getAllTableNames(): Promise<string[]>;\n\n /** Get full table metadata for a single table */\n protected abstract getTable(tableName: string): Promise<Table>;\n\n /** Find FKs FROM this table (outgoing relationships) */\n protected abstract findOutgoingRelations(\n tableName: string,\n ctx: GroundingContext,\n ): Promise<Relationship[]>;\n\n /** Find FKs TO this table (incoming relationships) */\n protected abstract findIncomingRelations(\n tableName: string,\n ctx: GroundingContext,\n ): Promise<Relationship[]>;\n\n override async contributeEntities(ctx: GroundingContext): Promise<void> {\n await this.execute(ctx);\n }\n\n /**\n * Execute the grounding process.\n * Writes discovered tables and relationships to the context.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const seedTables = await this.applyFilter();\n const forward = this.#forward;\n const backward = this.#backward;\n\n // No traversal at all - just add the seed tables\n if (!forward && !backward) {\n const tables = await Promise.all(\n seedTables.map(async (name, index) => {\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: index + 1,\n total: seedTables.length,\n });\n return applyColumnFilter(await this.getTable(name), this.#columns);\n }),\n );\n ctx.tables.push(...tables);\n return;\n }\n\n const tables: Record<string, Table> = {};\n const allRelationships: Relationship[] = [];\n const seenRelationships = new Set<string>();\n\n // Track depth separately for forward/backward using BFS\n const forwardQueue: Array<{ name: string; depth: number }> = [];\n const backwardQueue: Array<{ name: string; depth: number }> = [];\n const forwardVisited = new Set<string>();\n const backwardVisited = new Set<string>();\n let loadedCount = 0;\n\n // Initialize queues with seed tables at depth 0\n for (const name of seedTables) {\n if (forward) forwardQueue.push({ name, depth: 0 });\n if (backward) backwardQueue.push({ name, depth: 0 });\n }\n\n // Process forward (child\u2192parent)\n const forwardLimit = forward === true ? Infinity : forward || 0;\n while (forwardQueue.length > 0) {\n const item = forwardQueue.shift();\n if (!item) break;\n const { name, depth } = item;\n\n if (forwardVisited.has(name)) continue;\n forwardVisited.add(name);\n\n if (!tables[name]) {\n loadedCount++;\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: loadedCount,\n });\n tables[name] = applyColumnFilter(\n await this.getTable(name),\n this.#columns,\n );\n }\n\n if (depth < forwardLimit) {\n const rels = await this.findOutgoingRelations(name, ctx);\n for (const rel of rels) {\n if (!this.isRelationshipVisible(rel)) continue;\n this.addRelationship(rel, allRelationships, seenRelationships);\n if (!forwardVisited.has(rel.referenced_table)) {\n forwardQueue.push({ name: rel.referenced_table, depth: depth + 1 });\n }\n }\n }\n }\n\n // Process backward (parent\u2192child)\n const backwardLimit = backward === true ? Infinity : backward || 0;\n while (backwardQueue.length > 0) {\n const item = backwardQueue.shift();\n if (!item) break;\n const { name, depth } = item;\n\n if (backwardVisited.has(name)) continue;\n backwardVisited.add(name);\n\n if (!tables[name]) {\n loadedCount++;\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'tables',\n table: name,\n message: `Loading table ${name}...`,\n current: loadedCount,\n });\n tables[name] = applyColumnFilter(\n await this.getTable(name),\n this.#columns,\n );\n }\n\n if (depth < backwardLimit) {\n const rels = await this.findIncomingRelations(name, ctx);\n for (const rel of rels) {\n if (!this.isRelationshipVisible(rel)) continue;\n this.addRelationship(rel, allRelationships, seenRelationships);\n if (!backwardVisited.has(rel.table)) {\n backwardQueue.push({ name: rel.table, depth: depth + 1 });\n }\n }\n }\n }\n\n // Write to context\n const tablesList = Object.values(tables);\n ctx.tables.push(...tablesList);\n ctx.relationships.push(...allRelationships);\n }\n\n /**\n * Apply the filter to get seed table names.\n * If filter is an explicit array, skip querying all table names.\n */\n protected async applyFilter(): Promise<string[]> {\n const filter = this.#filter;\n if (Array.isArray(filter)) {\n return filter;\n }\n const names = await this.getAllTableNames();\n if (!filter) {\n return names;\n }\n if (filter instanceof RegExp) {\n return names.filter((name) => filter.test(name));\n }\n return names.filter(filter);\n }\n\n /**\n * Add a relationship to the collection, deduplicating by key.\n */\n protected addRelationship(\n rel: Relationship,\n all: Relationship[],\n seen: Set<string>,\n ): void {\n const key = `${rel.table}:${rel.from.join(',')}:${rel.referenced_table}:${rel.to.join(',')}`;\n if (!seen.has(key)) {\n seen.add(key);\n all.push(rel);\n }\n }\n\n protected isRelationshipVisible(rel: Relationship): boolean {\n return (\n this.areColumnsVisible(rel.from, this.#columns?.[rel.table]) &&\n this.areColumnsVisible(rel.to, this.#columns?.[rel.referenced_table])\n );\n }\n\n protected areColumnsVisible(names: string[], filter?: Filter): boolean {\n if (!filter) return true;\n return (\n filterColumns(\n names.map((name) => ({ name })),\n filter,\n ).length === names.length\n );\n }\n}\n", "import { z } from 'zod';\n\nimport type { Adapter, ColumnStats } from '../adapter.ts';\nimport {\n ColumnStatsGrounding,\n type ColumnStatsGroundingConfig,\n} from '../groundings/column-stats.grounding.ts';\nimport type { Column, GroundingContext } from '../groundings/context.ts';\nimport { numericValue } from '../groundings/rows.ts';\n\n/**\n * A pg_stats row. null_frac, n_distinct and correlation are float4, which pg\n * reads as numbers; histogram_bounds is cast to its text form '{a,b}'.\n * correlation and histogram_bounds are null when ANALYZE did not compute them.\n */\nconst pgStatsRow = z.object({\n schemaname: z.string(),\n tablename: z.string(),\n attname: z.string(),\n null_frac: z.number().nullable(),\n n_distinct: z.number().nullable(),\n histogram_bounds: z.string().nullable(),\n correlation: z.number().nullable(),\n});\n\ntype PgStatsRow = z.output<typeof pgStatsRow>;\n\n/**\n * MIN/MAX cast to text; AVG of a numeric expression is numeric, which pg\n * returns as a decimal string. All three are null for an empty table.\n */\nconst liveStatsRow = z.object({\n min_value: z.string().nullable(),\n max_value: z.string().nullable(),\n null_fraction: numericValue.nullable(),\n});\n\nexport class PostgresColumnStatsGrounding extends ColumnStatsGrounding {\n #adapter: Adapter;\n #pgStatsCache = new Map<string, Map<string, PgStatsRow>>();\n\n constructor(adapter: Adapter, config: ColumnStatsGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n override async execute(ctx: GroundingContext): Promise<void> {\n await this.#fetchAllPgStats(ctx);\n await super.execute(ctx);\n }\n\n async #fetchAllPgStats(ctx: GroundingContext): Promise<void> {\n const allContainers = [...ctx.tables, ...ctx.views];\n if (allContainers.length === 0) return;\n\n const conditions = allContainers.map((container) => {\n const { schema, table } = this.#adapter.parseTableName(container.name);\n return `(schemaname = '${this.#adapter.escapeString(schema)}' AND tablename = '${this.#adapter.escapeString(table)}')`;\n });\n\n const rows = await this.#adapter.runQuery(\n `\n SELECT\n schemaname,\n tablename,\n attname,\n null_frac,\n n_distinct,\n histogram_bounds::text,\n correlation\n FROM pg_stats\n WHERE ${conditions.join(' OR ')}\n `,\n pgStatsRow,\n );\n\n for (const row of rows) {\n const tableName = allContainers.find((c) => {\n const { schema, table } = this.#adapter.parseTableName(c.name);\n return schema === row.schemaname && table === row.tablename;\n })?.name;\n if (!tableName) continue;\n\n let map = this.#pgStatsCache.get(tableName);\n if (!map) {\n map = new Map();\n this.#pgStatsCache.set(tableName, map);\n }\n map.set(row.attname, row);\n }\n }\n\n protected override async collectStats(\n tableName: string,\n column: Column,\n ): Promise<ColumnStats | undefined> {\n const cached = this.#pgStatsCache.get(tableName)?.get(column.name);\n if (cached) {\n return this.#fromPgStats(cached);\n }\n\n return this.#collectStatsLive(tableName, column);\n }\n\n #fromPgStats(row: PgStatsRow): ColumnStats | undefined {\n const bounds = row.histogram_bounds\n ? this.#parsePgArray(row.histogram_bounds)\n : undefined;\n\n const nullFraction = this.#adapter.toNumber(row.null_frac);\n const nDistinct = this.#adapter.toNumber(row.n_distinct);\n const correlation = this.#adapter.toNumber(row.correlation);\n\n const result: ColumnStats = {\n ...(bounds?.length && { min: bounds[0] }),\n ...(bounds?.length && { max: bounds[bounds.length - 1] }),\n ...(nullFraction != null && {\n nullFraction: Math.max(0, Math.min(1, nullFraction)),\n }),\n ...(nDistinct != null && { nDistinct }),\n ...(correlation != null && {\n correlation: Math.max(-1, Math.min(1, correlation)),\n }),\n };\n\n return Object.keys(result).length > 0 ? result : undefined;\n }\n\n async #collectStatsLive(\n tableName: string,\n column: Column,\n ): Promise<ColumnStats | undefined> {\n if (!this.#shouldCollectStats(column.type)) {\n return undefined;\n }\n\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const tableIdentifier = `${this.#adapter.quoteIdentifier(schema)}.${this.#adapter.quoteIdentifier(table)}`;\n const columnIdentifier = this.#adapter.quoteIdentifier(column.name);\n\n const rows = await this.#adapter.runQuery(\n `\n SELECT\n MIN(${columnIdentifier})::text AS min_value,\n MAX(${columnIdentifier})::text AS max_value,\n AVG(CASE WHEN ${columnIdentifier} IS NULL THEN 1.0 ELSE 0.0 END) AS null_fraction\n FROM ${tableIdentifier}\n `,\n liveStatsRow,\n );\n\n if (!rows.length) {\n return undefined;\n }\n\n const min = rows[0]?.min_value;\n const max = rows[0]?.max_value;\n const nullFraction = this.#adapter.toNumber(rows[0]?.null_fraction);\n\n if (min == null && max == null && nullFraction == null) {\n return undefined;\n }\n\n return {\n min: min ?? undefined,\n max: max ?? undefined,\n nullFraction:\n nullFraction != null && Number.isFinite(nullFraction)\n ? Math.max(0, Math.min(1, nullFraction))\n : undefined,\n };\n }\n\n #shouldCollectStats(type: string | undefined): boolean {\n if (!type) {\n return false;\n }\n const normalized = type.toLowerCase();\n return /int|real|numeric|double|float|decimal|date|time|serial/.test(\n normalized,\n );\n }\n\n #parsePgArray(text: string): string[] {\n const inner =\n text.startsWith('{') && text.endsWith('}') ? text.slice(1, -1) : text;\n\n if (!inner) {\n return [];\n }\n\n const values: string[] = [];\n let current = '';\n let inQuote = false;\n\n for (let i = 0; i < inner.length; i++) {\n const ch = inner[i];\n\n if (inQuote) {\n if (ch === '\"' && inner[i + 1] === '\"') {\n current += '\"';\n i++;\n } else if (ch === '\"') {\n inQuote = false;\n } else {\n current += ch;\n }\n } else if (ch === '\"') {\n inQuote = true;\n } else if (ch === ',') {\n values.push(current);\n current = '';\n } else {\n current += ch;\n }\n }\n\n values.push(current);\n return values;\n }\n}\n", "import { z } from 'zod';\n\n// Row shapes shared by every adapter because no driver changes them.\n\n/** A text column aliased `name`, such as a table or view name. */\nexport const nameRow = z.object({ name: z.string() });\n\n/** `SELECT <engine version function> AS version`. */\nexport const versionRow = z.object({ version: z.string() });\n\n/** The current database's name, aliased `db`. */\nexport const databaseRow = z.object({ db: z.string() });\n\n/** A view's stored definition, aliased `definition`; NULL where the engine hides it. */\nexport const viewDefinitionRow = z.object({\n definition: z.string().nullable(),\n});\n\n/** `SELECT DISTINCT <column> AS value`: whatever the column stores. */\nexport const distinctValueRow = z.object({ value: z.unknown() });\n\n/** A distinct value the query casts to text after filtering out NULLs. */\nexport const textValueRow = z.object({ value: z.string() });\n\n/**\n * A number as drivers return it: a JS number, a bigint (DuckDB BIGINT, the\n * mariadb connector, node:sqlite readBigInts) or a decimal string (pg and\n * tedious BIGINT, NUMERIC and DECIMAL). Read it with Adapter.toNumber().\n */\nexport const numericValue = z.union([z.number(), z.bigint(), z.string()]);\n", "import pMemoize from 'p-memoize';\nimport { z } from 'zod';\n\nimport type { Adapter } from '../adapter.ts';\nimport {\n type Column,\n ColumnValuesGrounding,\n type ColumnValuesGroundingConfig,\n} from '../groundings/column-values.grounding.ts';\n\n/** An ENUM label with its type; typname, nspname and enumlabel are names. */\nconst enumValueRow = z.object({\n type_name: z.string(),\n type_schema: z.string(),\n enum_value: z.string(),\n});\n\n/** The type a column was declared with, from information_schema.columns. */\nconst columnTypeRow = z.object({\n udt_name: z.string(),\n udt_schema: z.string(),\n});\n\n/** `SELECT DISTINCT <column>::text AS value`. */\nconst textValueRow = z.object({ value: z.string().nullable() });\n\nexport class PostgresColumnValuesGrounding extends ColumnValuesGrounding {\n #adapter: Adapter;\n /** Every ENUM type's values, loaded once on first use; a failed load runs again. */\n readonly #enumValues: () => Promise<Map<string, string[]>>;\n\n constructor(adapter: Adapter, config: ColumnValuesGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n this.#enumValues = pMemoize(() => this.#loadEnumValues());\n }\n\n /**\n * Load all ENUM types and their values, keyed by schema-qualified and by\n * bare type name. One query is more efficient than one per column.\n */\n async #loadEnumValues(): Promise<Map<string, string[]>> {\n const enumValues = new Map<string, string[]>();\n const rows = await this.#adapter.runQuery(\n `\n SELECT\n t.typname AS type_name,\n n.nspname AS type_schema,\n e.enumlabel AS enum_value\n FROM pg_type t\n JOIN pg_enum e ON t.oid = e.enumtypid\n JOIN pg_namespace n ON n.oid = t.typnamespace\n ORDER BY t.typname, e.enumsortorder\n `,\n enumValueRow,\n );\n\n for (const row of rows) {\n const key = `${row.type_schema}.${row.type_name}`;\n const existing = enumValues.get(key) ?? [];\n existing.push(row.enum_value);\n enumValues.set(key, existing);\n\n // Also key it without schema for convenience\n const simpleKey = row.type_name;\n const simpleExisting = enumValues.get(simpleKey) ?? [];\n simpleExisting.push(row.enum_value);\n enumValues.set(simpleKey, simpleExisting);\n }\n\n return enumValues;\n }\n\n protected override async collectEnumValues(\n tableName: string,\n column: Column,\n ): Promise<string[] | undefined> {\n // USER-DEFINED type in PostgreSQL could be ENUM\n if (column.type.toLowerCase() !== 'user-defined') {\n return undefined;\n }\n\n const enumValues = await this.#enumValues();\n\n // Get the actual type name for this column\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const rows = await this.#adapter.runQuery(\n `\n SELECT udt_name, udt_schema\n FROM information_schema.columns\n WHERE table_schema = '${this.#adapter.escapeString(schema)}'\n AND table_name = '${this.#adapter.escapeString(table)}'\n AND column_name = '${this.#adapter.escapeString(column.name)}'\n `,\n columnTypeRow,\n );\n\n if (!rows.length) {\n return undefined;\n }\n\n const { udt_name, udt_schema } = rows[0];\n\n // Look up in cache\n const fullKey = `${udt_schema}.${udt_name}`;\n const values = enumValues.get(fullKey) ?? enumValues.get(udt_name);\n\n return values?.length ? values : undefined;\n }\n\n protected override async collectLowCardinality(\n tableName: string,\n column: Column,\n ): Promise<string[] | undefined> {\n if (this.#isHighCardinality(column)) {\n return undefined;\n }\n\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const tableIdentifier = `${this.#adapter.quoteIdentifier(schema)}.${this.#adapter.quoteIdentifier(table)}`;\n const columnIdentifier = this.#adapter.quoteIdentifier(column.name);\n const limit = this.lowCardinalityLimit + 1;\n\n const sql = `\n SELECT DISTINCT ${columnIdentifier}::text AS value\n FROM ${tableIdentifier}\n WHERE ${columnIdentifier} IS NOT NULL\n LIMIT ${limit}\n `;\n\n const rows = await this.#adapter.runQuery(sql, textValueRow);\n\n if (!rows.length || rows.length > this.lowCardinalityLimit) {\n return undefined;\n }\n\n const values: string[] = [];\n for (const row of rows) {\n if (row.value == null) {\n return undefined;\n }\n values.push(row.value);\n }\n\n return values.length ? values : undefined;\n }\n\n #isHighCardinality(column: Column): boolean {\n const nDistinct = column.stats?.nDistinct;\n if (nDistinct == null) return false;\n if (nDistinct > 0) return nDistinct > this.lowCardinalityLimit;\n return true;\n }\n}\n", "import { z } from 'zod';\n\nimport type { Adapter, TableConstraint } from '../adapter.ts';\nimport {\n ConstraintGrounding,\n type ConstraintGroundingConfig,\n} from '../groundings/constraint.grounding.ts';\n\n/**\n * One key column of a pg_constraint row. contype is a \"char\", which pg reads\n * as a one-letter string; the column and referenced-table members come from\n * LEFT JOINs, so they are null for a CHECK without columns or a non-foreign key.\n */\nconst constraintRow = z.object({\n constraint_name: z.string(),\n constraint_type: z.string(),\n definition: z.string().nullable(),\n column_name: z.string().nullable(),\n ref_schema: z.string().nullable(),\n ref_table: z.string().nullable(),\n ref_column: z.string().nullable(),\n});\n\n/** information_schema.columns: is_nullable is 'YES' or 'NO'. */\nconst columnDefaultRow = z.object({\n column_name: z.string(),\n column_default: z.string().nullable(),\n is_nullable: z.string(),\n});\n\n/**\n * PostgreSQL implementation of ConstraintGrounding.\n */\nexport class PostgresConstraintGrounding extends ConstraintGrounding {\n #adapter: Adapter;\n\n constructor(adapter: Adapter, config: ConstraintGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getConstraints(\n tableName: string,\n ): Promise<TableConstraint[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const constraints: TableConstraint[] = [];\n\n // Get PRIMARY KEY, FOREIGN KEY, CHECK, and UNIQUE constraints from pg_constraint\n // contype: p=primary key, f=foreign key, c=check, u=unique\n const constraintRows = await this.#adapter.runQuery(\n `\n SELECT\n con.conname AS constraint_name,\n con.contype AS constraint_type,\n pg_get_constraintdef(con.oid) AS definition,\n a.attname AS column_name,\n ref_nsp.nspname AS ref_schema,\n ref_rel.relname AS ref_table,\n ref_a.attname AS ref_column\n FROM pg_constraint con\n JOIN pg_class rel ON rel.oid = con.conrelid\n JOIN pg_namespace nsp ON nsp.oid = rel.relnamespace\n LEFT JOIN LATERAL unnest(con.conkey) WITH ORDINALITY AS key(attnum, ord) ON TRUE\n LEFT JOIN pg_attribute a ON a.attrelid = rel.oid AND a.attnum = key.attnum\n LEFT JOIN pg_class ref_rel ON ref_rel.oid = con.confrelid\n LEFT JOIN pg_namespace ref_nsp ON ref_nsp.oid = ref_rel.relnamespace\n LEFT JOIN LATERAL unnest(con.confkey) WITH ORDINALITY AS ref_key(attnum, ord) ON key.ord = ref_key.ord\n LEFT JOIN pg_attribute ref_a ON ref_a.attrelid = ref_rel.oid AND ref_a.attnum = ref_key.attnum\n WHERE nsp.nspname = '${this.#adapter.escapeString(schema)}'\n AND rel.relname = '${this.#adapter.escapeString(table)}'\n AND con.contype IN ('p', 'f', 'c', 'u')\n ORDER BY con.conname, key.ord\n `,\n constraintRow,\n );\n\n // Group by constraint name\n const constraintMap = new Map<\n string,\n {\n type: string;\n definition: string | null;\n columns: string[];\n refSchema: string | null;\n refTable: string | null;\n refColumns: string[];\n }\n >();\n\n for (const row of constraintRows) {\n const existing = constraintMap.get(row.constraint_name);\n if (existing) {\n if (row.column_name && !existing.columns.includes(row.column_name)) {\n existing.columns.push(row.column_name);\n }\n if (row.ref_column && !existing.refColumns.includes(row.ref_column)) {\n existing.refColumns.push(row.ref_column);\n }\n } else {\n constraintMap.set(row.constraint_name, {\n type: row.constraint_type,\n definition: row.definition,\n columns: row.column_name ? [row.column_name] : [],\n refSchema: row.ref_schema,\n refTable: row.ref_table,\n refColumns: row.ref_column ? [row.ref_column] : [],\n });\n }\n }\n\n for (const [name, data] of constraintMap) {\n if (data.type === 'p') {\n // PRIMARY KEY constraint\n constraints.push({\n name,\n type: 'PRIMARY_KEY',\n columns: data.columns,\n });\n } else if (data.type === 'f') {\n // FOREIGN KEY constraint\n const referencedTable =\n data.refSchema && data.refTable\n ? `${data.refSchema}.${data.refTable}`\n : (data.refTable ?? undefined);\n constraints.push({\n name,\n type: 'FOREIGN_KEY',\n columns: data.columns,\n referencedTable,\n referencedColumns: data.refColumns,\n });\n } else if (data.type === 'c') {\n // CHECK constraint\n constraints.push({\n name,\n type: 'CHECK',\n definition:\n data.definition?.replace(/^CHECK\\s*\\(/i, '').replace(/\\)$/, '') ||\n undefined,\n columns: data.columns.length > 0 ? data.columns : undefined,\n });\n } else if (data.type === 'u') {\n // UNIQUE constraint\n constraints.push({\n name,\n type: 'UNIQUE',\n columns: data.columns,\n });\n }\n }\n\n // Get NOT NULL and DEFAULT from information_schema\n const columnRows = await this.#adapter.runQuery(\n `\n SELECT\n column_name,\n column_default,\n is_nullable\n FROM information_schema.columns\n WHERE table_schema = '${this.#adapter.escapeString(schema)}'\n AND table_name = '${this.#adapter.escapeString(table)}'\n `,\n columnDefaultRow,\n );\n\n for (const col of columnRows) {\n // NOT NULL constraint (exclude primary key columns which are implicitly NOT NULL)\n const pkConstraint = constraints.find((c) => c.type === 'PRIMARY_KEY');\n const isPkColumn = pkConstraint?.columns?.includes(col.column_name);\n if (col.is_nullable === 'NO' && !isPkColumn) {\n constraints.push({\n name: `${table}_${col.column_name}_notnull`,\n type: 'NOT_NULL',\n columns: [col.column_name],\n });\n }\n\n // DEFAULT constraint\n if (col.column_default != null) {\n constraints.push({\n name: `${table}_${col.column_name}_default`,\n type: 'DEFAULT',\n columns: [col.column_name],\n defaultValue: col.column_default,\n });\n }\n }\n\n return constraints;\n }\n}\n", "import { z } from 'zod';\n\nimport type { Adapter, TableIndex } from '../adapter.ts';\nimport {\n IndexesGrounding,\n type IndexesGroundingConfig,\n} from '../groundings/indexes.grounding.ts';\n\n/**\n * One indexed column. relname, attname and amname are name columns (strings),\n * indisunique a bool, and array_position() an int4 (a number).\n */\nconst indexRow = z.object({\n index_name: z.string(),\n column_name: z.string(),\n is_unique: z.boolean(),\n index_type: z.string(),\n column_position: z.number(),\n});\n\n/**\n * PostgreSQL implementation of IndexesGrounding.\n */\nexport class PostgresIndexesGrounding extends IndexesGrounding {\n #adapter: Adapter;\n\n constructor(adapter: Adapter, config: IndexesGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getIndexes(\n tableName: string,\n ): Promise<TableIndex[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n\n const rows = await this.#adapter.runQuery(\n `\n SELECT\n i.relname AS index_name,\n a.attname AS column_name,\n ix.indisunique AS is_unique,\n am.amname AS index_type,\n array_position(ix.indkey, a.attnum) AS column_position\n FROM pg_index ix\n JOIN pg_class i ON i.oid = ix.indexrelid\n JOIN pg_class t ON t.oid = ix.indrelid\n JOIN pg_namespace n ON n.oid = t.relnamespace\n JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)\n JOIN pg_am am ON am.oid = i.relam\n WHERE n.nspname = '${this.#adapter.escapeString(schema)}'\n AND t.relname = '${this.#adapter.escapeString(table)}'\n ORDER BY i.relname, array_position(ix.indkey, a.attnum)\n `,\n indexRow,\n );\n\n return this.#groupIndexes(rows);\n }\n\n #groupIndexes(rows: z.output<typeof indexRow>[]): TableIndex[] {\n const indexes = new Map<string, TableIndex>();\n\n for (const row of rows) {\n if (!row.index_name || !row.column_name) continue;\n\n const existing = indexes.get(row.index_name);\n if (existing) {\n existing.columns.push(row.column_name);\n } else {\n indexes.set(row.index_name, {\n name: row.index_name,\n columns: [row.column_name],\n unique: row.is_unique,\n type: row.index_type?.toUpperCase(),\n });\n }\n }\n\n return Array.from(indexes.values());\n }\n}\n", "import type { Adapter, AdapterInfo } from '../adapter.ts';\nimport {\n InfoGrounding,\n type InfoGroundingConfig,\n} from '../groundings/info.grounding.ts';\nimport { databaseRow, versionRow } from '../groundings/rows.ts';\n\n/**\n * PostgreSQL implementation of InfoGrounding.\n */\nexport class PostgresInfoGrounding extends InfoGrounding {\n #adapter: Adapter;\n\n constructor(adapter: Adapter, config: InfoGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async collectInfo(): Promise<AdapterInfo> {\n const [versionRows, dbRows] = await Promise.all([\n this.#adapter.runQuery('SELECT version() AS version', versionRow),\n this.#adapter.runQuery('SELECT current_database() AS db', databaseRow),\n ]);\n\n return {\n dialect: 'postgresql',\n version: versionRows[0]?.version,\n database: dbRows[0]?.db,\n details: {\n parameterPlaceholder: '$1, $2, $3, ...',\n identifierQuoting:\n 'PostgreSQL lowercases unquoted identifiers. To preserve mixed-case names, wrap table and column names in double quotes: SELECT \"columnName\" FROM \"TableName\"',\n },\n };\n }\n}\n", "import nodeSqlParser from 'node-sql-parser';\n\nimport type { SQLScopeErrorPayload } from '../agents/exceptions.ts';\nimport { buildScopeParseErrorPayload } from '../sql-scope-error.ts';\nimport { recoverPostgresTypedLiteralParserGap } from './postgres/postgres-parser-workaround.ts';\nimport type {\n SqlPolicyAnalyzer,\n SqlPolicyContext,\n SqlPolicyViolation,\n} from './sql-policy.ts';\n\nexport type ParserDialect =\n 'bigquery' | 'mysql' | 'postgresql' | 'sqlite' | 'transactsql';\n\ninterface SqlEntityReference {\n db?: string | null;\n table: string;\n}\n\ntype AstLike = Record<string, unknown>;\n\nexport type ParserReadOnlyPolicy = {\n blockedFunctions?: readonly string[];\n blockedFunctionPrefixes?: readonly string[];\n blockAssignments?: boolean;\n blockQualifiedFunctions?: boolean;\n blockLockingReads?: boolean;\n blockSelectInto?: boolean;\n blockServerQualifiedRelations?: boolean;\n blockTableHints?: boolean;\n};\n\ntype ScopeVisitState = {\n cteNames: Set<string>;\n references: Map<string, SqlEntityReference>;\n};\n\nconst READ_ONLY_MESSAGE = 'only SELECT or WITH queries allowed';\nconst { Parser } = nodeSqlParser;\nconst parser = new Parser();\n\n/**\n * Internal base for dialect analyzers backed by node-sql-parser.\n * Server-backed analyzers implement SqlPolicyAnalyzer directly.\n */\nexport abstract class ParserSqlPolicyAnalyzer implements SqlPolicyAnalyzer {\n protected abstract readonly dialects: readonly ParserDialect[];\n protected readonly readOnlyPolicy: ParserReadOnlyPolicy = {};\n\n async analyze(\n sql: string,\n context: SqlPolicyContext,\n ): Promise<SqlPolicyViolation | null> {\n if (!this.#isReadOnly(sql)) {\n return { kind: 'read-only', message: READ_ONLY_MESSAGE };\n }\n\n const scopeError = await this.#checkScope(sql, context);\n return scopeError ? { kind: 'scope', payload: scopeError } : null;\n }\n\n #isReadOnly(sql: string): boolean {\n const statements = this.#readParsedStatements(sql);\n if (statements) {\n return (\n statements.length === 1 &&\n statements[0]?.type === 'select' &&\n !containsBlockedOperation(statements[0], this.readOnlyPolicy)\n );\n }\n\n const keyword = firstStatementKeyword(sql);\n return keyword === 'SELECT' || keyword === 'WITH';\n }\n\n #readParsedStatements(sql: string): AstLike[] | null {\n for (const dialect of this.dialects) {\n try {\n return this.#parseStatements(sql, dialect);\n } catch {\n // Parser coverage failures are handled by scope/adapter validation later.\n }\n }\n return null;\n }\n\n async #checkScope(\n sql: string,\n context: SqlPolicyContext,\n ): Promise<SQLScopeErrorPayload | null> {\n let references: SqlEntityReference[] | null = null;\n let lastError: unknown;\n let lastDialect = this.dialects[0]!;\n\n for (const dialect of this.dialects) {\n try {\n references = extractBaseEntityReferences(this.#parseAst(sql, dialect));\n break;\n } catch (error) {\n lastDialect = dialect;\n lastError = error;\n }\n }\n\n if (references === null) {\n return buildScopeParseErrorPayload(sql, lastDialect, lastError);\n }\n if (references.length === 0) return null;\n\n const allowedEntities = await context.resolveAllowedEntities();\n const allowedQualified = new Set(\n allowedEntities.map((entity) => entity.toLowerCase()),\n );\n const allowedUnqualified = new Set<string>();\n for (const entity of allowedEntities) {\n const dot = entity.lastIndexOf('.');\n allowedUnqualified.add(\n (dot === -1 ? entity : entity.slice(dot + 1)).toLowerCase(),\n );\n }\n\n const outOfScope = references\n .map((reference) =>\n reference.db ? `${reference.db}.${reference.table}` : reference.table,\n )\n .filter((name) => {\n const lower = name.toLowerCase();\n if (!name.includes('.')) {\n return !allowedQualified.has(lower) && !allowedUnqualified.has(lower);\n }\n if (allowedQualified.has(lower)) return false;\n\n const parts = lower.split('.');\n return (\n parts.length < 3 || !allowedQualified.has(parts.slice(-2).join('.'))\n );\n });\n\n return outOfScope.length === 0\n ? null\n : buildOutOfScopePayload(sql, outOfScope, [...allowedEntities]);\n }\n\n #parseStatements(sql: string, dialect: ParserDialect): AstLike[] {\n return parseStatements(this.#parseAst(sql, dialect));\n }\n\n #parseAst(sql: string, dialect: ParserDialect): unknown {\n let parserSql = sql;\n const attempted = new Set([sql]);\n\n while (true) {\n try {\n return parser.astify(parserSql, { database: dialect });\n } catch (error) {\n const recovered =\n dialect === 'postgresql'\n ? recoverPostgresTypedLiteralParserGap(parserSql, error)\n : null;\n if (!recovered || attempted.has(recovered)) throw error;\n attempted.add(recovered);\n parserSql = recovered;\n }\n }\n }\n}\n\nfunction parseStatements(ast: unknown): AstLike[] {\n const statements: unknown[] = Array.isArray(ast) ? ast : [ast];\n return statements.filter(isAstLike);\n}\n\nfunction containsBlockedOperation(\n node: unknown,\n policy: ParserReadOnlyPolicy,\n): boolean {\n if (Array.isArray(node)) {\n return node.some((item) => containsBlockedOperation(item, policy));\n }\n if (!isAstLike(node)) return false;\n\n if (\n policy.blockSelectInto &&\n node.type === 'select' &&\n isAstLike(node.into) &&\n node.into.type === 'into'\n ) {\n return true;\n }\n if (policy.blockLockingReads && node.locking_read != null) return true;\n if (policy.blockAssignments && node.type === 'assign') return true;\n if (\n policy.blockServerQualifiedRelations &&\n isTableReferenceNode(node) &&\n typeof node.server === 'string'\n ) {\n return true;\n }\n if (policy.blockTableHints && node.table_hint != null) return true;\n\n if (node.type === 'function') {\n const functionIdentifier = readFunctionIdentifier(node);\n if (\n functionIdentifier &&\n policy.blockQualifiedFunctions &&\n functionIdentifier.parts.length > 1\n ) {\n return true;\n }\n if (\n functionIdentifier &&\n policy.blockedFunctions?.some(\n (blocked) => blocked.toLowerCase() === functionIdentifier.parts.at(-1),\n )\n ) {\n return true;\n }\n if (\n functionIdentifier &&\n policy.blockedFunctionPrefixes?.some((prefix) =>\n functionIdentifier.parts.at(-1)?.startsWith(prefix.toLowerCase()),\n )\n ) {\n return true;\n }\n }\n\n return Object.values(node).some((value) =>\n containsBlockedOperation(value, policy),\n );\n}\n\nfunction readFunctionIdentifier(node: AstLike): { parts: string[] } | null {\n if (!isAstLike(node.name)) return null;\n const parts: string[] = [];\n\n if (\n isAstLike(node.name.schema) &&\n typeof node.name.schema.value === 'string'\n ) {\n appendIdentifierParts(parts, node.name.schema.value);\n }\n\n const names = Array.isArray(node.name.name) ? node.name.name : [];\n for (const name of names) {\n if (isAstLike(name) && typeof name.value === 'string') {\n appendIdentifierParts(parts, name.value);\n }\n }\n\n return parts.length > 0 ? { parts } : null;\n}\n\nfunction appendIdentifierParts(parts: string[], value: string): void {\n parts.push(\n ...value\n .toLowerCase()\n .split('.')\n .filter((part) => part.length > 0),\n );\n}\n\nfunction extractBaseEntityReferences(ast: unknown): SqlEntityReference[] {\n const state: ScopeVisitState = {\n cteNames: new Set<string>(),\n references: new Map<string, SqlEntityReference>(),\n };\n\n visitNode(ast, state);\n return Array.from(state.references.values());\n}\n\nfunction firstStatementKeyword(sql: string): string | null {\n let offset = 0;\n\n while (offset < sql.length) {\n if (/\\s/.test(sql[offset])) {\n offset++;\n continue;\n }\n\n if (sql.startsWith('--', offset)) {\n offset += 2;\n while (\n offset < sql.length &&\n sql[offset] !== '\\n' &&\n sql[offset] !== '\\r'\n ) {\n offset++;\n }\n continue;\n }\n\n if (sql.startsWith('/*', offset)) {\n const commentEnd = sql.indexOf('*/', offset + 2);\n if (commentEnd === -1) return null;\n offset = commentEnd + 2;\n continue;\n }\n\n const keyword = /^[A-Za-z]+/.exec(sql.slice(offset));\n return keyword ? keyword[0].toUpperCase() : null;\n }\n\n return null;\n}\n\nfunction buildOutOfScopePayload(\n sql: string,\n referencedEntities: string[],\n allowedEntities: string[],\n): SQLScopeErrorPayload {\n return {\n error: `Query references entities outside grounded scope: ${referencedEntities.join(', ')}`,\n error_type: 'OUT_OF_SCOPE',\n suggestion:\n 'Restrict the query to grounded tables/views or expand grounding to include the referenced entities.',\n sql_attempted: sql,\n referenced_entities: referencedEntities,\n allowed_entities: allowedEntities,\n };\n}\n\nfunction visitNode(node: unknown, state: ScopeVisitState): void {\n if (Array.isArray(node)) {\n for (const item of node) visitNode(item, state);\n return;\n }\n if (!isAstLike(node)) return;\n\n if (isStatementNode(node)) {\n visitStatement(node, state);\n return;\n }\n\n if (isTableReferenceNode(node)) addReference(node, state);\n for (const value of Object.values(node)) visitNode(value, state);\n}\n\nfunction visitStatement(node: AstLike, parentState: ScopeVisitState): void {\n const localState: ScopeVisitState = {\n cteNames: new Set(parentState.cteNames),\n references: parentState.references,\n };\n const withItems = Array.isArray(node.with) ? node.with : [];\n\n for (const item of withItems) {\n if (!isAstLike(item)) continue;\n const cteName = readCteName(item);\n if (cteName) localState.cteNames.add(caseFold(cteName));\n }\n\n for (const item of withItems) {\n if (isAstLike(item)) visitNode(item.stmt, localState);\n }\n\n for (const [key, value] of Object.entries(node)) {\n if (key !== 'with') visitNode(value, localState);\n }\n}\n\nfunction addReference(node: AstLike, state: ScopeVisitState): void {\n const table = typeof node.table === 'string' ? node.table : null;\n if (!table || state.cteNames.has(caseFold(table))) return;\n\n const db = typeof node.db === 'string' ? node.db : null;\n const key = db ? `${db}.${table}` : table;\n if (!state.references.has(key)) state.references.set(key, { db, table });\n}\n\nfunction readCteName(node: AstLike): string | undefined {\n const name = node.name;\n if (typeof name === 'string') return name;\n if (!isAstLike(name)) return undefined;\n return typeof name.value === 'string' ? name.value : undefined;\n}\n\nfunction isStatementNode(node: AstLike): boolean {\n return (\n typeof node.type === 'string' &&\n ['delete', 'insert', 'replace', 'select', 'update'].includes(node.type)\n );\n}\n\nfunction isTableReferenceNode(node: AstLike): boolean {\n if (node.type === 'column_ref' || typeof node.table !== 'string')\n return false;\n\n return (\n 'addition' in node ||\n 'as' in node ||\n 'db' in node ||\n 'join' in node ||\n 'operator' in node ||\n 'surround' in node ||\n 'table_hint' in node ||\n 'temporal_table' in node\n );\n}\n\nfunction isAstLike(value: unknown): value is AstLike {\n return typeof value === 'object' && value !== null;\n}\n\nfunction caseFold(value: string): string {\n return value.toLowerCase();\n}\n", "import type { SQLScopeErrorPayload } from './agents/exceptions.ts';\n\nexport function buildScopeParseErrorPayload(\n sql: string,\n parserDialect: string,\n error: unknown,\n): SQLScopeErrorPayload {\n const parserError =\n error instanceof Error ? error.message : String(error ?? 'Unknown error');\n\n return {\n error: `SQL scope analysis failed before validation/execution: ${parserError}`,\n error_type: 'SQL_SCOPE_PARSE_ERROR',\n suggestion:\n 'Rewrite the query into simpler SQL that can be analyzed safely, or extend parser coverage for this dialect feature.',\n sql_attempted: sql,\n parser_dialect: parserDialect,\n parser_error: parserError,\n };\n}\n", "/**\n * Temporary workaround for a node-sql-parser 5.4.0 PostgreSQL grammar\n * shortcoming: it rejects valid typed string constants such as\n * `TIMESTAMPTZ 'epoch'`. Remove this module and its parser retry once\n * node-sql-parser supports PostgreSQL typed string constants natively.\n */\n\nconst TYPE_BEFORE_LITERAL =\n /(?<type>(?:pg_catalog\\.)?[A-Za-z_][A-Za-z0-9_$]*(?:\\s+(?:varying|precision))?(?:\\s*\\(\\s*\\d+(?:\\s*,\\s*\\d+)?\\s*\\))?(?:\\s+(?:with|without)\\s+time\\s+zone)?)\\s*$/i;\nconst TIME_ZONE_SUFFIX = /^\\s+time\\s+zone\\s+/i;\nconst TIME_BEFORE_SUFFIX =\n /(?<type>time(?:stamp)?(?:\\s*\\(\\s*\\d+\\s*\\))?)\\s+(?<qualifier>with|without)$/i;\n\nexport function recoverPostgresTypedLiteralParserGap(\n sql: string,\n error: unknown,\n): string | null {\n const errorOffset = parserErrorOffset(error);\n if (errorOffset === null) return null;\n\n const prefix = sql.slice(0, errorOffset);\n let literalStart = errorOffset;\n let literalEnd = findLiteralEnd(sql, literalStart);\n let typeMatch = TYPE_BEFORE_LITERAL.exec(prefix);\n let type = typeMatch?.groups?.type;\n\n if (literalEnd === null) {\n const suffixMatch = TIME_ZONE_SUFFIX.exec(sql.slice(errorOffset));\n typeMatch = TIME_BEFORE_SUFFIX.exec(prefix);\n type =\n typeMatch?.groups?.type && typeMatch.groups.qualifier && suffixMatch\n ? `${typeMatch.groups.type} ${typeMatch.groups.qualifier} TIME ZONE`\n : undefined;\n literalStart = errorOffset + (suffixMatch?.[0].length ?? 0);\n literalEnd = findLiteralEnd(sql, literalStart);\n }\n if (!type || typeMatch?.index === undefined || literalEnd === null)\n return null;\n\n // PostgreSQL defines type 'value' and CAST('value' AS type) as equivalent.\n return (\n prefix.slice(0, typeMatch.index) +\n `CAST(${sql.slice(literalStart, literalEnd)} AS ${parserType(type)})` +\n sql.slice(literalEnd)\n );\n}\n\nfunction parserErrorOffset(error: unknown): number | null {\n if (typeof error !== 'object' || error === null) return null;\n const location = Reflect.get(error, 'location');\n if (typeof location !== 'object' || location === null) return null;\n const start = Reflect.get(location, 'start');\n if (typeof start !== 'object' || start === null) return null;\n const offset = Reflect.get(start, 'offset');\n return typeof offset === 'number' ? offset : null;\n}\n\nfunction findLiteralEnd(sql: string, start: number): number | null {\n if (sql[start] !== \"'\") {\n const delimiter = /^\\$(?:[A-Za-z_][A-Za-z0-9_]*)?\\$/.exec(\n sql.slice(start),\n )?.[0];\n if (!delimiter) return null;\n const end = sql.indexOf(delimiter, start + delimiter.length);\n return end === -1 ? null : end + delimiter.length;\n }\n\n let offset = start + 1;\n while (offset < sql.length) {\n if (sql[offset] === '\\\\') {\n offset += 2;\n continue;\n }\n if (sql[offset] !== \"'\") {\n offset++;\n continue;\n }\n if (sql[offset + 1] === \"'\") {\n offset += 2;\n continue;\n }\n return offset + 1;\n }\n return null;\n}\n\nfunction parserType(type: string): string {\n const unqualified = type.replace(/^pg_catalog\\./i, '');\n const timetz = /^timetz(\\s*\\([^)]*\\))?$/i.exec(unqualified);\n return timetz ? `TIME${timetz[1] ?? ''} WITH TIME ZONE` : unqualified;\n}\n", "import { ParserSqlPolicyAnalyzer } from '../parser-sql-policy.ts';\n\nexport class PostgresSqlPolicyAnalyzer extends ParserSqlPolicyAnalyzer {\n protected readonly dialects = ['postgresql'] as const;\n protected override readonly readOnlyPolicy = {\n blockSelectInto: true,\n blockedFunctionPrefixes: [\n 'DBLINK_',\n 'LO_',\n 'PG_ADVISORY_',\n 'PG_LS_',\n 'PG_TRY_ADVISORY_',\n ],\n blockedFunctions: [\n 'NEXTVAL',\n 'PG_CANCEL_BACKEND',\n 'PG_READ_BINARY_FILE',\n 'PG_READ_FILE',\n 'PG_RELOAD_CONF',\n 'PG_NOTIFY',\n 'PG_ROTATE_LOGFILE',\n 'PG_SLEEP',\n 'PG_STAT_FILE',\n 'PG_TERMINATE_BACKEND',\n 'SET_CONFIG',\n 'SETVAL',\n ],\n } as const;\n}\n", "import {\n Adapter,\n type ExecuteFunction,\n type GroundingFn,\n type ValidateFunction,\n} from '../adapter.ts';\nimport { PostgresSqlPolicyAnalyzer } from './postgres.sql-policy.ts';\n\nexport type PostgresAdapterOptions = {\n execute: ExecuteFunction;\n validate?: ValidateFunction;\n grounding: GroundingFn[];\n schemas?: string[];\n};\n\nconst POSTGRES_ERROR_MAP: Record<string, { type: string; hint: string }> = {\n '42P01': {\n type: 'MISSING_TABLE',\n hint: 'Check the database schema for the correct table name. Include the schema prefix if necessary.',\n },\n '42703': {\n type: 'INVALID_COLUMN',\n hint: 'Verify the column exists on the referenced table and use table aliases to disambiguate.',\n },\n '42601': {\n type: 'SYNTAX_ERROR',\n hint: 'There is a SQL syntax error. Review keywords, punctuation, and the overall query shape.',\n },\n '42P10': {\n type: 'INVALID_COLUMN',\n hint: 'Columns referenced in GROUP BY/SELECT must exist. Double-check the column names and aliases.',\n },\n '42883': {\n type: 'INVALID_FUNCTION',\n hint: 'The function or operator you used is not recognized. Confirm its name and argument types.',\n },\n};\n\nfunction isPostgresError(\n error: unknown,\n): error is { code?: string; message?: string } {\n return (\n typeof error === 'object' &&\n error !== null &&\n 'code' in error &&\n typeof error.code === 'string'\n );\n}\n\nexport function formatPostgresError(sql: string, error: unknown) {\n const errorMessage =\n error instanceof Error\n ? error.message\n : typeof error === 'string'\n ? error\n : 'Unknown error occurred';\n\n if (isPostgresError(error)) {\n const metadata = POSTGRES_ERROR_MAP[error.code ?? ''];\n if (metadata) {\n return {\n error: errorMessage,\n error_type: metadata.type,\n suggestion: metadata.hint,\n sql_attempted: sql,\n };\n }\n }\n\n return {\n error: errorMessage,\n error_type: 'UNKNOWN_ERROR',\n suggestion: 'Review the query and try again',\n sql_attempted: sql,\n };\n}\n\nexport class Postgres extends Adapter {\n #options: PostgresAdapterOptions;\n override readonly grounding: GroundingFn[];\n override readonly defaultSchema = 'public';\n override readonly systemSchemas = ['pg_catalog', 'information_schema'];\n override readonly formatterLanguage = 'postgresql';\n\n constructor(options: PostgresAdapterOptions) {\n super(new PostgresSqlPolicyAnalyzer());\n if (!options || typeof options.execute !== 'function') {\n throw new Error('Postgres adapter requires an execute function.');\n }\n this.#options = {\n ...options,\n schemas: options.schemas?.length ? options.schemas : undefined,\n };\n this.grounding = options.grounding;\n }\n\n override async executeImpl(sql: string) {\n return this.#options.execute(sql);\n }\n\n override async validateImpl(sql: string) {\n const validator: ValidateFunction =\n this.#options.validate ??\n (async (text: string) => {\n await this.#options.execute(`EXPLAIN ${text}`);\n });\n\n try {\n return await validator(sql);\n } catch (error) {\n return JSON.stringify(formatPostgresError(sql, error));\n }\n }\n\n override quoteIdentifier(name: string): string {\n return `\"${name.replace(/\"/g, '\"\"')}\"`;\n }\n\n override escape(value: string): string {\n return value.replace(/\"/g, '\"\"');\n }\n\n override buildSampleRowsQuery(\n tableName: string,\n columns: string[] | undefined,\n limit: number,\n ): string {\n const { schema, table } = this.parseTableName(tableName);\n const tableIdentifier = schema\n ? `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(table)}`\n : this.quoteIdentifier(table);\n const columnList = columns?.length\n ? columns.map((c) => this.quoteIdentifier(c)).join(', ')\n : '*';\n return `SELECT ${columnList} FROM ${tableIdentifier} LIMIT ${limit}`;\n }\n\n /**\n * The schemas introspection is limited to; table and view discovery use\n * them unless a grounding lists its own.\n */\n get schemas(): string[] | undefined {\n return this.#options.schemas;\n }\n\n protected override async queryRows(sql: string): Promise<unknown[]> {\n return this.rowsFrom(await this.#options.execute(sql), ['rows']);\n }\n}\n", "import { z } from 'zod';\n\nimport type { Adapter } from '../adapter.ts';\nimport {\n RowCountGrounding,\n type RowCountGroundingConfig,\n} from '../groundings/row-count.grounding.ts';\nimport { numericValue } from '../groundings/rows.ts';\n\n// Both counts are bigint (int8), which pg returns as a decimal string unless\n// the pool installs its own int8 parser.\n\nconst estimateRow = z.object({ estimate: numericValue.nullable() });\n\nconst countRow = z.object({ count: numericValue.nullable() });\n\nexport class PostgresRowCountGrounding extends RowCountGrounding {\n #adapter: Adapter;\n\n constructor(adapter: Adapter, config: RowCountGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n }\n\n protected override async getRowCount(\n tableName: string,\n ): Promise<number | undefined> {\n const estimate = await this.#getEstimatedRowCount(tableName);\n if (estimate != null && estimate > 0) {\n return Math.round(estimate);\n }\n\n return this.#getLiveRowCount(tableName);\n }\n\n async #getEstimatedRowCount(tableName: string): Promise<number | undefined> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const rows = await this.#adapter.runQuery(\n `\n SELECT c.reltuples::bigint AS estimate\n FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE n.nspname = '${this.#adapter.escapeString(schema)}'\n AND c.relname = '${this.#adapter.escapeString(table)}'\n `,\n estimateRow,\n );\n\n return this.#adapter.toNumber(rows[0]?.estimate);\n }\n\n async #getLiveRowCount(tableName: string): Promise<number | undefined> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n const tableIdentifier = `${this.#adapter.quoteIdentifier(schema)}.${this.#adapter.quoteIdentifier(table)}`;\n\n const rows = await this.#adapter.runQuery(\n `SELECT COUNT(*) as count FROM ${tableIdentifier}`,\n countRow,\n );\n\n return this.#adapter.toNumber(rows[0]?.count);\n }\n}\n", "import { z } from 'zod';\n\nimport type { Relationship, Table } from '../adapter.ts';\nimport { nameRow } from '../groundings/rows.ts';\nimport {\n TableGrounding,\n type TableGroundingConfig,\n} from '../groundings/table.grounding.ts';\nimport { columnRow } from './postgres-rows.ts';\nimport type { Postgres } from './postgres.ts';\n\n/** One column pair of a foreign key, read from pg_constraint. */\nconst relationshipRow = z.object({\n constraint_name: z.string(),\n table_schema: z.string(),\n table_name: z.string(),\n column_name: z.string(),\n foreign_table_schema: z.string(),\n foreign_table_name: z.string(),\n foreign_column_name: z.string(),\n});\n\nexport interface PostgresTableGroundingConfig extends TableGroundingConfig {\n /** Schemas to include (defaults to the adapter's schemas option) */\n schemas?: string[];\n}\n\n/**\n * PostgreSQL implementation of TableGrounding.\n *\n * PostgreSQL can query incoming relationships directly via pg_constraint,\n * so no caching is needed like SQLite.\n */\nexport class PostgresTableGrounding extends TableGrounding {\n #adapter: Postgres;\n #schemas?: string[];\n\n constructor(adapter: Postgres, config: PostgresTableGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n this.#schemas = config.schemas ?? adapter.schemas;\n }\n\n protected override async getAllTableNames(): Promise<string[]> {\n const rows = await this.#adapter.runQuery(\n `\n SELECT DISTINCT table_schema || '.' || table_name AS name\n FROM information_schema.tables\n WHERE table_type = 'BASE TABLE'\n ${this.#adapter.buildSchemaFilter('table_schema', this.#schemas)}\n ORDER BY name\n `,\n nameRow,\n );\n return rows.map((r) => r.name);\n }\n\n protected override async getTable(tableName: string): Promise<Table> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n\n const columns = await this.#adapter.runQuery(\n `\n SELECT column_name, data_type\n FROM information_schema.columns\n WHERE table_schema = '${this.#adapter.escapeString(schema)}'\n AND table_name = '${this.#adapter.escapeString(table)}'\n ORDER BY ordinal_position\n `,\n columnRow,\n );\n\n return {\n name: tableName,\n schema,\n rawName: table,\n columns: columns.map((col) => ({\n name: col.column_name ?? 'unknown',\n type: col.data_type ?? 'unknown',\n })),\n };\n }\n\n protected override async findOutgoingRelations(\n tableName: string,\n ): Promise<Relationship[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n return this.#foreignKeys(\n `nsp.nspname = '${this.#adapter.escapeString(schema)}'\n AND rel.relname = '${this.#adapter.escapeString(table)}'`,\n );\n }\n\n protected override async findIncomingRelations(\n tableName: string,\n ): Promise<Relationship[]> {\n const { schema, table } = this.#adapter.parseTableName(tableName);\n return this.#foreignKeys(\n `ref_nsp.nspname = '${this.#adapter.escapeString(schema)}'\n AND ref_rel.relname = '${this.#adapter.escapeString(table)}'`,\n );\n }\n\n /**\n * The foreign keys matching `where`. unnest(conkey, confkey) WITH\n * ORDINALITY pairs each column with the column it references by position,\n * and each side carries its own schema, so composite and cross-schema keys\n * come back whole.\n */\n async #foreignKeys(where: string): Promise<Relationship[]> {\n const rows = await this.#adapter.runQuery(\n `\n SELECT\n con.conname AS constraint_name,\n nsp.nspname AS table_schema,\n rel.relname AS table_name,\n att.attname AS column_name,\n ref_nsp.nspname AS foreign_table_schema,\n ref_rel.relname AS foreign_table_name,\n ref_att.attname AS foreign_column_name\n FROM pg_constraint AS con\n JOIN pg_class AS rel ON rel.oid = con.conrelid\n JOIN pg_namespace AS nsp ON nsp.oid = rel.relnamespace\n JOIN pg_class AS ref_rel ON ref_rel.oid = con.confrelid\n JOIN pg_namespace AS ref_nsp ON ref_nsp.oid = ref_rel.relnamespace\n CROSS JOIN LATERAL unnest(con.conkey, con.confkey)\n WITH ORDINALITY AS key(attnum, ref_attnum, ord)\n JOIN pg_attribute AS att\n ON att.attrelid = con.conrelid AND att.attnum = key.attnum\n JOIN pg_attribute AS ref_att\n ON ref_att.attrelid = con.confrelid AND ref_att.attnum = key.ref_attnum\n WHERE con.contype = 'f'\n AND ${where}\n ORDER BY nsp.nspname, rel.relname, con.conname, key.ord\n `,\n relationshipRow,\n );\n\n const relationships = new Map<string, Relationship>();\n for (const row of rows) {\n const table = `${row.table_schema}.${row.table_name}`;\n const key = `${table}:${row.constraint_name}`;\n const relationship = relationships.get(key) ?? {\n table,\n from: [],\n referenced_table: `${row.foreign_table_schema}.${row.foreign_table_name}`,\n to: [],\n };\n relationship.from.push(row.column_name);\n relationship.to.push(row.foreign_column_name);\n relationships.set(key, relationship);\n }\n return Array.from(relationships.values());\n }\n}\n", "import { z } from 'zod';\n\n// Rows of PostgreSQL catalog queries, as node-postgres returns them with its\n// default type parsers: name, text and information_schema identifier columns\n// are strings.\n\n/** `SELECT column_name, data_type FROM information_schema.columns`. */\nexport const columnRow = z.object({\n column_name: z.string().nullable(),\n data_type: z.string().nullable(),\n});\n", "import type { ColumnStats, Filter } from '../adapter.ts';\nimport {\n AbstractGrounding,\n type ColumnsFilter,\n applyColumnFilter,\n} from './abstract.grounding.ts';\nimport type { GroundingContext } from './context.ts';\n\n/**\n * Represents a database view with its metadata.\n */\nexport interface View {\n name: string;\n schema?: string;\n rawName?: string;\n /** The SQL definition of the view (CREATE VIEW statement or query) */\n definition?: string;\n columns: {\n name: string;\n type: string;\n /** Low cardinality marker */\n kind?: 'LowCardinality';\n /** Distinct values for low cardinality columns */\n values?: string[];\n /** Column statistics (min, max, nullFraction) */\n stats?: ColumnStats;\n }[];\n}\n\n/**\n * Configuration for ViewGrounding.\n */\nexport interface ViewGroundingConfig {\n /** Filter to select views */\n filter?: Filter;\n /**\n * Per-view column filter.\n * Maps view name to a Filter that selects which columns to keep.\n * Views not listed keep all their columns.\n */\n columns?: ColumnsFilter;\n /** Whether to fetch the SQL definition of each view (default: true) */\n includeDefinition?: boolean;\n}\n\n/**\n * Abstract base class for view grounding\n *\n * The `execute()` method implements the algorithm that discovers views.\n * Subclasses implement the database-specific hooks:\n * - `getAllViewNames()` - list all views\n * - `getView()` - get view metadata\n */\nexport abstract class ViewGrounding extends AbstractGrounding {\n #filter?: Filter;\n #columns?: ColumnsFilter;\n protected includeDefinition: boolean;\n\n constructor(config: ViewGroundingConfig = {}) {\n super('view', 'views');\n this.#filter = config.filter;\n this.#columns = config.columns;\n this.includeDefinition = config.includeDefinition ?? true;\n }\n\n /** Get all view names in the database */\n protected abstract getAllViewNames(): Promise<string[]>;\n\n /** Get full view metadata for a single view */\n protected abstract getView(viewName: string): Promise<View>;\n\n override async contributeEntities(ctx: GroundingContext): Promise<void> {\n await this.execute(ctx);\n }\n\n /**\n * Execute the grounding process.\n * Writes discovered views to the context.\n */\n async execute(ctx: GroundingContext): Promise<void> {\n const viewNames = await this.applyFilter();\n const views = await Promise.all(\n viewNames.map(async (name, index) => {\n ctx.onProgress({\n type: 'phase:progress',\n phase: 'views',\n table: name,\n message: `Loading view ${name}...`,\n current: index + 1,\n total: viewNames.length,\n });\n return applyColumnFilter(await this.getView(name), this.#columns);\n }),\n );\n ctx.views.push(...views);\n }\n\n /**\n * Apply the filter to get view names.\n * If filter is an explicit array, skip querying all view names.\n */\n protected async applyFilter(): Promise<string[]> {\n const filter = this.#filter;\n if (Array.isArray(filter)) {\n return filter;\n }\n const names = await this.getAllViewNames();\n if (!filter) {\n return names;\n }\n if (filter instanceof RegExp) {\n return names.filter((name) => filter.test(name));\n }\n return names.filter(filter);\n }\n}\n", "import { nameRow, viewDefinitionRow } from '../groundings/rows.ts';\nimport {\n type View,\n ViewGrounding,\n type ViewGroundingConfig,\n} from '../groundings/view.grounding.ts';\nimport { columnRow } from './postgres-rows.ts';\nimport type { Postgres } from './postgres.ts';\n\nexport interface PostgresViewGroundingConfig extends ViewGroundingConfig {\n /** Schemas to include (defaults to the adapter's schemas option) */\n schemas?: string[];\n}\n\n/**\n * PostgreSQL implementation of ViewGrounding.\n */\nexport class PostgresViewGrounding extends ViewGrounding {\n #adapter: Postgres;\n #schemas?: string[];\n\n constructor(adapter: Postgres, config: PostgresViewGroundingConfig = {}) {\n super(config);\n this.#adapter = adapter;\n this.#schemas = config.schemas ?? adapter.schemas;\n }\n\n protected override async getAllViewNames(): Promise<string[]> {\n const rows = await this.#adapter.runQuery(\n `\n SELECT table_schema || '.' || table_name AS name\n FROM information_schema.views\n WHERE 1=1\n ${this.#adapter.buildSchemaFilter('table_schema', this.#schemas)}\n ORDER BY name\n `,\n nameRow,\n );\n return rows.map((r) => r.name);\n }\n\n protected override async getView(viewName: string): Promise<View> {\n const { schema, table: view } = this.#adapter.parseTableName(viewName);\n\n let definition: string | undefined;\n if (this.includeDefinition) {\n const defRows = await this.#adapter.runQuery(\n `\n SELECT definition\n FROM pg_views\n WHERE schemaname = '${this.#adapter.escapeString(schema)}'\n AND viewname = '${this.#adapter.escapeString(view)}'\n `,\n viewDefinitionRow,\n );\n definition = defRows[0]?.definition ?? undefined;\n }\n\n const columns = await this.#adapter.runQuery(\n `\n SELECT column_name, data_type\n FROM information_schema.columns\n WHERE table_schema = '${this.#adapter.escapeString(schema)}'\n AND table_name = '${this.#adapter.escapeString(view)}'\n ORDER BY ordinal_position\n `,\n columnRow,\n );\n\n return {\n name: viewName,\n schema,\n rawName: view,\n definition,\n columns: columns.map((col) => ({\n name: col.column_name ?? 'unknown',\n type: col.data_type ?? 'unknown',\n })),\n };\n }\n}\n", "import { type Adapter, groundingFor } from '../adapter.ts';\nimport { type ColumnStatsGroundingConfig } from '../groundings/column-stats.grounding.ts';\nimport { type ColumnValuesGroundingConfig } from '../groundings/column-values.grounding.ts';\nimport { type ConstraintGroundingConfig } from '../groundings/constraint.grounding.ts';\nimport { type IndexesGroundingConfig } from '../groundings/indexes.grounding.ts';\nimport { type InfoGroundingConfig } from '../groundings/info.grounding.ts';\nimport { type RowCountGroundingConfig } from '../groundings/row-count.grounding.ts';\nimport { type TableGroundingConfig } from '../groundings/table.grounding.ts';\nimport type { ViewGroundingConfig } from '../groundings/view.grounding.ts';\nimport { PostgresColumnStatsGrounding } from './column-stats.postgres.grounding.ts';\nimport { PostgresColumnValuesGrounding } from './column-values.postgres.grounding.ts';\nimport { PostgresConstraintGrounding } from './constraint.postgres.grounding.ts';\nimport { PostgresIndexesGrounding } from './indexes.postgres.grounding.ts';\nimport { PostgresInfoGrounding } from './info.postgres.grounding.ts';\nimport { Postgres } from './postgres.ts';\nimport { PostgresRowCountGrounding } from './row-count.postgres.grounding.ts';\nimport { PostgresTableGrounding } from './table.postgres.grounding.ts';\nimport { PostgresViewGrounding } from './view.postgres.grounding.ts';\n\nexport * from './postgres.ts';\nexport { PostgresSqlPolicyAnalyzer } from './postgres.sql-policy.ts';\n\nexport function tables(config: TableGroundingConfig = {}) {\n return groundingFor(\n Postgres,\n (adapter) => new PostgresTableGrounding(adapter, config),\n );\n}\n\nexport function info(config: InfoGroundingConfig = {}) {\n return (adapter: Adapter) => new PostgresInfoGrounding(adapter, config);\n}\n\nexport function views(config: ViewGroundingConfig = {}) {\n return groundingFor(\n Postgres,\n (adapter) => new PostgresViewGrounding(adapter, config),\n );\n}\n\nexport function columnStats(config: ColumnStatsGroundingConfig = {}) {\n return (adapter: Adapter) => {\n return new PostgresColumnStatsGrounding(adapter, config);\n };\n}\n\nexport function columnValues(config: ColumnValuesGroundingConfig = {}) {\n return (adapter: Adapter) => {\n return new PostgresColumnValuesGrounding(adapter, config);\n };\n}\n\nexport function indexes(config: IndexesGroundingConfig = {}) {\n return (adapter: Adapter) => {\n return new PostgresIndexesGrounding(adapter, config);\n };\n}\n\nexport function rowCount(config: RowCountGroundingConfig = {}) {\n return (adapter: Adapter) => {\n return new PostgresRowCountGrounding(adapter, config);\n };\n}\n\nexport function constraints(config: ConstraintGroundingConfig = {}) {\n return (adapter: Adapter) => {\n return new PostgresConstraintGrounding(adapter, config);\n };\n}\n\nexport default {\n tables,\n info,\n views,\n columnStats,\n columnValues,\n indexes,\n rowCount,\n constraints,\n Postgres,\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["column", "c", "column", "constraint", "table", "column", "constraints", "table", "table", "index", "column", "table", "tables", "index", "z", "z", "z", "table", "column", "pMemoize", "z", "z", "textValueRow", "pMemoize", "column", "table", "z", "z", "table", "constraints", "z", "z", "table", "indexes", "table", "table", "z", "z", "table", "z", "z", "z", "table", "relationship", "views", "index", "view"]
|
|
7
7
|
}
|