orez 0.2.30 → 0.2.32

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.
@@ -1033,6 +1033,18 @@ function equalityExpr(left, right) {
1033
1033
  },
1034
1034
  };
1035
1035
  }
1036
+ function numericLiteralValue(value) {
1037
+ const literal = astLiteralValue(unwrapTypeCast(value));
1038
+ if (typeof literal !== 'number')
1039
+ return null;
1040
+ return Number.isFinite(literal) ? literal : null;
1041
+ }
1042
+ function isDivisionByMillis(value) {
1043
+ const expr = unwrapTypeCast(value)?.A_Expr;
1044
+ if (expr?.kind !== 'AEXPR_OP' || operatorName(expr) !== '/')
1045
+ return false;
1046
+ return numericLiteralValue(expr.rexpr) === 1000;
1047
+ }
1036
1048
  function startsWithExpr(func, context) {
1037
1049
  const args = func.args ?? [];
1038
1050
  if (args.length < 2)
@@ -1130,6 +1142,14 @@ function postgresTimestampText(value) {
1130
1142
  const withSpace = raw.replace('T', ' ');
1131
1143
  return withSpace.endsWith('Z') ? `${withSpace.slice(0, -1)}+00` : withSpace;
1132
1144
  }
1145
+ function epochMillisParamValue(value) {
1146
+ const millis = timestampMillisValue(value);
1147
+ if (millis !== null)
1148
+ return millis;
1149
+ const raw = value instanceof Date ? value.toISOString() : String(value);
1150
+ const date = new Date(raw);
1151
+ return Number.isFinite(date.getTime()) ? date.getTime() : value;
1152
+ }
1133
1153
  function paramNumbersForOids(oids, matches) {
1134
1154
  const numbers = new Set();
1135
1155
  for (let index = 0; index < oids.length; index++) {
@@ -1750,8 +1770,12 @@ function rewriteNode(value, context) {
1750
1770
  return rewriteNode(value.FuncCall.args[0], context);
1751
1771
  }
1752
1772
  if (name === 'to_timestamp' && value.FuncCall.args?.[0]) {
1773
+ const arg = value.FuncCall.args[0];
1774
+ if (isDivisionByMillis(arg)) {
1775
+ collectParamRefs(arg, (paramNumber) => context?.epochMillisParamNumbers?.add(paramNumber));
1776
+ }
1753
1777
  return funcCallNode('datetime', [
1754
- rewriteNode(value.FuncCall.args[0], context),
1778
+ rewriteNode(arg, context),
1755
1779
  stringConst('unixepoch'),
1756
1780
  ]);
1757
1781
  }
@@ -2201,19 +2225,45 @@ function normalizeAlterTable(stmt) {
2201
2225
  const skipIfColumnMissingByCmd = new Map();
2202
2226
  const schemaColumnsByCmd = new Map();
2203
2227
  const metadataOnlySchemaColumns = [];
2228
+ const syntheticStatements = [];
2204
2229
  for (const cmdNode of stmt.cmds ?? []) {
2205
2230
  const cmd = cmdNode.AlterTableCmd;
2206
2231
  if (!cmd)
2207
2232
  continue;
2233
+ if (cmd.subtype === 'AT_AddConstraint') {
2234
+ const constraint = cmd.def?.Constraint;
2235
+ const contype = constraint?.contype;
2236
+ if (table &&
2237
+ (contype === 'CONSTR_UNIQUE' || contype === 'CONSTR_PRIMARY') &&
2238
+ Array.isArray(constraint.keys)) {
2239
+ const columns = constraint.keys.map(stringValue).filter(Boolean);
2240
+ if (columns.length) {
2241
+ const name = constraint.conname ||
2242
+ `${table}_${columns.join('_')}_${contype === 'CONSTR_PRIMARY' ? 'pkey' : 'key'}`;
2243
+ syntheticStatements.push({
2244
+ sql: `CREATE UNIQUE INDEX IF NOT EXISTS ${quoteIdentifier(name)} ON ${quoteIdentifier(table)} (${columns.map(quoteIdentifier).join(', ')})`,
2245
+ isDDL: true,
2246
+ });
2247
+ }
2248
+ }
2249
+ continue;
2250
+ }
2251
+ if (cmd.subtype === 'AT_DropConstraint') {
2252
+ if (cmd.name) {
2253
+ syntheticStatements.push({
2254
+ sql: `DROP INDEX IF EXISTS ${quoteIdentifier(cmd.name)}`,
2255
+ isDDL: true,
2256
+ });
2257
+ }
2258
+ continue;
2259
+ }
2208
2260
  if (cmd.subtype === 'AT_AlterColumnType') {
2209
2261
  const schemaColumn = schemaColumnForAlterColumnType(tableRef, cmd);
2210
2262
  if (schemaColumn)
2211
2263
  metadataOnlySchemaColumns.push(schemaColumn);
2212
2264
  continue;
2213
2265
  }
2214
- if (cmd.subtype === 'AT_AddConstraint' ||
2215
- cmd.subtype === 'AT_DropConstraint' ||
2216
- cmd.subtype === 'AT_ReplicaIdentity' ||
2266
+ if (cmd.subtype === 'AT_ReplicaIdentity' ||
2217
2267
  cmd.subtype?.startsWith('AT_AlterColumn') ||
2218
2268
  cmd.subtype === 'AT_ColumnDefault' ||
2219
2269
  cmd.subtype === 'AT_SetNotNull' ||
@@ -2244,6 +2294,7 @@ function normalizeAlterTable(stmt) {
2244
2294
  skipIfColumnMissingByCmd,
2245
2295
  schemaColumnsByCmd,
2246
2296
  metadataOnlySchemaColumns,
2297
+ syntheticStatements,
2247
2298
  };
2248
2299
  }
2249
2300
  function normalizeRename(stmt) {
@@ -2927,11 +2978,47 @@ function sqliteTriggerEvents(events) {
2927
2978
  function sqliteTriggerName(base, event, eventCount) {
2928
2979
  return eventCount === 1 ? base : `${base}_${event.toLowerCase()}`;
2929
2980
  }
2981
+ function threadReplyCountTriggerStatements(node) {
2982
+ const table = publicationTableRefForRangeVar(node.relation);
2983
+ if (!table || table.table !== 'message')
2984
+ return null;
2985
+ const events = sqliteTriggerEvents(Number(node.events ?? 0));
2986
+ if (events.length === 0)
2987
+ return null;
2988
+ return events.map((event) => {
2989
+ const row = event === 'DELETE' ? 'OLD' : 'NEW';
2990
+ const triggerName = sqliteTriggerName(node.trigname, event, events.length);
2991
+ return {
2992
+ sql: `CREATE TRIGGER IF NOT EXISTS ${quoteIdentifier(triggerName)}
2993
+ AFTER ${event} ON ${quoteIdentifier(table.table)}
2994
+ FOR EACH ROW
2995
+ WHEN ${row}."threadId" IS NOT NULL
2996
+ BEGIN
2997
+ UPDATE "thread"
2998
+ SET "replyCount" = min(11, (
2999
+ SELECT COUNT(*)
3000
+ FROM "message"
3001
+ WHERE "threadId" = ${row}."threadId"
3002
+ AND "deleted" = 0
3003
+ AND "type" IS DISTINCT FROM 'draft'
3004
+ AND "id" IS DISTINCT FROM (
3005
+ SELECT "messageId" FROM "thread" WHERE "id" = ${row}."threadId"
3006
+ )
3007
+ ))
3008
+ WHERE "id" = ${row}."threadId";
3009
+ END`,
3010
+ isDDL: true,
3011
+ };
3012
+ });
3013
+ }
2930
3014
  function createTriggerStatements(node, context) {
2931
3015
  const fnName = functionName({ funcname: node.funcname });
2932
3016
  const fn = fnName ? context?.triggerFunctions?.get(fnName) : undefined;
2933
3017
  if (!fn)
2934
3018
  return null;
3019
+ if (fnName === 'updatethreadreplycount') {
3020
+ return threadReplyCountTriggerStatements(node);
3021
+ }
2935
3022
  if (findKeywordOutsideQuotes(fn.body, 'TG_OP') >= 0 ||
2936
3023
  findKeywordOutsideQuotes(fn.body, 'TG_ARGV') >= 0 ||
2937
3024
  findKeywordOutsideQuotes(fn.body, 'TG_NAME') >= 0 ||
@@ -3055,13 +3142,16 @@ function rewriteParsedStatement(version, rawStmt, context) {
3055
3142
  if (nodeType === 'AlterTableStmt') {
3056
3143
  alterMetadata = normalizeAlterTable(node);
3057
3144
  if (!node.cmds?.length) {
3058
- return alterMetadata.metadataOnlySchemaColumns.length
3059
- ? {
3145
+ const statements = [];
3146
+ if (alterMetadata.metadataOnlySchemaColumns.length) {
3147
+ statements.push({
3060
3148
  sql: '',
3061
3149
  isDDL: true,
3062
3150
  schemaColumns: alterMetadata.metadataOnlySchemaColumns,
3063
- }
3064
- : null;
3151
+ });
3152
+ }
3153
+ statements.push(...alterMetadata.syntheticStatements);
3154
+ return statements.length ? statements : null;
3065
3155
  }
3066
3156
  }
3067
3157
  else if (nodeType === 'CreateStmt') {
@@ -3113,7 +3203,8 @@ function rewriteParsedStatement(version, rawStmt, context) {
3113
3203
  else {
3114
3204
  rewriteNode(node, context);
3115
3205
  }
3116
- if (nodeType === 'AlterTableStmt' && node.cmds.length > 1) {
3206
+ if (nodeType === 'AlterTableStmt' &&
3207
+ (node.cmds.length > 1 || alterMetadata?.syntheticStatements.length)) {
3117
3208
  const statements = [];
3118
3209
  if (alterMetadata?.metadataOnlySchemaColumns.length) {
3119
3210
  statements.push({
@@ -3122,6 +3213,7 @@ function rewriteParsedStatement(version, rawStmt, context) {
3122
3213
  schemaColumns: alterMetadata.metadataOnlySchemaColumns,
3123
3214
  });
3124
3215
  }
3216
+ statements.push(...(alterMetadata?.syntheticStatements ?? []));
3125
3217
  statements.push(...node.cmds.map((cmdNode) => {
3126
3218
  const singleStmt = {
3127
3219
  [nodeType]: {
@@ -3141,6 +3233,11 @@ function rewriteParsedStatement(version, rawStmt, context) {
3141
3233
  ...(context?.jsonParamNumbers?.size
3142
3234
  ? { jsonParamNumbers: new Set(context.jsonParamNumbers) }
3143
3235
  : null),
3236
+ ...(context?.epochMillisParamNumbers?.size
3237
+ ? {
3238
+ epochMillisParamNumbers: new Set(context.epochMillisParamNumbers),
3239
+ }
3240
+ : null),
3144
3241
  ...(cmdSchemaColumns?.length ? { schemaColumns: cmdSchemaColumns } : null),
3145
3242
  ...(skipIfColumnExists ? { skipIfColumnExists } : null),
3146
3243
  ...(skipIfColumnMissing ? { skipIfColumnMissing } : null),
@@ -3180,6 +3277,9 @@ function rewriteParsedStatement(version, rawStmt, context) {
3180
3277
  ...(context?.jsonParamNumbers?.size
3181
3278
  ? { jsonParamNumbers: new Set(context.jsonParamNumbers) }
3182
3279
  : null),
3280
+ ...(context?.epochMillisParamNumbers?.size
3281
+ ? { epochMillisParamNumbers: new Set(context.epochMillisParamNumbers) }
3282
+ : null),
3183
3283
  ...(schemaColumns.length ? { schemaColumns } : null),
3184
3284
  ...(schemaMetadataChanges.length ? { schemaMetadataChanges } : null),
3185
3285
  ...(skipIfColumnExists ? { skipIfColumnExists } : null),
@@ -4803,6 +4903,7 @@ export class DoBackend {
4803
4903
  if (rewritten && !rewritten.startsWith('--')) {
4804
4904
  const arrayParamNumbers = new Set();
4805
4905
  const jsonParamNumbers = new Set(inferredJsonParamNumbers);
4906
+ const epochMillisParamNumbers = new Set();
4806
4907
  const schemaColumns = [];
4807
4908
  const schemaMetadataChanges = [];
4808
4909
  const publicationChanges = [];
@@ -4813,6 +4914,9 @@ export class DoBackend {
4813
4914
  for (const number of statement.jsonParamNumbers ?? []) {
4814
4915
  jsonParamNumbers.add(number);
4815
4916
  }
4917
+ for (const number of statement.epochMillisParamNumbers ?? []) {
4918
+ epochMillisParamNumbers.add(number);
4919
+ }
4816
4920
  schemaColumns.push(...(statement.schemaColumns ?? []));
4817
4921
  schemaMetadataChanges.push(...(statement.schemaMetadataChanges ?? []));
4818
4922
  publicationChanges.push(...(statement.publicationChanges ?? []));
@@ -4825,6 +4929,7 @@ export class DoBackend {
4825
4929
  ...(arrayParamNumbers.size ? { arrayParamNumbers } : null),
4826
4930
  ...(jsonParamNumbers.size ? { jsonParamNumbers } : null),
4827
4931
  ...(timestampParamNumbers.size ? { timestampParamNumbers } : null),
4932
+ ...(epochMillisParamNumbers.size ? { epochMillisParamNumbers } : null),
4828
4933
  ...(booleanParamNumbers.size ? { booleanParamNumbers } : null),
4829
4934
  ...(schemaColumns.length ? { schemaColumns } : null),
4830
4935
  ...(schemaMetadataChanges.length ? { schemaMetadataChanges } : null),
@@ -4841,6 +4946,13 @@ export class DoBackend {
4841
4946
  ? { jsonParamNumbers: inferredJsonParamNumbers }
4842
4947
  : null),
4843
4948
  ...(timestampParamNumbers.size ? { timestampParamNumbers } : null),
4949
+ ...(rewrittenStatements.some((statement) => statement.epochMillisParamNumbers?.size)
4950
+ ? {
4951
+ epochMillisParamNumbers: new Set(rewrittenStatements.flatMap((statement) => [
4952
+ ...(statement.epochMillisParamNumbers ?? []),
4953
+ ])),
4954
+ }
4955
+ : null),
4844
4956
  ...(booleanParamNumbers.size ? { booleanParamNumbers } : null),
4845
4957
  schemaColumns: rewrittenStatements.flatMap((statement) => statement.schemaColumns ?? []),
4846
4958
  schemaMetadataChanges: rewrittenStatements.flatMap((statement) => statement.schemaMetadataChanges ?? []),
@@ -4907,7 +5019,7 @@ export class DoBackend {
4907
5019
  return buildCommandComplete('SET');
4908
5020
  try {
4909
5021
  if (isCatalogQuery(sql)) {
4910
- const catalogSql = this.inlineParams(sql, portal.params, portal.arrayParamNumbers, portal.jsonParamNumbers, portal.timestampParamNumbers, portal.booleanParamNumbers);
5022
+ const catalogSql = this.inlineParams(sql, portal.params, portal.arrayParamNumbers, portal.jsonParamNumbers, portal.timestampParamNumbers, portal.epochMillisParamNumbers, portal.booleanParamNumbers);
4911
5023
  const result = await this.handleCatalogQuery(catalogSql);
4912
5024
  return concat(buildRowDescription(result.fields), ...result.rows.map((r) => buildDataRow(r, result.fields)), buildCommandComplete(`SELECT ${result.rows.length}`));
4913
5025
  }
@@ -4918,7 +5030,7 @@ export class DoBackend {
4918
5030
  await this.snapshotTransactionWrite(statement);
4919
5031
  const tracking = statement ? this.trackingForStatement(statement) : undefined;
4920
5032
  const execSql = tracking?.returningSQL ?? sql;
4921
- const bound = this.sqliteBoundSQL(execSql, portal.params, portal.arrayParamNumbers, portal.jsonParamNumbers, portal.timestampParamNumbers, portal.booleanParamNumbers);
5033
+ const bound = this.sqliteBoundSQL(execSql, portal.params, portal.arrayParamNumbers, portal.jsonParamNumbers, portal.timestampParamNumbers, portal.epochMillisParamNumbers, portal.booleanParamNumbers);
4922
5034
  const result = await this.doExecResult(bound.sql, bound.params, tracking ? this.trackingRequest(tracking) : undefined);
4923
5035
  if (portal.schemaColumns?.length) {
4924
5036
  await this.applyStatementMetadata([{ sql, schemaColumns: portal.schemaColumns }]);
@@ -5043,11 +5155,12 @@ export class DoBackend {
5043
5155
  return { rows: [] };
5044
5156
  }
5045
5157
  if (isCatalogQuery(rewritten)) {
5046
- const catalogSql = this.inlineStatementParams(rewritten, params, statements, inferredJsonParamNumbers, timestampParamNumbers, booleanParamNumbers);
5158
+ const catalogSql = this.inlineStatementParams(rewritten, params, statements, inferredJsonParamNumbers, timestampParamNumbers, new Set(), booleanParamNumbers);
5047
5159
  return { rows: (await this.handleCatalogQuery(catalogSql)).rows };
5048
5160
  }
5049
5161
  const arrayParamNumbers = new Set();
5050
5162
  const jsonParamNumbers = new Set(inferredJsonParamNumbers);
5163
+ const epochMillisParamNumbers = new Set();
5051
5164
  for (const statement of statements) {
5052
5165
  for (const number of statement.arrayParamNumbers ?? []) {
5053
5166
  arrayParamNumbers.add(number);
@@ -5055,14 +5168,17 @@ export class DoBackend {
5055
5168
  for (const number of statement.jsonParamNumbers ?? []) {
5056
5169
  jsonParamNumbers.add(number);
5057
5170
  }
5171
+ for (const number of statement.epochMillisParamNumbers ?? []) {
5172
+ epochMillisParamNumbers.add(number);
5173
+ }
5058
5174
  }
5059
- const bound = this.sqliteBoundSQL(rewritten, params, arrayParamNumbers, jsonParamNumbers, timestampParamNumbers, booleanParamNumbers);
5175
+ const bound = this.sqliteBoundSQL(rewritten, params, arrayParamNumbers, jsonParamNumbers, timestampParamNumbers, epochMillisParamNumbers, booleanParamNumbers);
5060
5176
  const statement = statements.length === 1 ? statements[0] : undefined;
5061
5177
  if (statement)
5062
5178
  await this.snapshotTransactionWrite(statement);
5063
5179
  const tracking = statement ? this.trackingForStatement(statement) : undefined;
5064
5180
  const execBound = tracking
5065
- ? this.sqliteBoundSQL(tracking.returningSQL, params, arrayParamNumbers, jsonParamNumbers, timestampParamNumbers, booleanParamNumbers)
5181
+ ? this.sqliteBoundSQL(tracking.returningSQL, params, arrayParamNumbers, jsonParamNumbers, timestampParamNumbers, epochMillisParamNumbers, booleanParamNumbers)
5066
5182
  : bound;
5067
5183
  const result = await this.doExecResult(execBound.sql, execBound.params, tracking ? this.trackingRequest(tracking) : undefined);
5068
5184
  await this.applyStatementMetadata(statements);
@@ -5083,11 +5199,13 @@ export class DoBackend {
5083
5199
  return cached;
5084
5200
  const arrayParamNumbers = new Set();
5085
5201
  const jsonParamNumbers = new Set();
5202
+ const epochMillisParamNumbers = new Set();
5086
5203
  const statements = rewriteSQLStatements(sql, {
5087
5204
  skippedFunctionNames: this.skippedFunctionNames,
5088
5205
  triggerFunctions: this.triggerFunctions,
5089
5206
  arrayParamNumbers,
5090
5207
  jsonParamNumbers,
5208
+ epochMillisParamNumbers,
5091
5209
  });
5092
5210
  if (this.canCacheRewrite(statements)) {
5093
5211
  this.rememberRewrite(key, statements);
@@ -5118,14 +5236,16 @@ export class DoBackend {
5118
5236
  rewriteSQL(sql) {
5119
5237
  const arrayParamNumbers = new Set();
5120
5238
  const jsonParamNumbers = new Set();
5239
+ const epochMillisParamNumbers = new Set();
5121
5240
  return rewriteSQL(sql, {
5122
5241
  skippedFunctionNames: this.skippedFunctionNames,
5123
5242
  triggerFunctions: this.triggerFunctions,
5124
5243
  arrayParamNumbers,
5125
5244
  jsonParamNumbers,
5245
+ epochMillisParamNumbers,
5126
5246
  });
5127
5247
  }
5128
- inlineStatementParams(sql, params, statements, inferredJsonParamNumbers = new Set(), timestampParamNumbers = new Set(), booleanParamNumbers = new Set()) {
5248
+ inlineStatementParams(sql, params, statements, inferredJsonParamNumbers = new Set(), timestampParamNumbers = new Set(), epochMillisParamNumbers = new Set(), booleanParamNumbers = new Set()) {
5129
5249
  if (!params?.length)
5130
5250
  return sql;
5131
5251
  const arrayParamNumbers = new Set();
@@ -5137,8 +5257,11 @@ export class DoBackend {
5137
5257
  for (const number of statement.jsonParamNumbers ?? []) {
5138
5258
  jsonParamNumbers.add(number);
5139
5259
  }
5260
+ for (const number of statement.epochMillisParamNumbers ?? []) {
5261
+ epochMillisParamNumbers.add(number);
5262
+ }
5140
5263
  }
5141
- return this.inlineParams(sql, params, arrayParamNumbers, jsonParamNumbers, timestampParamNumbers, booleanParamNumbers);
5264
+ return this.inlineParams(sql, params, arrayParamNumbers, jsonParamNumbers, timestampParamNumbers, epochMillisParamNumbers, booleanParamNumbers);
5142
5265
  }
5143
5266
  async doExec(sql, params) {
5144
5267
  return (await this.doExecResult(sql, params)).rows;
@@ -5837,6 +5960,12 @@ export class DoBackend {
5837
5960
  sqlLiteral(val, options) {
5838
5961
  if (val === null || val === undefined)
5839
5962
  return 'NULL';
5963
+ if (options?.pgEpochMillisAsNumber) {
5964
+ const millis = epochMillisParamValue(val);
5965
+ if (typeof millis === 'number')
5966
+ return String(millis);
5967
+ val = millis;
5968
+ }
5840
5969
  if (options?.pgTimestampAsText)
5841
5970
  return `'${postgresTimestampText(val).replace(/'/g, "''")}'`;
5842
5971
  if (options?.pgJsonAsJson) {
@@ -5872,7 +6001,7 @@ export class DoBackend {
5872
6001
  return `'${val.replace(/'/g, "''")}'`;
5873
6002
  return String(val);
5874
6003
  }
5875
- inlineParams(sql, params, arrayParamNumbers = new Set(), jsonParamNumbers = new Set(), timestampParamNumbers = new Set(), booleanParamNumbers = new Set()) {
6004
+ inlineParams(sql, params, arrayParamNumbers = new Set(), jsonParamNumbers = new Set(), timestampParamNumbers = new Set(), epochMillisParamNumbers = new Set(), booleanParamNumbers = new Set()) {
5876
6005
  let out = '';
5877
6006
  for (let i = 0; i < sql.length;) {
5878
6007
  const ch = sql[i];
@@ -5951,6 +6080,7 @@ export class DoBackend {
5951
6080
  pgArrayAsJson: arrayParamNumbers.has(number),
5952
6081
  pgJsonAsJson: jsonParamNumbers.has(number),
5953
6082
  pgTimestampAsText: timestampParamNumbers.has(number),
6083
+ pgEpochMillisAsNumber: epochMillisParamNumbers.has(number),
5954
6084
  pgBooleanAsInteger: booleanParamNumbers.has(number),
5955
6085
  })
5956
6086
  : sql.slice(i, end);
@@ -5965,6 +6095,8 @@ export class DoBackend {
5965
6095
  sqliteParamValue(value, options) {
5966
6096
  if (value === null || value === undefined)
5967
6097
  return null;
6098
+ if (options?.pgEpochMillisAsNumber)
6099
+ return epochMillisParamValue(value);
5968
6100
  if (options?.pgTimestampAsText)
5969
6101
  return postgresTimestampText(value);
5970
6102
  if (options?.pgJsonAsJson)
@@ -5991,7 +6123,7 @@ export class DoBackend {
5991
6123
  return JSON.stringify(value);
5992
6124
  return value;
5993
6125
  }
5994
- sqliteBoundSQL(sql, params, arrayParamNumbers = new Set(), jsonParamNumbers = new Set(), timestampParamNumbers = new Set(), booleanParamNumbers = new Set()) {
6126
+ sqliteBoundSQL(sql, params, arrayParamNumbers = new Set(), jsonParamNumbers = new Set(), timestampParamNumbers = new Set(), epochMillisParamNumbers = new Set(), booleanParamNumbers = new Set()) {
5995
6127
  if (!params?.length)
5996
6128
  return { sql, params: [] };
5997
6129
  let out = '';
@@ -6073,6 +6205,7 @@ export class DoBackend {
6073
6205
  pgArrayAsJson: arrayParamNumbers.has(number),
6074
6206
  pgJsonAsJson: jsonParamNumbers.has(number),
6075
6207
  pgTimestampAsText: timestampParamNumbers.has(number),
6208
+ pgEpochMillisAsNumber: epochMillisParamNumbers.has(number),
6076
6209
  pgBooleanAsInteger: booleanParamNumbers.has(number),
6077
6210
  }));
6078
6211
  }