effect-qb 0.21.0 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/index.js +663 -261
  2. package/dist/mysql.js +2840 -492
  3. package/dist/postgres/metadata.js +113 -14
  4. package/dist/postgres.js +2596 -285
  5. package/dist/sqlite.js +2783 -450
  6. package/dist/standard.js +663 -261
  7. package/package.json +1 -1
  8. package/src/internal/analytics.ts +264 -0
  9. package/src/internal/coercion/errors.d.ts +1 -1
  10. package/src/internal/coercion/errors.ts +1 -1
  11. package/src/internal/custom-sql-renderer.ts +20 -0
  12. package/src/internal/dialect-numeric.ts +332 -0
  13. package/src/internal/dialect-renderers/mysql.ts +68 -13
  14. package/src/internal/dialect-renderers/postgres.ts +83 -13
  15. package/src/internal/dialect-renderers/sqlite.ts +57 -13
  16. package/src/internal/dynamic.ts +131 -0
  17. package/src/internal/executor.ts +198 -7
  18. package/src/internal/expression-ast.ts +62 -1
  19. package/src/internal/fragment.ts +120 -0
  20. package/src/internal/function-constraints.ts +105 -0
  21. package/src/internal/grouping-key.ts +26 -0
  22. package/src/internal/numeric.ts +204 -0
  23. package/src/internal/query.ts +13 -1
  24. package/src/internal/runtime/normalize.ts +5 -2
  25. package/src/internal/runtime/schema.ts +2 -1
  26. package/src/internal/standard-dsl.ts +43 -20
  27. package/src/internal/window-frame.ts +30 -0
  28. package/src/internal/window-renderer.ts +25 -0
  29. package/src/mysql/executor.ts +126 -45
  30. package/src/mysql/function/aggregate.ts +87 -1
  31. package/src/mysql/function/index.ts +5 -2
  32. package/src/mysql/function/numeric.ts +185 -0
  33. package/src/mysql/function/temporal.ts +6 -6
  34. package/src/mysql/function/window.ts +12 -0
  35. package/src/mysql/internal/dsl.ts +38 -20
  36. package/src/mysql.ts +2 -0
  37. package/src/postgres/executor.ts +111 -45
  38. package/src/postgres/function/aggregate.ts +124 -1
  39. package/src/postgres/function/core.ts +2 -1
  40. package/src/postgres/function/index.ts +19 -1
  41. package/src/postgres/function/numeric.ts +246 -0
  42. package/src/postgres/function/window.ts +12 -0
  43. package/src/postgres/internal/dsl.ts +38 -20
  44. package/src/sqlite/executor.ts +96 -45
  45. package/src/sqlite/function/aggregate.ts +90 -1
  46. package/src/sqlite/function/index.ts +5 -2
  47. package/src/sqlite/function/numeric.ts +139 -0
  48. package/src/sqlite/function/window.ts +12 -0
  49. package/src/sqlite/internal/dsl.ts +38 -20
  50. package/src/sqlite.ts +2 -0
  51. package/src/standard/function/core.ts +8 -1
  52. package/src/standard/function/index.ts +18 -11
  53. package/src/standard/function/string.ts +1 -1
  54. package/src/standard/function/window.ts +10 -1
  55. package/src/standard/query.ts +19 -7
  56. package/src/standard/type.ts +16 -0
  57. package/src/standard.ts +4 -0
  58. package/src/standard/function/temporal.ts +0 -78
package/dist/index.js CHANGED
@@ -2457,8 +2457,9 @@ var normalizeOffsetTime = (value) => {
2457
2457
  return `${formatLocalTime(validDate(value))}Z`;
2458
2458
  }
2459
2459
  const raw = expectString(value, "offset time").trim();
2460
- if (isValidOffsetTimeString(raw)) {
2461
- return raw;
2460
+ const canonical = raw.replace(/([+-]\d{2})$/, "$1:00").replace(/([+-]\d{2})(\d{2})$/, "$1:$2");
2461
+ if (isValidOffsetTimeString(canonical)) {
2462
+ return canonical;
2462
2463
  }
2463
2464
  throw new Error("Expected an offset-time value");
2464
2465
  };
@@ -3520,6 +3521,14 @@ var castTargetGroupingKey = (target) => {
3520
3521
  };
3521
3522
  var escapeGroupingText = (value) => value.replace(/\\/g, "\\\\").replace(/,/g, "\\,").replace(/\|/g, "\\|").replace(/=/g, "\\=").replace(/>/g, "\\>");
3522
3523
  var functionCallNameGroupingKey = (name) => escapeGroupingText(name);
3524
+ var customSqlGroupingKey = (strings, values) => strings.map((part, index4) => {
3525
+ const value = values[index4];
3526
+ if (value === undefined) {
3527
+ return escapeGroupingText(part);
3528
+ }
3529
+ const rendered = isExpression2(value) ? groupingKeyOfExpression(value) : `identifier:${value.parts.map(escapeGroupingText).join(".")}`;
3530
+ return `${escapeGroupingText(part)}${rendered}`;
3531
+ }).join("|");
3523
3532
  var quantifiedComparisonGroupingName = (kind) => kind === "comparisonAny" ? "compareAny" : "compareAll";
3524
3533
  var caseGroupingKey = (branches, fallback) => {
3525
3534
  const typedBranches = branches;
@@ -3601,12 +3610,19 @@ var groupingKeyOfExpression = (expression) => {
3601
3610
  return `collate(${requiredExpressionGroupingKey("collate", ast.value)},${collationGroupingKey(ast.collation)})`;
3602
3611
  case "function":
3603
3612
  return `function(${functionCallNameGroupingKey(ast.name)},${functionCallArgsGroupingKey(ast.args)})`;
3613
+ case "customSql":
3614
+ return `customSql(${customSqlGroupingKey(ast.strings, ast.values)})`;
3604
3615
  case "isNull":
3605
3616
  case "isNotNull":
3606
3617
  case "not":
3607
3618
  case "upper":
3608
3619
  case "lower":
3609
3620
  case "count":
3621
+ case "sum":
3622
+ case "avg":
3623
+ case "abs":
3624
+ case "round":
3625
+ case "negate":
3610
3626
  case "max":
3611
3627
  case "min":
3612
3628
  return `${ast.kind}(${requiredExpressionGroupingKey(ast.kind, ast.value)})`;
@@ -3627,6 +3643,11 @@ var groupingKeyOfExpression = (expression) => {
3627
3643
  case "contains":
3628
3644
  case "containedBy":
3629
3645
  case "overlaps":
3646
+ case "add":
3647
+ case "subtract":
3648
+ case "multiply":
3649
+ case "divide":
3650
+ case "modulo":
3630
3651
  return `${ast.kind}(${requiredBinaryExpressionGroupingKey(ast.kind, ast.left, ast.right)})`;
3631
3652
  case "and":
3632
3653
  case "or":
@@ -3702,6 +3723,31 @@ var dedupeGroupedExpressions = (values) => {
3702
3723
  });
3703
3724
  };
3704
3725
 
3726
+ // src/internal/window-frame.ts
3727
+ var validateBoundary = (boundary) => {
3728
+ if (typeof boundary === "object") {
3729
+ const value = "preceding" in boundary ? boundary.preceding : boundary.following;
3730
+ if (!Number.isSafeInteger(value) || value < 0) {
3731
+ throw new Error("window frame offsets must be non-negative safe integers");
3732
+ }
3733
+ }
3734
+ };
3735
+ var validateWindowFrame = (frame) => {
3736
+ if (frame === undefined) {
3737
+ return;
3738
+ }
3739
+ validateBoundary(frame.start);
3740
+ if (frame.end !== undefined) {
3741
+ validateBoundary(frame.end);
3742
+ }
3743
+ if (frame.start === "unboundedFollowing") {
3744
+ throw new Error("window frame cannot start with unbounded following");
3745
+ }
3746
+ if (frame.end === "unboundedPreceding") {
3747
+ throw new Error("window frame cannot end with unbounded preceding");
3748
+ }
3749
+ };
3750
+
3705
3751
  // src/internal/dsl-transaction-ddl-runtime.ts
3706
3752
  var renderTransactionIsolationLevel = (isolationLevel) => {
3707
3753
  if (isolationLevel === undefined) {
@@ -5033,6 +5079,10 @@ var extractRequiredFromDialectInputRuntime = (value) => {
5033
5079
  return Object.keys(expression[TypeId].dependencies);
5034
5080
  };
5035
5081
  var normalizeWindowSpec = (spec) => {
5082
+ if (spec?.frame !== undefined) {
5083
+ throw new Error("over does not accept an explicit frame on the portable Function API; use a dialect Function.over helper");
5084
+ }
5085
+ validateWindowFrame(spec?.frame);
5036
5086
  const partitionBy = [...spec?.partitionBy ?? []];
5037
5087
  const orderBy = (spec?.orderBy ?? []).map((term) => {
5038
5088
  const direction = term.direction ?? "asc";
@@ -5043,7 +5093,8 @@ var normalizeWindowSpec = (spec) => {
5043
5093
  });
5044
5094
  return {
5045
5095
  partitionBy,
5046
- orderBy
5096
+ orderBy,
5097
+ frame: spec?.frame
5047
5098
  };
5048
5099
  };
5049
5100
  var mergeWindowExpressions = (value, partitionBy, orderBy) => value === undefined ? [...partitionBy, ...orderBy.map((term) => term.value)] : [value, ...partitionBy, ...orderBy.map((term) => term.value)];
@@ -5180,34 +5231,6 @@ var isNotNull = (value) => {
5180
5231
  value: expression
5181
5232
  });
5182
5233
  };
5183
- var upper = (value) => {
5184
- const expression = toDialectStringExpression(value);
5185
- return makeExpression2({
5186
- runtime: "",
5187
- dbType: profile.textDb,
5188
- nullability: expression[TypeId].nullability,
5189
- dialect: expression[TypeId].dialect,
5190
- kind: expression[TypeId].kind,
5191
- dependencies: expression[TypeId].dependencies
5192
- }, {
5193
- kind: "upper",
5194
- value: expression
5195
- });
5196
- };
5197
- var lower = (value) => {
5198
- const expression = toDialectStringExpression(value);
5199
- return makeExpression2({
5200
- runtime: "",
5201
- dbType: profile.textDb,
5202
- nullability: expression[TypeId].nullability,
5203
- dialect: expression[TypeId].dialect,
5204
- kind: expression[TypeId].kind,
5205
- dependencies: expression[TypeId].dependencies
5206
- }, {
5207
- kind: "lower",
5208
- value: expression
5209
- });
5210
- };
5211
5234
  var collate = (value, collation) => {
5212
5235
  const expression = toDialectStringExpression(value);
5213
5236
  const normalizedCollation = typeof collation === "string" ? [collation] : collation;
@@ -5737,8 +5760,8 @@ var any_ = (...values) => or(...values);
5737
5760
  var count = (value) => {
5738
5761
  const expression = toDialectExpression(value);
5739
5762
  return makeExpression2({
5740
- runtime: 0,
5741
- dbType: profile.numericDb,
5763
+ runtime: undefined,
5764
+ dbType: standardDatatypes.bigint(),
5742
5765
  nullability: "never",
5743
5766
  dialect: expression[TypeId].dialect,
5744
5767
  kind: "aggregate",
@@ -5824,15 +5847,16 @@ var over = (value, spec = {}) => {
5824
5847
  function: "over",
5825
5848
  value,
5826
5849
  partitionBy: normalized.partitionBy,
5827
- orderBy: normalized.orderBy
5850
+ orderBy: normalized.orderBy,
5851
+ frame: normalized.frame
5828
5852
  });
5829
5853
  };
5830
5854
  var buildNumberWindow = (kind, spec) => {
5831
5855
  const normalized = normalizeWindowSpec(spec);
5832
5856
  const expressions = mergeWindowExpressions(undefined, normalized.partitionBy, normalized.orderBy);
5833
5857
  return makeExpression2({
5834
- runtime: 0,
5835
- dbType: profile.numericDb,
5858
+ runtime: undefined,
5859
+ dbType: standardDatatypes.bigint(),
5836
5860
  nullability: "never",
5837
5861
  dialect: expressions.find((expression) => expression[TypeId].dialect !== undefined)?.[TypeId].dialect ?? profile.dialect,
5838
5862
  kind: "window",
@@ -5841,7 +5865,8 @@ var buildNumberWindow = (kind, spec) => {
5841
5865
  kind: "window",
5842
5866
  function: kind,
5843
5867
  partitionBy: normalized.partitionBy,
5844
- orderBy: normalized.orderBy
5868
+ orderBy: normalized.orderBy,
5869
+ frame: normalized.frame
5845
5870
  });
5846
5871
  };
5847
5872
  var rowNumber = (spec) => buildNumberWindow("rowNumber", spec);
@@ -5885,21 +5910,6 @@ var coalesce = (...values) => {
5885
5910
  values: expressions
5886
5911
  });
5887
5912
  };
5888
- var call = (name, ...args) => {
5889
- const expressions = args.map((value) => toDialectExpression(value));
5890
- return makeExpression2({
5891
- runtime: undefined,
5892
- dbType: profile.textDb,
5893
- nullability: "maybe",
5894
- dialect: expressions.find((value) => value[TypeId].dialect !== undefined)?.[TypeId].dialect ?? profile.dialect,
5895
- kind: mergeAggregationManyRuntime(expressions),
5896
- dependencies: mergeManyDependencies(expressions)
5897
- }, {
5898
- kind: "function",
5899
- name,
5900
- args: expressions
5901
- });
5902
- };
5903
5913
  var resolveCaseNullabilityRuntime = (values) => {
5904
5914
  let sawNever = false;
5905
5915
  let sawMaybe = false;
@@ -6389,39 +6399,78 @@ var {
6389
6399
 
6390
6400
  // src/standard/cast.ts
6391
6401
  var to = (...args) => args.length === 1 ? (value) => cast(value, args[0]) : cast(args[0], args[1]);
6402
+ // src/standard/type.ts
6403
+ var driverValueMapping4 = (dbType, mapping) => ({
6404
+ ...dbType,
6405
+ driverValueMapping: mapping
6406
+ });
6407
+ var type2 = {
6408
+ ...standardDatatypes,
6409
+ driverValueMapping: driverValueMapping4
6410
+ };
6411
+ // src/internal/fragment.ts
6412
+ var exports_fragment = {};
6413
+ __export(exports_fragment, {
6414
+ identifier: () => identifier,
6415
+ expression: () => expression
6416
+ });
6417
+ var identifier = (...parts) => ({
6418
+ kind: "sqlIdentifier",
6419
+ parts
6420
+ });
6421
+ var expression = (options2) => (strings, ...values2) => {
6422
+ const expressions = values2.filter((value) => (TypeId in value));
6423
+ return makeExpression2({
6424
+ runtime: undefined,
6425
+ dbType: options2.dbType,
6426
+ runtimeSchema: options2.schema,
6427
+ driverValueMapping: options2.dbType.driverValueMapping,
6428
+ nullability: options2.nullability,
6429
+ dialect: expressions.find((value) => value[TypeId].dialect !== "standard")?.[TypeId].dialect ?? expressions[0]?.[TypeId].dialect ?? options2.dbType.dialect,
6430
+ kind: options2.kind ?? mergeAggregationManyRuntime(expressions),
6431
+ dependencies: mergeManyDependencies(expressions)
6432
+ }, {
6433
+ kind: "customSql",
6434
+ strings: [...strings],
6435
+ values: values2
6436
+ });
6437
+ };
6392
6438
  // src/standard/function/index.ts
6393
6439
  var exports_function = {};
6394
6440
  __export(exports_function, {
6395
6441
  window: () => exports_window,
6396
- upper: () => upper,
6397
- temporal: () => exports_temporal,
6442
+ subtract: () => subtract,
6398
6443
  string: () => exports_string,
6399
6444
  rowNumber: () => rowNumber,
6400
6445
  rank: () => rank,
6401
6446
  over: () => over,
6402
- now: () => now,
6447
+ negate: () => negate,
6448
+ multiply: () => multiply,
6403
6449
  min: () => min,
6404
6450
  max: () => max,
6405
- lower: () => lower,
6406
- localTimestamp: () => localTimestamp,
6407
- localTime: () => localTime,
6451
+ lead: () => lead,
6452
+ lastValue: () => lastValue,
6453
+ lag: () => lag,
6454
+ firstValue: () => firstValue,
6408
6455
  denseRank: () => denseRank,
6409
- currentTimestamp: () => currentTimestamp,
6410
- currentTime: () => currentTime,
6411
- currentDate: () => currentDate,
6412
6456
  count: () => count,
6413
6457
  core: () => exports_core,
6414
6458
  concat: () => concat,
6415
6459
  coalesce: () => coalesce,
6416
- call: () => call,
6417
- aggregate: () => exports_aggregate
6460
+ aggregate: () => exports_aggregate,
6461
+ add: () => add,
6462
+ abs: () => abs
6418
6463
  });
6419
6464
 
6420
6465
  // src/standard/function/core.ts
6421
6466
  var exports_core = {};
6422
6467
  __export(exports_core, {
6468
+ subtract: () => subtract,
6469
+ negate: () => negate,
6470
+ multiply: () => multiply,
6423
6471
  coalesce: () => coalesce,
6424
- call: () => call
6472
+ add: () => add,
6473
+ abs: () => abs
6425
6474
  });
6426
6475
 
6427
6476
  // src/standard/query.ts
@@ -6430,17 +6479,17 @@ __export(exports_query, {
6430
6479
  withRecursive: () => withRecursive_,
6431
6480
  with: () => with_,
6432
6481
  where: () => where,
6482
+ when: () => when,
6433
6483
  values: () => exportedValues,
6434
6484
  upsert: () => upsert,
6435
- upper: () => upper,
6436
6485
  update: () => update,
6437
6486
  unnest: () => exportedUnnest,
6438
6487
  union_query_capabilities: () => union_query_capabilities,
6439
6488
  unionAll: () => unionAll,
6440
6489
  union: () => union,
6441
- type: () => type,
6442
6490
  truncate: () => truncate,
6443
6491
  transaction: () => transaction,
6492
+ subtract: () => subtract,
6444
6493
  select: () => exportedSelect,
6445
6494
  scalar: () => scalar,
6446
6495
  savepoint: () => savepoint,
@@ -6458,25 +6507,30 @@ __export(exports_query, {
6458
6507
  overlaps: () => overlaps,
6459
6508
  over: () => over,
6460
6509
  orderBy: () => orderBy,
6510
+ orAll: () => orAll,
6461
6511
  or: () => or,
6462
6512
  onConflict: () => onConflict,
6463
6513
  offset: () => offset,
6464
6514
  notIn: () => notIn,
6465
6515
  not: () => not,
6466
6516
  neq: () => neq,
6517
+ negate: () => negate,
6518
+ multiply: () => multiply,
6467
6519
  min: () => min,
6468
6520
  merge: () => merge2,
6469
6521
  max: () => max,
6470
6522
  match: () => match,
6471
6523
  lte: () => lte,
6472
6524
  lt: () => lt,
6473
- lower: () => lower,
6474
6525
  lock: () => lock,
6475
6526
  literal: () => literal,
6476
6527
  limit: () => limit,
6477
6528
  like: () => like,
6478
6529
  leftJoin: () => leftJoin,
6530
+ lead: () => lead,
6479
6531
  lateral: () => lateral,
6532
+ lastValue: () => lastValue,
6533
+ lag: () => lag,
6480
6534
  isNull: () => isNull,
6481
6535
  isNotNull: () => isNotNull,
6482
6536
  isNotDistinctFrom: () => isNotDistinctFrom,
@@ -6485,6 +6539,7 @@ __export(exports_query, {
6485
6539
  intersect: () => intersect,
6486
6540
  insert: () => exportedInsert,
6487
6541
  innerJoin: () => innerJoin,
6542
+ includeIf: () => includeIf,
6488
6543
  inSubquery: () => inSubquery,
6489
6544
  in: () => in_,
6490
6545
  ilike: () => ilike,
@@ -6494,6 +6549,7 @@ __export(exports_query, {
6494
6549
  groupBy: () => groupBy,
6495
6550
  fullJoin: () => fullJoin,
6496
6551
  from: () => exportedFrom,
6552
+ firstValue: () => firstValue,
6497
6553
  exists: () => exists,
6498
6554
  excluded: () => excluded,
6499
6555
  exceptAll: () => exceptAll,
@@ -6519,18 +6575,214 @@ __export(exports_query, {
6519
6575
  coalesce: () => coalesce,
6520
6576
  cast: () => cast,
6521
6577
  case: () => case_,
6522
- call: () => call,
6523
6578
  between: () => between,
6524
6579
  as: () => as,
6525
6580
  any: () => any_,
6581
+ andAll: () => andAll,
6526
6582
  and: () => and,
6527
- all: () => all_
6583
+ all: () => all_,
6584
+ add: () => add,
6585
+ abs: () => abs
6586
+ });
6587
+
6588
+ // src/internal/numeric.ts
6589
+ import * as Schema7 from "effect/Schema";
6590
+ var numberLiteral = (value) => makeExpression2({
6591
+ runtime: value,
6592
+ dbType: standardDatatypes.real(),
6593
+ runtimeSchema: Schema7.Number,
6594
+ nullability: "never",
6595
+ dialect: "standard",
6596
+ kind: "scalar",
6597
+ dependencies: {}
6598
+ }, {
6599
+ kind: "literal",
6600
+ value
6528
6601
  });
6602
+ var toExpression = (value) => typeof value === "number" ? numberLiteral(value) : value;
6603
+ var retargetLiteral = (value, target) => {
6604
+ const ast = value[TypeId2];
6605
+ if (ast.kind !== "literal") {
6606
+ return value;
6607
+ }
6608
+ const state = target[TypeId];
6609
+ return makeExpression2({
6610
+ runtime: value[TypeId].runtime,
6611
+ dbType: state.dbType,
6612
+ runtimeSchema: state.runtimeSchema,
6613
+ driverValueMapping: state.driverValueMapping,
6614
+ nullability: value[TypeId].nullability,
6615
+ dialect: state.dialect,
6616
+ kind: "scalar",
6617
+ dependencies: {}
6618
+ }, ast);
6619
+ };
6620
+ var binary = (kind, left, right) => {
6621
+ let leftExpression = toExpression(left);
6622
+ let rightExpression = toExpression(right);
6623
+ const leftAst = leftExpression[TypeId2];
6624
+ const rightAst = rightExpression[TypeId2];
6625
+ if (leftAst.kind === "literal" && rightAst.kind !== "literal") {
6626
+ leftExpression = retargetLiteral(leftExpression, rightExpression);
6627
+ } else if (rightAst.kind === "literal" && leftAst.kind !== "literal") {
6628
+ rightExpression = retargetLiteral(rightExpression, leftExpression);
6629
+ }
6630
+ const values2 = [leftExpression, rightExpression];
6631
+ return makeExpression2({
6632
+ runtime: 0,
6633
+ dbType: leftExpression[TypeId].dbType,
6634
+ runtimeSchema: Schema7.Number,
6635
+ driverValueMapping: leftExpression[TypeId].driverValueMapping,
6636
+ nullability: mergeNullabilityManyRuntime(values2),
6637
+ dialect: values2.find((value) => value[TypeId].dialect !== "standard")?.[TypeId].dialect ?? leftExpression[TypeId].dialect,
6638
+ kind: mergeAggregationManyRuntime(values2),
6639
+ dependencies: mergeManyDependencies(values2)
6640
+ }, {
6641
+ kind,
6642
+ left: leftExpression,
6643
+ right: rightExpression
6644
+ });
6645
+ };
6646
+ var add = (left, right) => binary("add", left, right);
6647
+ var subtract = (left, right) => binary("subtract", left, right);
6648
+ var multiply = (left, right) => binary("multiply", left, right);
6649
+ var unary = (kind, value, nullability, resultKind) => {
6650
+ const expression2 = toExpression(value);
6651
+ return makeExpression2({
6652
+ runtime: 0,
6653
+ dbType: expression2[TypeId].dbType,
6654
+ runtimeSchema: Schema7.Number,
6655
+ driverValueMapping: expression2[TypeId].driverValueMapping,
6656
+ nullability,
6657
+ dialect: expression2[TypeId].dialect,
6658
+ kind: resultKind,
6659
+ dependencies: expression2[TypeId].dependencies
6660
+ }, {
6661
+ kind,
6662
+ value: expression2
6663
+ });
6664
+ };
6665
+ var abs = (value) => {
6666
+ const expression2 = toExpression(value);
6667
+ return unary("abs", value, expression2[TypeId].nullability, expression2[TypeId].kind);
6668
+ };
6669
+ var negate = (value) => {
6670
+ const expression2 = toExpression(value);
6671
+ return unary("negate", value, expression2[TypeId].nullability, expression2[TypeId].kind);
6672
+ };
6673
+ // src/internal/dynamic.ts
6674
+ import * as Schema8 from "effect/Schema";
6675
+ var booleanLiteral = (value) => makeExpression2({
6676
+ runtime: value,
6677
+ dbType: standardDatatypes.boolean(),
6678
+ runtimeSchema: Schema8.Boolean,
6679
+ nullability: "never",
6680
+ dialect: "standard",
6681
+ kind: "scalar",
6682
+ dependencies: {}
6683
+ }, {
6684
+ kind: "literal",
6685
+ value
6686
+ });
6687
+ var combine = (kind, values2, identity) => {
6688
+ if (values2.length === 0) {
6689
+ return booleanLiteral(identity);
6690
+ }
6691
+ const expressions = values2.map((value) => typeof value === "boolean" ? booleanLiteral(value) : value);
6692
+ return makeExpression2({
6693
+ runtime: identity,
6694
+ dbType: standardDatatypes.boolean(),
6695
+ runtimeSchema: Schema8.Boolean,
6696
+ nullability: mergeNullabilityManyRuntime(expressions),
6697
+ dialect: expressions.find((value) => value[TypeId].dialect !== "standard")?.[TypeId].dialect ?? expressions[0][TypeId].dialect,
6698
+ kind: "scalar",
6699
+ dependencies: mergeManyDependencies(expressions)
6700
+ }, {
6701
+ kind,
6702
+ values: expressions
6703
+ });
6704
+ };
6705
+ var andAll = (values2) => combine("and", values2, true);
6706
+ var orAll = (values2) => combine("or", values2, false);
6707
+ var when = (condition, modifier) => (value) => condition ? modifier(value) : value;
6708
+ var includeIf = (condition, selection) => condition ? selection : {};
6709
+ // src/internal/analytics.ts
6710
+ var normalizeSpec = (spec) => {
6711
+ validateWindowFrame(spec.frame);
6712
+ return {
6713
+ partitionBy: spec.partitionBy ?? [],
6714
+ orderBy: spec.orderBy.map((term) => ({
6715
+ value: term.value,
6716
+ direction: term.direction ?? "asc"
6717
+ })),
6718
+ frame: spec.frame
6719
+ };
6720
+ };
6721
+ var rejectExplicitPortableFrame = (functionName, spec) => {
6722
+ if (spec.frame !== undefined) {
6723
+ throw new Error(`${functionName} does not accept an explicit frame on the portable Function API; use a dialect Function helper`);
6724
+ }
6725
+ };
6726
+ var windowExpression = (kind, value, spec, nullability, options2 = {}) => {
6727
+ const normalized = normalizeSpec(spec);
6728
+ const { fallbackDialect, ...astOptions } = options2;
6729
+ const expressions = [
6730
+ value,
6731
+ ...normalized.partitionBy,
6732
+ ...normalized.orderBy.map((term) => term.value),
6733
+ ...options2.offset === undefined ? [] : [options2.offset],
6734
+ ...options2.defaultValue === undefined ? [] : [options2.defaultValue]
6735
+ ];
6736
+ return makeExpression2({
6737
+ runtime: undefined,
6738
+ dbType: value[TypeId].dbType,
6739
+ runtimeSchema: value[TypeId].runtimeSchema,
6740
+ driverValueMapping: value[TypeId].driverValueMapping,
6741
+ nullability,
6742
+ dialect: expressions.find((entry) => entry[TypeId].dialect !== "standard")?.[TypeId].dialect ?? fallbackDialect ?? value[TypeId].dialect,
6743
+ kind: "window",
6744
+ dependencies: mergeManyDependencies(expressions)
6745
+ }, {
6746
+ kind: "window",
6747
+ function: kind,
6748
+ value,
6749
+ ...astOptions,
6750
+ ...normalized
6751
+ });
6752
+ };
6753
+ var lag = (value, options2) => {
6754
+ rejectExplicitPortableFrame("lag", options2.spec);
6755
+ if (options2.offset !== undefined && (!Number.isSafeInteger(options2.offset) || options2.offset < 0)) {
6756
+ throw new Error("lag offset must be a non-negative safe integer");
6757
+ }
6758
+ return windowExpression("lag", value, options2.spec, "maybe", {
6759
+ ...options2.offset === undefined && options2.default === undefined ? {} : { offset: literal(options2.offset ?? 1) },
6760
+ ...options2.default === undefined ? {} : { defaultValue: literal(options2.default) }
6761
+ });
6762
+ };
6763
+ var lead = (value, options2) => {
6764
+ rejectExplicitPortableFrame("lead", options2.spec);
6765
+ if (options2.offset !== undefined && (!Number.isSafeInteger(options2.offset) || options2.offset < 0)) {
6766
+ throw new Error("lead offset must be a non-negative safe integer");
6767
+ }
6768
+ return windowExpression("lead", value, options2.spec, "maybe", {
6769
+ ...options2.offset === undefined && options2.default === undefined ? {} : { offset: literal(options2.offset ?? 1) },
6770
+ ...options2.default === undefined ? {} : { defaultValue: literal(options2.default) }
6771
+ });
6772
+ };
6773
+ var firstValue = (value, spec) => {
6774
+ rejectExplicitPortableFrame("firstValue", spec);
6775
+ return windowExpression("firstValue", value, spec, value[TypeId].nullability);
6776
+ };
6777
+ var lastValue = (value, spec) => {
6778
+ rejectExplicitPortableFrame("lastValue", spec);
6779
+ return windowExpression("lastValue", value, spec, value[TypeId].nullability);
6780
+ };
6781
+ var makeDialectFirstValue = (dialect) => (value, spec) => windowExpression("firstValue", value, spec, "maybe", { fallbackDialect: dialect });
6782
+ var makeDialectLastValue = (dialect) => (value, spec) => windowExpression("lastValue", value, spec, "maybe", { fallbackDialect: dialect });
6529
6783
  // src/standard/function/string.ts
6530
6784
  var exports_string = {};
6531
6785
  __export(exports_string, {
6532
- upper: () => upper,
6533
- lower: () => lower,
6534
6786
  concat: () => concat
6535
6787
  });
6536
6788
  // src/standard/function/aggregate.ts
@@ -6546,37 +6798,12 @@ __export(exports_window, {
6546
6798
  rowNumber: () => rowNumber,
6547
6799
  rank: () => rank,
6548
6800
  over: () => over,
6801
+ lead: () => lead,
6802
+ lastValue: () => lastValue,
6803
+ lag: () => lag,
6804
+ firstValue: () => firstValue,
6549
6805
  denseRank: () => denseRank
6550
6806
  });
6551
- // src/standard/function/temporal.ts
6552
- var exports_temporal = {};
6553
- __export(exports_temporal, {
6554
- now: () => now,
6555
- localTimestamp: () => localTimestamp,
6556
- localTime: () => localTime,
6557
- currentTimestamp: () => currentTimestamp,
6558
- currentTime: () => currentTime,
6559
- currentDate: () => currentDate
6560
- });
6561
- var makeTemporal = (name, dbType, runtimeSchema) => makeExpression2({
6562
- runtime: undefined,
6563
- dbType,
6564
- runtimeSchema,
6565
- nullability: "never",
6566
- dialect: "standard",
6567
- kind: "scalar",
6568
- dependencies: {}
6569
- }, {
6570
- kind: "function",
6571
- name,
6572
- args: []
6573
- });
6574
- var now = () => makeTemporal("now", standardDatatypes.timestamp(), InstantStringSchema);
6575
- var currentDate = () => makeTemporal("current_date", standardDatatypes.date(), LocalDateStringSchema);
6576
- var currentTime = () => makeTemporal("current_time", standardDatatypes.time(), LocalTimeStringSchema);
6577
- var currentTimestamp = () => makeTemporal("current_timestamp", standardDatatypes.timestamp(), LocalDateTimeStringSchema);
6578
- var localTime = () => makeTemporal("localtime", standardDatatypes.time(), LocalTimeStringSchema);
6579
- var localTimestamp = () => makeTemporal("localtimestamp", standardDatatypes.timestamp(), LocalDateTimeStringSchema);
6580
6807
  // src/standard/json.ts
6581
6808
  var exports_json = {};
6582
6809
  __export(exports_json, {
@@ -6811,27 +7038,32 @@ var pathExists = (...args) => {
6811
7038
  var exports_executor = {};
6812
7039
  __export(exports_executor, {
6813
7040
  withTransaction: () => withTransaction,
7041
+ withResultContracts: () => withResultContracts,
6814
7042
  streamFromSqlClient: () => streamFromSqlClient,
6815
7043
  remapRows: () => remapRows,
7044
+ nonEmpty: () => nonEmpty,
6816
7045
  makeRowDecoder: () => makeRowDecoder,
6817
7046
  make: () => make3,
6818
7047
  hasWriteCapability: () => hasWriteCapability,
6819
7048
  fromSqlClient: () => fromSqlClient,
6820
7049
  fromDriver: () => fromDriver,
7050
+ explainQuery: () => explainQuery,
7051
+ exactlyOne: () => exactlyOne,
6821
7052
  driver: () => driver,
6822
7053
  decodeRows: () => decodeRows,
6823
- decodeChunk: () => decodeChunk
7054
+ decodeChunk: () => decodeChunk,
7055
+ atMostOne: () => atMostOne
6824
7056
  });
6825
7057
  import * as Chunk from "effect/Chunk";
6826
7058
  import * as Effect from "effect/Effect";
6827
7059
  import * as Exit from "effect/Exit";
6828
7060
  import * as Option from "effect/Option";
6829
- import * as Schema9 from "effect/Schema";
7061
+ import * as Schema11 from "effect/Schema";
6830
7062
  import * as SqlClient from "effect/unstable/sql/SqlClient";
6831
7063
  import * as Stream from "effect/Stream";
6832
7064
 
6833
7065
  // src/internal/runtime/driver-value-mapping.ts
6834
- import * as Schema7 from "effect/Schema";
7066
+ import * as Schema9 from "effect/Schema";
6835
7067
  var runtimeTagOfDbType = (dbType) => {
6836
7068
  if (dbType === undefined) {
6837
7069
  return;
@@ -6896,16 +7128,16 @@ var isJsonDbType = (dbType) => {
6896
7128
  const variant = dbType.variant;
6897
7129
  return variant === "json" || variant === "jsonb";
6898
7130
  };
6899
- var schemaAccepts = (schema3, value) => schema3 !== undefined && Schema7.is(schema3)(value);
7131
+ var schemaAccepts = (schema3, value) => schema3 !== undefined && Schema9.is(schema3)(value);
6900
7132
  var encodeWithSchema = (schema3, value) => {
6901
7133
  if (schema3 === undefined) {
6902
7134
  return { value, encoded: false };
6903
7135
  }
6904
- if (!Schema7.is(schema3)(value)) {
7136
+ if (!Schema9.is(schema3)(value)) {
6905
7137
  return { value, encoded: false };
6906
7138
  }
6907
7139
  return {
6908
- value: Schema7.encodeUnknownSync(schema3)(value),
7140
+ value: Schema9.encodeUnknownSync(schema3)(value),
6909
7141
  encoded: true
6910
7142
  };
6911
7143
  };
@@ -7001,20 +7233,20 @@ var renderJsonSelectSql = (sql, context) => {
7001
7233
  };
7002
7234
 
7003
7235
  // src/internal/runtime/schema.ts
7004
- import * as Schema8 from "effect/Schema";
7236
+ import * as Schema10 from "effect/Schema";
7005
7237
  import * as SchemaAST from "effect/SchemaAST";
7006
7238
  var schemaCache = new WeakMap;
7007
- var FiniteNumberSchema = Schema8.Number.check(Schema8.isFinite());
7239
+ var FiniteNumberSchema = Schema10.Number.check(Schema10.isFinite());
7008
7240
  var runtimeSchemaForTag = (tag) => {
7009
7241
  switch (tag) {
7010
7242
  case "string":
7011
- return Schema8.String;
7243
+ return Schema10.String;
7012
7244
  case "number":
7013
7245
  return FiniteNumberSchema;
7014
7246
  case "bigintString":
7015
7247
  return BigIntStringSchema;
7016
7248
  case "boolean":
7017
- return Schema8.Boolean;
7249
+ return Schema10.Boolean;
7018
7250
  case "json":
7019
7251
  return JsonValueSchema;
7020
7252
  case "localDate":
@@ -7032,13 +7264,13 @@ var runtimeSchemaForTag = (tag) => {
7032
7264
  case "decimalString":
7033
7265
  return DecimalStringSchema;
7034
7266
  case "bytes":
7035
- return Schema8.Uint8Array;
7267
+ return Schema10.Uint8Array;
7036
7268
  case "array":
7037
- return Schema8.Array(Schema8.Unknown);
7269
+ return Schema10.Array(Schema10.Unknown);
7038
7270
  case "record":
7039
- return Schema8.Record(Schema8.String, Schema8.Unknown);
7271
+ return Schema10.Record(Schema10.String, Schema10.Unknown);
7040
7272
  case "null":
7041
- return Schema8.Null;
7273
+ return Schema10.Null;
7042
7274
  case "unknown":
7043
7275
  return;
7044
7276
  }
@@ -7051,22 +7283,22 @@ var runtimeSchemaForDbType = (dbType) => {
7051
7283
  return runtimeSchemaForDbType(dbType.base);
7052
7284
  }
7053
7285
  if ("element" in dbType) {
7054
- return Schema8.Array(runtimeSchemaForDbType(dbType.element) ?? Schema8.Unknown);
7286
+ return Schema10.Array(runtimeSchemaForDbType(dbType.element) ?? Schema10.Unknown);
7055
7287
  }
7056
7288
  if ("fields" in dbType) {
7057
- const fields = Object.fromEntries(Object.entries(dbType.fields).map(([key3, field]) => [key3, runtimeSchemaForDbType(field) ?? Schema8.Unknown]));
7058
- return Schema8.Struct(fields);
7289
+ const fields = Object.fromEntries(Object.entries(dbType.fields).map(([key3, field]) => [key3, runtimeSchemaForDbType(field) ?? Schema10.Unknown]));
7290
+ return Schema10.Struct(fields);
7059
7291
  }
7060
7292
  if ("variant" in dbType && dbType.variant === "json") {
7061
7293
  return JsonValueSchema;
7062
7294
  }
7063
7295
  if ("variant" in dbType && (dbType.variant === "enum" || dbType.variant === "set")) {
7064
- return Schema8.String;
7296
+ return Schema10.String;
7065
7297
  }
7066
7298
  const runtimeTag = runtimeTagOfBaseDbType2(dbType);
7067
7299
  return runtimeTag === undefined ? undefined : runtimeSchemaForTag(runtimeTag);
7068
7300
  };
7069
- var makeSchemaFromAst = (ast) => Schema8.make(ast);
7301
+ var makeSchemaFromAst = (ast) => Schema10.make(ast);
7070
7302
  var unionAst = (asts) => {
7071
7303
  if (asts.length === 0) {
7072
7304
  return;
@@ -7156,7 +7388,7 @@ var unionSchemas = (schemas) => {
7156
7388
  if (resolved.length === 1) {
7157
7389
  return resolved[0];
7158
7390
  }
7159
- return Schema8.Union(resolved);
7391
+ return Schema10.Union(resolved);
7160
7392
  };
7161
7393
  var firstSelectedExpression = (plan) => {
7162
7394
  const selection = getAst(plan).select;
@@ -7191,9 +7423,9 @@ var jsonCompatibleSchema = (schema3) => {
7191
7423
  };
7192
7424
  var buildStructSchema = (entries, context) => {
7193
7425
  const fields = Object.fromEntries(entries.map((entry) => [entry.key, expressionRuntimeSchema(entry.value, context) ?? JsonValueSchema]));
7194
- return Schema8.Struct(fields);
7426
+ return Schema10.Struct(fields);
7195
7427
  };
7196
- var buildTupleSchema = (values2, context) => Schema8.Tuple(values2.map((value) => expressionRuntimeSchema(value, context) ?? JsonValueSchema));
7428
+ var buildTupleSchema = (values2, context) => Schema10.Tuple(values2.map((value) => expressionRuntimeSchema(value, context) ?? JsonValueSchema));
7197
7429
  var deriveCaseSchema = (ast, context) => {
7198
7430
  if (context === undefined) {
7199
7431
  return unionSchemas([
@@ -7221,22 +7453,22 @@ var deriveCaseSchema = (ast, context) => {
7221
7453
  const elseSchema = expressionRuntimeSchema(ast.else, { assumptions: elseAssumptions });
7222
7454
  return unionSchemas(elseSchema === undefined ? schemas : [...schemas, elseSchema]);
7223
7455
  };
7224
- var deriveRuntimeSchema = (expression, context) => {
7225
- const state = expression[TypeId];
7456
+ var deriveRuntimeSchema = (expression2, context) => {
7457
+ const state = expression2[TypeId];
7226
7458
  if (state.runtimeSchema !== undefined) {
7227
7459
  return state.runtimeSchema;
7228
7460
  }
7229
- const ast = expression[TypeId2];
7461
+ const ast = expression2[TypeId2];
7230
7462
  switch (ast.kind) {
7231
7463
  case "column":
7232
7464
  case "excluded":
7233
7465
  return state.runtimeSchema;
7234
7466
  case "literal":
7235
7467
  if (ast.value === null) {
7236
- return Schema8.Null;
7468
+ return Schema10.Null;
7237
7469
  }
7238
7470
  if (typeof ast.value === "string" || typeof ast.value === "number" || typeof ast.value === "boolean") {
7239
- return Schema8.Literal(ast.value);
7471
+ return Schema10.Literal(ast.value);
7240
7472
  }
7241
7473
  return runtimeSchemaForDbType(state.dbType);
7242
7474
  case "cast":
@@ -7272,7 +7504,7 @@ var deriveRuntimeSchema = (expression, context) => {
7272
7504
  case "jsonHasAllKeys":
7273
7505
  case "jsonPathExists":
7274
7506
  case "jsonPathMatch":
7275
- return Schema8.Boolean;
7507
+ return Schema10.Boolean;
7276
7508
  case "upper":
7277
7509
  case "lower":
7278
7510
  case "concat":
@@ -7281,8 +7513,9 @@ var deriveRuntimeSchema = (expression, context) => {
7281
7513
  case "jsonAccessText":
7282
7514
  case "jsonTraverseText":
7283
7515
  case "jsonTypeOf":
7284
- return Schema8.String;
7516
+ return Schema10.String;
7285
7517
  case "count":
7518
+ return runtimeSchemaForDbType(state.dbType);
7286
7519
  case "jsonLength":
7287
7520
  return FiniteNumberSchema;
7288
7521
  case "max":
@@ -7297,7 +7530,7 @@ var deriveRuntimeSchema = (expression, context) => {
7297
7530
  return selection === undefined ? undefined : expressionRuntimeSchema(selection, context);
7298
7531
  }
7299
7532
  case "window":
7300
- return ast.function === "over" && ast.value !== undefined ? expressionRuntimeSchema(ast.value, context) : FiniteNumberSchema;
7533
+ return ast.function === "over" && ast.value !== undefined ? expressionRuntimeSchema(ast.value, context) : runtimeSchemaForDbType(state.dbType);
7301
7534
  case "jsonGet":
7302
7535
  case "jsonPath":
7303
7536
  case "jsonAccess":
@@ -7329,23 +7562,102 @@ var deriveRuntimeSchema = (expression, context) => {
7329
7562
  case "jsonToJsonb":
7330
7563
  return jsonCompatibleSchema(expressionRuntimeSchema(ast.value, context));
7331
7564
  case "jsonKeys":
7332
- return Schema8.Array(Schema8.String);
7565
+ return Schema10.Array(Schema10.String);
7333
7566
  }
7334
7567
  };
7335
- var expressionRuntimeSchema = (expression, context) => {
7568
+ var expressionRuntimeSchema = (expression2, context) => {
7336
7569
  if (context !== undefined) {
7337
- return deriveRuntimeSchema(expression, context) ?? runtimeSchemaForDbType(expression[TypeId].dbType);
7570
+ return deriveRuntimeSchema(expression2, context) ?? runtimeSchemaForDbType(expression2[TypeId].dbType);
7338
7571
  }
7339
- const cached = schemaCache.get(expression);
7340
- if (cached !== undefined || schemaCache.has(expression)) {
7572
+ const cached = schemaCache.get(expression2);
7573
+ if (cached !== undefined || schemaCache.has(expression2)) {
7341
7574
  return cached;
7342
7575
  }
7343
- const resolved = deriveRuntimeSchema(expression) ?? runtimeSchemaForDbType(expression[TypeId].dbType);
7344
- schemaCache.set(expression, resolved);
7576
+ const resolved = deriveRuntimeSchema(expression2) ?? runtimeSchemaForDbType(expression2[TypeId].dbType);
7577
+ schemaCache.set(expression2, resolved);
7345
7578
  return resolved;
7346
7579
  };
7347
7580
 
7581
+ // src/internal/renderer.ts
7582
+ var TypeId10 = Symbol.for("effect-qb/Renderer");
7583
+ var projectionPathKey = (path2) => JSON.stringify(path2);
7584
+ var formatProjectionPath2 = (path2) => path2.join(".");
7585
+ var validateProjectionPathsMatchSelection = (plan, projections) => {
7586
+ const expected = flattenSelection(getAst(plan).select);
7587
+ const expectedPaths = new Set(expected.map((projection) => projectionPathKey(projection.path)));
7588
+ const actualPaths = new Set(projections.map((projection) => projectionPathKey(projection.path)));
7589
+ for (const projection of projections) {
7590
+ if (!expectedPaths.has(projectionPathKey(projection.path))) {
7591
+ throw new Error(`Projection path ${formatProjectionPath2(projection.path)} does not exist in the query selection`);
7592
+ }
7593
+ }
7594
+ for (const projection of expected) {
7595
+ if (!actualPaths.has(projectionPathKey(projection.path))) {
7596
+ throw new Error(`Projection path ${formatProjectionPath2(projection.path)} is missing from rendered projections`);
7597
+ }
7598
+ }
7599
+ };
7600
+ function makeTrusted(dialect, render2) {
7601
+ return makeRenderer(dialect, render2, false);
7602
+ }
7603
+ var makeRenderer = (dialect, render2, validate) => {
7604
+ if (typeof render2 !== "function") {
7605
+ throw new Error(`Renderer.make requires an explicit render implementation for dialect: ${dialect}`);
7606
+ }
7607
+ return {
7608
+ dialect,
7609
+ render(plan) {
7610
+ const rendered = render2(plan);
7611
+ const projections = rendered.projections ?? [];
7612
+ if (validate) {
7613
+ validateProjections(projections);
7614
+ validateProjectionPathsMatchSelection(plan, projections);
7615
+ }
7616
+ return {
7617
+ sql: rendered.sql,
7618
+ params: rendered.params ?? [],
7619
+ projections,
7620
+ valueMappings: rendered.valueMappings,
7621
+ dialect,
7622
+ [TypeId10]: {
7623
+ row: undefined,
7624
+ dialect
7625
+ }
7626
+ };
7627
+ }
7628
+ };
7629
+ };
7630
+
7348
7631
  // src/internal/executor.ts
7632
+ var atMostOne = (self) => Effect.flatMap(self, (rows) => rows.length <= 1 ? Effect.succeed(rows.length === 0 ? Option.none() : Option.some(rows[0])) : Effect.fail({
7633
+ _tag: "ResultCardinalityError",
7634
+ expected: "zeroOrOne",
7635
+ actual: rows.length
7636
+ }));
7637
+ var exactlyOne = (self) => Effect.flatMap(self, (rows) => rows.length === 1 ? Effect.succeed(rows[0]) : Effect.fail({
7638
+ _tag: "ResultCardinalityError",
7639
+ expected: "exactlyOne",
7640
+ actual: rows.length
7641
+ }));
7642
+ var nonEmpty = (self) => Effect.flatMap(self, (rows) => rows.length > 0 ? Effect.succeed(rows) : Effect.fail({
7643
+ _tag: "ResultCardinalityError",
7644
+ expected: "nonEmpty",
7645
+ actual: 0
7646
+ }));
7647
+ var withResultContracts = (base) => {
7648
+ const executeResult = base.executeResult ?? ((plan) => Effect.map(base.execute(plan), (rows) => ({ rows })));
7649
+ return {
7650
+ ...base,
7651
+ executeResult,
7652
+ prepare(plan) {
7653
+ return {
7654
+ execute: base.execute(plan),
7655
+ executeResult: executeResult(plan),
7656
+ stream: base.stream(plan)
7657
+ };
7658
+ }
7659
+ };
7660
+ };
7349
7661
  var setPath2 = (target, path2, value) => {
7350
7662
  let current = target;
7351
7663
  for (let index5 = 0;index5 < path2.length - 1; index5++) {
@@ -7399,8 +7711,8 @@ var remapRows = (query, rows) => rows.map((row) => {
7399
7711
  }
7400
7712
  return decoded;
7401
7713
  });
7402
- var makeRowDecodeError = (rendered, projection, expression, raw, stage, cause, normalized) => {
7403
- const schemaError = Schema9.isSchemaError(cause) ? {
7714
+ var makeRowDecodeError = (rendered, projection, expression2, raw, stage, cause, normalized) => {
7715
+ const schemaError = Schema11.isSchemaError(cause) ? {
7404
7716
  message: cause.message,
7405
7717
  issue: cause.issue
7406
7718
  } : undefined;
@@ -7416,7 +7728,7 @@ var makeRowDecodeError = (rendered, projection, expression, raw, stage, cause, n
7416
7728
  alias: projection.alias,
7417
7729
  path: projection.path
7418
7730
  },
7419
- dbType: expression[TypeId].dbType,
7731
+ dbType: expression2[TypeId].dbType,
7420
7732
  raw,
7421
7733
  normalized,
7422
7734
  stage,
@@ -7424,13 +7736,13 @@ var makeRowDecodeError = (rendered, projection, expression, raw, stage, cause, n
7424
7736
  ...schemaError === undefined ? {} : { schemaError }
7425
7737
  };
7426
7738
  };
7427
- var hasOptionalSourceDependency = (expression, scope) => {
7428
- const state = expression[TypeId];
7739
+ var hasOptionalSourceDependency = (expression2, scope) => {
7740
+ const state = expression2[TypeId];
7429
7741
  return Object.keys(state.dependencies).some((sourceName) => !scope.absentSourceNames.has(sourceName) && scope.sourceModes.get(sourceName) === "optional");
7430
7742
  };
7431
- var effectiveRuntimeNullability = (expression, scope) => {
7432
- const nullability = expression[TypeId].nullability;
7433
- const ast = expression[TypeId2];
7743
+ var effectiveRuntimeNullability = (expression2, scope) => {
7744
+ const nullability = expression2[TypeId].nullability;
7745
+ const ast = expression2[TypeId2];
7434
7746
  if (nullability === "always") {
7435
7747
  return "always";
7436
7748
  }
@@ -7443,10 +7755,10 @@ var effectiveRuntimeNullability = (expression, scope) => {
7443
7755
  return "never";
7444
7756
  }
7445
7757
  }
7446
- if (Object.keys(expression[TypeId].dependencies).some((sourceName) => scope.absentSourceNames.has(sourceName))) {
7758
+ if (Object.keys(expression2[TypeId].dependencies).some((sourceName) => scope.absentSourceNames.has(sourceName))) {
7447
7759
  return "always";
7448
7760
  }
7449
- return hasOptionalSourceDependency(expression, scope) ? "maybe" : nullability;
7761
+ return hasOptionalSourceDependency(expression2, scope) ? "maybe" : nullability;
7450
7762
  };
7451
7763
  var dbTypeAllowsTopLevelJsonNull = (dbType) => {
7452
7764
  if ("base" in dbType) {
@@ -7454,46 +7766,46 @@ var dbTypeAllowsTopLevelJsonNull = (dbType) => {
7454
7766
  }
7455
7767
  return "variant" in dbType && dbType.variant === "json" || dbType.runtime === "json";
7456
7768
  };
7457
- var schemaAcceptsNull = (schema3) => schema3 !== undefined && Schema9.is(schema3)(null);
7458
- var decodeProjectionValue = (rendered, projection, expression, raw, scope, driverMode, valueMappings) => {
7769
+ var schemaAcceptsNull = (schema3) => schema3 !== undefined && Schema11.is(schema3)(null);
7770
+ var decodeProjectionValue = (rendered, projection, expression2, raw, scope, driverMode, valueMappings) => {
7459
7771
  let normalized = raw;
7460
7772
  if (driverMode === "raw") {
7461
7773
  try {
7462
7774
  normalized = fromDriverValue(raw, {
7463
7775
  dialect: rendered.dialect,
7464
- dbType: expression[TypeId].dbType,
7465
- runtimeSchema: expression[TypeId].runtimeSchema,
7466
- driverValueMapping: expression[TypeId].driverValueMapping,
7776
+ dbType: expression2[TypeId].dbType,
7777
+ runtimeSchema: expression2[TypeId].runtimeSchema,
7778
+ driverValueMapping: expression2[TypeId].driverValueMapping,
7467
7779
  valueMappings
7468
7780
  });
7469
7781
  } catch (cause2) {
7470
- throw makeRowDecodeError(rendered, projection, expression, raw, "normalize", cause2);
7782
+ throw makeRowDecodeError(rendered, projection, expression2, raw, "normalize", cause2);
7471
7783
  }
7472
7784
  }
7473
- const nullability = effectiveRuntimeNullability(expression, scope);
7474
- const schema3 = expressionRuntimeSchema(expression, { assumptions: scope.assumptions });
7785
+ const nullability = effectiveRuntimeNullability(expression2, scope);
7786
+ const schema3 = expressionRuntimeSchema(expression2, { assumptions: scope.assumptions });
7475
7787
  if (normalized === null) {
7476
7788
  if (nullability === "never") {
7477
- if (dbTypeAllowsTopLevelJsonNull(expression[TypeId].dbType) && schemaAcceptsNull(schema3)) {
7789
+ if (dbTypeAllowsTopLevelJsonNull(expression2[TypeId].dbType) && schemaAcceptsNull(schema3)) {
7478
7790
  return null;
7479
7791
  }
7480
- throw makeRowDecodeError(rendered, projection, expression, raw, "schema", new Error("Received null for a non-null projection"), normalized);
7792
+ throw makeRowDecodeError(rendered, projection, expression2, raw, "schema", new Error("Received null for a non-null projection"), normalized);
7481
7793
  }
7482
7794
  return null;
7483
7795
  }
7484
7796
  if (nullability === "always") {
7485
- throw makeRowDecodeError(rendered, projection, expression, raw, "schema", new Error("Received non-null for an always-null projection"), normalized);
7797
+ throw makeRowDecodeError(rendered, projection, expression2, raw, "schema", new Error("Received non-null for an always-null projection"), normalized);
7486
7798
  }
7487
- if (dbTypeAllowsTopLevelJsonNull(expression[TypeId].dbType) && !isJsonValue(normalized)) {
7488
- throw makeRowDecodeError(rendered, projection, expression, raw, "schema", new Error("Expected a JSON value"), normalized);
7799
+ if (dbTypeAllowsTopLevelJsonNull(expression2[TypeId].dbType) && !isJsonValue(normalized)) {
7800
+ throw makeRowDecodeError(rendered, projection, expression2, raw, "schema", new Error("Expected a JSON value"), normalized);
7489
7801
  }
7490
7802
  if (schema3 === undefined) {
7491
7803
  return normalized;
7492
7804
  }
7493
- if (Schema9.is(schema3)(normalized)) {
7805
+ if (Schema11.is(schema3)(normalized)) {
7494
7806
  return normalized;
7495
7807
  }
7496
- const decoded = Schema9.decodeUnknownExit(schema3)(normalized);
7808
+ const decoded = Schema11.decodeUnknownExit(schema3)(normalized);
7497
7809
  if (Exit.isSuccess(decoded)) {
7498
7810
  return decoded.value;
7499
7811
  }
@@ -7501,7 +7813,7 @@ var decodeProjectionValue = (rendered, projection, expression, raw, scope, drive
7501
7813
  onNone: () => decoded.cause,
7502
7814
  onSome: (schemaError) => schemaError
7503
7815
  });
7504
- throw makeRowDecodeError(rendered, projection, expression, raw, "schema", cause, normalized);
7816
+ throw makeRowDecodeError(rendered, projection, expression2, raw, "schema", cause, normalized);
7505
7817
  };
7506
7818
  var makeRowDecoder = (rendered, plan, options2 = {}) => {
7507
7819
  const projections = flattenSelection(getAst(plan).select);
@@ -7512,14 +7824,14 @@ var makeRowDecoder = (rendered, plan, options2 = {}) => {
7512
7824
  return (row) => {
7513
7825
  const decoded = {};
7514
7826
  for (const projection of rendered.projections) {
7515
- const expression = byPath.get(JSON.stringify(projection.path));
7516
- if (expression === undefined) {
7827
+ const expression2 = byPath.get(JSON.stringify(projection.path));
7828
+ if (expression2 === undefined) {
7517
7829
  throw new Error(`Rendered projection path '${projection.path.join(".")}' does not exist in the query selection`);
7518
7830
  }
7519
7831
  if (!(projection.alias in row)) {
7520
- throw makeRowDecodeError(rendered, projection, expression, undefined, "schema", new Error(`Missing required projection alias '${projection.alias}'`));
7832
+ throw makeRowDecodeError(rendered, projection, expression2, undefined, "schema", new Error(`Missing required projection alias '${projection.alias}'`));
7521
7833
  }
7522
- setPath2(decoded, projection.path, decodeProjectionValue(rendered, projection, expression, row[projection.alias], scope, driverMode, valueMappings));
7834
+ setPath2(decoded, projection.path, decodeProjectionValue(rendered, projection, expression2, row[projection.alias], scope, driverMode, valueMappings));
7523
7835
  }
7524
7836
  return decoded;
7525
7837
  };
@@ -7532,7 +7844,7 @@ var decodeRows = (rendered, plan, rows, options2 = {}) => {
7532
7844
  const decodeRow = makeRowDecoder(rendered, plan, options2);
7533
7845
  return rows.map((row) => decodeRow(row));
7534
7846
  };
7535
- var make3 = (dialect, execute) => ({
7847
+ var make3 = (dialect, execute) => withResultContracts({
7536
7848
  dialect,
7537
7849
  execute(plan) {
7538
7850
  return execute(plan);
@@ -7552,23 +7864,81 @@ function driver(dialect, executeOrHandlers) {
7552
7864
  return Stream.unwrap(Effect.map(executeOrHandlers(query), (rows) => Stream.fromIterable(rows)));
7553
7865
  }
7554
7866
  return executeOrHandlers.stream(query);
7555
- }
7867
+ },
7868
+ ...typeof executeOrHandlers === "function" || executeOrHandlers.executeResult === undefined ? {} : { executeResult: executeOrHandlers.executeResult }
7556
7869
  };
7557
7870
  }
7558
7871
  var fromDriver = (renderer, sqlDriver) => {
7559
- const executor = {
7872
+ const renderedCache = new WeakMap;
7873
+ const render2 = (plan) => {
7874
+ const cached = renderedCache.get(plan);
7875
+ if (cached !== undefined) {
7876
+ return cached;
7877
+ }
7878
+ const rendered = renderer.render(plan);
7879
+ renderedCache.set(plan, rendered);
7880
+ return rendered;
7881
+ };
7882
+ const executor = withResultContracts({
7560
7883
  dialect: renderer.dialect,
7561
7884
  execute(plan) {
7562
- const rendered = renderer.render(plan);
7885
+ const rendered = render2(plan);
7563
7886
  return Effect.map(sqlDriver.execute(rendered), (rows) => remapRows(rendered, rows));
7564
7887
  },
7888
+ executeResult(plan) {
7889
+ const rendered = render2(plan);
7890
+ const result = sqlDriver.executeResult ? sqlDriver.executeResult(rendered) : Effect.map(sqlDriver.execute(rendered), (rows) => ({ rows }));
7891
+ return Effect.map(result, ({ rows, ...metadata }) => ({
7892
+ ...metadata,
7893
+ rows: remapRows(rendered, rows)
7894
+ }));
7895
+ },
7565
7896
  stream(plan) {
7566
- const rendered = renderer.render(plan);
7897
+ const rendered = render2(plan);
7567
7898
  return Stream.mapArray(sqlDriver.stream(rendered), (rows) => remapRows(rendered, rows));
7568
7899
  }
7569
- };
7900
+ });
7570
7901
  return executor;
7571
7902
  };
7903
+ var explainQuery = (query, options2 = {}) => {
7904
+ const analyze = options2.analyze ?? false;
7905
+ const format = options2.format ?? "text";
7906
+ let prefix;
7907
+ switch (query.dialect) {
7908
+ case "postgres":
7909
+ prefix = `explain (${[
7910
+ ...analyze ? ["analyze true"] : [],
7911
+ `format ${format}`
7912
+ ].join(", ")}) `;
7913
+ break;
7914
+ case "mysql":
7915
+ if (analyze && format === "json") {
7916
+ throw new Error("MySQL EXPLAIN ANALYZE cannot be combined with JSON format");
7917
+ }
7918
+ prefix = analyze ? "explain analyze " : format === "json" ? "explain format=json " : "explain ";
7919
+ break;
7920
+ case "sqlite":
7921
+ if (analyze || format === "json") {
7922
+ throw new Error("SQLite EXPLAIN QUERY PLAN does not support analyze or JSON format");
7923
+ }
7924
+ prefix = "explain query plan ";
7925
+ break;
7926
+ default:
7927
+ if (analyze || format === "json") {
7928
+ throw new Error("Portable EXPLAIN only supports text plans without analyze");
7929
+ }
7930
+ prefix = "explain ";
7931
+ }
7932
+ return {
7933
+ ...query,
7934
+ sql: prefix + query.sql,
7935
+ projections: [],
7936
+ [TypeId10]: {
7937
+ row: undefined,
7938
+ dialect: query.dialect
7939
+ }
7940
+ };
7941
+ };
7572
7942
  var streamFromSqlClient = (query) => Stream.unwrap(Effect.flatMap(SqlClient.SqlClient, (sql) => Effect.flatMap(Effect.serviceOption(sql.transactionService), Option.match({
7573
7943
  onNone: () => sql.reserve,
7574
7944
  onSome: ([connection]) => Effect.succeed(connection)
@@ -7593,11 +7963,11 @@ __export(exports_table2, {
7593
7963
  foreignKey: () => foreignKey3,
7594
7964
  check: () => check3,
7595
7965
  alias: () => alias2,
7596
- TypeId: () => TypeId10,
7966
+ TypeId: () => TypeId11,
7597
7967
  OptionsSymbol: () => OptionsSymbol2,
7598
7968
  Class: () => Class2
7599
7969
  });
7600
- var TypeId10 = TypeId7;
7970
+ var TypeId11 = TypeId7;
7601
7971
  var OptionsSymbol2 = OptionsSymbol;
7602
7972
  var options2 = options;
7603
7973
  var option2 = option;
@@ -7683,68 +8053,18 @@ var named5 = (name) => (option3) => mapOption(option3, (spec) => ({
7683
8053
  name
7684
8054
  }));
7685
8055
  // src/standard/renderer.ts
7686
- var exports_renderer = {};
7687
- __export(exports_renderer, {
8056
+ var exports_renderer2 = {};
8057
+ __export(exports_renderer2, {
7688
8058
  make: () => make10
7689
8059
  });
7690
8060
  import { pipeArguments as pipeArguments8 } from "effect/Pipeable";
7691
8061
 
7692
- // src/internal/renderer.ts
7693
- var TypeId11 = Symbol.for("effect-qb/Renderer");
7694
- var projectionPathKey = (path2) => JSON.stringify(path2);
7695
- var formatProjectionPath2 = (path2) => path2.join(".");
7696
- var validateProjectionPathsMatchSelection = (plan, projections) => {
7697
- const expected = flattenSelection(getAst(plan).select);
7698
- const expectedPaths = new Set(expected.map((projection) => projectionPathKey(projection.path)));
7699
- const actualPaths = new Set(projections.map((projection) => projectionPathKey(projection.path)));
7700
- for (const projection of projections) {
7701
- if (!expectedPaths.has(projectionPathKey(projection.path))) {
7702
- throw new Error(`Projection path ${formatProjectionPath2(projection.path)} does not exist in the query selection`);
7703
- }
7704
- }
7705
- for (const projection of expected) {
7706
- if (!actualPaths.has(projectionPathKey(projection.path))) {
7707
- throw new Error(`Projection path ${formatProjectionPath2(projection.path)} is missing from rendered projections`);
7708
- }
7709
- }
7710
- };
7711
- function makeTrusted(dialect, render2) {
7712
- return makeRenderer(dialect, render2, false);
7713
- }
7714
- var makeRenderer = (dialect, render2, validate) => {
7715
- if (typeof render2 !== "function") {
7716
- throw new Error(`Renderer.make requires an explicit render implementation for dialect: ${dialect}`);
7717
- }
7718
- return {
7719
- dialect,
7720
- render(plan) {
7721
- const rendered = render2(plan);
7722
- const projections = rendered.projections ?? [];
7723
- if (validate) {
7724
- validateProjections(projections);
7725
- validateProjectionPathsMatchSelection(plan, projections);
7726
- }
7727
- return {
7728
- sql: rendered.sql,
7729
- params: rendered.params ?? [],
7730
- projections,
7731
- valueMappings: rendered.valueMappings,
7732
- dialect,
7733
- [TypeId11]: {
7734
- row: undefined,
7735
- dialect
7736
- }
7737
- };
7738
- }
7739
- };
7740
- };
7741
-
7742
8062
  // src/internal/sql-expression-renderer.ts
7743
8063
  var renderQueryAst = (ast, state, dialect) => {
7744
8064
  return dialect.renderQueryAst(ast, state, dialect);
7745
8065
  };
7746
- var renderExpression = (expression, state, dialect) => {
7747
- return dialect.renderExpression(expression, state, dialect);
8066
+ var renderExpression = (expression2, state, dialect) => {
8067
+ return dialect.renderExpression(expression2, state, dialect);
7748
8068
  };
7749
8069
 
7750
8070
  // src/internal/dialect.ts
@@ -7757,7 +8077,36 @@ var quoteBacktickIdentifier = (value) => {
7757
8077
  var renderDbTypeName = (value) => value;
7758
8078
 
7759
8079
  // src/internal/dialect-renderers/postgres.ts
7760
- import * as Schema10 from "effect/Schema";
8080
+ import * as Schema12 from "effect/Schema";
8081
+
8082
+ // src/internal/custom-sql-renderer.ts
8083
+ var renderCustomSql = (node, state, dialect, renderExpression2) => node.strings.map((part, index6) => {
8084
+ const value = node.values[index6];
8085
+ if (value === undefined) {
8086
+ return part;
8087
+ }
8088
+ return part + (TypeId in value ? renderExpression2(value, state, dialect) : value.parts.map((segment) => dialect.quoteIdentifier(segment)).join("."));
8089
+ }).join("");
8090
+
8091
+ // src/internal/window-renderer.ts
8092
+ var renderBoundary = (boundary) => {
8093
+ if (boundary === "unboundedPreceding") {
8094
+ return "unbounded preceding";
8095
+ }
8096
+ if (boundary === "currentRow") {
8097
+ return "current row";
8098
+ }
8099
+ if (boundary === "unboundedFollowing") {
8100
+ return "unbounded following";
8101
+ }
8102
+ if ("preceding" in boundary) {
8103
+ return `${boundary.preceding} preceding`;
8104
+ }
8105
+ return `${boundary.following} following`;
8106
+ };
8107
+ var renderWindowFrame = (frame) => frame.end === undefined ? `${frame.unit} ${renderBoundary(frame.start)}` : `${frame.unit} between ${renderBoundary(frame.start)} and ${renderBoundary(frame.end)}`;
8108
+
8109
+ // src/internal/dialect-renderers/postgres.ts
7761
8110
  var renderDbType = (dialect, dbType) => {
7762
8111
  return renderDbTypeName(renderPortableDatatypeDdlType(dialect.name, dbType.kind) ?? dbType.kind);
7763
8112
  };
@@ -7898,11 +8247,11 @@ var renderPostgresDdlLiteral = (value, state, context = {}) => {
7898
8247
  }
7899
8248
  throw new Error("Unsupported postgres DDL literal value");
7900
8249
  };
7901
- var renderDdlExpression = (expression, state, dialect) => {
7902
- if (isSchemaExpression(expression)) {
7903
- return render(expression);
8250
+ var renderDdlExpression = (expression2, state, dialect) => {
8251
+ if (isSchemaExpression(expression2)) {
8252
+ return render(expression2);
7904
8253
  }
7905
- return renderExpression2(expression, state, {
8254
+ return renderExpression2(expression2, state, {
7906
8255
  ...dialect,
7907
8256
  renderLiteral: renderPostgresDdlLiteral
7908
8257
  });
@@ -8031,6 +8380,15 @@ var renderBinaryExpression = (functionName, operator, left, right, state, dialec
8031
8380
  const [leftExpression, rightExpression] = expectBinaryExpressions(functionName, left, right);
8032
8381
  return `(${renderExpression2(leftExpression, state, dialect)} ${operator} ${renderExpression2(rightExpression, state, dialect)})`;
8033
8382
  };
8383
+ var renderNumericExpression = (expression2, state, dialect) => {
8384
+ const rendered = renderExpression2(expression2, state, dialect);
8385
+ const ast = expression2[TypeId2];
8386
+ return dialect.name === "postgres" && ast.kind === "literal" ? `cast(${rendered} as ${renderCastType(dialect, expression2[TypeId].dbType)})` : rendered;
8387
+ };
8388
+ var renderNumericBinaryExpression = (functionName, operator, left, right, state, dialect) => {
8389
+ const [leftExpression, rightExpression] = expectBinaryExpressions(functionName, left, right);
8390
+ return `(${renderNumericExpression(leftExpression, state, dialect)} ${operator} ${renderNumericExpression(rightExpression, state, dialect)})`;
8391
+ };
8034
8392
  var postgresRangeSubtypeByKind = {
8035
8393
  int4range: "int4",
8036
8394
  int8range: "int8",
@@ -8211,21 +8569,21 @@ var renderPostgresJsonValue = (value, state, dialect) => {
8211
8569
  }
8212
8570
  return value[TypeId].dbType.kind === "jsonb" ? rendered : `cast(${rendered} as jsonb)`;
8213
8571
  };
8214
- var expressionDriverContext = (expression, state, dialect) => ({
8572
+ var expressionDriverContext = (expression2, state, dialect) => ({
8215
8573
  dialect: dialect.name,
8216
8574
  valueMappings: state.valueMappings,
8217
- dbType: expression[TypeId].dbType,
8218
- runtimeSchema: expression[TypeId].runtimeSchema,
8219
- driverValueMapping: expression[TypeId].driverValueMapping
8575
+ dbType: expression2[TypeId].dbType,
8576
+ runtimeSchema: expression2[TypeId].runtimeSchema,
8577
+ driverValueMapping: expression2[TypeId].driverValueMapping
8220
8578
  });
8221
- var renderJsonInputExpression = (expression, state, dialect) => renderJsonSelectSql(renderExpression2(expression, state, dialect), expressionDriverContext(expression, state, dialect));
8579
+ var renderJsonInputExpression = (expression2, state, dialect) => renderJsonSelectSql(renderExpression2(expression2, state, dialect), expressionDriverContext(expression2, state, dialect));
8222
8580
  var encodeArrayValues = (values2, column2, state, dialect) => values2.map((value) => {
8223
8581
  if (value === null && column2.metadata.nullable) {
8224
8582
  return null;
8225
8583
  }
8226
- const runtimeSchemaAccepts = column2.schema !== undefined && Schema10.is(column2.schema)(value);
8584
+ const runtimeSchemaAccepts = column2.schema !== undefined && Schema12.is(column2.schema)(value);
8227
8585
  const normalizedValue = runtimeSchemaAccepts ? value : normalizeDbValue(column2.metadata.dbType, value);
8228
- const encodedValue = column2.schema === undefined || runtimeSchemaAccepts ? normalizedValue : Schema10.decodeUnknownSync(column2.schema)(normalizedValue);
8586
+ const encodedValue = column2.schema === undefined || runtimeSchemaAccepts ? normalizedValue : Schema12.decodeUnknownSync(column2.schema)(normalizedValue);
8229
8587
  return toDriverValue(encodedValue, {
8230
8588
  dialect: dialect.name,
8231
8589
  valueMappings: state.valueMappings,
@@ -8287,7 +8645,7 @@ var renderFunctionCall = (name, args, state, dialect) => {
8287
8645
  }
8288
8646
  return `${functionName}(${renderedArgs})`;
8289
8647
  };
8290
- var renderJsonExpression = (expression, ast, state, dialect) => {
8648
+ var renderJsonExpression = (expression2, ast, state, dialect) => {
8291
8649
  const kind = typeof ast.kind === "string" ? ast.kind : undefined;
8292
8650
  if (!kind) {
8293
8651
  return;
@@ -8295,7 +8653,7 @@ var renderJsonExpression = (expression, ast, state, dialect) => {
8295
8653
  const base = extractJsonBase(ast);
8296
8654
  const segments = extractJsonPathSegments(ast);
8297
8655
  const exact = segments.every((segment) => segment.kind === "key" || segment.kind === "index");
8298
- const postgresExpressionKind = dialect.name === "postgres" && isJsonExpression2(expression) ? renderPostgresJsonKind(expression) : undefined;
8656
+ const postgresExpressionKind = dialect.name === "postgres" && isJsonExpression2(expression2) ? renderPostgresJsonKind(expression2) : undefined;
8299
8657
  const postgresBaseKind = dialect.name === "postgres" && isJsonExpression2(base) ? renderPostgresJsonKind(base) : undefined;
8300
8658
  switch (kind) {
8301
8659
  case "jsonGet":
@@ -8596,7 +8954,7 @@ var renderTransactionClause = (clause, dialect) => {
8596
8954
  var renderSelectionList = (selection, state, dialect) => {
8597
8955
  const flattened = flattenSelection(selection);
8598
8956
  const projections = selectionProjections(selection);
8599
- const sql = flattened.map(({ expression, alias: alias3 }) => `${renderSelectSql(renderExpression2(expression, state, dialect), expressionDriverContext(expression, state, dialect))} as ${dialect.quoteIdentifier(alias3)}`).join(", ");
8957
+ const sql = flattened.map(({ expression: expression2, alias: alias3 }) => `${renderSelectSql(renderExpression2(expression2, state, dialect), expressionDriverContext(expression2, state, dialect))} as ${dialect.quoteIdentifier(alias3)}`).join(", ");
8600
8958
  return {
8601
8959
  sql,
8602
8960
  projections
@@ -9028,9 +9386,9 @@ var renderSubqueryExpressionPlan = (plan, state, dialect) => {
9028
9386
  }
9029
9387
  return renderQueryAst2(getAst(plan), state, dialect).sql;
9030
9388
  };
9031
- var renderExpression2 = (expression, state, dialect) => {
9032
- const rawAst = expression[TypeId2];
9033
- const jsonSql = renderJsonExpression(expression, rawAst, state, dialect);
9389
+ var renderExpression2 = (expression2, state, dialect) => {
9390
+ const rawAst = expression2[TypeId2];
9391
+ const jsonSql = renderJsonExpression(expression2, rawAst, state, dialect);
9034
9392
  if (jsonSql !== undefined) {
9035
9393
  return jsonSql;
9036
9394
  }
@@ -9053,7 +9411,7 @@ var renderExpression2 = (expression, state, dialect) => {
9053
9411
  if (typeof ast.value === "number" && !Number.isFinite(ast.value)) {
9054
9412
  throw new Error("Expected a finite numeric value");
9055
9413
  }
9056
- return dialect.renderLiteral(ast.value, state, expression[TypeId]);
9414
+ return dialect.renderLiteral(ast.value, state, expression2[TypeId]);
9057
9415
  case "excluded":
9058
9416
  if (state.allowExcluded !== true) {
9059
9417
  throw new Error("excluded(...) is only supported inside insert conflict handlers");
@@ -9065,6 +9423,8 @@ var renderExpression2 = (expression, state, dialect) => {
9065
9423
  return `(${renderExpression2(expectValueExpression("collate", ast.value), state, dialect)} collate ${renderCollation(ast.collation)})`;
9066
9424
  case "function":
9067
9425
  return renderFunctionCall(ast.name, ast.args, state, dialect);
9426
+ case "customSql":
9427
+ return renderCustomSql(ast, state, dialect, renderExpression2);
9068
9428
  case "eq":
9069
9429
  return renderBinaryExpression("eq", "=", ast.left, ast.right, state, dialect);
9070
9430
  case "neq":
@@ -9077,6 +9437,16 @@ var renderExpression2 = (expression, state, dialect) => {
9077
9437
  return renderBinaryExpression("gt", ">", ast.left, ast.right, state, dialect);
9078
9438
  case "gte":
9079
9439
  return renderBinaryExpression("gte", ">=", ast.left, ast.right, state, dialect);
9440
+ case "add":
9441
+ return renderNumericBinaryExpression("add", "+", ast.left, ast.right, state, dialect);
9442
+ case "subtract":
9443
+ return renderNumericBinaryExpression("subtract", "-", ast.left, ast.right, state, dialect);
9444
+ case "multiply":
9445
+ return renderNumericBinaryExpression("multiply", "*", ast.left, ast.right, state, dialect);
9446
+ case "divide":
9447
+ return renderNumericBinaryExpression("divide", "/", ast.left, ast.right, state, dialect);
9448
+ case "modulo":
9449
+ return renderNumericBinaryExpression("modulo", "%", ast.left, ast.right, state, dialect);
9080
9450
  case "like":
9081
9451
  return renderBinaryExpression("like", "like", ast.left, ast.right, state, dialect);
9082
9452
  case "ilike": {
@@ -9170,6 +9540,16 @@ var renderExpression2 = (expression, state, dialect) => {
9170
9540
  return `lower(${renderExpression2(expectValueExpression("lower", ast.value), state, dialect)})`;
9171
9541
  case "count":
9172
9542
  return `count(${renderExpression2(expectValueExpression("count", ast.value), state, dialect)})`;
9543
+ case "sum":
9544
+ return `sum(${renderNumericExpression(expectValueExpression("sum", ast.value), state, dialect)})`;
9545
+ case "avg":
9546
+ return `avg(${renderNumericExpression(expectValueExpression("avg", ast.value), state, dialect)})`;
9547
+ case "abs":
9548
+ return `abs(${renderNumericExpression(expectValueExpression("abs", ast.value), state, dialect)})`;
9549
+ case "round":
9550
+ return `round(${renderNumericExpression(expectValueExpression("round", ast.value), state, dialect)})`;
9551
+ case "negate":
9552
+ return `(-${renderNumericExpression(expectValueExpression("negate", ast.value), state, dialect)})`;
9173
9553
  case "max":
9174
9554
  return `max(${renderExpression2(expectValueExpression("max", ast.value), state, dialect)})`;
9175
9555
  case "min":
@@ -9215,23 +9595,43 @@ var renderExpression2 = (expression, state, dialect) => {
9215
9595
  case "window": {
9216
9596
  const partitionBy = ast.partitionBy;
9217
9597
  const orderBy2 = ast.orderBy;
9218
- const clauses = [];
9219
- if (partitionBy.length > 0) {
9220
- clauses.push(`partition by ${partitionBy.map((value) => renderExpression2(value, state, dialect)).join(", ")}`);
9221
- }
9222
- if (orderBy2.length > 0) {
9223
- clauses.push(`order by ${orderBy2.map((entry) => `${renderExpression2(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`);
9224
- }
9225
- const specification = clauses.join(" ");
9598
+ const renderSpecification = () => {
9599
+ const clauses = [];
9600
+ if (partitionBy.length > 0) {
9601
+ clauses.push(`partition by ${partitionBy.map((value) => renderExpression2(value, state, dialect)).join(", ")}`);
9602
+ }
9603
+ if (orderBy2.length > 0) {
9604
+ clauses.push(`order by ${orderBy2.map((entry) => `${renderExpression2(entry.value, state, dialect)} ${entry.direction}`).join(", ")}`);
9605
+ }
9606
+ if (ast.frame !== undefined) {
9607
+ clauses.push(renderWindowFrame(ast.frame));
9608
+ }
9609
+ return clauses.join(" ");
9610
+ };
9226
9611
  switch (ast.function) {
9227
9612
  case "rowNumber":
9228
- return `row_number() over (${specification})`;
9613
+ return `row_number() over (${renderSpecification()})`;
9229
9614
  case "rank":
9230
- return `rank() over (${specification})`;
9615
+ return `rank() over (${renderSpecification()})`;
9231
9616
  case "denseRank":
9232
- return `dense_rank() over (${specification})`;
9617
+ return `dense_rank() over (${renderSpecification()})`;
9233
9618
  case "over":
9234
- return `${renderExpression2(ast.value, state, dialect)} over (${specification})`;
9619
+ return `${renderExpression2(ast.value, state, dialect)} over (${renderSpecification()})`;
9620
+ case "lag":
9621
+ case "lead": {
9622
+ const args = [renderExpression2(ast.value, state, dialect)];
9623
+ if (ast.offset !== undefined) {
9624
+ args.push(renderExpression2(ast.offset, state, dialect));
9625
+ }
9626
+ if (ast.defaultValue !== undefined) {
9627
+ args.push(renderExpression2(ast.defaultValue, state, dialect));
9628
+ }
9629
+ return `${ast.function}(${args.join(", ")}) over (${renderSpecification()})`;
9630
+ }
9631
+ case "firstValue":
9632
+ return `first_value(${renderExpression2(ast.value, state, dialect)}) over (${renderSpecification()})`;
9633
+ case "lastValue":
9634
+ return `last_value(${renderExpression2(ast.value, state, dialect)}) over (${renderSpecification()})`;
9235
9635
  }
9236
9636
  break;
9237
9637
  }
@@ -9357,15 +9757,17 @@ var applyCategory2 = applyCategory;
9357
9757
  var merge4 = merge;
9358
9758
  export {
9359
9759
  exports_unique as Unique,
9760
+ type2 as Type,
9360
9761
  exports_table2 as Table,
9361
9762
  exports_scalar as Scalar,
9362
9763
  exports_row_set as RowSet,
9363
- exports_renderer as Renderer,
9764
+ exports_renderer2 as Renderer,
9364
9765
  exports_query as Query,
9365
9766
  exports_primary_key as PrimaryKey,
9366
9767
  exports_json as Json,
9367
9768
  exports_standard as Index,
9368
9769
  exports_function as Function,
9770
+ exports_fragment as Fragment,
9369
9771
  exports_foreign_key as ForeignKey,
9370
9772
  exports_executor as Executor,
9371
9773
  exports_datatypes as Datatypes,