{
  "version": 3,
  "sources": ["../../../../src/workers/d1/database.worker.ts", "../../../../src/workers/d1/dumpSql.ts"],
  "sourcesContent": ["import assert from \"node:assert\";\nimport {\n\tget,\n\tHttpError,\n\tMiniflareDurableObject,\n\tPOST,\n\tviewToBuffer,\n} from \"miniflare:shared\";\nimport { z } from \"miniflare:zod\";\nimport { dumpSql } from \"./dumpSql\";\nimport type {\n\tMiniflareDurableObjectEnv,\n\tRouteHandler,\n\tTypedSqlStorage,\n\tTypedValue,\n} from \"miniflare:shared\";\n\nconst D1ValueSchema = z.union([\n\tz.number(),\n\tz.string(),\n\tz.null(),\n\tz.number().array(),\n]);\ntype D1Value = z.infer<typeof D1ValueSchema>;\n\nconst D1QuerySchema = z.object({\n\tsql: z.string(),\n\tparams: z.array(D1ValueSchema).nullable().optional(),\n});\ntype D1Query = z.infer<typeof D1QuerySchema>;\nconst D1QueriesSchema = z.union([D1QuerySchema, z.array(D1QuerySchema)]);\n\nconst D1_EXPORT_PRAGMA = `PRAGMA miniflare_d1_export(?,?,?);`;\ntype D1ExportPragma = [\n\t{ sql: typeof D1_EXPORT_PRAGMA; params: [number, number, ...string[]] },\n];\n\nconst D1ResultsFormatSchema = z\n\t.enum([\"ARRAY_OF_OBJECTS\", \"ROWS_AND_COLUMNS\", \"NONE\"])\n\t.catch(\"ARRAY_OF_OBJECTS\");\n\ntype D1ResultsFormat = z.infer<typeof D1ResultsFormatSchema>;\n\ninterface D1RowsAndColumns {\n\tcolumns: string[];\n\trows: D1Value[][];\n}\n\ntype D1Results = D1RowsAndColumns | Record<string, D1Value>[] | undefined;\n\nconst served_by = \"miniflare.db\";\ninterface D1SuccessResponse {\n\tsuccess: true;\n\tresults: D1Results;\n\tmeta: {\n\t\tserved_by: string;\n\t\tduration: number;\n\t\tchanges: number;\n\t\tlast_row_id: number;\n\t\tchanged_db: boolean;\n\t\tsize_after: number;\n\t\trows_read: number;\n\t\trows_written: number;\n\t};\n}\ninterface D1FailureResponse {\n\tsuccess: false;\n\terror: string;\n}\n\n// See https://github.com/cloudflare/workerd/blob/bcaf44290296c71f396175c30b43cff6b570231f/src/cloudflare/internal/d1-api.ts#L68-L72\nconst D1_SESSION_COMMIT_TOKEN_HTTP_HEADER = \"x-cf-d1-session-commit-token\";\n\nexport class D1Error extends HttpError {\n\tconstructor(readonly cause: unknown) {\n\t\tsuper(500);\n\t}\n\n\ttoResponse(): Response {\n\t\tconst error =\n\t\t\ttypeof this.cause === \"object\" &&\n\t\t\tthis.cause !== null &&\n\t\t\t\"message\" in this.cause &&\n\t\t\ttypeof this.cause.message === \"string\"\n\t\t\t\t? this.cause.message\n\t\t\t\t: String(this.cause);\n\t\tconst response: D1FailureResponse = { success: false, error };\n\t\treturn Response.json(response);\n\t}\n}\n\nfunction convertParams(params: D1Query[\"params\"]): TypedValue[] {\n\treturn (params ?? []).map((param) =>\n\t\t// If `param` is an array, assume it's a byte array\n\t\tArray.isArray(param) ? viewToBuffer(new Uint8Array(param)) : param\n\t);\n}\n\nfunction convertRows(rows: TypedValue[][]): D1Value[][] {\n\treturn rows.map((row) =>\n\t\trow.map((value) => {\n\t\t\tlet normalised: D1Value;\n\t\t\tif (value instanceof ArrayBuffer) {\n\t\t\t\t// If `value` is an array, convert it to a regular numeric array\n\t\t\t\tnormalised = Array.from(new Uint8Array(value));\n\t\t\t} else {\n\t\t\t\tnormalised = value;\n\t\t\t}\n\t\t\treturn normalised;\n\t\t})\n\t);\n}\n\nfunction rowsToObjects(\n\tcolumns: string[],\n\trows: D1Value[][]\n): Record<string, D1Value>[] {\n\treturn rows.map((row) =>\n\t\tObject.fromEntries(columns.map((name, i) => [name, row[i]]))\n\t);\n}\n\nfunction sqlStmts(db: TypedSqlStorage) {\n\treturn {\n\t\tgetChanges: db.prepare<[], { totalChanges: number; lastRowId: number }>(\n\t\t\t\"SELECT total_changes() AS totalChanges, last_insert_rowid() AS lastRowId\"\n\t\t),\n\t};\n}\n\nexport class D1DatabaseObject extends MiniflareDurableObject {\n\treadonly #stmts: ReturnType<typeof sqlStmts>;\n\n\tconstructor(state: DurableObjectState, env: MiniflareDurableObjectEnv) {\n\t\tsuper(state, env);\n\t\tthis.#stmts = sqlStmts(this.db);\n\t}\n\n\t#changes() {\n\t\tconst changes = get(this.#stmts.getChanges());\n\t\tassert(changes !== undefined);\n\t\treturn changes;\n\t}\n\n\t#query = (format: D1ResultsFormat, query: D1Query): D1SuccessResponse => {\n\t\tconst beforeTime = performance.now();\n\n\t\tconst beforeSize = this.state.storage.sql.databaseSize;\n\t\tconst beforeChanges = this.#changes();\n\n\t\tconst params = convertParams(query.params ?? []);\n\t\tconst cursor = this.db.prepare(query.sql)(...params);\n\t\tconst columns = cursor.columnNames;\n\t\tconst rows = convertRows(Array.from(cursor.raw()));\n\n\t\tlet results = undefined;\n\t\tif (format === \"ROWS_AND_COLUMNS\") results = { columns, rows };\n\t\telse results = rowsToObjects(columns, rows);\n\t\t// Note that the \"NONE\" format behaviour here is inconsistent with workerd.\n\t\t// See comment: https://github.com/cloudflare/workers-sdk/pull/5917#issuecomment-2133313156\n\n\t\tconst afterTime = performance.now();\n\t\tconst afterSize = this.state.storage.sql.databaseSize;\n\t\tconst afterChanges = this.#changes();\n\n\t\tconst duration = afterTime - beforeTime;\n\t\tconst changes = afterChanges.totalChanges - beforeChanges.totalChanges;\n\n\t\tconst hasChanges = changes !== 0;\n\t\tconst lastRowChanged = afterChanges.lastRowId !== beforeChanges.lastRowId;\n\t\tconst sizeChanged = afterSize !== beforeSize;\n\t\tconst changed = hasChanges || lastRowChanged || sizeChanged;\n\n\t\treturn {\n\t\t\tsuccess: true,\n\t\t\tresults,\n\t\t\tmeta: {\n\t\t\t\tserved_by,\n\t\t\t\tduration,\n\t\t\t\tchanges,\n\t\t\t\tlast_row_id: afterChanges.lastRowId,\n\t\t\t\tchanged_db: changed,\n\t\t\t\tsize_after: afterSize,\n\t\t\t\trows_read: cursor.rowsRead,\n\t\t\t\trows_written: cursor.rowsWritten,\n\t\t\t},\n\t\t};\n\t};\n\n\t#txn(queries: D1Query[], format: D1ResultsFormat): D1SuccessResponse[] {\n\t\t// Filter out queries that are just comments\n\t\tqueries = queries.filter(\n\t\t\t(query) => query.sql.replace(/^\\s+--.*/gm, \"\").trim().length > 0\n\t\t);\n\t\tif (queries.length === 0) {\n\t\t\tconst error = new Error(\"No SQL statements detected.\");\n\t\t\tthrow new D1Error(error);\n\t\t}\n\n\t\ttry {\n\t\t\treturn this.state.storage.transactionSync(() =>\n\t\t\t\tqueries.map(this.#query.bind(this, format))\n\t\t\t);\n\t\t} catch (e) {\n\t\t\tthrow new D1Error(e);\n\t\t}\n\t}\n\n\t@POST(\"/query\")\n\t@POST(\"/execute\")\n\tqueryExecute: RouteHandler = async (req) => {\n\t\tlet queries = D1QueriesSchema.parse(await req.json());\n\t\tif (!Array.isArray(queries)) queries = [queries];\n\n\t\t// Special local-mode-only handlers\n\t\tif (this.#isExportPragma(queries)) {\n\t\t\treturn this.#doExportData(queries);\n\t\t}\n\n\t\tconst { searchParams } = new URL(req.url);\n\t\tconst resultsFormat = D1ResultsFormatSchema.parse(\n\t\t\tsearchParams.get(\"resultsFormat\")\n\t\t);\n\n\t\treturn Response.json(this.#txn(queries, resultsFormat), {\n\t\t\theaders: {\n\t\t\t\t[D1_SESSION_COMMIT_TOKEN_HTTP_HEADER]:\n\t\t\t\t\tawait this.state.storage.getCurrentBookmark(),\n\t\t\t},\n\t\t});\n\t};\n\n\t#isExportPragma(queries: D1Query[]): queries is D1ExportPragma {\n\t\treturn (\n\t\t\tqueries.length === 1 &&\n\t\t\tqueries[0].sql === D1_EXPORT_PRAGMA &&\n\t\t\t(queries[0].params?.length || 0) >= 2\n\t\t);\n\t}\n\n\t#doExportData(\n\t\tqueries: [\n\t\t\t{ sql: typeof D1_EXPORT_PRAGMA; params: [number, number, ...string[]] },\n\t\t]\n\t) {\n\t\tconst [noSchema, noData, ...tables] = queries[0].params;\n\t\tconst options = {\n\t\t\tnoSchema: Boolean(noSchema),\n\t\t\tnoData: Boolean(noData),\n\t\t\ttables,\n\t\t};\n\t\treturn Response.json({\n\t\t\tsuccess: true,\n\t\t\tresults: [Array.from(dumpSql(this.state.storage.sql, options))],\n\t\t\tmeta: {},\n\t\t});\n\t}\n}\n", "// NOTE: this file is duplicated between miniflare and d1-workers, and should be kept in sync by hand.\n// Please tag someone from the D1 team as a reviewer and they will do this for you.\n//\n// NOTE: this function duplicates the logic inside SQLite's shell.c.in as close\n// as possible, with any deviations noted.\nimport type { SqlStorage } from \"@cloudflare/workers-types/experimental\";\n\n/** Stats tracking for dumpSql. Will be mutated in place if provided. */\nexport interface DumpSqlStats {\n\trows_read: number;\n\trows_written: number;\n\t// Stats for tracking INSERT statement sizes (column names are always included)\n\t/** Number of INSERT statements over 100KB (current size, with column names) */\n\tinserts_over_100kb_with_column_names: number;\n\t/** Number of INSERT statements that would be over 100KB without column names (for backward comparison) */\n\tinserts_already_over_100kb: number;\n\t/** Total number of INSERT statements generated */\n\ttotal_inserts: number;\n\t/** Maximum INSERT statement size without column names (hypothetical, for backward comparison) */\n\tmax_insert_size: number;\n\t/** Maximum INSERT statement size (current size, with column names) */\n\tmax_insert_size_with_column_names: number;\n}\n\nexport function* dumpSql(\n\tdb: SqlStorage,\n\toptions?: {\n\t\tnoSchema?: boolean;\n\t\tnoData?: boolean;\n\t\ttables?: string[];\n\t},\n\t/** Optional stats tracking. Will be mutated in place if provided */\n\tstats?: DumpSqlStats\n) {\n\t// WARNING: the caller in D1 assumes non-empty exports, so think carefully before removing this initial yield.\n\tyield `PRAGMA defer_foreign_keys=TRUE;`;\n\n\t// Empty set means include all tables\n\tconst filterTables = new Set(options?.tables || []);\n\tconst { noData, noSchema } = options || {};\n\n\t// Taken from SQLite shell.c.in https://github.com/sqlite/sqlite/blob/105c20648e1b05839fd0638686b95f2e3998abcb/src/shell.c.in#L8463-L8469\n\t// @ts-expect-error -- SqlStorageStatement needs to be callable\n\tconst tables_cursor = db.prepare(`\n    SELECT name, type, sql\n      FROM sqlite_schema AS o\n    WHERE (true) AND type=='table'\n      AND sql NOT NULL\n    ORDER BY tbl_name='sqlite_sequence', rowid;\n  `)();\n\tconst tables: { name: string; type: string; sql: string }[] =\n\t\tArray.from(tables_cursor);\n\tif (stats) {\n\t\tstats.rows_read += tables_cursor.rowsRead;\n\t\tstats.rows_written += tables_cursor.rowsWritten;\n\t}\n\n\tfor (const { name: table, sql } of tables) {\n\t\tif (filterTables.size > 0 && !filterTables.has(table)) continue;\n\n\t\tif (table === \"sqlite_sequence\") {\n\t\t\tif (!noSchema) yield `DELETE FROM sqlite_sequence;`;\n\t\t} else if (table.match(/^sqlite_stat./)) {\n\t\t\t// This feels like it should really appear _after_ the contents of sqlite_stat[1,4] but I'm choosing\n\t\t\t// to match SQLite's dump output exactly so writing it immediately like they do.\n\t\t\tif (!noSchema) yield `ANALYZE sqlite_schema;`;\n\t\t} else if (sql.startsWith(`CREATE VIRTUAL TABLE`)) {\n\t\t\tthrow new Error(\n\t\t\t\t`D1 Export error: cannot export databases with Virtual Tables (fts5)`\n\t\t\t);\n\t\t} else if (table.startsWith(\"_cf_\") || table.startsWith(\"sqlite_\")) {\n\t\t\tcontinue;\n\t\t} else {\n\t\t\t// SQLite dump has an extremely weird behaviour where, if the table was explicitly\n\t\t\t// quoted i.e. \"Table\", then in the dump it has `IF NOT EXISTS` injected. I don't understand\n\t\t\t// why, but on the off chance there's a good reason to I am following suit.\n\t\t\tif (sql.match(/CREATE TABLE ['\"].*/)) {\n\t\t\t\tif (!noSchema) yield `CREATE TABLE IF NOT EXISTS ${sql.substring(13)};`;\n\t\t\t} else {\n\t\t\t\tif (!noSchema) yield `${sql};`;\n\t\t\t}\n\t\t}\n\n\t\tif (noData) continue;\n\t\t// eslint-disable-next-line workers-sdk/no-unsafe-command-execution -- input is escaped via escapeId() so this PRAGMA call is safe\n\t\tconst columns_cursor = db.exec(`PRAGMA table_info=${escapeId(table)}`);\n\n\t\tconst columns = Array.from(columns_cursor) as {\n\t\t\tcid: string;\n\t\t\tname: string;\n\t\t\ttype: string;\n\t\t\tnotnull: number;\n\t\t\tdflt_val: string | null;\n\t\t\tpk: number;\n\t\t}[];\n\t\tif (stats) {\n\t\t\tstats.rows_read += columns_cursor.rowsRead;\n\t\t\tstats.rows_written += columns_cursor.rowsWritten;\n\t\t}\n\n\t\tconst select = `SELECT ${columns.map((c) => escapeId(c.name)).join(\", \")} FROM ${escapeId(table)};`;\n\t\tconst rows_cursor = db.exec(select);\n\t\tconst columnNames = columns.map((c) => escapeId(c.name)).join(\",\");\n\t\t// The column names portion is: \" (\" + columnNames + \")\" = 3 + columnNames.length\n\t\tconst columnNamesOverhead = 3 + columnNames.length;\n\t\tfor (const dataRow of rows_cursor.raw()) {\n\t\t\tconst formattedCells = dataRow.map((cell: unknown, i: number) => {\n\t\t\t\tconst colType = columns[i].type;\n\t\t\t\tconst cellType = typeof cell;\n\t\t\t\tif (cell === null) {\n\t\t\t\t\treturn \"NULL\";\n\t\t\t\t} else if (cellType === \"number\") {\n\t\t\t\t\treturn cell;\n\t\t\t\t} else if (cellType === \"string\") {\n\t\t\t\t\treturn outputQuotedEscapedString(cell);\n\t\t\t\t} else if (cell instanceof ArrayBuffer) {\n\t\t\t\t\treturn `X'${Array.prototype.map\n\t\t\t\t\t\t.call(new Uint8Array(cell), (b) => b.toString(16).padStart(2, \"0\"))\n\t\t\t\t\t\t.join(\"\")}'`;\n\t\t\t\t} else {\n\t\t\t\t\tconsole.error({\n\t\t\t\t\t\tmessage: \"dumpSql: unexpected cell type\",\n\t\t\t\t\t\tcolType,\n\t\t\t\t\t\tcellType,\n\t\t\t\t\t\tcell,\n\t\t\t\t\t\tcolumn: columns[i],\n\t\t\t\t\t});\n\t\t\t\t\treturn \"ERROR\";\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tconst insertStmt = `INSERT INTO ${escapeId(table)} (${columnNames}) VALUES(${formattedCells.join(\",\")});`;\n\n\t\t\t// Track stats for INSERT statement sizes\n\t\t\tif (stats) {\n\t\t\t\tconst currentSize = insertStmt.length;\n\t\t\t\t// Calculate what the size would be without column names (for comparison)\n\t\t\t\tconst sizeWithoutColumnNames = currentSize - columnNamesOverhead;\n\t\t\t\tconst LIMIT = 100 * 1024; // 100KB\n\n\t\t\t\tstats.total_inserts++;\n\t\t\t\tif (sizeWithoutColumnNames > LIMIT) {\n\t\t\t\t\tstats.inserts_already_over_100kb++;\n\t\t\t\t}\n\t\t\t\tif (currentSize > LIMIT) {\n\t\t\t\t\tstats.inserts_over_100kb_with_column_names++;\n\t\t\t\t}\n\t\t\t\tif (sizeWithoutColumnNames > stats.max_insert_size) {\n\t\t\t\t\tstats.max_insert_size = sizeWithoutColumnNames;\n\t\t\t\t}\n\t\t\t\tif (currentSize > stats.max_insert_size_with_column_names) {\n\t\t\t\t\tstats.max_insert_size_with_column_names = currentSize;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tyield insertStmt;\n\t\t}\n\t\tif (stats) {\n\t\t\tstats.rows_read += rows_cursor.rowsRead;\n\t\t\tstats.rows_written += rows_cursor.rowsWritten;\n\t\t}\n\t}\n\n\tif (!noSchema) {\n\t\t// Taken from SQLite shell.c.in https://github.com/sqlite/sqlite/blob/105c20648e1b05839fd0638686b95f2e3998abcb/src/shell.c.in#L8473-L8478\n\t\tconst rest_of_schema = db.exec(\n\t\t\t[\n\t\t\t\t\"SELECT name, sql\",\n\t\t\t\t\"FROM sqlite_schema AS o\",\n\t\t\t\t\"WHERE (true) AND sql NOT NULL\",\n\t\t\t\t\"  AND type IN ('index', 'trigger', 'view')\",\n\t\t\t\t// 'DESC' appears in the code linked above but the observed behaviour of SQLite appears otherwise\n\t\t\t\t\"ORDER BY type COLLATE NOCASE\",\n\t\t\t].join(\" \")\n\t\t);\n\t\tfor (const { name, sql } of rest_of_schema) {\n\t\t\tif (filterTables.size > 0 && !filterTables.has(name as string)) continue;\n\t\t\tyield `${sql};`;\n\t\t}\n\t\tif (stats) {\n\t\t\tstats.rows_read += rest_of_schema.rowsRead;\n\t\t\tstats.rows_written += rest_of_schema.rowsWritten;\n\t\t}\n\t}\n}\n\n// Ported `output_quoted_escaped_string` from https://github.com/sqlite/sqlite/blob/master/src/shell.c.in#L1799-L1862\nfunction outputQuotedEscapedString(cell: unknown) {\n\tlet lfs = false;\n\tlet crs = false;\n\n\tconst quotesOrNewlinesRegexp = /'|(\\n)|(\\r)/g;\n\n\t// Function to replace ' with '', while also tracking whether the string contains any \\r or \\n chars\n\tconst escapeQuotesDetectingNewlines = (_: string, lf: string, cr: string) => {\n\t\tif (lf) {\n\t\t\tlfs = true;\n\t\t\treturn `\\\\n`;\n\t\t}\n\t\tif (cr) {\n\t\t\tcrs = true;\n\t\t\treturn `\\\\r`;\n\t\t}\n\t\treturn `''`;\n\t};\n\n\tconst escaped_string = (cell as string).replace(\n\t\tquotesOrNewlinesRegexp,\n\t\tescapeQuotesDetectingNewlines\n\t);\n\tlet output_string = `'${escaped_string}'`;\n\tif (crs) output_string = `replace(${output_string},'\\\\r',char(13))`;\n\tif (lfs) output_string = `replace(${output_string},'\\\\n',char(10))`;\n\treturn output_string;\n}\n\n// Ported from quoteChar: https://github.com/sqlite/sqlite/blob/378bf82e2bc09734b8c5869f9b148efe37d29527/src/shell.c.in#L990\nexport function sqliteQuote(token: string) {\n\t// Empty input\n\treturn token.length === 0 ||\n\t\t// Doesn't start with alpha or underscore\n\t\t!token.match(/^[a-zA-Z_]/) ||\n\t\ttoken.match(/\\W/) ||\n\t\tSQLITE_KEYWORDS.has(token.toUpperCase())\n\t\t? `\"${token}\"`\n\t\t: token;\n}\n\n/**\n * Escape an identifier for use in SQL statements.\n * @param id - The identifier to escape.\n * @returns\n */\nfunction escapeId(id: string) {\n\treturn `\"${id.replace(/\"/g, '\"\"')}\"`;\n}\n\n// List taken from `aKeywordTable` inhttps://github.com/sqlite/sqlite/blob/378bf82e2bc09734b8c5869f9b148efe37d29527/tool/mkkeywordhash.c#L172\n// prettier-ignore\nexport const SQLITE_KEYWORDS = new Set([\n  \"ABORT\", \"ACTION\", \"ADD\", \"AFTER\", \"ALL\", \"ALTER\", \"ALWAYS\", \"ANALYZE\", \"AND\", \"AS\", \"ASC\",\n  \"ATTACH\", \"AUTOINCREMENT\", \"BEFORE\", \"BEGIN\", \"BETWEEN\", \"BY\", \"CASCADE\", \"CASE\", \"CAST\",\n  \"CHECK\", \"COLLATE\", \"COLUMN\", \"COMMIT\", \"CONFLICT\", \"CONSTRAINT\", \"CREATE\", \"CROSS\", \"CURRENT\",\n  \"CURRENT_DATE\", \"CURRENT_TIME\", \"CURRENT_TIMESTAMP\", \"DATABASE\", \"DEFAULT\", \"DEFERRED\",\n  \"DEFERRABLE\", \"DELETE\", \"DESC\", \"DETACH\", \"DISTINCT\", \"DO\", \"DROP\", \"END\", \"EACH\", \"ELSE\",\n  \"ESCAPE\", \"EXCEPT\", \"EXCLUSIVE\", \"EXCLUDE\", \"EXISTS\", \"EXPLAIN\", \"FAIL\", \"FILTER\", \"FIRST\",\n  \"FOLLOWING\", \"FOR\", \"FOREIGN\", \"FROM\", \"FULL\", \"GENERATED\", \"GLOB\", \"GROUP\", \"GROUPS\", \"HAVING\",\n  \"IF\", \"IGNORE\", \"IMMEDIATE\", \"IN\", \"INDEX\", \"INDEXED\", \"INITIALLY\", \"INNER\", \"INSERT\", \"INSTEAD\",\n  \"INTERSECT\", \"INTO\", \"IS\", \"ISNULL\", \"JOIN\", \"KEY\", \"LAST\", \"LEFT\", \"LIKE\", \"LIMIT\", \"MATCH\",\n  \"MATERIALIZED\", \"NATURAL\", \"NO\", \"NOT\", \"NOTHING\", \"NOTNULL\", \"NULL\", \"NULLS\", \"OF\", \"OFFSET\",\n  \"ON\", \"OR\", \"ORDER\", \"OTHERS\", \"OUTER\", \"OVER\", \"PARTITION\", \"PLAN\", \"PRAGMA\", \"PRECEDING\",\n  \"PRIMARY\", \"QUERY\", \"RAISE\", \"RANGE\", \"RECURSIVE\", \"REFERENCES\", \"REGEXP\", \"REINDEX\", \"RELEASE\",\n  \"RENAME\", \"REPLACE\", \"RESTRICT\", \"RETURNING\", \"RIGHT\", \"ROLLBACK\", \"ROW\", \"ROWS\", \"SAVEPOINT\",\n  \"SELECT\", \"SET\", \"TABLE\", \"TEMP\", \"TEMPORARY\", \"THEN\", \"TIES\", \"TO\", \"TRANSACTION\", \"TRIGGER\",\n  \"UNBOUNDED\", \"UNION\", \"UNIQUE\", \"UPDATE\", \"USING\", \"VACUUM\", \"VALUES\", \"VIEW\", \"VIRTUAL\", \"WHEN\",\n  \"WHERE\", \"WINDOW\", \"WITH\", \"WITHOUT\"\n]);\n"],
  "mappings": ";;;;;;;;;AAAA,OAAO,YAAY;AACnB;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAAS,SAAS;;;ACgBX,UAAU,QAChB,IACA,SAMA,OACC;AAED,QAAM;AAGN,MAAM,eAAe,IAAI,IAAI,SAAS,UAAU,CAAC,CAAC,GAC5C,EAAE,QAAQ,SAAS,IAAI,WAAW,CAAC,GAInC,gBAAgB,GAAG,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAM/B,EAAE,GACE,SACL,MAAM,KAAK,aAAa;AACzB,EAAI,UACH,MAAM,aAAa,cAAc,UACjC,MAAM,gBAAgB,cAAc;AAGrC,WAAW,EAAE,MAAM,OAAO,IAAI,KAAK,QAAQ;AAC1C,QAAI,aAAa,OAAO,KAAK,CAAC,aAAa,IAAI,KAAK,EAAG;AAEvD,QAAI,UAAU;AACb,MAAK,aAAU,MAAM;AAAA,aACX,MAAM,MAAM,eAAe;AAGrC,MAAK,aAAU,MAAM;AAAA,SACf;AAAA,UAAI,IAAI,WAAW,sBAAsB;AAC/C,cAAM,IAAI;AAAA,UACT;AAAA,QACD;AACM,UAAI,MAAM,WAAW,MAAM,KAAK,MAAM,WAAW,SAAS;AAChE;AAKA,MAAI,IAAI,MAAM,qBAAqB,IAC7B,aAAU,MAAM,8BAA8B,IAAI,UAAU,EAAE,CAAC,OAE/D,aAAU,MAAM,GAAG,GAAG;AAAA;AAI7B,QAAI,OAAQ;AAEZ,QAAM,iBAAiB,GAAG,KAAK,qBAAqB,SAAS,KAAK,CAAC,EAAE,GAE/D,UAAU,MAAM,KAAK,cAAc;AAQzC,IAAI,UACH,MAAM,aAAa,eAAe,UAClC,MAAM,gBAAgB,eAAe;AAGtC,QAAM,SAAS,UAAU,QAAQ,IAAI,CAAC,MAAM,SAAS,EAAE,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,SAAS,SAAS,KAAK,CAAC,KAC1F,cAAc,GAAG,KAAK,MAAM,GAC5B,cAAc,QAAQ,IAAI,CAAC,MAAM,SAAS,EAAE,IAAI,CAAC,EAAE,KAAK,GAAG,GAE3D,sBAAsB,IAAI,YAAY;AAC5C,aAAW,WAAW,YAAY,IAAI,GAAG;AACxC,UAAM,iBAAiB,QAAQ,IAAI,CAAC,MAAe,MAAc;AAChE,YAAM,UAAU,QAAQ,CAAC,EAAE,MACrB,WAAW,OAAO;AACxB,eAAI,SAAS,OACL,SACG,aAAa,WAChB,OACG,aAAa,WAChB,0BAA0B,IAAI,IAC3B,gBAAgB,cACnB,KAAK,MAAM,UAAU,IAC1B,KAAK,IAAI,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EACjE,KAAK,EAAE,CAAC,OAEV,QAAQ,MAAM;AAAA,UACb,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAQ,QAAQ,CAAC;AAAA,QAClB,CAAC,GACM;AAAA,MAET,CAAC,GAEK,aAAa,eAAe,SAAS,KAAK,CAAC,KAAK,WAAW,YAAY,eAAe,KAAK,GAAG,CAAC;AAGrG,UAAI,OAAO;AACV,YAAM,cAAc,WAAW,QAEzB,yBAAyB,cAAc,qBACvC,QAAQ,MAAM;AAEpB,cAAM,iBACF,yBAAyB,SAC5B,MAAM,8BAEH,cAAc,SACjB,MAAM,wCAEH,yBAAyB,MAAM,oBAClC,MAAM,kBAAkB,yBAErB,cAAc,MAAM,sCACvB,MAAM,oCAAoC;AAAA,MAE5C;AAEA,YAAM;AAAA,IACP;AACA,IAAI,UACH,MAAM,aAAa,YAAY,UAC/B,MAAM,gBAAgB,YAAY;AAAA,EAEpC;AAEA,MAAI,CAAC,UAAU;AAEd,QAAM,iBAAiB,GAAG;AAAA,MACzB;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QAEA;AAAA,MACD,EAAE,KAAK,GAAG;AAAA,IACX;AACA,aAAW,EAAE,MAAM,IAAI,KAAK;AAC3B,MAAI,aAAa,OAAO,KAAK,CAAC,aAAa,IAAI,IAAc,MAC7D,MAAM,GAAG,GAAG;AAEb,IAAI,UACH,MAAM,aAAa,eAAe,UAClC,MAAM,gBAAgB,eAAe;AAAA,EAEvC;AACD;AAGA,SAAS,0BAA0B,MAAe;AACjD,MAAI,MAAM,IACN,MAAM,IAEJ,yBAAyB,gBAGzB,gCAAgC,CAAC,GAAW,IAAY,OACzD,MACH,MAAM,IACC,SAEJ,MACH,MAAM,IACC,SAED,MAOJ,gBAAgB,IAJI,KAAgB;AAAA,IACvC;AAAA,IACA;AAAA,EACD,CACsC;AACtC,SAAI,QAAK,gBAAgB,WAAW,aAAa,qBAC7C,QAAK,gBAAgB,WAAW,aAAa,qBAC1C;AACR;AAmBA,SAAS,SAAS,IAAY;AAC7B,SAAO,IAAI,GAAG,QAAQ,MAAM,IAAI,CAAC;AAClC;;;AD1NA,IAAM,gBAAgB,EAAE,MAAM;AAAA,EAC7B,EAAE,OAAO;AAAA,EACT,EAAE,OAAO;AAAA,EACT,EAAE,KAAK;AAAA,EACP,EAAE,OAAO,EAAE,MAAM;AAClB,CAAC,GAGK,gBAAgB,EAAE,OAAO;AAAA,EAC9B,KAAK,EAAE,OAAO;AAAA,EACd,QAAQ,EAAE,MAAM,aAAa,EAAE,SAAS,EAAE,SAAS;AACpD,CAAC,GAEK,kBAAkB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,aAAa,CAAC,CAAC,GAEjE,mBAAmB,sCAKnB,wBAAwB,EAC5B,KAAK,CAAC,oBAAoB,oBAAoB,MAAM,CAAC,EACrD,MAAM,kBAAkB,GAWpB,YAAY,gBAqBZ,sCAAsC,gCAE/B,UAAN,cAAsB,UAAU;AAAA,EACtC,YAAqB,OAAgB;AACpC,UAAM,GAAG;AADW;AAAA,EAErB;AAAA,EAFqB;AAAA,EAIrB,aAAuB;AAQtB,QAAM,WAA8B,EAAE,SAAS,IAAO,OANrD,OAAO,KAAK,SAAU,YACtB,KAAK,UAAU,QACf,aAAa,KAAK,SAClB,OAAO,KAAK,MAAM,WAAY,WAC3B,KAAK,MAAM,UACX,OAAO,KAAK,KAAK,EACuC;AAC5D,WAAO,SAAS,KAAK,QAAQ;AAAA,EAC9B;AACD;AAEA,SAAS,cAAc,QAAyC;AAC/D,UAAQ,UAAU,CAAC,GAAG;AAAA,IAAI,CAAC;AAAA;AAAA,MAE1B,MAAM,QAAQ,KAAK,IAAI,aAAa,IAAI,WAAW,KAAK,CAAC,IAAI;AAAA;AAAA,EAC9D;AACD;AAEA,SAAS,YAAY,MAAmC;AACvD,SAAO,KAAK;AAAA,IAAI,CAAC,QAChB,IAAI,IAAI,CAAC,UAAU;AAClB,UAAI;AACJ,aAAI,iBAAiB,cAEpB,aAAa,MAAM,KAAK,IAAI,WAAW,KAAK,CAAC,IAE7C,aAAa,OAEP;AAAA,IACR,CAAC;AAAA,EACF;AACD;AAEA,SAAS,cACR,SACA,MAC4B;AAC5B,SAAO,KAAK;AAAA,IAAI,CAAC,QAChB,OAAO,YAAY,QAAQ,IAAI,CAAC,MAAM,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;AAAA,EAC5D;AACD;AAEA,SAAS,SAAS,IAAqB;AACtC,SAAO;AAAA,IACN,YAAY,GAAG;AAAA,MACd;AAAA,IACD;AAAA,EACD;AACD;AAEO,IAAM,mBAAN,cAA+B,uBAAuB;AAAA,EACnD;AAAA,EAET,YAAY,OAA2B,KAAgC;AACtE,UAAM,OAAO,GAAG,GAChB,KAAK,SAAS,SAAS,KAAK,EAAE;AAAA,EAC/B;AAAA,EAEA,WAAW;AACV,QAAM,UAAU,IAAI,KAAK,OAAO,WAAW,CAAC;AAC5C,kBAAO,YAAY,MAAS,GACrB;AAAA,EACR;AAAA,EAEA,SAAS,CAAC,QAAyB,UAAsC;AACxE,QAAM,aAAa,YAAY,IAAI,GAE7B,aAAa,KAAK,MAAM,QAAQ,IAAI,cACpC,gBAAgB,KAAK,SAAS,GAE9B,SAAS,cAAc,MAAM,UAAU,CAAC,CAAC,GACzC,SAAS,KAAK,GAAG,QAAQ,MAAM,GAAG,EAAE,GAAG,MAAM,GAC7C,UAAU,OAAO,aACjB,OAAO,YAAY,MAAM,KAAK,OAAO,IAAI,CAAC,CAAC,GAE7C;AACJ,IAAI,WAAW,qBAAoB,UAAU,EAAE,SAAS,KAAK,IACxD,UAAU,cAAc,SAAS,IAAI;AAI1C,QAAM,YAAY,YAAY,IAAI,GAC5B,YAAY,KAAK,MAAM,QAAQ,IAAI,cACnC,eAAe,KAAK,SAAS,GAE7B,WAAW,YAAY,YACvB,UAAU,aAAa,eAAe,cAAc,cAEpD,aAAa,YAAY,GACzB,iBAAiB,aAAa,cAAc,cAAc,WAE1D,UAAU,cAAc,kBADV,cAAc;AAGlC,WAAO;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,MAAM;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,aAAa,aAAa;AAAA,QAC1B,YAAY;AAAA,QACZ,YAAY;AAAA,QACZ,WAAW,OAAO;AAAA,QAClB,cAAc,OAAO;AAAA,MACtB;AAAA,IACD;AAAA,EACD;AAAA,EAEA,KAAK,SAAoB,QAA8C;AAKtE,QAHA,UAAU,QAAQ;AAAA,MACjB,CAAC,UAAU,MAAM,IAAI,QAAQ,cAAc,EAAE,EAAE,KAAK,EAAE,SAAS;AAAA,IAChE,GACI,QAAQ,WAAW,GAAG;AACzB,UAAM,QAAQ,IAAI,MAAM,6BAA6B;AACrD,YAAM,IAAI,QAAQ,KAAK;AAAA,IACxB;AAEA,QAAI;AACH,aAAO,KAAK,MAAM,QAAQ;AAAA,QAAgB,MACzC,QAAQ,IAAI,KAAK,OAAO,KAAK,MAAM,MAAM,CAAC;AAAA,MAC3C;AAAA,IACD,SAAS,GAAG;AACX,YAAM,IAAI,QAAQ,CAAC;AAAA,IACpB;AAAA,EACD;AAAA,EAIA,eAA6B,OAAO,QAAQ;AAC3C,QAAI,UAAU,gBAAgB,MAAM,MAAM,IAAI,KAAK,CAAC;AAIpD,QAHK,MAAM,QAAQ,OAAO,MAAG,UAAU,CAAC,OAAO,IAG3C,KAAK,gBAAgB,OAAO;AAC/B,aAAO,KAAK,cAAc,OAAO;AAGlC,QAAM,EAAE,aAAa,IAAI,IAAI,IAAI,IAAI,GAAG,GAClC,gBAAgB,sBAAsB;AAAA,MAC3C,aAAa,IAAI,eAAe;AAAA,IACjC;AAEA,WAAO,SAAS,KAAK,KAAK,KAAK,SAAS,aAAa,GAAG;AAAA,MACvD,SAAS;AAAA,QACR,CAAC,mCAAmC,GACnC,MAAM,KAAK,MAAM,QAAQ,mBAAmB;AAAA,MAC9C;AAAA,IACD,CAAC;AAAA,EACF;AAAA,EAEA,gBAAgB,SAA+C;AAC9D,WACC,QAAQ,WAAW,KACnB,QAAQ,CAAC,EAAE,QAAQ,qBAClB,QAAQ,CAAC,EAAE,QAAQ,UAAU,MAAM;AAAA,EAEtC;AAAA,EAEA,cACC,SAGC;AACD,QAAM,CAAC,UAAU,QAAQ,GAAG,MAAM,IAAI,QAAQ,CAAC,EAAE,QAC3C,UAAU;AAAA,MACf,UAAU,EAAQ;AAAA,MAClB,QAAQ,EAAQ;AAAA,MAChB;AAAA,IACD;AACA,WAAO,SAAS,KAAK;AAAA,MACpB,SAAS;AAAA,MACT,SAAS,CAAC,MAAM,KAAK,QAAQ,KAAK,MAAM,QAAQ,KAAK,OAAO,CAAC,CAAC;AAAA,MAC9D,MAAM,CAAC;AAAA,IACR,CAAC;AAAA,EACF;AACD;AA/CC;AAAA,EAFC,KAAK,QAAQ;AAAA,EACb,KAAK,UAAU;AAAA,GA/EJ,iBAgFZ;",
  "names": []
}
