prisma-sql 1.78.0 → 1.79.1

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.
@@ -78,6 +78,25 @@ function stableJson(value) {
78
78
  2
79
79
  );
80
80
  }
81
+ function cleanDatabaseUrl(url) {
82
+ try {
83
+ const parsed = new URL(url);
84
+ parsed.search = "";
85
+ if (parsed.password) {
86
+ parsed.password = "***";
87
+ }
88
+ if (parsed.username && parsed.username.length > 0) {
89
+ if (parsed.username.length <= 3) {
90
+ parsed.username = "***";
91
+ } else {
92
+ parsed.username = parsed.username.slice(0, 3) + "***";
93
+ }
94
+ }
95
+ return parsed.toString();
96
+ } catch (error) {
97
+ return "[invalid-url]";
98
+ }
99
+ }
81
100
 
82
101
  // src/cardinality-planner.ts
83
102
  function quoteIdent(dialect, ident) {
@@ -88,7 +107,7 @@ function createDatabaseExecutor(options) {
88
107
  const { databaseUrl, connectTimeoutMs = 3e4 } = options;
89
108
  {
90
109
  const postgres = yield import('postgres');
91
- const sql = postgres.default(databaseUrl, {
110
+ const sql = postgres.default(cleanDatabaseUrl(databaseUrl), {
92
111
  connect_timeout: Math.ceil(connectTimeoutMs / 1e3),
93
112
  max: 1
94
113
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/pure-utils.ts","../src/cardinality-planner.ts","../src/collect-planner-stats.ts"],"names":["isAbsolute","resolve","config","writeFile"],"mappings":"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","file":"collect-planner-stats.cjs","sourcesContent":["import type { RelStats } from '../cardinality-planner'\n\nexport function toNumberOrZero(v: unknown): number {\n if (typeof v === 'number' && Number.isFinite(v)) return v\n if (typeof v === 'bigint') return Number(v)\n if (typeof v === 'string' && v.trim() !== '') {\n const n = Number(v)\n if (Number.isFinite(n)) return n\n }\n return 0\n}\n\nexport function clampStatsMonotonic(\n avg: number,\n p95: number,\n p99: number,\n max: number,\n coverage: number,\n): RelStats {\n const safeAvg = Math.max(1, avg)\n const safeP95 = Math.max(safeAvg, p95)\n const safeP99 = Math.max(safeP95, p99)\n const safeMax = Math.max(safeP99, max)\n const safeCoverage = Math.max(0, Math.min(1, coverage))\n return {\n avg: safeAvg,\n p95: safeP95,\n p99: safeP99,\n max: safeMax,\n coverage: safeCoverage,\n }\n}\n\nexport function normalizeStats(row: Record<string, unknown>): RelStats {\n return clampStatsMonotonic(\n toNumberOrZero(row.avg),\n toNumberOrZero(row.p95),\n toNumberOrZero(row.p99),\n toNumberOrZero(row.max),\n toNumberOrZero(row.coverage),\n )\n}\n\nexport function stableJson(value: unknown): string {\n return JSON.stringify(\n value,\n (_k, v) => {\n if (!v || typeof v !== 'object' || Array.isArray(v)) return v\n const obj = v as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const k of Object.keys(obj).sort()) out[k] = obj[k]\n return out\n },\n 2,\n )\n}\n\nexport function cleanDatabaseUrl(url: string): string {\n try {\n const parsed = new URL(url)\n parsed.search = ''\n\n if (parsed.password) {\n parsed.password = '***'\n }\n\n if (parsed.username && parsed.username.length > 0) {\n if (parsed.username.length <= 3) {\n parsed.username = '***'\n } else {\n parsed.username = parsed.username.slice(0, 3) + '***'\n }\n }\n\n return parsed.toString()\n } catch (error) {\n return '[invalid-url]'\n }\n}\n\nexport function createQueryKey(\n processedQuery: Record<string, unknown>,\n): string {\n return JSON.stringify(processedQuery, (key, value) => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value).sort()) {\n sorted[k] = (value as any)[k]\n }\n return sorted\n }\n return value\n })\n}\n\nexport function countTotalQueries(\n queries: Map<string, Map<string, Map<string, any>>>,\n): number {\n return Array.from(queries.values()).reduce(\n (sum, methodMap) =>\n sum +\n Array.from(methodMap.values()).reduce(\n (s, queryMap) => s + queryMap.size,\n 0,\n ),\n 0,\n )\n}\n","import { DMMF } from '@prisma/generator-helper'\nimport {\n toNumberOrZero,\n clampStatsMonotonic,\n normalizeStats,\n stableJson,\n cleanDatabaseUrl,\n} from './utils/pure-utils'\nimport { SqlDialect } from './sql-builder-dialect'\n\ntype Executor = {\n query: (\n sql: string,\n params?: unknown[],\n ) => Promise<Array<Record<string, unknown>>>\n}\n\ninterface DatabaseExecutor {\n query: (\n sql: string,\n params?: unknown[],\n ) => Promise<Array<Record<string, unknown>>>\n}\n\nexport type RelStats = {\n avg: number\n p95: number\n p99: number\n max: number\n coverage: number\n}\n\nexport type RelationStatsMap = Record<string, Record<string, RelStats>>\n\nexport type GeneratePlannerArtifacts = {\n relationStats: RelationStatsMap\n roundtripRowEquivalent: number\n jsonRowFactor: number\n}\n\ntype RelEdge = {\n parentModel: string\n relName: string\n childModel: string\n parentTable: string\n childTable: string\n parentPkColumns: string[]\n childFkColumns: string[]\n isMany: boolean\n}\n\nfunction quoteIdent(dialect: SqlDialect, ident: string): string {\n return `\"${ident.replace(/\"/g, '\"\"')}\"`\n}\n\nexport async function createDatabaseExecutor(options: {\n databaseUrl: string\n dialect: 'postgres' | 'sqlite'\n connectTimeoutMs?: number\n}): Promise<{ executor: DatabaseExecutor; cleanup: () => Promise<void> }> {\n const { databaseUrl, dialect, connectTimeoutMs = 30000 } = options\n\n if (dialect === 'postgres') {\n const postgres = await import('postgres')\n const sql = postgres.default(databaseUrl, {\n connect_timeout: Math.ceil(connectTimeoutMs / 1000),\n max: 1,\n })\n\n return {\n executor: {\n query: async (q: string, params?: unknown[]) => {\n return await sql.unsafe(q, (params ?? []) as any[])\n },\n },\n cleanup: async () => {\n await sql.end()\n },\n }\n }\n\n throw new Error(`createDatabaseExecutor does not support dialect: ${dialect}`)\n}\n\nfunction extractMeasurableOneToManyEdges(datamodel: DMMF.Datamodel): RelEdge[] {\n const modelByName = new Map(datamodel.models.map((m) => [m.name, m]))\n const edges: RelEdge[] = []\n\n for (const parent of datamodel.models) {\n const pkFields = parent.fields.filter((f) => f.isId)\n if (pkFields.length === 0) continue\n\n const parentPk = pkFields.map((f) => f.dbName || f.name)\n const parentTable = parent.dbName || parent.name\n\n for (const f of parent.fields) {\n if (!f.relationName) continue\n if (!f.isList) continue\n\n const child = modelByName.get(f.type)\n if (!child) continue\n\n const childRelField = child.fields.find(\n (cf) => cf.relationName === f.relationName && cf.type === parent.name,\n )\n if (!childRelField) continue\n\n const fkFieldNames = childRelField.relationFromFields || []\n if (fkFieldNames.length === 0) continue\n\n const fkFields = fkFieldNames.map((name) => {\n const fld = child.fields.find((x) => x.name === name)\n return fld ? fld.dbName || fld.name : name\n })\n\n const refFieldNames = childRelField.relationToFields || []\n if (refFieldNames.length === 0) continue\n\n const references = refFieldNames.map((name) => {\n const fld = parent.fields.find((x) => x.name === name)\n return fld ? fld.dbName || fld.name : name\n })\n\n if (fkFields.length !== references.length) continue\n\n const childTable = child.dbName || child.name\n\n edges.push({\n parentModel: parent.name,\n relName: f.name,\n childModel: child.name,\n parentTable,\n childTable,\n parentPkColumns: references,\n childFkColumns: fkFields,\n isMany: true,\n })\n }\n }\n\n return edges\n}\n\nfunction buildPostgresStatsSql(edge: RelEdge): string {\n const childTable = quoteIdent('postgres', edge.childTable)\n const parentTable = quoteIdent('postgres', edge.parentTable)\n const groupCols = edge.childFkColumns\n .map((c) => quoteIdent('postgres', c))\n .join(', ')\n\n return `\nWITH counts AS (\n SELECT ${groupCols}, COUNT(*) AS cnt\n FROM ${childTable}\n GROUP BY ${groupCols}\n),\ntotal_parents AS (\n SELECT COUNT(*) AS total FROM ${parentTable}\n)\nSELECT\n AVG(cnt)::float AS avg,\n MAX(cnt)::int AS max,\n PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY cnt)::float AS p95,\n PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY cnt)::float AS p99,\n (SELECT COUNT(*) FROM counts)::float / GREATEST(1, (SELECT total FROM total_parents)) AS coverage\nFROM counts\n`.trim()\n}\n\nfunction buildSqliteStatsSql(edge: RelEdge): string {\n const childTable = quoteIdent('sqlite', edge.childTable)\n const parentTable = quoteIdent('sqlite', edge.parentTable)\n const groupCols = edge.childFkColumns\n .map((c) => quoteIdent('sqlite', c))\n .join(', ')\n\n return `\nWITH counts AS (\n SELECT ${groupCols}, COUNT(*) AS cnt\n FROM ${childTable}\n GROUP BY ${groupCols}\n),\nn AS (\n SELECT COUNT(*) AS total FROM counts\n),\nparent_n AS (\n SELECT COUNT(*) AS total FROM ${parentTable}\n),\nordered AS (\n SELECT cnt\n FROM counts\n ORDER BY cnt\n)\nSELECT\n (SELECT AVG(cnt) FROM counts) AS avg,\n (SELECT MAX(cnt) FROM counts) AS max,\n (\n SELECT cnt\n FROM ordered\n LIMIT 1\n OFFSET (\n SELECT\n CASE\n WHEN total <= 1 THEN 0\n ELSE CAST((0.95 * (total - 1)) AS INT)\n END\n FROM n\n )\n ) AS p95,\n (\n SELECT cnt\n FROM ordered\n LIMIT 1\n OFFSET (\n SELECT\n CASE\n WHEN total <= 1 THEN 0\n ELSE CAST((0.99 * (total - 1)) AS INT)\n END\n FROM n\n )\n ) AS p99,\n CAST((SELECT total FROM n) AS FLOAT) / MAX(1, (SELECT total FROM parent_n)) AS coverage\n`.trim()\n}\n\nfunction buildFanoutStatsSql(dialect: SqlDialect, edge: RelEdge): string {\n return dialect === 'postgres'\n ? buildPostgresStatsSql(edge)\n : buildSqliteStatsSql(edge)\n}\n\nasync function findLargestTable(params: {\n executor: Executor\n dialect: SqlDialect\n datamodel: DMMF.Datamodel\n}): Promise<{ tableName: string; rowCount: number } | null> {\n const { executor, dialect, datamodel } = params\n\n let best: { tableName: string; rowCount: number } | null = null\n\n for (const model of datamodel.models) {\n const table = quoteIdent(dialect, model.dbName || model.name)\n try {\n const rows = await executor.query(`SELECT COUNT(*) AS cnt FROM ${table}`)\n const count = toNumberOrZero(rows[0]?.cnt)\n if (!best || count > best.rowCount) {\n best = { tableName: table, rowCount: count }\n }\n } catch (_) {}\n }\n\n return best\n}\n\nasync function measureRoundtripCost(params: {\n executor: Executor\n dialect: SqlDialect\n datamodel: DMMF.Datamodel\n}): Promise<number> {\n const { executor, dialect, datamodel } = params\n const WARMUP = 5\n const SAMPLES = 15\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query('SELECT 1')\n }\n\n const roundtripTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query('SELECT 1')\n roundtripTimes.push(performance.now() - start)\n }\n roundtripTimes.sort((a, b) => a - b)\n const medianRoundtrip = roundtripTimes[Math.floor(SAMPLES / 2)]\n\n console.log(\n ` [roundtrip] SELECT 1 times (ms): min=${roundtripTimes[0].toFixed(3)} median=${medianRoundtrip.toFixed(3)} max=${roundtripTimes[SAMPLES - 1].toFixed(3)}`,\n )\n\n const largest = await findLargestTable({ executor, dialect, datamodel })\n\n if (!largest || largest.rowCount < 50) {\n console.log(\n ` [roundtrip] Largest table: ${largest?.tableName ?? 'none'} (${largest?.rowCount ?? 0} rows) — too small, using default 50`,\n )\n return 50\n }\n\n console.log(\n ` [roundtrip] Using table ${largest.tableName} (${largest.rowCount} rows)`,\n )\n\n return estimateFromQueryPairRatio({\n executor,\n tableName: largest.tableName,\n medianRoundtrip,\n tableRowCount: largest.rowCount,\n })\n}\n\nasync function estimateFromQueryPairRatio(params: {\n executor: Executor\n tableName: string\n medianRoundtrip: number\n tableRowCount: number\n}): Promise<number> {\n const { executor, tableName, medianRoundtrip, tableRowCount } = params\n const WARMUP = 5\n const SAMPLES = 10\n\n const smallLimit = 1\n const largeLimit = Math.min(1000, tableRowCount)\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${largeLimit}`)\n }\n\n const smallTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n smallTimes.push(performance.now() - start)\n }\n smallTimes.sort((a, b) => a - b)\n const medianSmall = smallTimes[Math.floor(SAMPLES / 2)]\n\n const largeTimes: number[] = []\n let actualLargeRows = 0\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n const rows = await executor.query(\n `SELECT * FROM ${tableName} LIMIT ${largeLimit}`,\n )\n largeTimes.push(performance.now() - start)\n actualLargeRows = rows.length\n }\n largeTimes.sort((a, b) => a - b)\n const medianLarge = largeTimes[Math.floor(SAMPLES / 2)]\n\n const rowDiff = actualLargeRows - smallLimit\n const timeDiff = medianLarge - medianSmall\n\n console.log(\n ` [roundtrip] LIMIT ${smallLimit}: median=${medianSmall.toFixed(3)}ms`,\n )\n console.log(\n ` [roundtrip] LIMIT ${largeLimit} (got ${actualLargeRows}): median=${medianLarge.toFixed(3)}ms`,\n )\n console.log(\n ` [roundtrip] Time diff: ${timeDiff.toFixed(3)}ms for ${rowDiff} rows`,\n )\n\n if (rowDiff < 50 || timeDiff <= 0.05) {\n console.log(\n ` [roundtrip] Insufficient signal (need ≥50 row diff and >0.05ms time diff), defaulting to 50`,\n )\n return 50\n }\n\n const perRow = timeDiff / rowDiff\n\n const sequentialTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n sequentialTimes.push(performance.now() - start)\n }\n sequentialTimes.sort((a, b) => a - b)\n const median3Sequential = sequentialTimes[Math.floor(SAMPLES / 2)]\n\n const marginalQueryCost = (median3Sequential - medianSmall) / 2\n\n console.log(\n ` [roundtrip] 3x sequential LIMIT 1: median=${median3Sequential.toFixed(3)}ms`,\n )\n console.log(` [roundtrip] Single query: ${medianSmall.toFixed(3)}ms`)\n console.log(\n ` [roundtrip] Marginal query cost: ${marginalQueryCost.toFixed(3)}ms`,\n )\n console.log(` [roundtrip] Per-row cost: ${perRow.toFixed(4)}ms`)\n\n const equivalent = Math.round(marginalQueryCost / perRow)\n\n console.log(` [roundtrip] Raw equivalent: ${equivalent} rows`)\n\n const clamped = Math.max(10, Math.min(500, equivalent))\n console.log(` [roundtrip] Final (clamped): ${clamped} rows`)\n\n return clamped\n}\n\nasync function measureJsonOverhead(params: {\n executor: Executor\n tableName: string\n tableRowCount: number\n}): Promise<number> {\n const { executor, tableName, tableRowCount } = params\n const WARMUP = 3\n const SAMPLES = 10\n const limit = Math.min(500, tableRowCount)\n\n const rawSql = `SELECT * FROM ${tableName} LIMIT ${limit}`\n\n const colsResult = await executor.query(\n `SELECT column_name FROM information_schema.columns WHERE table_name = ${tableName.replace(/\"/g, \"'\")} LIMIT 10`,\n )\n\n let aggSql: string\n if (colsResult.length >= 3) {\n const cols = colsResult.slice(0, 6).map((r) => `\"${r.column_name}\"`)\n const aggExprs = cols.map((c) => `array_agg(${c})`).join(', ')\n const groupCol = cols[0]\n aggSql = `SELECT ${groupCol}, ${aggExprs} FROM ${tableName} GROUP BY ${groupCol} LIMIT ${limit}`\n } else {\n aggSql = `SELECT json_agg(t) FROM (SELECT * FROM ${tableName} LIMIT ${limit}) t`\n }\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query(rawSql)\n await executor.query(aggSql)\n }\n\n const rawTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(rawSql)\n rawTimes.push(performance.now() - start)\n }\n rawTimes.sort((a, b) => a - b)\n const medianRaw = rawTimes[Math.floor(SAMPLES / 2)]\n\n const aggTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(aggSql)\n aggTimes.push(performance.now() - start)\n }\n aggTimes.sort((a, b) => a - b)\n const medianAgg = aggTimes[Math.floor(SAMPLES / 2)]\n\n const factor = medianRaw > 0.01 ? medianAgg / medianRaw : 3.0\n\n console.log(` [json] Raw ${limit} rows: ${medianRaw.toFixed(3)}ms`)\n console.log(` [json] array_agg grouped: ${medianAgg.toFixed(3)}ms`)\n console.log(` [json] Overhead factor: ${factor.toFixed(2)}x`)\n\n return Math.max(1.5, Math.min(8.0, factor))\n}\n\nasync function collectPostgresStatsFromCatalog(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n}): Promise<RelationStatsMap> {\n const { executor, datamodel } = params\n const edges = extractMeasurableOneToManyEdges(datamodel)\n const out: RelationStatsMap = {}\n\n const tablesToAnalyze = new Set<string>()\n for (const edge of edges) {\n tablesToAnalyze.add(edge.parentTable)\n tablesToAnalyze.add(edge.childTable)\n }\n\n for (const table of tablesToAnalyze) {\n try {\n await executor.query(`ANALYZE ${quoteIdent('postgres', table)}`)\n } catch (_) {}\n }\n\n const tableStatsQuery = `\n SELECT\n c.relname as table_name,\n c.reltuples::bigint as row_count\n FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE c.relkind = 'r'\n AND n.nspname NOT IN ('pg_catalog', 'information_schema')\n `\n\n const tableStats = await executor.query(tableStatsQuery, [])\n const rowCounts = new Map<string, number>()\n\n for (const row of tableStats) {\n const tableName = String(row.table_name)\n const count = toNumberOrZero(row.row_count)\n rowCounts.set(tableName, count)\n }\n\n for (const edge of edges) {\n const parentRows = rowCounts.get(edge.parentTable) || 0\n const childRows = rowCounts.get(edge.childTable) || 0\n\n if (parentRows === 0 || childRows === 0) {\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = {\n avg: 1,\n p95: 1,\n p99: 1,\n max: 1,\n coverage: 0,\n }\n continue\n }\n\n const fkColumn = edge.childFkColumns[0]\n\n const statsQuery = `\n SELECT\n s.n_distinct,\n s.correlation,\n (s.most_common_freqs)[1] as max_freq\n FROM pg_stats s\n WHERE s.tablename = $1\n AND s.attname = $2\n AND s.schemaname NOT IN ('pg_catalog', 'information_schema')\n `\n\n const statsRows = await executor.query(statsQuery, [\n edge.childTable,\n fkColumn,\n ])\n\n let avg: number\n let p95: number\n let p99: number\n let max: number\n let coverage: number\n\n if (statsRows.length > 0) {\n const stats = statsRows[0]\n const nDistinct = toNumberOrZero(stats.n_distinct)\n const correlation =\n stats.correlation !== null ? Number(stats.correlation) : 0\n const maxFreq = stats.max_freq !== null ? Number(stats.max_freq) : null\n\n const distinctCount =\n nDistinct < 0\n ? Math.abs(nDistinct) * childRows\n : nDistinct > 0\n ? nDistinct\n : parentRows\n\n avg =\n distinctCount > 0 ? childRows / distinctCount : childRows / parentRows\n coverage = Math.min(1, distinctCount / parentRows)\n\n const skewFactor = Math.abs(correlation) > 0.5 ? 2.5 : 1.5\n p95 = avg * skewFactor\n p99 = avg * (skewFactor * 1.3)\n\n max = maxFreq ? Math.ceil(childRows * maxFreq) : Math.ceil(p99 * 1.5)\n } else {\n avg = childRows / parentRows\n coverage = 1\n p95 = avg * 2\n p99 = avg * 3\n max = avg * 5\n }\n\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = clampStatsMonotonic(\n Math.ceil(avg),\n Math.ceil(p95),\n Math.ceil(p99),\n Math.ceil(max),\n coverage,\n )\n }\n\n return out\n}\n\nasync function collectPreciseCardinalities(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n}): Promise<RelationStatsMap> {\n const { executor, datamodel, dialect } = params\n const edges = extractMeasurableOneToManyEdges(datamodel)\n const out: RelationStatsMap = {}\n\n for (const edge of edges) {\n const sql = buildFanoutStatsSql(dialect, edge)\n const rows = await executor.query(sql, [])\n const row = rows[0] || {}\n const stats = normalizeStats(row)\n\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = stats\n }\n\n return out\n}\n\nasync function collectRelationCardinalities(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n mode?: 'fast' | 'precise'\n}): Promise<RelationStatsMap> {\n const { executor, datamodel, dialect, mode = 'precise' } = params\n\n if (dialect === 'postgres' && mode === 'fast') {\n const stats = await collectPostgresStatsFromCatalog({ executor, datamodel })\n\n let allTrivial = true\n for (const model of Object.values(stats)) {\n for (const rel of Object.values(model)) {\n if (rel.avg > 1 || rel.coverage > 0.5) {\n allTrivial = false\n break\n }\n }\n if (!allTrivial) break\n }\n\n if (allTrivial && Object.keys(stats).length > 0) {\n console.warn('⚠ Catalog stats look stale, falling back to precise mode')\n return collectPreciseCardinalities({ executor, datamodel, dialect })\n }\n\n return stats\n }\n\n return collectPreciseCardinalities({ executor, datamodel, dialect })\n}\n\nexport async function collectPlannerArtifacts(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n mode?: 'fast' | 'precise'\n}): Promise<GeneratePlannerArtifacts> {\n const { executor, datamodel, dialect, mode } = params\n\n const largest = await findLargestTable({ executor, dialect, datamodel })\n\n const [relationStats, roundtripRowEquivalent, jsonRowFactor] =\n await Promise.all([\n collectRelationCardinalities({ executor, datamodel, dialect, mode }),\n measureRoundtripCost({ executor, dialect, datamodel }),\n largest && largest.rowCount >= 50 && dialect === 'postgres'\n ? measureJsonOverhead({\n executor,\n tableName: largest.tableName,\n tableRowCount: largest.rowCount,\n })\n : Promise.resolve(1.5),\n ])\n\n console.log(` Roundtrip cost: ~${roundtripRowEquivalent} row equivalents`)\n console.log(` JSON overhead factor: ${jsonRowFactor.toFixed(2)}x`)\n\n return { relationStats, roundtripRowEquivalent, jsonRowFactor }\n}\n\nexport function emitPlannerGeneratedModule(\n artifacts: GeneratePlannerArtifacts,\n): string {\n return [\n `export const RELATION_STATS = ${stableJson(artifacts.relationStats)} as const`,\n ``,\n `export type RelationStats = typeof RELATION_STATS`,\n ``,\n `export const ROUNDTRIP_ROW_EQUIVALENT = ${artifacts.roundtripRowEquivalent}`,\n ``,\n `export const JSON_ROW_FACTOR = ${artifacts.jsonRowFactor.toFixed(2)}`,\n ``,\n ].join('\\n')\n}\n","#!/usr/bin/env node\nimport { config } from 'dotenv'\nimport { writeFile } from 'fs/promises'\nimport { resolve, isAbsolute } from 'path'\nimport {\n createDatabaseExecutor,\n collectPlannerArtifacts,\n emitPlannerGeneratedModule,\n GeneratePlannerArtifacts,\n} from './cardinality-planner'\n\nconst CONNECT_TIMEOUT_MS = 10000\n\nfunction parseArgs(argv: string[]): { output: string; clientPath: string } {\n const outputIdx = argv.indexOf('--output')\n const clientIdx = argv.indexOf('--prisma-client')\n\n const output =\n outputIdx !== -1 && argv[outputIdx + 1]\n ? argv[outputIdx + 1]\n : './dist/prisma/generated/sql/planner.generated.js'\n\n const clientPath =\n clientIdx !== -1 && argv[clientIdx + 1]\n ? argv[clientIdx + 1]\n : '@prisma/client'\n\n return { output, clientPath }\n}\n\nfunction resolveOutput(output: string): string {\n return isAbsolute(output) ? output : resolve(process.cwd(), output)\n}\n\nfunction resolveClientPath(p: string): string {\n if (p.startsWith('.') || isAbsolute(p)) {\n return resolve(process.cwd(), p)\n }\n if (p.includes('/') && !p.startsWith('@')) {\n return resolve(process.cwd(), p)\n }\n return p\n}\n\nfunction emitCJS(artifacts: GeneratePlannerArtifacts): string {\n const ts = emitPlannerGeneratedModule(artifacts)\n return ts\n .replace(/^export const (\\w+)/gm, 'exports.$1')\n .replace(/^import .*$/gm, '')\n .trimStart()\n}\n\nasync function connectWithTimeout(\n databaseUrl: string,\n dialect: 'postgres' | 'sqlite',\n): Promise<{ executor: any; cleanup: () => Promise<void> }> {\n let settled = false\n\n const connectPromise = createDatabaseExecutor({ databaseUrl, dialect }).then(\n (conn) => {\n if (settled) {\n conn.cleanup().catch(() => {})\n throw new Error('Timed out')\n }\n return conn\n },\n )\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n const id = setTimeout(() => {\n settled = true\n reject(new Error(`Connection timed out after ${CONNECT_TIMEOUT_MS}ms`))\n }, CONNECT_TIMEOUT_MS)\n id.unref?.()\n })\n\n try {\n const result = await Promise.race([connectPromise, timeoutPromise])\n settled = true\n return result\n } catch (err) {\n settled = true\n throw err\n }\n}\n\nasync function main() {\n config()\n\n const skipPlanner =\n process.env.PRISMA_SQL_SKIP_PLANNER === '1' ||\n process.env.PRISMA_SQL_SKIP_PLANNER === 'true'\n\n if (skipPlanner) {\n console.log(\n '[prisma-sql] ⏭ Skipping planner stats (PRISMA_SQL_SKIP_PLANNER)',\n )\n process.exit(0)\n }\n\n const { output, clientPath } = parseArgs(process.argv.slice(2))\n const outputPath = resolveOutput(output)\n\n const url = process.env.DATABASE_URL\n if (!url) {\n console.warn(\n '[prisma-sql] DATABASE_URL not set, skipping planner stats collection',\n )\n process.exit(0)\n }\n\n let executor: any\n let cleanup: (() => Promise<void>) | undefined\n\n try {\n const conn = await connectWithTimeout(url, 'postgres')\n executor = conn.executor\n cleanup = conn.cleanup\n } catch (err) {\n console.warn(\n '[prisma-sql] Failed to connect:',\n err instanceof Error ? err.message : err,\n )\n process.exit(0)\n }\n\n try {\n let dmmf: any\n try {\n const resolvedClientPath = resolveClientPath(clientPath)\n const client = require(resolvedClientPath)\n dmmf = client.Prisma?.dmmf ?? client.dmmf\n if (!dmmf?.datamodel) {\n throw new Error(`Could not read dmmf.datamodel from ${clientPath}`)\n }\n } catch (err) {\n throw new Error(\n `Failed to load Prisma client from \"${clientPath}\": ${err instanceof Error ? err.message : err}`,\n )\n }\n\n const artifacts = await collectPlannerArtifacts({\n executor,\n datamodel: dmmf.datamodel,\n dialect: 'postgres',\n })\n\n await writeFile(outputPath, emitCJS(artifacts as any), 'utf8')\n console.log('[prisma-sql] ✓ Planner stats written to', outputPath)\n } catch (err) {\n console.warn(\n '[prisma-sql] Failed to collect stats:',\n err instanceof Error ? err.message : err,\n )\n } finally {\n await cleanup?.()\n }\n\n process.exit(0)\n}\n\nmain()\n"]}
1
+ {"version":3,"sources":["../src/utils/pure-utils.ts","../src/cardinality-planner.ts","../src/collect-planner-stats.ts"],"names":["isAbsolute","resolve","config","writeFile"],"mappings":"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","file":"collect-planner-stats.cjs","sourcesContent":["import type { RelStats } from '../cardinality-planner'\n\nexport function toNumberOrZero(v: unknown): number {\n if (typeof v === 'number' && Number.isFinite(v)) return v\n if (typeof v === 'bigint') return Number(v)\n if (typeof v === 'string' && v.trim() !== '') {\n const n = Number(v)\n if (Number.isFinite(n)) return n\n }\n return 0\n}\n\nexport function clampStatsMonotonic(\n avg: number,\n p95: number,\n p99: number,\n max: number,\n coverage: number,\n): RelStats {\n const safeAvg = Math.max(1, avg)\n const safeP95 = Math.max(safeAvg, p95)\n const safeP99 = Math.max(safeP95, p99)\n const safeMax = Math.max(safeP99, max)\n const safeCoverage = Math.max(0, Math.min(1, coverage))\n return {\n avg: safeAvg,\n p95: safeP95,\n p99: safeP99,\n max: safeMax,\n coverage: safeCoverage,\n }\n}\n\nexport function normalizeStats(row: Record<string, unknown>): RelStats {\n return clampStatsMonotonic(\n toNumberOrZero(row.avg),\n toNumberOrZero(row.p95),\n toNumberOrZero(row.p99),\n toNumberOrZero(row.max),\n toNumberOrZero(row.coverage),\n )\n}\n\nexport function stableJson(value: unknown): string {\n return JSON.stringify(\n value,\n (_k, v) => {\n if (!v || typeof v !== 'object' || Array.isArray(v)) return v\n const obj = v as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const k of Object.keys(obj).sort()) out[k] = obj[k]\n return out\n },\n 2,\n )\n}\n\nexport function cleanDatabaseUrl(url: string): string {\n try {\n const parsed = new URL(url)\n parsed.search = ''\n\n if (parsed.password) {\n parsed.password = '***'\n }\n\n if (parsed.username && parsed.username.length > 0) {\n if (parsed.username.length <= 3) {\n parsed.username = '***'\n } else {\n parsed.username = parsed.username.slice(0, 3) + '***'\n }\n }\n\n return parsed.toString()\n } catch (error) {\n return '[invalid-url]'\n }\n}\n\nexport function createQueryKey(\n processedQuery: Record<string, unknown>,\n): string {\n return JSON.stringify(processedQuery, (key, value) => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value).sort()) {\n sorted[k] = (value as any)[k]\n }\n return sorted\n }\n return value\n })\n}\n\nexport function countTotalQueries(\n queries: Map<string, Map<string, Map<string, any>>>,\n): number {\n return Array.from(queries.values()).reduce(\n (sum, methodMap) =>\n sum +\n Array.from(methodMap.values()).reduce(\n (s, queryMap) => s + queryMap.size,\n 0,\n ),\n 0,\n )\n}\n","import { DMMF } from '@prisma/generator-helper'\nimport {\n toNumberOrZero,\n clampStatsMonotonic,\n normalizeStats,\n stableJson,\n cleanDatabaseUrl,\n} from './utils/pure-utils'\nimport { SqlDialect } from './sql-builder-dialect'\n\ntype Executor = {\n query: (\n sql: string,\n params?: unknown[],\n ) => Promise<Array<Record<string, unknown>>>\n}\n\ninterface DatabaseExecutor {\n query: (\n sql: string,\n params?: unknown[],\n ) => Promise<Array<Record<string, unknown>>>\n}\n\nexport type RelStats = {\n avg: number\n p95: number\n p99: number\n max: number\n coverage: number\n}\n\nexport type RelationStatsMap = Record<string, Record<string, RelStats>>\n\nexport type GeneratePlannerArtifacts = {\n relationStats: RelationStatsMap\n roundtripRowEquivalent: number\n jsonRowFactor: number\n}\n\ntype RelEdge = {\n parentModel: string\n relName: string\n childModel: string\n parentTable: string\n childTable: string\n parentPkColumns: string[]\n childFkColumns: string[]\n isMany: boolean\n}\n\nfunction quoteIdent(dialect: SqlDialect, ident: string): string {\n return `\"${ident.replace(/\"/g, '\"\"')}\"`\n}\n\nexport async function createDatabaseExecutor(options: {\n databaseUrl: string\n dialect: 'postgres' | 'sqlite'\n connectTimeoutMs?: number\n}): Promise<{ executor: DatabaseExecutor; cleanup: () => Promise<void> }> {\n const { databaseUrl, dialect, connectTimeoutMs = 30000 } = options\n\n if (dialect === 'postgres') {\n const postgres = await import('postgres')\n const sql = postgres.default(cleanDatabaseUrl(databaseUrl), {\n connect_timeout: Math.ceil(connectTimeoutMs / 1000),\n max: 1,\n })\n\n return {\n executor: {\n query: async (q: string, params?: unknown[]) => {\n return await sql.unsafe(q, (params ?? []) as any[])\n },\n },\n cleanup: async () => {\n await sql.end()\n },\n }\n }\n\n throw new Error(`createDatabaseExecutor does not support dialect: ${dialect}`)\n}\n\nfunction extractMeasurableOneToManyEdges(datamodel: DMMF.Datamodel): RelEdge[] {\n const modelByName = new Map(datamodel.models.map((m) => [m.name, m]))\n const edges: RelEdge[] = []\n\n for (const parent of datamodel.models) {\n const pkFields = parent.fields.filter((f) => f.isId)\n if (pkFields.length === 0) continue\n\n const parentPk = pkFields.map((f) => f.dbName || f.name)\n const parentTable = parent.dbName || parent.name\n\n for (const f of parent.fields) {\n if (!f.relationName) continue\n if (!f.isList) continue\n\n const child = modelByName.get(f.type)\n if (!child) continue\n\n const childRelField = child.fields.find(\n (cf) => cf.relationName === f.relationName && cf.type === parent.name,\n )\n if (!childRelField) continue\n\n const fkFieldNames = childRelField.relationFromFields || []\n if (fkFieldNames.length === 0) continue\n\n const fkFields = fkFieldNames.map((name) => {\n const fld = child.fields.find((x) => x.name === name)\n return fld ? fld.dbName || fld.name : name\n })\n\n const refFieldNames = childRelField.relationToFields || []\n if (refFieldNames.length === 0) continue\n\n const references = refFieldNames.map((name) => {\n const fld = parent.fields.find((x) => x.name === name)\n return fld ? fld.dbName || fld.name : name\n })\n\n if (fkFields.length !== references.length) continue\n\n const childTable = child.dbName || child.name\n\n edges.push({\n parentModel: parent.name,\n relName: f.name,\n childModel: child.name,\n parentTable,\n childTable,\n parentPkColumns: references,\n childFkColumns: fkFields,\n isMany: true,\n })\n }\n }\n\n return edges\n}\n\nfunction buildPostgresStatsSql(edge: RelEdge): string {\n const childTable = quoteIdent('postgres', edge.childTable)\n const parentTable = quoteIdent('postgres', edge.parentTable)\n const groupCols = edge.childFkColumns\n .map((c) => quoteIdent('postgres', c))\n .join(', ')\n\n return `\nWITH counts AS (\n SELECT ${groupCols}, COUNT(*) AS cnt\n FROM ${childTable}\n GROUP BY ${groupCols}\n),\ntotal_parents AS (\n SELECT COUNT(*) AS total FROM ${parentTable}\n)\nSELECT\n AVG(cnt)::float AS avg,\n MAX(cnt)::int AS max,\n PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY cnt)::float AS p95,\n PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY cnt)::float AS p99,\n (SELECT COUNT(*) FROM counts)::float / GREATEST(1, (SELECT total FROM total_parents)) AS coverage\nFROM counts\n`.trim()\n}\n\nfunction buildSqliteStatsSql(edge: RelEdge): string {\n const childTable = quoteIdent('sqlite', edge.childTable)\n const parentTable = quoteIdent('sqlite', edge.parentTable)\n const groupCols = edge.childFkColumns\n .map((c) => quoteIdent('sqlite', c))\n .join(', ')\n\n return `\nWITH counts AS (\n SELECT ${groupCols}, COUNT(*) AS cnt\n FROM ${childTable}\n GROUP BY ${groupCols}\n),\nn AS (\n SELECT COUNT(*) AS total FROM counts\n),\nparent_n AS (\n SELECT COUNT(*) AS total FROM ${parentTable}\n),\nordered AS (\n SELECT cnt\n FROM counts\n ORDER BY cnt\n)\nSELECT\n (SELECT AVG(cnt) FROM counts) AS avg,\n (SELECT MAX(cnt) FROM counts) AS max,\n (\n SELECT cnt\n FROM ordered\n LIMIT 1\n OFFSET (\n SELECT\n CASE\n WHEN total <= 1 THEN 0\n ELSE CAST((0.95 * (total - 1)) AS INT)\n END\n FROM n\n )\n ) AS p95,\n (\n SELECT cnt\n FROM ordered\n LIMIT 1\n OFFSET (\n SELECT\n CASE\n WHEN total <= 1 THEN 0\n ELSE CAST((0.99 * (total - 1)) AS INT)\n END\n FROM n\n )\n ) AS p99,\n CAST((SELECT total FROM n) AS FLOAT) / MAX(1, (SELECT total FROM parent_n)) AS coverage\n`.trim()\n}\n\nfunction buildFanoutStatsSql(dialect: SqlDialect, edge: RelEdge): string {\n return dialect === 'postgres'\n ? buildPostgresStatsSql(edge)\n : buildSqliteStatsSql(edge)\n}\n\nasync function findLargestTable(params: {\n executor: Executor\n dialect: SqlDialect\n datamodel: DMMF.Datamodel\n}): Promise<{ tableName: string; rowCount: number } | null> {\n const { executor, dialect, datamodel } = params\n\n let best: { tableName: string; rowCount: number } | null = null\n\n for (const model of datamodel.models) {\n const table = quoteIdent(dialect, model.dbName || model.name)\n try {\n const rows = await executor.query(`SELECT COUNT(*) AS cnt FROM ${table}`)\n const count = toNumberOrZero(rows[0]?.cnt)\n if (!best || count > best.rowCount) {\n best = { tableName: table, rowCount: count }\n }\n } catch (_) {}\n }\n\n return best\n}\n\nasync function measureRoundtripCost(params: {\n executor: Executor\n dialect: SqlDialect\n datamodel: DMMF.Datamodel\n}): Promise<number> {\n const { executor, dialect, datamodel } = params\n const WARMUP = 5\n const SAMPLES = 15\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query('SELECT 1')\n }\n\n const roundtripTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query('SELECT 1')\n roundtripTimes.push(performance.now() - start)\n }\n roundtripTimes.sort((a, b) => a - b)\n const medianRoundtrip = roundtripTimes[Math.floor(SAMPLES / 2)]\n\n console.log(\n ` [roundtrip] SELECT 1 times (ms): min=${roundtripTimes[0].toFixed(3)} median=${medianRoundtrip.toFixed(3)} max=${roundtripTimes[SAMPLES - 1].toFixed(3)}`,\n )\n\n const largest = await findLargestTable({ executor, dialect, datamodel })\n\n if (!largest || largest.rowCount < 50) {\n console.log(\n ` [roundtrip] Largest table: ${largest?.tableName ?? 'none'} (${largest?.rowCount ?? 0} rows) — too small, using default 50`,\n )\n return 50\n }\n\n console.log(\n ` [roundtrip] Using table ${largest.tableName} (${largest.rowCount} rows)`,\n )\n\n return estimateFromQueryPairRatio({\n executor,\n tableName: largest.tableName,\n medianRoundtrip,\n tableRowCount: largest.rowCount,\n })\n}\n\nasync function estimateFromQueryPairRatio(params: {\n executor: Executor\n tableName: string\n medianRoundtrip: number\n tableRowCount: number\n}): Promise<number> {\n const { executor, tableName, medianRoundtrip, tableRowCount } = params\n const WARMUP = 5\n const SAMPLES = 10\n\n const smallLimit = 1\n const largeLimit = Math.min(1000, tableRowCount)\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${largeLimit}`)\n }\n\n const smallTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n smallTimes.push(performance.now() - start)\n }\n smallTimes.sort((a, b) => a - b)\n const medianSmall = smallTimes[Math.floor(SAMPLES / 2)]\n\n const largeTimes: number[] = []\n let actualLargeRows = 0\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n const rows = await executor.query(\n `SELECT * FROM ${tableName} LIMIT ${largeLimit}`,\n )\n largeTimes.push(performance.now() - start)\n actualLargeRows = rows.length\n }\n largeTimes.sort((a, b) => a - b)\n const medianLarge = largeTimes[Math.floor(SAMPLES / 2)]\n\n const rowDiff = actualLargeRows - smallLimit\n const timeDiff = medianLarge - medianSmall\n\n console.log(\n ` [roundtrip] LIMIT ${smallLimit}: median=${medianSmall.toFixed(3)}ms`,\n )\n console.log(\n ` [roundtrip] LIMIT ${largeLimit} (got ${actualLargeRows}): median=${medianLarge.toFixed(3)}ms`,\n )\n console.log(\n ` [roundtrip] Time diff: ${timeDiff.toFixed(3)}ms for ${rowDiff} rows`,\n )\n\n if (rowDiff < 50 || timeDiff <= 0.05) {\n console.log(\n ` [roundtrip] Insufficient signal (need ≥50 row diff and >0.05ms time diff), defaulting to 50`,\n )\n return 50\n }\n\n const perRow = timeDiff / rowDiff\n\n const sequentialTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n sequentialTimes.push(performance.now() - start)\n }\n sequentialTimes.sort((a, b) => a - b)\n const median3Sequential = sequentialTimes[Math.floor(SAMPLES / 2)]\n\n const marginalQueryCost = (median3Sequential - medianSmall) / 2\n\n console.log(\n ` [roundtrip] 3x sequential LIMIT 1: median=${median3Sequential.toFixed(3)}ms`,\n )\n console.log(` [roundtrip] Single query: ${medianSmall.toFixed(3)}ms`)\n console.log(\n ` [roundtrip] Marginal query cost: ${marginalQueryCost.toFixed(3)}ms`,\n )\n console.log(` [roundtrip] Per-row cost: ${perRow.toFixed(4)}ms`)\n\n const equivalent = Math.round(marginalQueryCost / perRow)\n\n console.log(` [roundtrip] Raw equivalent: ${equivalent} rows`)\n\n const clamped = Math.max(10, Math.min(500, equivalent))\n console.log(` [roundtrip] Final (clamped): ${clamped} rows`)\n\n return clamped\n}\n\nasync function measureJsonOverhead(params: {\n executor: Executor\n tableName: string\n tableRowCount: number\n}): Promise<number> {\n const { executor, tableName, tableRowCount } = params\n const WARMUP = 3\n const SAMPLES = 10\n const limit = Math.min(500, tableRowCount)\n\n const rawSql = `SELECT * FROM ${tableName} LIMIT ${limit}`\n\n const colsResult = await executor.query(\n `SELECT column_name FROM information_schema.columns WHERE table_name = ${tableName.replace(/\"/g, \"'\")} LIMIT 10`,\n )\n\n let aggSql: string\n if (colsResult.length >= 3) {\n const cols = colsResult.slice(0, 6).map((r) => `\"${r.column_name}\"`)\n const aggExprs = cols.map((c) => `array_agg(${c})`).join(', ')\n const groupCol = cols[0]\n aggSql = `SELECT ${groupCol}, ${aggExprs} FROM ${tableName} GROUP BY ${groupCol} LIMIT ${limit}`\n } else {\n aggSql = `SELECT json_agg(t) FROM (SELECT * FROM ${tableName} LIMIT ${limit}) t`\n }\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query(rawSql)\n await executor.query(aggSql)\n }\n\n const rawTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(rawSql)\n rawTimes.push(performance.now() - start)\n }\n rawTimes.sort((a, b) => a - b)\n const medianRaw = rawTimes[Math.floor(SAMPLES / 2)]\n\n const aggTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(aggSql)\n aggTimes.push(performance.now() - start)\n }\n aggTimes.sort((a, b) => a - b)\n const medianAgg = aggTimes[Math.floor(SAMPLES / 2)]\n\n const factor = medianRaw > 0.01 ? medianAgg / medianRaw : 3.0\n\n console.log(` [json] Raw ${limit} rows: ${medianRaw.toFixed(3)}ms`)\n console.log(` [json] array_agg grouped: ${medianAgg.toFixed(3)}ms`)\n console.log(` [json] Overhead factor: ${factor.toFixed(2)}x`)\n\n return Math.max(1.5, Math.min(8.0, factor))\n}\n\nasync function collectPostgresStatsFromCatalog(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n}): Promise<RelationStatsMap> {\n const { executor, datamodel } = params\n const edges = extractMeasurableOneToManyEdges(datamodel)\n const out: RelationStatsMap = {}\n\n const tablesToAnalyze = new Set<string>()\n for (const edge of edges) {\n tablesToAnalyze.add(edge.parentTable)\n tablesToAnalyze.add(edge.childTable)\n }\n\n for (const table of tablesToAnalyze) {\n try {\n await executor.query(`ANALYZE ${quoteIdent('postgres', table)}`)\n } catch (_) {}\n }\n\n const tableStatsQuery = `\n SELECT\n c.relname as table_name,\n c.reltuples::bigint as row_count\n FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE c.relkind = 'r'\n AND n.nspname NOT IN ('pg_catalog', 'information_schema')\n `\n\n const tableStats = await executor.query(tableStatsQuery, [])\n const rowCounts = new Map<string, number>()\n\n for (const row of tableStats) {\n const tableName = String(row.table_name)\n const count = toNumberOrZero(row.row_count)\n rowCounts.set(tableName, count)\n }\n\n for (const edge of edges) {\n const parentRows = rowCounts.get(edge.parentTable) || 0\n const childRows = rowCounts.get(edge.childTable) || 0\n\n if (parentRows === 0 || childRows === 0) {\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = {\n avg: 1,\n p95: 1,\n p99: 1,\n max: 1,\n coverage: 0,\n }\n continue\n }\n\n const fkColumn = edge.childFkColumns[0]\n\n const statsQuery = `\n SELECT\n s.n_distinct,\n s.correlation,\n (s.most_common_freqs)[1] as max_freq\n FROM pg_stats s\n WHERE s.tablename = $1\n AND s.attname = $2\n AND s.schemaname NOT IN ('pg_catalog', 'information_schema')\n `\n\n const statsRows = await executor.query(statsQuery, [\n edge.childTable,\n fkColumn,\n ])\n\n let avg: number\n let p95: number\n let p99: number\n let max: number\n let coverage: number\n\n if (statsRows.length > 0) {\n const stats = statsRows[0]\n const nDistinct = toNumberOrZero(stats.n_distinct)\n const correlation =\n stats.correlation !== null ? Number(stats.correlation) : 0\n const maxFreq = stats.max_freq !== null ? Number(stats.max_freq) : null\n\n const distinctCount =\n nDistinct < 0\n ? Math.abs(nDistinct) * childRows\n : nDistinct > 0\n ? nDistinct\n : parentRows\n\n avg =\n distinctCount > 0 ? childRows / distinctCount : childRows / parentRows\n coverage = Math.min(1, distinctCount / parentRows)\n\n const skewFactor = Math.abs(correlation) > 0.5 ? 2.5 : 1.5\n p95 = avg * skewFactor\n p99 = avg * (skewFactor * 1.3)\n\n max = maxFreq ? Math.ceil(childRows * maxFreq) : Math.ceil(p99 * 1.5)\n } else {\n avg = childRows / parentRows\n coverage = 1\n p95 = avg * 2\n p99 = avg * 3\n max = avg * 5\n }\n\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = clampStatsMonotonic(\n Math.ceil(avg),\n Math.ceil(p95),\n Math.ceil(p99),\n Math.ceil(max),\n coverage,\n )\n }\n\n return out\n}\n\nasync function collectPreciseCardinalities(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n}): Promise<RelationStatsMap> {\n const { executor, datamodel, dialect } = params\n const edges = extractMeasurableOneToManyEdges(datamodel)\n const out: RelationStatsMap = {}\n\n for (const edge of edges) {\n const sql = buildFanoutStatsSql(dialect, edge)\n const rows = await executor.query(sql, [])\n const row = rows[0] || {}\n const stats = normalizeStats(row)\n\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = stats\n }\n\n return out\n}\n\nasync function collectRelationCardinalities(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n mode?: 'fast' | 'precise'\n}): Promise<RelationStatsMap> {\n const { executor, datamodel, dialect, mode = 'precise' } = params\n\n if (dialect === 'postgres' && mode === 'fast') {\n const stats = await collectPostgresStatsFromCatalog({ executor, datamodel })\n\n let allTrivial = true\n for (const model of Object.values(stats)) {\n for (const rel of Object.values(model)) {\n if (rel.avg > 1 || rel.coverage > 0.5) {\n allTrivial = false\n break\n }\n }\n if (!allTrivial) break\n }\n\n if (allTrivial && Object.keys(stats).length > 0) {\n console.warn('⚠ Catalog stats look stale, falling back to precise mode')\n return collectPreciseCardinalities({ executor, datamodel, dialect })\n }\n\n return stats\n }\n\n return collectPreciseCardinalities({ executor, datamodel, dialect })\n}\n\nexport async function collectPlannerArtifacts(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n mode?: 'fast' | 'precise'\n}): Promise<GeneratePlannerArtifacts> {\n const { executor, datamodel, dialect, mode } = params\n\n const largest = await findLargestTable({ executor, dialect, datamodel })\n\n const [relationStats, roundtripRowEquivalent, jsonRowFactor] =\n await Promise.all([\n collectRelationCardinalities({ executor, datamodel, dialect, mode }),\n measureRoundtripCost({ executor, dialect, datamodel }),\n largest && largest.rowCount >= 50 && dialect === 'postgres'\n ? measureJsonOverhead({\n executor,\n tableName: largest.tableName,\n tableRowCount: largest.rowCount,\n })\n : Promise.resolve(1.5),\n ])\n\n console.log(` Roundtrip cost: ~${roundtripRowEquivalent} row equivalents`)\n console.log(` JSON overhead factor: ${jsonRowFactor.toFixed(2)}x`)\n\n return { relationStats, roundtripRowEquivalent, jsonRowFactor }\n}\n\nexport function emitPlannerGeneratedModule(\n artifacts: GeneratePlannerArtifacts,\n): string {\n return [\n `export const RELATION_STATS = ${stableJson(artifacts.relationStats)} as const`,\n ``,\n `export type RelationStats = typeof RELATION_STATS`,\n ``,\n `export const ROUNDTRIP_ROW_EQUIVALENT = ${artifacts.roundtripRowEquivalent}`,\n ``,\n `export const JSON_ROW_FACTOR = ${artifacts.jsonRowFactor.toFixed(2)}`,\n ``,\n ].join('\\n')\n}\n","#!/usr/bin/env node\nimport { config } from 'dotenv'\nimport { writeFile } from 'fs/promises'\nimport { resolve, isAbsolute } from 'path'\nimport {\n createDatabaseExecutor,\n collectPlannerArtifacts,\n emitPlannerGeneratedModule,\n GeneratePlannerArtifacts,\n} from './cardinality-planner'\n\nconst CONNECT_TIMEOUT_MS = 10000\n\nfunction parseArgs(argv: string[]): { output: string; clientPath: string } {\n const outputIdx = argv.indexOf('--output')\n const clientIdx = argv.indexOf('--prisma-client')\n\n const output =\n outputIdx !== -1 && argv[outputIdx + 1]\n ? argv[outputIdx + 1]\n : './dist/prisma/generated/sql/planner.generated.js'\n\n const clientPath =\n clientIdx !== -1 && argv[clientIdx + 1]\n ? argv[clientIdx + 1]\n : '@prisma/client'\n\n return { output, clientPath }\n}\n\nfunction resolveOutput(output: string): string {\n return isAbsolute(output) ? output : resolve(process.cwd(), output)\n}\n\nfunction resolveClientPath(p: string): string {\n if (p.startsWith('.') || isAbsolute(p)) {\n return resolve(process.cwd(), p)\n }\n if (p.includes('/') && !p.startsWith('@')) {\n return resolve(process.cwd(), p)\n }\n return p\n}\n\nfunction emitCJS(artifacts: GeneratePlannerArtifacts): string {\n const ts = emitPlannerGeneratedModule(artifacts)\n return ts\n .replace(/^export const (\\w+)/gm, 'exports.$1')\n .replace(/^import .*$/gm, '')\n .trimStart()\n}\n\nasync function connectWithTimeout(\n databaseUrl: string,\n dialect: 'postgres' | 'sqlite',\n): Promise<{ executor: any; cleanup: () => Promise<void> }> {\n let settled = false\n\n const connectPromise = createDatabaseExecutor({ databaseUrl, dialect }).then(\n (conn) => {\n if (settled) {\n conn.cleanup().catch(() => {})\n throw new Error('Timed out')\n }\n return conn\n },\n )\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n const id = setTimeout(() => {\n settled = true\n reject(new Error(`Connection timed out after ${CONNECT_TIMEOUT_MS}ms`))\n }, CONNECT_TIMEOUT_MS)\n id.unref?.()\n })\n\n try {\n const result = await Promise.race([connectPromise, timeoutPromise])\n settled = true\n return result\n } catch (err) {\n settled = true\n throw err\n }\n}\n\nasync function main() {\n config()\n\n const skipPlanner =\n process.env.PRISMA_SQL_SKIP_PLANNER === '1' ||\n process.env.PRISMA_SQL_SKIP_PLANNER === 'true'\n\n if (skipPlanner) {\n console.log(\n '[prisma-sql] ⏭ Skipping planner stats (PRISMA_SQL_SKIP_PLANNER)',\n )\n process.exit(0)\n }\n\n const { output, clientPath } = parseArgs(process.argv.slice(2))\n const outputPath = resolveOutput(output)\n\n const url = process.env.DATABASE_URL\n if (!url) {\n console.warn(\n '[prisma-sql] DATABASE_URL not set, skipping planner stats collection',\n )\n process.exit(0)\n }\n\n let executor: any\n let cleanup: (() => Promise<void>) | undefined\n\n try {\n const conn = await connectWithTimeout(url, 'postgres')\n executor = conn.executor\n cleanup = conn.cleanup\n } catch (err) {\n console.warn(\n '[prisma-sql] Failed to connect:',\n err instanceof Error ? err.message : err,\n )\n process.exit(0)\n }\n\n try {\n let dmmf: any\n try {\n const resolvedClientPath = resolveClientPath(clientPath)\n const client = require(resolvedClientPath)\n dmmf = client.Prisma?.dmmf ?? client.dmmf\n if (!dmmf?.datamodel) {\n throw new Error(`Could not read dmmf.datamodel from ${clientPath}`)\n }\n } catch (err) {\n throw new Error(\n `Failed to load Prisma client from \"${clientPath}\": ${err instanceof Error ? err.message : err}`,\n )\n }\n\n const artifacts = await collectPlannerArtifacts({\n executor,\n datamodel: dmmf.datamodel,\n dialect: 'postgres',\n })\n\n await writeFile(outputPath, emitCJS(artifacts as any), 'utf8')\n console.log('[prisma-sql] ✓ Planner stats written to', outputPath)\n } catch (err) {\n console.warn(\n '[prisma-sql] Failed to collect stats:',\n err instanceof Error ? err.message : err,\n )\n } finally {\n await cleanup?.()\n }\n\n process.exit(0)\n}\n\nmain()\n"]}
@@ -76,6 +76,25 @@ function stableJson(value) {
76
76
  2
77
77
  );
78
78
  }
79
+ function cleanDatabaseUrl(url) {
80
+ try {
81
+ const parsed = new URL(url);
82
+ parsed.search = "";
83
+ if (parsed.password) {
84
+ parsed.password = "***";
85
+ }
86
+ if (parsed.username && parsed.username.length > 0) {
87
+ if (parsed.username.length <= 3) {
88
+ parsed.username = "***";
89
+ } else {
90
+ parsed.username = parsed.username.slice(0, 3) + "***";
91
+ }
92
+ }
93
+ return parsed.toString();
94
+ } catch (error) {
95
+ return "[invalid-url]";
96
+ }
97
+ }
79
98
 
80
99
  // src/cardinality-planner.ts
81
100
  function quoteIdent(dialect, ident) {
@@ -86,7 +105,7 @@ function createDatabaseExecutor(options) {
86
105
  const { databaseUrl, connectTimeoutMs = 3e4 } = options;
87
106
  {
88
107
  const postgres = yield import('postgres');
89
- const sql = postgres.default(databaseUrl, {
108
+ const sql = postgres.default(cleanDatabaseUrl(databaseUrl), {
90
109
  connect_timeout: Math.ceil(connectTimeoutMs / 1e3),
91
110
  max: 1
92
111
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/pure-utils.ts","../src/cardinality-planner.ts","../src/collect-planner-stats.ts"],"names":[],"mappings":"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","file":"collect-planner-stats.js","sourcesContent":["import type { RelStats } from '../cardinality-planner'\n\nexport function toNumberOrZero(v: unknown): number {\n if (typeof v === 'number' && Number.isFinite(v)) return v\n if (typeof v === 'bigint') return Number(v)\n if (typeof v === 'string' && v.trim() !== '') {\n const n = Number(v)\n if (Number.isFinite(n)) return n\n }\n return 0\n}\n\nexport function clampStatsMonotonic(\n avg: number,\n p95: number,\n p99: number,\n max: number,\n coverage: number,\n): RelStats {\n const safeAvg = Math.max(1, avg)\n const safeP95 = Math.max(safeAvg, p95)\n const safeP99 = Math.max(safeP95, p99)\n const safeMax = Math.max(safeP99, max)\n const safeCoverage = Math.max(0, Math.min(1, coverage))\n return {\n avg: safeAvg,\n p95: safeP95,\n p99: safeP99,\n max: safeMax,\n coverage: safeCoverage,\n }\n}\n\nexport function normalizeStats(row: Record<string, unknown>): RelStats {\n return clampStatsMonotonic(\n toNumberOrZero(row.avg),\n toNumberOrZero(row.p95),\n toNumberOrZero(row.p99),\n toNumberOrZero(row.max),\n toNumberOrZero(row.coverage),\n )\n}\n\nexport function stableJson(value: unknown): string {\n return JSON.stringify(\n value,\n (_k, v) => {\n if (!v || typeof v !== 'object' || Array.isArray(v)) return v\n const obj = v as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const k of Object.keys(obj).sort()) out[k] = obj[k]\n return out\n },\n 2,\n )\n}\n\nexport function cleanDatabaseUrl(url: string): string {\n try {\n const parsed = new URL(url)\n parsed.search = ''\n\n if (parsed.password) {\n parsed.password = '***'\n }\n\n if (parsed.username && parsed.username.length > 0) {\n if (parsed.username.length <= 3) {\n parsed.username = '***'\n } else {\n parsed.username = parsed.username.slice(0, 3) + '***'\n }\n }\n\n return parsed.toString()\n } catch (error) {\n return '[invalid-url]'\n }\n}\n\nexport function createQueryKey(\n processedQuery: Record<string, unknown>,\n): string {\n return JSON.stringify(processedQuery, (key, value) => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value).sort()) {\n sorted[k] = (value as any)[k]\n }\n return sorted\n }\n return value\n })\n}\n\nexport function countTotalQueries(\n queries: Map<string, Map<string, Map<string, any>>>,\n): number {\n return Array.from(queries.values()).reduce(\n (sum, methodMap) =>\n sum +\n Array.from(methodMap.values()).reduce(\n (s, queryMap) => s + queryMap.size,\n 0,\n ),\n 0,\n )\n}\n","import { DMMF } from '@prisma/generator-helper'\nimport {\n toNumberOrZero,\n clampStatsMonotonic,\n normalizeStats,\n stableJson,\n cleanDatabaseUrl,\n} from './utils/pure-utils'\nimport { SqlDialect } from './sql-builder-dialect'\n\ntype Executor = {\n query: (\n sql: string,\n params?: unknown[],\n ) => Promise<Array<Record<string, unknown>>>\n}\n\ninterface DatabaseExecutor {\n query: (\n sql: string,\n params?: unknown[],\n ) => Promise<Array<Record<string, unknown>>>\n}\n\nexport type RelStats = {\n avg: number\n p95: number\n p99: number\n max: number\n coverage: number\n}\n\nexport type RelationStatsMap = Record<string, Record<string, RelStats>>\n\nexport type GeneratePlannerArtifacts = {\n relationStats: RelationStatsMap\n roundtripRowEquivalent: number\n jsonRowFactor: number\n}\n\ntype RelEdge = {\n parentModel: string\n relName: string\n childModel: string\n parentTable: string\n childTable: string\n parentPkColumns: string[]\n childFkColumns: string[]\n isMany: boolean\n}\n\nfunction quoteIdent(dialect: SqlDialect, ident: string): string {\n return `\"${ident.replace(/\"/g, '\"\"')}\"`\n}\n\nexport async function createDatabaseExecutor(options: {\n databaseUrl: string\n dialect: 'postgres' | 'sqlite'\n connectTimeoutMs?: number\n}): Promise<{ executor: DatabaseExecutor; cleanup: () => Promise<void> }> {\n const { databaseUrl, dialect, connectTimeoutMs = 30000 } = options\n\n if (dialect === 'postgres') {\n const postgres = await import('postgres')\n const sql = postgres.default(databaseUrl, {\n connect_timeout: Math.ceil(connectTimeoutMs / 1000),\n max: 1,\n })\n\n return {\n executor: {\n query: async (q: string, params?: unknown[]) => {\n return await sql.unsafe(q, (params ?? []) as any[])\n },\n },\n cleanup: async () => {\n await sql.end()\n },\n }\n }\n\n throw new Error(`createDatabaseExecutor does not support dialect: ${dialect}`)\n}\n\nfunction extractMeasurableOneToManyEdges(datamodel: DMMF.Datamodel): RelEdge[] {\n const modelByName = new Map(datamodel.models.map((m) => [m.name, m]))\n const edges: RelEdge[] = []\n\n for (const parent of datamodel.models) {\n const pkFields = parent.fields.filter((f) => f.isId)\n if (pkFields.length === 0) continue\n\n const parentPk = pkFields.map((f) => f.dbName || f.name)\n const parentTable = parent.dbName || parent.name\n\n for (const f of parent.fields) {\n if (!f.relationName) continue\n if (!f.isList) continue\n\n const child = modelByName.get(f.type)\n if (!child) continue\n\n const childRelField = child.fields.find(\n (cf) => cf.relationName === f.relationName && cf.type === parent.name,\n )\n if (!childRelField) continue\n\n const fkFieldNames = childRelField.relationFromFields || []\n if (fkFieldNames.length === 0) continue\n\n const fkFields = fkFieldNames.map((name) => {\n const fld = child.fields.find((x) => x.name === name)\n return fld ? fld.dbName || fld.name : name\n })\n\n const refFieldNames = childRelField.relationToFields || []\n if (refFieldNames.length === 0) continue\n\n const references = refFieldNames.map((name) => {\n const fld = parent.fields.find((x) => x.name === name)\n return fld ? fld.dbName || fld.name : name\n })\n\n if (fkFields.length !== references.length) continue\n\n const childTable = child.dbName || child.name\n\n edges.push({\n parentModel: parent.name,\n relName: f.name,\n childModel: child.name,\n parentTable,\n childTable,\n parentPkColumns: references,\n childFkColumns: fkFields,\n isMany: true,\n })\n }\n }\n\n return edges\n}\n\nfunction buildPostgresStatsSql(edge: RelEdge): string {\n const childTable = quoteIdent('postgres', edge.childTable)\n const parentTable = quoteIdent('postgres', edge.parentTable)\n const groupCols = edge.childFkColumns\n .map((c) => quoteIdent('postgres', c))\n .join(', ')\n\n return `\nWITH counts AS (\n SELECT ${groupCols}, COUNT(*) AS cnt\n FROM ${childTable}\n GROUP BY ${groupCols}\n),\ntotal_parents AS (\n SELECT COUNT(*) AS total FROM ${parentTable}\n)\nSELECT\n AVG(cnt)::float AS avg,\n MAX(cnt)::int AS max,\n PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY cnt)::float AS p95,\n PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY cnt)::float AS p99,\n (SELECT COUNT(*) FROM counts)::float / GREATEST(1, (SELECT total FROM total_parents)) AS coverage\nFROM counts\n`.trim()\n}\n\nfunction buildSqliteStatsSql(edge: RelEdge): string {\n const childTable = quoteIdent('sqlite', edge.childTable)\n const parentTable = quoteIdent('sqlite', edge.parentTable)\n const groupCols = edge.childFkColumns\n .map((c) => quoteIdent('sqlite', c))\n .join(', ')\n\n return `\nWITH counts AS (\n SELECT ${groupCols}, COUNT(*) AS cnt\n FROM ${childTable}\n GROUP BY ${groupCols}\n),\nn AS (\n SELECT COUNT(*) AS total FROM counts\n),\nparent_n AS (\n SELECT COUNT(*) AS total FROM ${parentTable}\n),\nordered AS (\n SELECT cnt\n FROM counts\n ORDER BY cnt\n)\nSELECT\n (SELECT AVG(cnt) FROM counts) AS avg,\n (SELECT MAX(cnt) FROM counts) AS max,\n (\n SELECT cnt\n FROM ordered\n LIMIT 1\n OFFSET (\n SELECT\n CASE\n WHEN total <= 1 THEN 0\n ELSE CAST((0.95 * (total - 1)) AS INT)\n END\n FROM n\n )\n ) AS p95,\n (\n SELECT cnt\n FROM ordered\n LIMIT 1\n OFFSET (\n SELECT\n CASE\n WHEN total <= 1 THEN 0\n ELSE CAST((0.99 * (total - 1)) AS INT)\n END\n FROM n\n )\n ) AS p99,\n CAST((SELECT total FROM n) AS FLOAT) / MAX(1, (SELECT total FROM parent_n)) AS coverage\n`.trim()\n}\n\nfunction buildFanoutStatsSql(dialect: SqlDialect, edge: RelEdge): string {\n return dialect === 'postgres'\n ? buildPostgresStatsSql(edge)\n : buildSqliteStatsSql(edge)\n}\n\nasync function findLargestTable(params: {\n executor: Executor\n dialect: SqlDialect\n datamodel: DMMF.Datamodel\n}): Promise<{ tableName: string; rowCount: number } | null> {\n const { executor, dialect, datamodel } = params\n\n let best: { tableName: string; rowCount: number } | null = null\n\n for (const model of datamodel.models) {\n const table = quoteIdent(dialect, model.dbName || model.name)\n try {\n const rows = await executor.query(`SELECT COUNT(*) AS cnt FROM ${table}`)\n const count = toNumberOrZero(rows[0]?.cnt)\n if (!best || count > best.rowCount) {\n best = { tableName: table, rowCount: count }\n }\n } catch (_) {}\n }\n\n return best\n}\n\nasync function measureRoundtripCost(params: {\n executor: Executor\n dialect: SqlDialect\n datamodel: DMMF.Datamodel\n}): Promise<number> {\n const { executor, dialect, datamodel } = params\n const WARMUP = 5\n const SAMPLES = 15\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query('SELECT 1')\n }\n\n const roundtripTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query('SELECT 1')\n roundtripTimes.push(performance.now() - start)\n }\n roundtripTimes.sort((a, b) => a - b)\n const medianRoundtrip = roundtripTimes[Math.floor(SAMPLES / 2)]\n\n console.log(\n ` [roundtrip] SELECT 1 times (ms): min=${roundtripTimes[0].toFixed(3)} median=${medianRoundtrip.toFixed(3)} max=${roundtripTimes[SAMPLES - 1].toFixed(3)}`,\n )\n\n const largest = await findLargestTable({ executor, dialect, datamodel })\n\n if (!largest || largest.rowCount < 50) {\n console.log(\n ` [roundtrip] Largest table: ${largest?.tableName ?? 'none'} (${largest?.rowCount ?? 0} rows) — too small, using default 50`,\n )\n return 50\n }\n\n console.log(\n ` [roundtrip] Using table ${largest.tableName} (${largest.rowCount} rows)`,\n )\n\n return estimateFromQueryPairRatio({\n executor,\n tableName: largest.tableName,\n medianRoundtrip,\n tableRowCount: largest.rowCount,\n })\n}\n\nasync function estimateFromQueryPairRatio(params: {\n executor: Executor\n tableName: string\n medianRoundtrip: number\n tableRowCount: number\n}): Promise<number> {\n const { executor, tableName, medianRoundtrip, tableRowCount } = params\n const WARMUP = 5\n const SAMPLES = 10\n\n const smallLimit = 1\n const largeLimit = Math.min(1000, tableRowCount)\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${largeLimit}`)\n }\n\n const smallTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n smallTimes.push(performance.now() - start)\n }\n smallTimes.sort((a, b) => a - b)\n const medianSmall = smallTimes[Math.floor(SAMPLES / 2)]\n\n const largeTimes: number[] = []\n let actualLargeRows = 0\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n const rows = await executor.query(\n `SELECT * FROM ${tableName} LIMIT ${largeLimit}`,\n )\n largeTimes.push(performance.now() - start)\n actualLargeRows = rows.length\n }\n largeTimes.sort((a, b) => a - b)\n const medianLarge = largeTimes[Math.floor(SAMPLES / 2)]\n\n const rowDiff = actualLargeRows - smallLimit\n const timeDiff = medianLarge - medianSmall\n\n console.log(\n ` [roundtrip] LIMIT ${smallLimit}: median=${medianSmall.toFixed(3)}ms`,\n )\n console.log(\n ` [roundtrip] LIMIT ${largeLimit} (got ${actualLargeRows}): median=${medianLarge.toFixed(3)}ms`,\n )\n console.log(\n ` [roundtrip] Time diff: ${timeDiff.toFixed(3)}ms for ${rowDiff} rows`,\n )\n\n if (rowDiff < 50 || timeDiff <= 0.05) {\n console.log(\n ` [roundtrip] Insufficient signal (need ≥50 row diff and >0.05ms time diff), defaulting to 50`,\n )\n return 50\n }\n\n const perRow = timeDiff / rowDiff\n\n const sequentialTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n sequentialTimes.push(performance.now() - start)\n }\n sequentialTimes.sort((a, b) => a - b)\n const median3Sequential = sequentialTimes[Math.floor(SAMPLES / 2)]\n\n const marginalQueryCost = (median3Sequential - medianSmall) / 2\n\n console.log(\n ` [roundtrip] 3x sequential LIMIT 1: median=${median3Sequential.toFixed(3)}ms`,\n )\n console.log(` [roundtrip] Single query: ${medianSmall.toFixed(3)}ms`)\n console.log(\n ` [roundtrip] Marginal query cost: ${marginalQueryCost.toFixed(3)}ms`,\n )\n console.log(` [roundtrip] Per-row cost: ${perRow.toFixed(4)}ms`)\n\n const equivalent = Math.round(marginalQueryCost / perRow)\n\n console.log(` [roundtrip] Raw equivalent: ${equivalent} rows`)\n\n const clamped = Math.max(10, Math.min(500, equivalent))\n console.log(` [roundtrip] Final (clamped): ${clamped} rows`)\n\n return clamped\n}\n\nasync function measureJsonOverhead(params: {\n executor: Executor\n tableName: string\n tableRowCount: number\n}): Promise<number> {\n const { executor, tableName, tableRowCount } = params\n const WARMUP = 3\n const SAMPLES = 10\n const limit = Math.min(500, tableRowCount)\n\n const rawSql = `SELECT * FROM ${tableName} LIMIT ${limit}`\n\n const colsResult = await executor.query(\n `SELECT column_name FROM information_schema.columns WHERE table_name = ${tableName.replace(/\"/g, \"'\")} LIMIT 10`,\n )\n\n let aggSql: string\n if (colsResult.length >= 3) {\n const cols = colsResult.slice(0, 6).map((r) => `\"${r.column_name}\"`)\n const aggExprs = cols.map((c) => `array_agg(${c})`).join(', ')\n const groupCol = cols[0]\n aggSql = `SELECT ${groupCol}, ${aggExprs} FROM ${tableName} GROUP BY ${groupCol} LIMIT ${limit}`\n } else {\n aggSql = `SELECT json_agg(t) FROM (SELECT * FROM ${tableName} LIMIT ${limit}) t`\n }\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query(rawSql)\n await executor.query(aggSql)\n }\n\n const rawTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(rawSql)\n rawTimes.push(performance.now() - start)\n }\n rawTimes.sort((a, b) => a - b)\n const medianRaw = rawTimes[Math.floor(SAMPLES / 2)]\n\n const aggTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(aggSql)\n aggTimes.push(performance.now() - start)\n }\n aggTimes.sort((a, b) => a - b)\n const medianAgg = aggTimes[Math.floor(SAMPLES / 2)]\n\n const factor = medianRaw > 0.01 ? medianAgg / medianRaw : 3.0\n\n console.log(` [json] Raw ${limit} rows: ${medianRaw.toFixed(3)}ms`)\n console.log(` [json] array_agg grouped: ${medianAgg.toFixed(3)}ms`)\n console.log(` [json] Overhead factor: ${factor.toFixed(2)}x`)\n\n return Math.max(1.5, Math.min(8.0, factor))\n}\n\nasync function collectPostgresStatsFromCatalog(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n}): Promise<RelationStatsMap> {\n const { executor, datamodel } = params\n const edges = extractMeasurableOneToManyEdges(datamodel)\n const out: RelationStatsMap = {}\n\n const tablesToAnalyze = new Set<string>()\n for (const edge of edges) {\n tablesToAnalyze.add(edge.parentTable)\n tablesToAnalyze.add(edge.childTable)\n }\n\n for (const table of tablesToAnalyze) {\n try {\n await executor.query(`ANALYZE ${quoteIdent('postgres', table)}`)\n } catch (_) {}\n }\n\n const tableStatsQuery = `\n SELECT\n c.relname as table_name,\n c.reltuples::bigint as row_count\n FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE c.relkind = 'r'\n AND n.nspname NOT IN ('pg_catalog', 'information_schema')\n `\n\n const tableStats = await executor.query(tableStatsQuery, [])\n const rowCounts = new Map<string, number>()\n\n for (const row of tableStats) {\n const tableName = String(row.table_name)\n const count = toNumberOrZero(row.row_count)\n rowCounts.set(tableName, count)\n }\n\n for (const edge of edges) {\n const parentRows = rowCounts.get(edge.parentTable) || 0\n const childRows = rowCounts.get(edge.childTable) || 0\n\n if (parentRows === 0 || childRows === 0) {\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = {\n avg: 1,\n p95: 1,\n p99: 1,\n max: 1,\n coverage: 0,\n }\n continue\n }\n\n const fkColumn = edge.childFkColumns[0]\n\n const statsQuery = `\n SELECT\n s.n_distinct,\n s.correlation,\n (s.most_common_freqs)[1] as max_freq\n FROM pg_stats s\n WHERE s.tablename = $1\n AND s.attname = $2\n AND s.schemaname NOT IN ('pg_catalog', 'information_schema')\n `\n\n const statsRows = await executor.query(statsQuery, [\n edge.childTable,\n fkColumn,\n ])\n\n let avg: number\n let p95: number\n let p99: number\n let max: number\n let coverage: number\n\n if (statsRows.length > 0) {\n const stats = statsRows[0]\n const nDistinct = toNumberOrZero(stats.n_distinct)\n const correlation =\n stats.correlation !== null ? Number(stats.correlation) : 0\n const maxFreq = stats.max_freq !== null ? Number(stats.max_freq) : null\n\n const distinctCount =\n nDistinct < 0\n ? Math.abs(nDistinct) * childRows\n : nDistinct > 0\n ? nDistinct\n : parentRows\n\n avg =\n distinctCount > 0 ? childRows / distinctCount : childRows / parentRows\n coverage = Math.min(1, distinctCount / parentRows)\n\n const skewFactor = Math.abs(correlation) > 0.5 ? 2.5 : 1.5\n p95 = avg * skewFactor\n p99 = avg * (skewFactor * 1.3)\n\n max = maxFreq ? Math.ceil(childRows * maxFreq) : Math.ceil(p99 * 1.5)\n } else {\n avg = childRows / parentRows\n coverage = 1\n p95 = avg * 2\n p99 = avg * 3\n max = avg * 5\n }\n\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = clampStatsMonotonic(\n Math.ceil(avg),\n Math.ceil(p95),\n Math.ceil(p99),\n Math.ceil(max),\n coverage,\n )\n }\n\n return out\n}\n\nasync function collectPreciseCardinalities(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n}): Promise<RelationStatsMap> {\n const { executor, datamodel, dialect } = params\n const edges = extractMeasurableOneToManyEdges(datamodel)\n const out: RelationStatsMap = {}\n\n for (const edge of edges) {\n const sql = buildFanoutStatsSql(dialect, edge)\n const rows = await executor.query(sql, [])\n const row = rows[0] || {}\n const stats = normalizeStats(row)\n\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = stats\n }\n\n return out\n}\n\nasync function collectRelationCardinalities(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n mode?: 'fast' | 'precise'\n}): Promise<RelationStatsMap> {\n const { executor, datamodel, dialect, mode = 'precise' } = params\n\n if (dialect === 'postgres' && mode === 'fast') {\n const stats = await collectPostgresStatsFromCatalog({ executor, datamodel })\n\n let allTrivial = true\n for (const model of Object.values(stats)) {\n for (const rel of Object.values(model)) {\n if (rel.avg > 1 || rel.coverage > 0.5) {\n allTrivial = false\n break\n }\n }\n if (!allTrivial) break\n }\n\n if (allTrivial && Object.keys(stats).length > 0) {\n console.warn('⚠ Catalog stats look stale, falling back to precise mode')\n return collectPreciseCardinalities({ executor, datamodel, dialect })\n }\n\n return stats\n }\n\n return collectPreciseCardinalities({ executor, datamodel, dialect })\n}\n\nexport async function collectPlannerArtifacts(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n mode?: 'fast' | 'precise'\n}): Promise<GeneratePlannerArtifacts> {\n const { executor, datamodel, dialect, mode } = params\n\n const largest = await findLargestTable({ executor, dialect, datamodel })\n\n const [relationStats, roundtripRowEquivalent, jsonRowFactor] =\n await Promise.all([\n collectRelationCardinalities({ executor, datamodel, dialect, mode }),\n measureRoundtripCost({ executor, dialect, datamodel }),\n largest && largest.rowCount >= 50 && dialect === 'postgres'\n ? measureJsonOverhead({\n executor,\n tableName: largest.tableName,\n tableRowCount: largest.rowCount,\n })\n : Promise.resolve(1.5),\n ])\n\n console.log(` Roundtrip cost: ~${roundtripRowEquivalent} row equivalents`)\n console.log(` JSON overhead factor: ${jsonRowFactor.toFixed(2)}x`)\n\n return { relationStats, roundtripRowEquivalent, jsonRowFactor }\n}\n\nexport function emitPlannerGeneratedModule(\n artifacts: GeneratePlannerArtifacts,\n): string {\n return [\n `export const RELATION_STATS = ${stableJson(artifacts.relationStats)} as const`,\n ``,\n `export type RelationStats = typeof RELATION_STATS`,\n ``,\n `export const ROUNDTRIP_ROW_EQUIVALENT = ${artifacts.roundtripRowEquivalent}`,\n ``,\n `export const JSON_ROW_FACTOR = ${artifacts.jsonRowFactor.toFixed(2)}`,\n ``,\n ].join('\\n')\n}\n","#!/usr/bin/env node\nimport { config } from 'dotenv'\nimport { writeFile } from 'fs/promises'\nimport { resolve, isAbsolute } from 'path'\nimport {\n createDatabaseExecutor,\n collectPlannerArtifacts,\n emitPlannerGeneratedModule,\n GeneratePlannerArtifacts,\n} from './cardinality-planner'\n\nconst CONNECT_TIMEOUT_MS = 10000\n\nfunction parseArgs(argv: string[]): { output: string; clientPath: string } {\n const outputIdx = argv.indexOf('--output')\n const clientIdx = argv.indexOf('--prisma-client')\n\n const output =\n outputIdx !== -1 && argv[outputIdx + 1]\n ? argv[outputIdx + 1]\n : './dist/prisma/generated/sql/planner.generated.js'\n\n const clientPath =\n clientIdx !== -1 && argv[clientIdx + 1]\n ? argv[clientIdx + 1]\n : '@prisma/client'\n\n return { output, clientPath }\n}\n\nfunction resolveOutput(output: string): string {\n return isAbsolute(output) ? output : resolve(process.cwd(), output)\n}\n\nfunction resolveClientPath(p: string): string {\n if (p.startsWith('.') || isAbsolute(p)) {\n return resolve(process.cwd(), p)\n }\n if (p.includes('/') && !p.startsWith('@')) {\n return resolve(process.cwd(), p)\n }\n return p\n}\n\nfunction emitCJS(artifacts: GeneratePlannerArtifacts): string {\n const ts = emitPlannerGeneratedModule(artifacts)\n return ts\n .replace(/^export const (\\w+)/gm, 'exports.$1')\n .replace(/^import .*$/gm, '')\n .trimStart()\n}\n\nasync function connectWithTimeout(\n databaseUrl: string,\n dialect: 'postgres' | 'sqlite',\n): Promise<{ executor: any; cleanup: () => Promise<void> }> {\n let settled = false\n\n const connectPromise = createDatabaseExecutor({ databaseUrl, dialect }).then(\n (conn) => {\n if (settled) {\n conn.cleanup().catch(() => {})\n throw new Error('Timed out')\n }\n return conn\n },\n )\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n const id = setTimeout(() => {\n settled = true\n reject(new Error(`Connection timed out after ${CONNECT_TIMEOUT_MS}ms`))\n }, CONNECT_TIMEOUT_MS)\n id.unref?.()\n })\n\n try {\n const result = await Promise.race([connectPromise, timeoutPromise])\n settled = true\n return result\n } catch (err) {\n settled = true\n throw err\n }\n}\n\nasync function main() {\n config()\n\n const skipPlanner =\n process.env.PRISMA_SQL_SKIP_PLANNER === '1' ||\n process.env.PRISMA_SQL_SKIP_PLANNER === 'true'\n\n if (skipPlanner) {\n console.log(\n '[prisma-sql] ⏭ Skipping planner stats (PRISMA_SQL_SKIP_PLANNER)',\n )\n process.exit(0)\n }\n\n const { output, clientPath } = parseArgs(process.argv.slice(2))\n const outputPath = resolveOutput(output)\n\n const url = process.env.DATABASE_URL\n if (!url) {\n console.warn(\n '[prisma-sql] DATABASE_URL not set, skipping planner stats collection',\n )\n process.exit(0)\n }\n\n let executor: any\n let cleanup: (() => Promise<void>) | undefined\n\n try {\n const conn = await connectWithTimeout(url, 'postgres')\n executor = conn.executor\n cleanup = conn.cleanup\n } catch (err) {\n console.warn(\n '[prisma-sql] Failed to connect:',\n err instanceof Error ? err.message : err,\n )\n process.exit(0)\n }\n\n try {\n let dmmf: any\n try {\n const resolvedClientPath = resolveClientPath(clientPath)\n const client = require(resolvedClientPath)\n dmmf = client.Prisma?.dmmf ?? client.dmmf\n if (!dmmf?.datamodel) {\n throw new Error(`Could not read dmmf.datamodel from ${clientPath}`)\n }\n } catch (err) {\n throw new Error(\n `Failed to load Prisma client from \"${clientPath}\": ${err instanceof Error ? err.message : err}`,\n )\n }\n\n const artifacts = await collectPlannerArtifacts({\n executor,\n datamodel: dmmf.datamodel,\n dialect: 'postgres',\n })\n\n await writeFile(outputPath, emitCJS(artifacts as any), 'utf8')\n console.log('[prisma-sql] ✓ Planner stats written to', outputPath)\n } catch (err) {\n console.warn(\n '[prisma-sql] Failed to collect stats:',\n err instanceof Error ? err.message : err,\n )\n } finally {\n await cleanup?.()\n }\n\n process.exit(0)\n}\n\nmain()\n"]}
1
+ {"version":3,"sources":["../src/utils/pure-utils.ts","../src/cardinality-planner.ts","../src/collect-planner-stats.ts"],"names":[],"mappings":"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","file":"collect-planner-stats.js","sourcesContent":["import type { RelStats } from '../cardinality-planner'\n\nexport function toNumberOrZero(v: unknown): number {\n if (typeof v === 'number' && Number.isFinite(v)) return v\n if (typeof v === 'bigint') return Number(v)\n if (typeof v === 'string' && v.trim() !== '') {\n const n = Number(v)\n if (Number.isFinite(n)) return n\n }\n return 0\n}\n\nexport function clampStatsMonotonic(\n avg: number,\n p95: number,\n p99: number,\n max: number,\n coverage: number,\n): RelStats {\n const safeAvg = Math.max(1, avg)\n const safeP95 = Math.max(safeAvg, p95)\n const safeP99 = Math.max(safeP95, p99)\n const safeMax = Math.max(safeP99, max)\n const safeCoverage = Math.max(0, Math.min(1, coverage))\n return {\n avg: safeAvg,\n p95: safeP95,\n p99: safeP99,\n max: safeMax,\n coverage: safeCoverage,\n }\n}\n\nexport function normalizeStats(row: Record<string, unknown>): RelStats {\n return clampStatsMonotonic(\n toNumberOrZero(row.avg),\n toNumberOrZero(row.p95),\n toNumberOrZero(row.p99),\n toNumberOrZero(row.max),\n toNumberOrZero(row.coverage),\n )\n}\n\nexport function stableJson(value: unknown): string {\n return JSON.stringify(\n value,\n (_k, v) => {\n if (!v || typeof v !== 'object' || Array.isArray(v)) return v\n const obj = v as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const k of Object.keys(obj).sort()) out[k] = obj[k]\n return out\n },\n 2,\n )\n}\n\nexport function cleanDatabaseUrl(url: string): string {\n try {\n const parsed = new URL(url)\n parsed.search = ''\n\n if (parsed.password) {\n parsed.password = '***'\n }\n\n if (parsed.username && parsed.username.length > 0) {\n if (parsed.username.length <= 3) {\n parsed.username = '***'\n } else {\n parsed.username = parsed.username.slice(0, 3) + '***'\n }\n }\n\n return parsed.toString()\n } catch (error) {\n return '[invalid-url]'\n }\n}\n\nexport function createQueryKey(\n processedQuery: Record<string, unknown>,\n): string {\n return JSON.stringify(processedQuery, (key, value) => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value).sort()) {\n sorted[k] = (value as any)[k]\n }\n return sorted\n }\n return value\n })\n}\n\nexport function countTotalQueries(\n queries: Map<string, Map<string, Map<string, any>>>,\n): number {\n return Array.from(queries.values()).reduce(\n (sum, methodMap) =>\n sum +\n Array.from(methodMap.values()).reduce(\n (s, queryMap) => s + queryMap.size,\n 0,\n ),\n 0,\n )\n}\n","import { DMMF } from '@prisma/generator-helper'\nimport {\n toNumberOrZero,\n clampStatsMonotonic,\n normalizeStats,\n stableJson,\n cleanDatabaseUrl,\n} from './utils/pure-utils'\nimport { SqlDialect } from './sql-builder-dialect'\n\ntype Executor = {\n query: (\n sql: string,\n params?: unknown[],\n ) => Promise<Array<Record<string, unknown>>>\n}\n\ninterface DatabaseExecutor {\n query: (\n sql: string,\n params?: unknown[],\n ) => Promise<Array<Record<string, unknown>>>\n}\n\nexport type RelStats = {\n avg: number\n p95: number\n p99: number\n max: number\n coverage: number\n}\n\nexport type RelationStatsMap = Record<string, Record<string, RelStats>>\n\nexport type GeneratePlannerArtifacts = {\n relationStats: RelationStatsMap\n roundtripRowEquivalent: number\n jsonRowFactor: number\n}\n\ntype RelEdge = {\n parentModel: string\n relName: string\n childModel: string\n parentTable: string\n childTable: string\n parentPkColumns: string[]\n childFkColumns: string[]\n isMany: boolean\n}\n\nfunction quoteIdent(dialect: SqlDialect, ident: string): string {\n return `\"${ident.replace(/\"/g, '\"\"')}\"`\n}\n\nexport async function createDatabaseExecutor(options: {\n databaseUrl: string\n dialect: 'postgres' | 'sqlite'\n connectTimeoutMs?: number\n}): Promise<{ executor: DatabaseExecutor; cleanup: () => Promise<void> }> {\n const { databaseUrl, dialect, connectTimeoutMs = 30000 } = options\n\n if (dialect === 'postgres') {\n const postgres = await import('postgres')\n const sql = postgres.default(cleanDatabaseUrl(databaseUrl), {\n connect_timeout: Math.ceil(connectTimeoutMs / 1000),\n max: 1,\n })\n\n return {\n executor: {\n query: async (q: string, params?: unknown[]) => {\n return await sql.unsafe(q, (params ?? []) as any[])\n },\n },\n cleanup: async () => {\n await sql.end()\n },\n }\n }\n\n throw new Error(`createDatabaseExecutor does not support dialect: ${dialect}`)\n}\n\nfunction extractMeasurableOneToManyEdges(datamodel: DMMF.Datamodel): RelEdge[] {\n const modelByName = new Map(datamodel.models.map((m) => [m.name, m]))\n const edges: RelEdge[] = []\n\n for (const parent of datamodel.models) {\n const pkFields = parent.fields.filter((f) => f.isId)\n if (pkFields.length === 0) continue\n\n const parentPk = pkFields.map((f) => f.dbName || f.name)\n const parentTable = parent.dbName || parent.name\n\n for (const f of parent.fields) {\n if (!f.relationName) continue\n if (!f.isList) continue\n\n const child = modelByName.get(f.type)\n if (!child) continue\n\n const childRelField = child.fields.find(\n (cf) => cf.relationName === f.relationName && cf.type === parent.name,\n )\n if (!childRelField) continue\n\n const fkFieldNames = childRelField.relationFromFields || []\n if (fkFieldNames.length === 0) continue\n\n const fkFields = fkFieldNames.map((name) => {\n const fld = child.fields.find((x) => x.name === name)\n return fld ? fld.dbName || fld.name : name\n })\n\n const refFieldNames = childRelField.relationToFields || []\n if (refFieldNames.length === 0) continue\n\n const references = refFieldNames.map((name) => {\n const fld = parent.fields.find((x) => x.name === name)\n return fld ? fld.dbName || fld.name : name\n })\n\n if (fkFields.length !== references.length) continue\n\n const childTable = child.dbName || child.name\n\n edges.push({\n parentModel: parent.name,\n relName: f.name,\n childModel: child.name,\n parentTable,\n childTable,\n parentPkColumns: references,\n childFkColumns: fkFields,\n isMany: true,\n })\n }\n }\n\n return edges\n}\n\nfunction buildPostgresStatsSql(edge: RelEdge): string {\n const childTable = quoteIdent('postgres', edge.childTable)\n const parentTable = quoteIdent('postgres', edge.parentTable)\n const groupCols = edge.childFkColumns\n .map((c) => quoteIdent('postgres', c))\n .join(', ')\n\n return `\nWITH counts AS (\n SELECT ${groupCols}, COUNT(*) AS cnt\n FROM ${childTable}\n GROUP BY ${groupCols}\n),\ntotal_parents AS (\n SELECT COUNT(*) AS total FROM ${parentTable}\n)\nSELECT\n AVG(cnt)::float AS avg,\n MAX(cnt)::int AS max,\n PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY cnt)::float AS p95,\n PERCENTILE_CONT(0.99) WITHIN GROUP (ORDER BY cnt)::float AS p99,\n (SELECT COUNT(*) FROM counts)::float / GREATEST(1, (SELECT total FROM total_parents)) AS coverage\nFROM counts\n`.trim()\n}\n\nfunction buildSqliteStatsSql(edge: RelEdge): string {\n const childTable = quoteIdent('sqlite', edge.childTable)\n const parentTable = quoteIdent('sqlite', edge.parentTable)\n const groupCols = edge.childFkColumns\n .map((c) => quoteIdent('sqlite', c))\n .join(', ')\n\n return `\nWITH counts AS (\n SELECT ${groupCols}, COUNT(*) AS cnt\n FROM ${childTable}\n GROUP BY ${groupCols}\n),\nn AS (\n SELECT COUNT(*) AS total FROM counts\n),\nparent_n AS (\n SELECT COUNT(*) AS total FROM ${parentTable}\n),\nordered AS (\n SELECT cnt\n FROM counts\n ORDER BY cnt\n)\nSELECT\n (SELECT AVG(cnt) FROM counts) AS avg,\n (SELECT MAX(cnt) FROM counts) AS max,\n (\n SELECT cnt\n FROM ordered\n LIMIT 1\n OFFSET (\n SELECT\n CASE\n WHEN total <= 1 THEN 0\n ELSE CAST((0.95 * (total - 1)) AS INT)\n END\n FROM n\n )\n ) AS p95,\n (\n SELECT cnt\n FROM ordered\n LIMIT 1\n OFFSET (\n SELECT\n CASE\n WHEN total <= 1 THEN 0\n ELSE CAST((0.99 * (total - 1)) AS INT)\n END\n FROM n\n )\n ) AS p99,\n CAST((SELECT total FROM n) AS FLOAT) / MAX(1, (SELECT total FROM parent_n)) AS coverage\n`.trim()\n}\n\nfunction buildFanoutStatsSql(dialect: SqlDialect, edge: RelEdge): string {\n return dialect === 'postgres'\n ? buildPostgresStatsSql(edge)\n : buildSqliteStatsSql(edge)\n}\n\nasync function findLargestTable(params: {\n executor: Executor\n dialect: SqlDialect\n datamodel: DMMF.Datamodel\n}): Promise<{ tableName: string; rowCount: number } | null> {\n const { executor, dialect, datamodel } = params\n\n let best: { tableName: string; rowCount: number } | null = null\n\n for (const model of datamodel.models) {\n const table = quoteIdent(dialect, model.dbName || model.name)\n try {\n const rows = await executor.query(`SELECT COUNT(*) AS cnt FROM ${table}`)\n const count = toNumberOrZero(rows[0]?.cnt)\n if (!best || count > best.rowCount) {\n best = { tableName: table, rowCount: count }\n }\n } catch (_) {}\n }\n\n return best\n}\n\nasync function measureRoundtripCost(params: {\n executor: Executor\n dialect: SqlDialect\n datamodel: DMMF.Datamodel\n}): Promise<number> {\n const { executor, dialect, datamodel } = params\n const WARMUP = 5\n const SAMPLES = 15\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query('SELECT 1')\n }\n\n const roundtripTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query('SELECT 1')\n roundtripTimes.push(performance.now() - start)\n }\n roundtripTimes.sort((a, b) => a - b)\n const medianRoundtrip = roundtripTimes[Math.floor(SAMPLES / 2)]\n\n console.log(\n ` [roundtrip] SELECT 1 times (ms): min=${roundtripTimes[0].toFixed(3)} median=${medianRoundtrip.toFixed(3)} max=${roundtripTimes[SAMPLES - 1].toFixed(3)}`,\n )\n\n const largest = await findLargestTable({ executor, dialect, datamodel })\n\n if (!largest || largest.rowCount < 50) {\n console.log(\n ` [roundtrip] Largest table: ${largest?.tableName ?? 'none'} (${largest?.rowCount ?? 0} rows) — too small, using default 50`,\n )\n return 50\n }\n\n console.log(\n ` [roundtrip] Using table ${largest.tableName} (${largest.rowCount} rows)`,\n )\n\n return estimateFromQueryPairRatio({\n executor,\n tableName: largest.tableName,\n medianRoundtrip,\n tableRowCount: largest.rowCount,\n })\n}\n\nasync function estimateFromQueryPairRatio(params: {\n executor: Executor\n tableName: string\n medianRoundtrip: number\n tableRowCount: number\n}): Promise<number> {\n const { executor, tableName, medianRoundtrip, tableRowCount } = params\n const WARMUP = 5\n const SAMPLES = 10\n\n const smallLimit = 1\n const largeLimit = Math.min(1000, tableRowCount)\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${largeLimit}`)\n }\n\n const smallTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n smallTimes.push(performance.now() - start)\n }\n smallTimes.sort((a, b) => a - b)\n const medianSmall = smallTimes[Math.floor(SAMPLES / 2)]\n\n const largeTimes: number[] = []\n let actualLargeRows = 0\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n const rows = await executor.query(\n `SELECT * FROM ${tableName} LIMIT ${largeLimit}`,\n )\n largeTimes.push(performance.now() - start)\n actualLargeRows = rows.length\n }\n largeTimes.sort((a, b) => a - b)\n const medianLarge = largeTimes[Math.floor(SAMPLES / 2)]\n\n const rowDiff = actualLargeRows - smallLimit\n const timeDiff = medianLarge - medianSmall\n\n console.log(\n ` [roundtrip] LIMIT ${smallLimit}: median=${medianSmall.toFixed(3)}ms`,\n )\n console.log(\n ` [roundtrip] LIMIT ${largeLimit} (got ${actualLargeRows}): median=${medianLarge.toFixed(3)}ms`,\n )\n console.log(\n ` [roundtrip] Time diff: ${timeDiff.toFixed(3)}ms for ${rowDiff} rows`,\n )\n\n if (rowDiff < 50 || timeDiff <= 0.05) {\n console.log(\n ` [roundtrip] Insufficient signal (need ≥50 row diff and >0.05ms time diff), defaulting to 50`,\n )\n return 50\n }\n\n const perRow = timeDiff / rowDiff\n\n const sequentialTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n await executor.query(`SELECT * FROM ${tableName} LIMIT ${smallLimit}`)\n sequentialTimes.push(performance.now() - start)\n }\n sequentialTimes.sort((a, b) => a - b)\n const median3Sequential = sequentialTimes[Math.floor(SAMPLES / 2)]\n\n const marginalQueryCost = (median3Sequential - medianSmall) / 2\n\n console.log(\n ` [roundtrip] 3x sequential LIMIT 1: median=${median3Sequential.toFixed(3)}ms`,\n )\n console.log(` [roundtrip] Single query: ${medianSmall.toFixed(3)}ms`)\n console.log(\n ` [roundtrip] Marginal query cost: ${marginalQueryCost.toFixed(3)}ms`,\n )\n console.log(` [roundtrip] Per-row cost: ${perRow.toFixed(4)}ms`)\n\n const equivalent = Math.round(marginalQueryCost / perRow)\n\n console.log(` [roundtrip] Raw equivalent: ${equivalent} rows`)\n\n const clamped = Math.max(10, Math.min(500, equivalent))\n console.log(` [roundtrip] Final (clamped): ${clamped} rows`)\n\n return clamped\n}\n\nasync function measureJsonOverhead(params: {\n executor: Executor\n tableName: string\n tableRowCount: number\n}): Promise<number> {\n const { executor, tableName, tableRowCount } = params\n const WARMUP = 3\n const SAMPLES = 10\n const limit = Math.min(500, tableRowCount)\n\n const rawSql = `SELECT * FROM ${tableName} LIMIT ${limit}`\n\n const colsResult = await executor.query(\n `SELECT column_name FROM information_schema.columns WHERE table_name = ${tableName.replace(/\"/g, \"'\")} LIMIT 10`,\n )\n\n let aggSql: string\n if (colsResult.length >= 3) {\n const cols = colsResult.slice(0, 6).map((r) => `\"${r.column_name}\"`)\n const aggExprs = cols.map((c) => `array_agg(${c})`).join(', ')\n const groupCol = cols[0]\n aggSql = `SELECT ${groupCol}, ${aggExprs} FROM ${tableName} GROUP BY ${groupCol} LIMIT ${limit}`\n } else {\n aggSql = `SELECT json_agg(t) FROM (SELECT * FROM ${tableName} LIMIT ${limit}) t`\n }\n\n for (let i = 0; i < WARMUP; i++) {\n await executor.query(rawSql)\n await executor.query(aggSql)\n }\n\n const rawTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(rawSql)\n rawTimes.push(performance.now() - start)\n }\n rawTimes.sort((a, b) => a - b)\n const medianRaw = rawTimes[Math.floor(SAMPLES / 2)]\n\n const aggTimes: number[] = []\n for (let i = 0; i < SAMPLES; i++) {\n const start = performance.now()\n await executor.query(aggSql)\n aggTimes.push(performance.now() - start)\n }\n aggTimes.sort((a, b) => a - b)\n const medianAgg = aggTimes[Math.floor(SAMPLES / 2)]\n\n const factor = medianRaw > 0.01 ? medianAgg / medianRaw : 3.0\n\n console.log(` [json] Raw ${limit} rows: ${medianRaw.toFixed(3)}ms`)\n console.log(` [json] array_agg grouped: ${medianAgg.toFixed(3)}ms`)\n console.log(` [json] Overhead factor: ${factor.toFixed(2)}x`)\n\n return Math.max(1.5, Math.min(8.0, factor))\n}\n\nasync function collectPostgresStatsFromCatalog(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n}): Promise<RelationStatsMap> {\n const { executor, datamodel } = params\n const edges = extractMeasurableOneToManyEdges(datamodel)\n const out: RelationStatsMap = {}\n\n const tablesToAnalyze = new Set<string>()\n for (const edge of edges) {\n tablesToAnalyze.add(edge.parentTable)\n tablesToAnalyze.add(edge.childTable)\n }\n\n for (const table of tablesToAnalyze) {\n try {\n await executor.query(`ANALYZE ${quoteIdent('postgres', table)}`)\n } catch (_) {}\n }\n\n const tableStatsQuery = `\n SELECT\n c.relname as table_name,\n c.reltuples::bigint as row_count\n FROM pg_class c\n JOIN pg_namespace n ON n.oid = c.relnamespace\n WHERE c.relkind = 'r'\n AND n.nspname NOT IN ('pg_catalog', 'information_schema')\n `\n\n const tableStats = await executor.query(tableStatsQuery, [])\n const rowCounts = new Map<string, number>()\n\n for (const row of tableStats) {\n const tableName = String(row.table_name)\n const count = toNumberOrZero(row.row_count)\n rowCounts.set(tableName, count)\n }\n\n for (const edge of edges) {\n const parentRows = rowCounts.get(edge.parentTable) || 0\n const childRows = rowCounts.get(edge.childTable) || 0\n\n if (parentRows === 0 || childRows === 0) {\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = {\n avg: 1,\n p95: 1,\n p99: 1,\n max: 1,\n coverage: 0,\n }\n continue\n }\n\n const fkColumn = edge.childFkColumns[0]\n\n const statsQuery = `\n SELECT\n s.n_distinct,\n s.correlation,\n (s.most_common_freqs)[1] as max_freq\n FROM pg_stats s\n WHERE s.tablename = $1\n AND s.attname = $2\n AND s.schemaname NOT IN ('pg_catalog', 'information_schema')\n `\n\n const statsRows = await executor.query(statsQuery, [\n edge.childTable,\n fkColumn,\n ])\n\n let avg: number\n let p95: number\n let p99: number\n let max: number\n let coverage: number\n\n if (statsRows.length > 0) {\n const stats = statsRows[0]\n const nDistinct = toNumberOrZero(stats.n_distinct)\n const correlation =\n stats.correlation !== null ? Number(stats.correlation) : 0\n const maxFreq = stats.max_freq !== null ? Number(stats.max_freq) : null\n\n const distinctCount =\n nDistinct < 0\n ? Math.abs(nDistinct) * childRows\n : nDistinct > 0\n ? nDistinct\n : parentRows\n\n avg =\n distinctCount > 0 ? childRows / distinctCount : childRows / parentRows\n coverage = Math.min(1, distinctCount / parentRows)\n\n const skewFactor = Math.abs(correlation) > 0.5 ? 2.5 : 1.5\n p95 = avg * skewFactor\n p99 = avg * (skewFactor * 1.3)\n\n max = maxFreq ? Math.ceil(childRows * maxFreq) : Math.ceil(p99 * 1.5)\n } else {\n avg = childRows / parentRows\n coverage = 1\n p95 = avg * 2\n p99 = avg * 3\n max = avg * 5\n }\n\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = clampStatsMonotonic(\n Math.ceil(avg),\n Math.ceil(p95),\n Math.ceil(p99),\n Math.ceil(max),\n coverage,\n )\n }\n\n return out\n}\n\nasync function collectPreciseCardinalities(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n}): Promise<RelationStatsMap> {\n const { executor, datamodel, dialect } = params\n const edges = extractMeasurableOneToManyEdges(datamodel)\n const out: RelationStatsMap = {}\n\n for (const edge of edges) {\n const sql = buildFanoutStatsSql(dialect, edge)\n const rows = await executor.query(sql, [])\n const row = rows[0] || {}\n const stats = normalizeStats(row)\n\n if (!out[edge.parentModel]) out[edge.parentModel] = {}\n out[edge.parentModel][edge.relName] = stats\n }\n\n return out\n}\n\nasync function collectRelationCardinalities(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n mode?: 'fast' | 'precise'\n}): Promise<RelationStatsMap> {\n const { executor, datamodel, dialect, mode = 'precise' } = params\n\n if (dialect === 'postgres' && mode === 'fast') {\n const stats = await collectPostgresStatsFromCatalog({ executor, datamodel })\n\n let allTrivial = true\n for (const model of Object.values(stats)) {\n for (const rel of Object.values(model)) {\n if (rel.avg > 1 || rel.coverage > 0.5) {\n allTrivial = false\n break\n }\n }\n if (!allTrivial) break\n }\n\n if (allTrivial && Object.keys(stats).length > 0) {\n console.warn('⚠ Catalog stats look stale, falling back to precise mode')\n return collectPreciseCardinalities({ executor, datamodel, dialect })\n }\n\n return stats\n }\n\n return collectPreciseCardinalities({ executor, datamodel, dialect })\n}\n\nexport async function collectPlannerArtifacts(params: {\n executor: Executor\n datamodel: DMMF.Datamodel\n dialect: SqlDialect\n mode?: 'fast' | 'precise'\n}): Promise<GeneratePlannerArtifacts> {\n const { executor, datamodel, dialect, mode } = params\n\n const largest = await findLargestTable({ executor, dialect, datamodel })\n\n const [relationStats, roundtripRowEquivalent, jsonRowFactor] =\n await Promise.all([\n collectRelationCardinalities({ executor, datamodel, dialect, mode }),\n measureRoundtripCost({ executor, dialect, datamodel }),\n largest && largest.rowCount >= 50 && dialect === 'postgres'\n ? measureJsonOverhead({\n executor,\n tableName: largest.tableName,\n tableRowCount: largest.rowCount,\n })\n : Promise.resolve(1.5),\n ])\n\n console.log(` Roundtrip cost: ~${roundtripRowEquivalent} row equivalents`)\n console.log(` JSON overhead factor: ${jsonRowFactor.toFixed(2)}x`)\n\n return { relationStats, roundtripRowEquivalent, jsonRowFactor }\n}\n\nexport function emitPlannerGeneratedModule(\n artifacts: GeneratePlannerArtifacts,\n): string {\n return [\n `export const RELATION_STATS = ${stableJson(artifacts.relationStats)} as const`,\n ``,\n `export type RelationStats = typeof RELATION_STATS`,\n ``,\n `export const ROUNDTRIP_ROW_EQUIVALENT = ${artifacts.roundtripRowEquivalent}`,\n ``,\n `export const JSON_ROW_FACTOR = ${artifacts.jsonRowFactor.toFixed(2)}`,\n ``,\n ].join('\\n')\n}\n","#!/usr/bin/env node\nimport { config } from 'dotenv'\nimport { writeFile } from 'fs/promises'\nimport { resolve, isAbsolute } from 'path'\nimport {\n createDatabaseExecutor,\n collectPlannerArtifacts,\n emitPlannerGeneratedModule,\n GeneratePlannerArtifacts,\n} from './cardinality-planner'\n\nconst CONNECT_TIMEOUT_MS = 10000\n\nfunction parseArgs(argv: string[]): { output: string; clientPath: string } {\n const outputIdx = argv.indexOf('--output')\n const clientIdx = argv.indexOf('--prisma-client')\n\n const output =\n outputIdx !== -1 && argv[outputIdx + 1]\n ? argv[outputIdx + 1]\n : './dist/prisma/generated/sql/planner.generated.js'\n\n const clientPath =\n clientIdx !== -1 && argv[clientIdx + 1]\n ? argv[clientIdx + 1]\n : '@prisma/client'\n\n return { output, clientPath }\n}\n\nfunction resolveOutput(output: string): string {\n return isAbsolute(output) ? output : resolve(process.cwd(), output)\n}\n\nfunction resolveClientPath(p: string): string {\n if (p.startsWith('.') || isAbsolute(p)) {\n return resolve(process.cwd(), p)\n }\n if (p.includes('/') && !p.startsWith('@')) {\n return resolve(process.cwd(), p)\n }\n return p\n}\n\nfunction emitCJS(artifacts: GeneratePlannerArtifacts): string {\n const ts = emitPlannerGeneratedModule(artifacts)\n return ts\n .replace(/^export const (\\w+)/gm, 'exports.$1')\n .replace(/^import .*$/gm, '')\n .trimStart()\n}\n\nasync function connectWithTimeout(\n databaseUrl: string,\n dialect: 'postgres' | 'sqlite',\n): Promise<{ executor: any; cleanup: () => Promise<void> }> {\n let settled = false\n\n const connectPromise = createDatabaseExecutor({ databaseUrl, dialect }).then(\n (conn) => {\n if (settled) {\n conn.cleanup().catch(() => {})\n throw new Error('Timed out')\n }\n return conn\n },\n )\n\n const timeoutPromise = new Promise<never>((_, reject) => {\n const id = setTimeout(() => {\n settled = true\n reject(new Error(`Connection timed out after ${CONNECT_TIMEOUT_MS}ms`))\n }, CONNECT_TIMEOUT_MS)\n id.unref?.()\n })\n\n try {\n const result = await Promise.race([connectPromise, timeoutPromise])\n settled = true\n return result\n } catch (err) {\n settled = true\n throw err\n }\n}\n\nasync function main() {\n config()\n\n const skipPlanner =\n process.env.PRISMA_SQL_SKIP_PLANNER === '1' ||\n process.env.PRISMA_SQL_SKIP_PLANNER === 'true'\n\n if (skipPlanner) {\n console.log(\n '[prisma-sql] ⏭ Skipping planner stats (PRISMA_SQL_SKIP_PLANNER)',\n )\n process.exit(0)\n }\n\n const { output, clientPath } = parseArgs(process.argv.slice(2))\n const outputPath = resolveOutput(output)\n\n const url = process.env.DATABASE_URL\n if (!url) {\n console.warn(\n '[prisma-sql] DATABASE_URL not set, skipping planner stats collection',\n )\n process.exit(0)\n }\n\n let executor: any\n let cleanup: (() => Promise<void>) | undefined\n\n try {\n const conn = await connectWithTimeout(url, 'postgres')\n executor = conn.executor\n cleanup = conn.cleanup\n } catch (err) {\n console.warn(\n '[prisma-sql] Failed to connect:',\n err instanceof Error ? err.message : err,\n )\n process.exit(0)\n }\n\n try {\n let dmmf: any\n try {\n const resolvedClientPath = resolveClientPath(clientPath)\n const client = require(resolvedClientPath)\n dmmf = client.Prisma?.dmmf ?? client.dmmf\n if (!dmmf?.datamodel) {\n throw new Error(`Could not read dmmf.datamodel from ${clientPath}`)\n }\n } catch (err) {\n throw new Error(\n `Failed to load Prisma client from \"${clientPath}\": ${err instanceof Error ? err.message : err}`,\n )\n }\n\n const artifacts = await collectPlannerArtifacts({\n executor,\n datamodel: dmmf.datamodel,\n dialect: 'postgres',\n })\n\n await writeFile(outputPath, emitCJS(artifacts as any), 'utf8')\n console.log('[prisma-sql] ✓ Planner stats written to', outputPath)\n } catch (err) {\n console.warn(\n '[prisma-sql] Failed to collect stats:',\n err instanceof Error ? err.message : err,\n )\n } finally {\n await cleanup?.()\n }\n\n process.exit(0)\n}\n\nmain()\n"]}
@@ -70,7 +70,7 @@ var require_package = __commonJS({
70
70
  "package.json"(exports$1, module) {
71
71
  module.exports = {
72
72
  name: "prisma-sql",
73
- version: "1.78.0",
73
+ version: "1.79.1",
74
74
  description: "Convert Prisma queries to optimized SQL with type safety. 2-7x faster than Prisma Client.",
75
75
  main: "dist/index.cjs",
76
76
  module: "dist/index.js",
@@ -8182,7 +8182,7 @@ function generateExtension(runtimeImportPath) {
8182
8182
  $parent?: any
8183
8183
  }
8184
8184
 
8185
- async function handleMethod(
8185
+ async function handleMethod(
8186
8186
  this: ModelContext,
8187
8187
  method: PrismaMethod,
8188
8188
  args: unknown
@@ -8194,6 +8194,7 @@ function generateExtension(runtimeImportPath) {
8194
8194
  }
8195
8195
 
8196
8196
  const startTime = Date.now()
8197
+ let sql: string | undefined
8197
8198
 
8198
8199
  try {
8199
8200
  if (args !== undefined && args !== null && typeof args !== 'object') {
@@ -8229,7 +8230,6 @@ function generateExtension(runtimeImportPath) {
8229
8230
 
8230
8231
  const queryKey = normalizeQuery(plan.filteredArgs)
8231
8232
  const prebakedQuery = QUERIES[modelName]?.[method]?.[queryKey]
8232
- let sql: string
8233
8233
  let params: unknown[]
8234
8234
  let prebaked = false
8235
8235
  let requiresReduction = false