effect-qb 0.16.0 → 0.19.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 (128) hide show
  1. package/README.md +4 -0
  2. package/dist/index.js +8065 -0
  3. package/dist/mysql.js +4036 -2418
  4. package/dist/postgres/metadata.js +2536 -625
  5. package/dist/postgres.js +8248 -7857
  6. package/dist/sqlite.js +8854 -0
  7. package/dist/standard.js +8019 -0
  8. package/package.json +15 -3
  9. package/src/casing.ts +71 -0
  10. package/src/index.ts +2 -0
  11. package/src/internal/casing.ts +89 -0
  12. package/src/internal/column-state.ts +11 -6
  13. package/src/internal/column.ts +44 -7
  14. package/src/internal/datatypes/define.ts +2 -1
  15. package/src/internal/datatypes/enrich.ts +23 -0
  16. package/src/internal/datatypes/lookup.ts +14 -7
  17. package/src/internal/derived-table.ts +7 -13
  18. package/src/internal/dialect-renderers/mysql.ts +2046 -0
  19. package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +867 -283
  20. package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +834 -358
  21. package/src/internal/dialect.ts +37 -0
  22. package/src/internal/dsl-mutation-runtime.ts +29 -10
  23. package/src/internal/dsl-plan-runtime.ts +41 -24
  24. package/src/internal/dsl-query-runtime.ts +11 -31
  25. package/src/internal/dsl-transaction-ddl-runtime.ts +61 -15
  26. package/src/internal/executor.ts +57 -15
  27. package/src/internal/expression-ast.ts +3 -2
  28. package/src/internal/grouping-key.ts +216 -9
  29. package/src/internal/implication-runtime.ts +3 -2
  30. package/src/internal/json/types.ts +155 -40
  31. package/src/internal/predicate/context.ts +14 -1
  32. package/src/internal/predicate/key.ts +19 -2
  33. package/src/internal/predicate/runtime.ts +30 -3
  34. package/src/internal/query.d.ts +38 -11
  35. package/src/internal/query.ts +315 -54
  36. package/src/internal/renderer.ts +51 -6
  37. package/src/internal/runtime/driver-value-mapping.ts +58 -0
  38. package/src/internal/runtime/normalize.ts +74 -43
  39. package/src/internal/runtime/schema.ts +5 -3
  40. package/src/internal/runtime/value.ts +153 -30
  41. package/src/internal/scalar.ts +6 -1
  42. package/src/internal/schema-derivation.d.ts +12 -61
  43. package/src/internal/schema-derivation.ts +90 -38
  44. package/src/internal/schema-expression.ts +2 -2
  45. package/src/internal/sql-expression-renderer.ts +19 -0
  46. package/src/internal/standard-dsl.ts +6885 -0
  47. package/src/internal/table-options.ts +229 -62
  48. package/src/internal/table.d.ts +33 -32
  49. package/src/internal/table.ts +469 -160
  50. package/src/mysql/column-extension.ts +3 -0
  51. package/src/mysql/column.ts +27 -12
  52. package/src/mysql/datatypes/index.ts +24 -2
  53. package/src/mysql/errors/catalog.ts +5 -5
  54. package/src/mysql/errors/normalize.ts +2 -2
  55. package/src/mysql/executor.ts +7 -5
  56. package/src/mysql/internal/dialect.ts +9 -4
  57. package/src/mysql/internal/dsl.ts +906 -324
  58. package/src/mysql/internal/renderer.ts +7 -2
  59. package/src/mysql/json.ts +37 -0
  60. package/src/mysql/query-extension.ts +16 -0
  61. package/src/mysql/query.ts +9 -2
  62. package/src/mysql/renderer.ts +31 -4
  63. package/src/mysql.ts +4 -12
  64. package/src/postgres/column-extension.ts +28 -0
  65. package/src/postgres/column.ts +9 -13
  66. package/src/postgres/datatypes/index.d.ts +2 -1
  67. package/src/postgres/datatypes/index.ts +3 -2
  68. package/src/postgres/errors/normalize.ts +2 -2
  69. package/src/postgres/executor.ts +55 -10
  70. package/src/postgres/function/core.ts +20 -4
  71. package/src/postgres/function/index.ts +1 -17
  72. package/src/postgres/internal/dialect.ts +9 -4
  73. package/src/postgres/internal/dsl.ts +850 -359
  74. package/src/postgres/internal/renderer.ts +7 -2
  75. package/src/postgres/internal/schema-ddl.ts +22 -9
  76. package/src/postgres/internal/schema-model.ts +244 -10
  77. package/src/postgres/json.ts +100 -24
  78. package/src/postgres/jsonb.ts +38 -0
  79. package/src/postgres/query-extension.ts +2 -0
  80. package/src/postgres/query.ts +9 -2
  81. package/src/postgres/renderer.ts +31 -4
  82. package/src/postgres/schema-management.ts +108 -16
  83. package/src/postgres/schema.ts +98 -15
  84. package/src/postgres/table.ts +203 -398
  85. package/src/postgres/type.ts +8 -7
  86. package/src/postgres.ts +9 -11
  87. package/src/sqlite/column-extension.ts +3 -0
  88. package/src/sqlite/column.ts +127 -0
  89. package/src/sqlite/datatypes/index.ts +80 -0
  90. package/src/sqlite/datatypes/spec.ts +98 -0
  91. package/src/sqlite/errors/catalog.ts +103 -0
  92. package/src/sqlite/errors/fields.ts +19 -0
  93. package/src/sqlite/errors/index.ts +19 -0
  94. package/src/sqlite/errors/normalize.ts +229 -0
  95. package/src/sqlite/errors/requirements.ts +71 -0
  96. package/src/sqlite/errors/types.ts +29 -0
  97. package/src/sqlite/executor.ts +229 -0
  98. package/src/sqlite/function/aggregate.ts +2 -0
  99. package/src/sqlite/function/core.ts +2 -0
  100. package/src/sqlite/function/index.ts +19 -0
  101. package/src/sqlite/function/string.ts +2 -0
  102. package/src/sqlite/function/temporal.ts +100 -0
  103. package/src/sqlite/function/window.ts +2 -0
  104. package/src/sqlite/internal/dialect.ts +42 -0
  105. package/src/sqlite/internal/dsl.ts +6979 -0
  106. package/src/sqlite/internal/renderer.ts +51 -0
  107. package/src/sqlite/json.ts +39 -0
  108. package/src/sqlite/query-extension.ts +2 -0
  109. package/src/sqlite/query.ts +196 -0
  110. package/src/sqlite/renderer.ts +51 -0
  111. package/src/sqlite.ts +14 -0
  112. package/src/standard/column.ts +163 -0
  113. package/src/standard/datatypes/index.ts +83 -0
  114. package/src/standard/datatypes/spec.ts +98 -0
  115. package/src/standard/dialect.ts +40 -0
  116. package/src/standard/function/aggregate.ts +2 -0
  117. package/src/standard/function/core.ts +2 -0
  118. package/src/standard/function/index.ts +18 -0
  119. package/src/standard/function/string.ts +2 -0
  120. package/src/standard/function/temporal.ts +78 -0
  121. package/src/standard/function/window.ts +2 -0
  122. package/src/standard/internal/renderer.ts +45 -0
  123. package/src/standard/query.ts +152 -0
  124. package/src/standard/renderer.ts +21 -0
  125. package/src/standard/table.ts +147 -0
  126. package/src/standard.ts +18 -0
  127. package/src/internal/aggregation-validation.ts +0 -57
  128. package/src/mysql/table.ts +0 -157
@@ -1,9 +1,10 @@
1
1
  import * as Query from "../../internal/query.js"
2
2
  import type * as Expression from "../../internal/scalar.js"
3
+ import type * as Casing from "../../internal/casing.js"
3
4
  import { type RenderState } from "../../internal/dialect.js"
4
5
  import { mysqlDialect } from "./dialect.js"
5
6
  import { type Projection } from "../../internal/projections.js"
6
- import { renderQueryAst } from "./sql-expression-renderer.js"
7
+ import { renderQueryAst } from "../../internal/sql-expression-renderer.js"
7
8
 
8
9
  /**
9
10
  * Internal rendered-query payload produced by the built-in MySQL renderer.
@@ -17,6 +18,7 @@ export interface MysqlRenderResult {
17
18
 
18
19
  export interface MysqlRenderOptions {
19
20
  readonly valueMappings?: Expression.DriverValueMappings
21
+ readonly casing?: Casing.Options
20
22
  }
21
23
 
22
24
  /**
@@ -29,8 +31,11 @@ export const renderMysqlPlan = <PlanValue extends Query.Plan.Any>(
29
31
  const state: RenderState = {
30
32
  params: [],
31
33
  valueMappings: options.valueMappings,
34
+ casing: options.casing,
32
35
  ctes: [],
33
- cteNames: new Set<string>()
36
+ cteNames: new Set<string>(),
37
+ cteSources: new Map<string, unknown>(),
38
+ sourceNames: new Map()
34
39
  }
35
40
  const rendered = renderQueryAst(
36
41
  Query.getAst(plan as Query.Plan.Any) as any,
package/src/mysql/json.ts CHANGED
@@ -1,2 +1,39 @@
1
1
  /** MySQL JSON expression helpers. */
2
2
  export { json } from "./internal/dsl.js"
3
+ import { json } from "./internal/dsl.js"
4
+
5
+ export const key = json.key
6
+ export const index = json.index
7
+ export const wildcard = json.wildcard
8
+ export const slice = json.slice
9
+ export const descend = json.descend
10
+ export const path = json.path
11
+ export const get = json.get
12
+ export const access = json.access
13
+ export const traverse = json.traverse
14
+ export const text = json.text
15
+ export const accessText = json.accessText
16
+ export const traverseText = json.traverseText
17
+ export const contains = json.contains
18
+ export const containedBy = json.containedBy
19
+ export const hasKey = json.hasKey
20
+ export const keyExists = json.keyExists
21
+ export const hasAnyKeys = json.hasAnyKeys
22
+ export const hasAllKeys = json.hasAllKeys
23
+ export const delete_ = json.delete
24
+ export { delete_ as delete }
25
+ export const remove = json.remove
26
+ export const set = json.set
27
+ export const insert = json.insert
28
+ export const concat = json.concat
29
+ export const merge = json.merge
30
+ export const buildObject = json.buildObject
31
+ export const buildArray = json.buildArray
32
+ export const toJson = json.toJson
33
+ export const toJsonb = json.toJsonb
34
+ export const typeOf = json.typeOf
35
+ export const length = json.length
36
+ export const keys = json.keys
37
+ export const stripNulls = json.stripNulls
38
+ export const pathExists = json.pathExists
39
+ export const pathMatch = json.pathMatch
@@ -0,0 +1,16 @@
1
+ import { lock } from "./query.js"
2
+
3
+ /** MySQL-only mutation modifier for UPDATE IGNORE. */
4
+ export const ignore = lock("ignore")
5
+
6
+ /** MySQL-only mutation modifier for DELETE QUICK. */
7
+ export const quick = lock("quick")
8
+
9
+ /** MySQL-only mutation modifier for LOW_PRIORITY mutations. */
10
+ export const lowPriority = lock("lowPriority")
11
+
12
+ /** MySQL-only mutation ordering and limiting. */
13
+ export { orderBy, limit } from "./query.js"
14
+
15
+ /** MySQL-only multi-target mutation forms. */
16
+ export { update, delete } from "./query.js"
@@ -16,7 +16,6 @@ import {
16
16
  type HavingPredicateInput,
17
17
  type OrderDirection,
18
18
  type OutputOfSelection,
19
- type MutationInputOf,
20
19
  type MutationTargetLike,
21
20
  type NumericExpressionInput,
22
21
  type PredicateInput,
@@ -136,8 +135,17 @@ export {
136
135
  orderBy,
137
136
  groupBy
138
137
  } from "./internal/dsl.js"
138
+ import type * as Expression from "../internal/scalar.js"
139
139
  export { mysqlType as type }
140
140
 
141
+ type MysqlMutationValueInput<Value> =
142
+ | Value
143
+ | Expression.Scalar<Value, Expression.DbType.Any, Expression.Nullability, "mysql", Expression.ScalarKind, Expression.BindingId>
144
+
145
+ export type MutationInputOf<Shape> = {
146
+ readonly [K in keyof Shape]: MysqlMutationValueInput<Shape[K]>
147
+ }
148
+
141
149
  type StructuredSource = AnyValuesSource | AnyUnnestSource | AnyTableFunctionSource
142
150
 
143
151
  type StructuredFromApi = <CurrentSource extends StructuredSource>(
@@ -163,7 +171,6 @@ export type {
163
171
  HavingPredicateInput,
164
172
  OrderDirection,
165
173
  OutputOfSelection,
166
- MutationInputOf,
167
174
  MutationTargetLike,
168
175
  NumericExpressionInput,
169
176
  PredicateInput,
@@ -1,5 +1,9 @@
1
+ import { pipeArguments, type Pipeable } from "effect/Pipeable"
2
+
1
3
  import * as CoreRenderer from "../internal/renderer.js"
4
+ import * as Casing from "../internal/casing.js"
2
5
  import type * as Expression from "../internal/scalar.js"
6
+ import type { MysqlDatatypeFamily, MysqlDatatypeKind } from "./datatypes/spec.js"
3
7
  import { renderMysqlPlan } from "./internal/renderer.js"
4
8
 
5
9
  /** MySQL-specialized rendered query shape. */
@@ -7,18 +11,41 @@ export type RenderedQuery<Row> = CoreRenderer.RenderedQuery<Row, "mysql">
7
11
  /** Extracts the row type carried by a MySQL rendered query. */
8
12
  export type RowOf<Value extends RenderedQuery<any>> = CoreRenderer.RowOf<Value>
9
13
  /** MySQL-specialized renderer contract. */
10
- export type Renderer = CoreRenderer.Renderer<"mysql">
14
+ export type Renderer = CoreRenderer.Renderer<"mysql"> & Pipeable & {
15
+ readonly [Casing.TypeId]: Casing.State
16
+ readonly withCasing: (options: Casing.Options) => Renderer
17
+ }
18
+
19
+ export type ValueMappings = Expression.DriverValueMappingsFor<MysqlDatatypeKind | "uuid", MysqlDatatypeFamily | "uuid">
11
20
 
12
21
  export interface MakeOptions {
13
- readonly valueMappings?: Expression.DriverValueMappings
22
+ readonly valueMappings?: ValueMappings
23
+ readonly casing?: Casing.Options
14
24
  }
15
25
 
16
26
  export { TypeId } from "../internal/renderer.js"
17
27
  export type { Projection } from "../internal/renderer.js"
18
28
 
29
+ const RendererProto = {
30
+ pipe(this: Pipeable) {
31
+ return pipeArguments(this, arguments)
32
+ }
33
+ }
34
+
19
35
  /** Creates the built-in MySQL renderer. */
20
- export const make = (options: MakeOptions = {}): Renderer =>
21
- CoreRenderer.make("mysql", (plan) => renderMysqlPlan(plan, options))
36
+ export const make = (options: MakeOptions = {}): Renderer => {
37
+ const renderer = CoreRenderer.makeTrusted("mysql", (plan) => renderMysqlPlan(plan, options))
38
+ return Object.assign(Object.create(RendererProto), renderer, {
39
+ [Casing.TypeId]: {
40
+ casing: options.casing
41
+ },
42
+ withCasing: (override: Casing.Options) =>
43
+ make({
44
+ ...options,
45
+ casing: Casing.merge(options.casing, override)
46
+ })
47
+ }) as Renderer
48
+ }
22
49
 
23
50
  /** Shared built-in MySQL renderer instance. */
24
51
  export const mysql = make()
package/src/mysql.ts CHANGED
@@ -1,22 +1,14 @@
1
- /** MySQL-specialized column-definition DSL. */
2
- export * as Column from "./mysql/column.js"
1
+ /** MySQL-specific column extensions. Portable columns are exported from `effect-qb`. */
2
+ export * as Column from "./mysql/column-extension.js"
3
3
  /** MySQL datatype witnesses and coercion families. */
4
4
  export * as Datatypes from "./mysql/datatypes/index.js"
5
5
  /** MySQL error catalog and error normalization helpers. */
6
6
  export * as Errors from "./mysql/errors/index.js"
7
- /** Shared scalar SQL interfaces and DB-type descriptors. */
8
- export * as Scalar from "./internal/scalar.js"
9
- /** MySQL-specialized SQL function expressions. */
10
- export * as Function from "./mysql/function/index.js"
11
7
  /** MySQL-specialized JSON expression helpers. */
12
8
  export * as Json from "./mysql/json.js"
13
9
  /** MySQL-specialized typed query execution contracts. */
14
10
  export * as Executor from "./mysql/executor.js"
15
- /** Shared logical row-set interfaces. */
16
- export * as RowSet from "./internal/row-set.js"
17
- /** MySQL-specialized query-construction DSL. */
18
- export * as Query from "./mysql/query.js"
19
- /** MySQL-specialized table-definition DSL. */
20
- export * as Table from "./mysql/table.js"
11
+ /** MySQL-specific query helpers. Portable queries are exported from the root package. */
12
+ export * as Query from "./mysql/query-extension.js"
21
13
  /** MySQL-specialized built-in renderer entrypoint. */
22
14
  export * as Renderer from "./mysql/renderer.js"
@@ -0,0 +1,28 @@
1
+ export {
2
+ array,
3
+ bit,
4
+ bytea,
5
+ custom,
6
+ ddlType,
7
+ float4,
8
+ float8,
9
+ foreignKey,
10
+ identityAlways,
11
+ identityByDefault,
12
+ index,
13
+ int2,
14
+ int8,
15
+ interval,
16
+ jsonb,
17
+ name,
18
+ oid,
19
+ pg_lsn,
20
+ regclass,
21
+ timetz,
22
+ timestamptz,
23
+ unique,
24
+ varbit,
25
+ xml
26
+ } from "./column.js"
27
+
28
+ export type { Any, AnyBound } from "./column.js"
@@ -3,6 +3,7 @@ import * as Schema from "effect/Schema"
3
3
  import * as BaseColumn from "../internal/column.js"
4
4
  import { makeColumnDefinition, type ColumnDefinition } from "../internal/column-state.js"
5
5
  import type * as Expression from "../internal/scalar.js"
6
+ import { enrichDbType } from "../internal/datatypes/enrich.js"
6
7
  import {
7
8
  BigIntStringSchema,
8
9
  DecimalStringSchema,
@@ -21,13 +22,6 @@ import {
21
22
  } from "../internal/runtime/value.js"
22
23
  import { postgresDatatypes } from "./datatypes/index.js"
23
24
 
24
- const enrichDbType = <Db extends Expression.DbType.Any>(dbType: Db): Db => {
25
- const candidate = (postgresDatatypes as unknown as Record<string, (() => Expression.DbType.Any) | undefined>)[dbType.kind]
26
- return typeof candidate === "function"
27
- ? { ...candidate(), ...dbType } as Db
28
- : dbType
29
- }
30
-
31
25
  const primitive = <Type, Db extends Expression.DbType.Any>(
32
26
  schema: Schema.Schema<Type, any, any>,
33
27
  dbType: Db
@@ -59,12 +53,14 @@ const boundedString = (length?: number): Schema.Schema<string> =>
59
53
  ? Schema.String
60
54
  : Schema.String.pipe(Schema.maxLength(length))
61
55
 
56
+ const finiteNumber = Schema.Number.pipe(Schema.finite())
57
+
62
58
  export const custom = <SchemaType extends Schema.Schema.Any, Db extends Expression.DbType.Any>(
63
59
  schema: SchemaType,
64
60
  dbType: Db
65
61
  ) =>
66
- makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
67
- dbType: enrichDbType(dbType),
62
+ makeColumnDefinition(schema as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
63
+ dbType: enrichDbType(postgresDatatypes, dbType),
68
64
  nullable: false,
69
65
  hasDefault: false,
70
66
  generated: false,
@@ -92,8 +88,8 @@ export const number = (options?: BaseColumn.NumericOptions) =>
92
88
  ddlType: renderNumericDdlType("numeric", options),
93
89
  identity: undefined
94
90
  })
95
- export const float4 = () => primitive(Schema.Number, postgresDatatypes.float4())
96
- export const float8 = () => primitive(Schema.Number, postgresDatatypes.float8())
91
+ export const float4 = () => primitive(finiteNumber, postgresDatatypes.float4())
92
+ export const float8 = () => primitive(finiteNumber, postgresDatatypes.float8())
97
93
  export const boolean = () => primitive(Schema.Boolean, postgresDatatypes.boolean())
98
94
  export const date = () => primitive(LocalDateStringSchema, postgresDatatypes.date())
99
95
  export const timestamp = () => primitive(LocalDateTimeStringSchema, postgresDatatypes.timestamp())
@@ -134,7 +130,7 @@ export const varchar = (length?: number) =>
134
130
  identity: undefined
135
131
  })
136
132
  export const json = <SchemaType extends Schema.Schema.Any>(schema: SchemaType) =>
137
- makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
133
+ makeColumnDefinition(schema as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
138
134
  dbType: postgresDatatypes.json(),
139
135
  nullable: false,
140
136
  hasDefault: false,
@@ -146,7 +142,7 @@ export const json = <SchemaType extends Schema.Schema.Any>(schema: SchemaType) =
146
142
  identity: undefined
147
143
  })
148
144
  export const jsonb = <SchemaType extends Schema.Schema.Any>(schema: SchemaType) =>
149
- makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
145
+ makeColumnDefinition(schema as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
150
146
  dbType: postgresDatatypes.jsonb(),
151
147
  nullable: false,
152
148
  hasDefault: false,
@@ -1,7 +1,8 @@
1
1
  import type * as Expression from "../../internal/scalar.js";
2
+ import type { NonEmptyStringInput } from "../../internal/table-options.js";
2
3
  import { postgresDatatypeFamilies, postgresDatatypeKinds } from "./spec.js";
3
4
  export declare const postgresDatatypes: {
4
- custom: <Kind extends string>(kind: Kind) => Expression.DbType.Base<"postgres", Kind>;
5
+ custom: <Kind extends string>(kind: NonEmptyStringInput<Kind>) => Expression.DbType.Base<"postgres", Kind>;
5
6
  text: () => Expression.DbType.Base<"postgres", "text"> & {
6
7
  readonly family: "text";
7
8
  readonly runtime: "string";
@@ -1,5 +1,6 @@
1
1
  import type { DatatypeModule } from "../../internal/datatypes/define.js"
2
2
  import type * as Expression from "../../internal/scalar.js"
3
+ import type { NonEmptyStringInput } from "../../internal/table-options.js"
3
4
  import { postgresDatatypeFamilies, postgresDatatypeKinds } from "./spec.js"
4
5
 
5
6
  const withMetadata = <Kind extends keyof typeof postgresDatatypeKinds & string>(
@@ -19,9 +20,9 @@ const withMetadata = <Kind extends keyof typeof postgresDatatypeKinds & string>(
19
20
  }
20
21
 
21
22
  const postgresDatatypeModule = {
22
- custom: (kind: string) => ({
23
+ custom: <Kind extends string>(kind: NonEmptyStringInput<Kind>) => ({
23
24
  dialect: "postgres",
24
- kind
25
+ kind: kind as Kind
25
26
  }),
26
27
  boolean: () => withMetadata("bool")
27
28
  } as Record<string, (...args: readonly any[]) => Expression.DbType.Base<"postgres", string>>
@@ -44,8 +44,8 @@ const asNumber = (value: unknown): number | undefined => {
44
44
  if (typeof value === "number" && Number.isFinite(value)) {
45
45
  return value
46
46
  }
47
- if (typeof value === "string" && value.trim() !== "") {
48
- const parsed = Number(value)
47
+ if (typeof value === "string" && /^[+-]?\d+$/.test(value.trim())) {
48
+ const parsed = Number(value.trim())
49
49
  return Number.isFinite(parsed) ? parsed : undefined
50
50
  }
51
51
  return undefined
@@ -6,6 +6,7 @@ import * as CoreExecutor from "../internal/executor.js"
6
6
  import * as CoreQuery from "../internal/query.js"
7
7
  import * as CoreRenderer from "../internal/renderer.js"
8
8
  import type * as Expression from "../internal/scalar.js"
9
+ import type { PostgresDatatypeFamily, PostgresDatatypeKind } from "./datatypes/spec.js"
9
10
  import { renderPostgresPlan } from "./internal/renderer.js"
10
11
  import {
11
12
  narrowPostgresDriverErrorForReadQuery,
@@ -24,12 +25,13 @@ export type Driver<Error = never, Context = never> = CoreExecutor.Driver<"postgr
24
25
  export type Executor<Error = never, Context = never> = CoreExecutor.Executor<"postgres", Error, Context>
25
26
  /** Postgres-specialized renderer contract. */
26
27
  export type Renderer = CoreRenderer.Renderer<"postgres">
28
+ export type ValueMappings = Expression.DriverValueMappingsFor<PostgresDatatypeKind, PostgresDatatypeFamily>
27
29
  /** Optional renderer / driver overrides for the standard Postgres executor pipeline. */
28
30
  export interface MakeOptions<Error = never, Context = never> {
29
31
  readonly renderer?: Renderer
30
32
  readonly driver?: Driver<Error, Context>
31
33
  readonly driverMode?: CoreExecutor.DriverMode
32
- readonly valueMappings?: Expression.DriverValueMappings
34
+ readonly valueMappings?: ValueMappings
33
35
  }
34
36
  /** Standard composed error shape for Postgres executors. */
35
37
  export type PostgresExecutorError = PostgresDriverError | RowDecodeError
@@ -55,12 +57,55 @@ export interface QueryExecutor<Context = never> {
55
57
  ): Stream.Stream<CoreQuery.ResultRow<PlanValue>, PostgresQueryError<PlanValue>, Context>
56
58
  }
57
59
 
60
+ type DriverExecute<Error, Context> = <Row>(
61
+ query: CoreRenderer.RenderedQuery<Row, "postgres">
62
+ ) => Effect.Effect<ReadonlyArray<FlatRow>, Error, Context>
63
+
64
+ type DriverHandlers<Error, Context> = {
65
+ readonly execute: DriverExecute<Error, Context>
66
+ readonly stream: <Row>(
67
+ query: CoreRenderer.RenderedQuery<Row, "postgres">
68
+ ) => Stream.Stream<FlatRow, Error, Context>
69
+ }
70
+
58
71
  /** Constructs a Postgres-specialized SQL driver. */
59
- export function driver(execute: any): Driver<any, any>
60
- export function driver(dialect: "postgres", execute: any): Driver<any, any>
61
- export function driver(dialectOrExecute: "postgres" | any, maybeExecute?: any): Driver<any, any> {
62
- const execute = typeof dialectOrExecute === "string" ? maybeExecute : dialectOrExecute
63
- return CoreExecutor.driver("postgres", execute as any)
72
+ export function driver<
73
+ Error = never,
74
+ Context = never
75
+ >(
76
+ execute: DriverExecute<Error, Context>
77
+ ): Driver<Error, Context>
78
+ export function driver<
79
+ Error = never,
80
+ Context = never
81
+ >(
82
+ handlers: DriverHandlers<Error, Context>
83
+ ): Driver<Error, Context>
84
+ export function driver<
85
+ Error = never,
86
+ Context = never
87
+ >(
88
+ dialect: "postgres",
89
+ execute: DriverExecute<Error, Context>
90
+ ): Driver<Error, Context>
91
+ export function driver<
92
+ Error = never,
93
+ Context = never
94
+ >(
95
+ dialect: "postgres",
96
+ handlers: DriverHandlers<Error, Context>
97
+ ): Driver<Error, Context>
98
+ export function driver<
99
+ Error = never,
100
+ Context = never
101
+ >(
102
+ dialectOrExecute: "postgres" | DriverExecute<Error, Context> | DriverHandlers<Error, Context>,
103
+ maybeExecute?: DriverExecute<Error, Context> | DriverHandlers<Error, Context>
104
+ ): Driver<Error, Context> {
105
+ const executeOrHandlers = typeof dialectOrExecute === "string" ? maybeExecute : dialectOrExecute
106
+ return typeof executeOrHandlers === "function"
107
+ ? CoreExecutor.driver("postgres", executeOrHandlers)
108
+ : CoreExecutor.driver("postgres", executeOrHandlers as DriverHandlers<Error, Context>)
64
109
  }
65
110
 
66
111
  const fromDriver = <
@@ -138,7 +183,7 @@ export function make(
138
183
  options: {
139
184
  readonly renderer?: Renderer
140
185
  readonly driverMode?: CoreExecutor.DriverMode
141
- readonly valueMappings?: Expression.DriverValueMappings
186
+ readonly valueMappings?: ValueMappings
142
187
  }
143
188
  ): QueryExecutor<SqlClient.SqlClient>
144
189
  export function make<Error = never, Context = never>(
@@ -146,7 +191,7 @@ export function make<Error = never, Context = never>(
146
191
  readonly renderer?: Renderer
147
192
  readonly driver: Driver<Error, Context>
148
193
  readonly driverMode?: CoreExecutor.DriverMode
149
- readonly valueMappings?: Expression.DriverValueMappings
194
+ readonly valueMappings?: ValueMappings
150
195
  }
151
196
  ): QueryExecutor<Context>
152
197
  export function make<Error = never, Context = never>(
@@ -154,14 +199,14 @@ export function make<Error = never, Context = never>(
154
199
  ): QueryExecutor<any> {
155
200
  if (options.driver) {
156
201
  return fromDriver(
157
- options.renderer ?? CoreRenderer.make("postgres", (plan) => renderPostgresPlan(plan, { valueMappings: options.valueMappings })),
202
+ options.renderer ?? CoreRenderer.makeTrusted("postgres", (plan) => renderPostgresPlan(plan, { valueMappings: options.valueMappings })),
158
203
  options.driver,
159
204
  options.driverMode,
160
205
  options.valueMappings
161
206
  )
162
207
  }
163
208
  return fromDriver(
164
- options.renderer ?? CoreRenderer.make("postgres", (plan) => renderPostgresPlan(plan, { valueMappings: options.valueMappings })),
209
+ options.renderer ?? CoreRenderer.makeTrusted("postgres", (plan) => renderPostgresPlan(plan, { valueMappings: options.valueMappings })),
165
210
  sqlClientDriver(),
166
211
  options.driverMode,
167
212
  options.valueMappings
@@ -1,8 +1,6 @@
1
1
  import type { ExpressionInput } from "../query.js"
2
2
  import {
3
- call,
4
3
  cast,
5
- coalesce,
6
4
  literal,
7
5
  nextVal as nextValInternal,
8
6
  type as postgresType,
@@ -11,12 +9,30 @@ import {
11
9
  import { isSequenceDefinition, type SequenceDefinition } from "../schema-management.js"
12
10
 
13
11
  /** Postgres scalar core functions. */
14
- export { coalesce, call, uuidGenerateV4 }
12
+ export { uuidGenerateV4 }
13
+
14
+ const safeUnquotedIdentifier = /^[a-z_][a-z0-9_$]*$/
15
+
16
+ const quoteIdentifier = (value: string): string =>
17
+ `"${value.replaceAll("\"", "\"\"")}"`
18
+
19
+ const renderIdentifier = (value: string): string =>
20
+ safeUnquotedIdentifier.test(value)
21
+ ? value
22
+ : quoteIdentifier(value)
23
+
24
+ const renderQualifiedSequenceName = (
25
+ value: SequenceDefinition<string, string | undefined>
26
+ ): string =>
27
+ value.schemaName === undefined || value.schemaName === "public"
28
+ ? renderIdentifier(value.name)
29
+ : `${renderIdentifier(value.schemaName)}.${renderIdentifier(value.name)}`
30
+
15
31
  export const nextVal = (
16
32
  value: ExpressionInput | SequenceDefinition<string, string | undefined>
17
33
  ) =>
18
34
  nextValInternal(
19
35
  isSequenceDefinition(value)
20
- ? cast(literal(value.qualifiedName()), postgresType.regclass())
36
+ ? cast(literal(renderQualifiedSequenceName(value)), postgresType.regclass())
21
37
  : value
22
38
  )
@@ -1,19 +1,3 @@
1
1
  export * as core from "./core.js"
2
- export * as string from "./string.js"
3
- export * as aggregate from "./aggregate.js"
4
- export * as window from "./window.js"
5
- export * as temporal from "./temporal.js"
6
2
 
7
- export { coalesce } from "./core.js"
8
- export { call, uuidGenerateV4, nextVal } from "./core.js"
9
- export { lower, upper, concat } from "./string.js"
10
- export { count, max, min } from "./aggregate.js"
11
- export { over, rowNumber, rank, denseRank } from "./window.js"
12
- export {
13
- currentDate,
14
- currentTime,
15
- currentTimestamp,
16
- localTime,
17
- localTimestamp,
18
- now
19
- } from "./temporal.js"
3
+ export { uuidGenerateV4, nextVal } from "./core.js"
@@ -1,7 +1,9 @@
1
- import type { RenderState, RenderValueContext, SqlDialect } from "../../internal/dialect.js"
1
+ import { quoteDoubleQuotedIdentifier, type RenderState, type RenderValueContext, type SqlDialect } from "../../internal/dialect.js"
2
+ import { renderExpression, renderQueryAst } from "../../internal/dialect-renderers/postgres.js"
2
3
  import { toDriverValue } from "../../internal/runtime/driver-value-mapping.js"
4
+ import { standardDialect } from "../../standard/dialect.js"
3
5
 
4
- const quoteIdentifier = (value: string): string => `"${value.replaceAll("\"", "\"\"")}"`
6
+ const quoteIdentifier = quoteDoubleQuotedIdentifier
5
7
 
6
8
  const renderLiteral = (value: unknown, state: RenderState, context: RenderValueContext = {}): string => {
7
9
  const driverValue = toDriverValue(value, {
@@ -23,11 +25,12 @@ const renderLiteral = (value: unknown, state: RenderState, context: RenderValueC
23
25
  * Built-in runtime dialect implementation for Postgres.
24
26
  */
25
27
  export const postgresDialect: SqlDialect<"postgres"> = {
28
+ ...standardDialect,
26
29
  name: "postgres",
27
30
  quoteIdentifier,
28
31
  renderLiteral,
29
32
  renderTableReference(tableName, baseTableName, schemaName) {
30
- const renderedBase = schemaName
33
+ const renderedBase = schemaName && schemaName !== "public"
31
34
  ? `${quoteIdentifier(schemaName)}.${quoteIdentifier(baseTableName)}`
32
35
  : quoteIdentifier(baseTableName)
33
36
  return tableName === baseTableName
@@ -36,5 +39,7 @@ export const postgresDialect: SqlDialect<"postgres"> = {
36
39
  },
37
40
  renderConcat(values) {
38
41
  return `(${values.join(" || ")})`
39
- }
42
+ },
43
+ renderQueryAst,
44
+ renderExpression
40
45
  }