@tanstack/db 0.0.14 → 0.0.16

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 (197) hide show
  1. package/dist/cjs/collection.cjs +117 -104
  2. package/dist/cjs/collection.cjs.map +1 -1
  3. package/dist/cjs/collection.d.cts +18 -21
  4. package/dist/cjs/index.cjs +31 -13
  5. package/dist/cjs/index.cjs.map +1 -1
  6. package/dist/cjs/index.d.cts +0 -1
  7. package/dist/cjs/query/builder/functions.cjs +107 -0
  8. package/dist/cjs/query/builder/functions.cjs.map +1 -0
  9. package/dist/cjs/query/builder/functions.d.cts +38 -0
  10. package/dist/cjs/query/builder/index.cjs +499 -0
  11. package/dist/cjs/query/builder/index.cjs.map +1 -0
  12. package/dist/cjs/query/builder/index.d.cts +324 -0
  13. package/dist/cjs/query/builder/ref-proxy.cjs +92 -0
  14. package/dist/cjs/query/builder/ref-proxy.cjs.map +1 -0
  15. package/dist/cjs/query/builder/ref-proxy.d.cts +28 -0
  16. package/dist/cjs/query/builder/types.d.cts +81 -0
  17. package/dist/cjs/query/compiler/evaluators.cjs +261 -0
  18. package/dist/cjs/query/compiler/evaluators.cjs.map +1 -0
  19. package/dist/cjs/query/compiler/evaluators.d.cts +11 -0
  20. package/dist/cjs/query/compiler/group-by.cjs +271 -0
  21. package/dist/cjs/query/compiler/group-by.cjs.map +1 -0
  22. package/dist/cjs/query/compiler/group-by.d.cts +7 -0
  23. package/dist/cjs/query/compiler/index.cjs +181 -0
  24. package/dist/cjs/query/compiler/index.cjs.map +1 -0
  25. package/dist/cjs/query/compiler/index.d.cts +15 -0
  26. package/dist/cjs/query/compiler/joins.cjs +116 -0
  27. package/dist/cjs/query/compiler/joins.cjs.map +1 -0
  28. package/dist/cjs/query/compiler/joins.d.cts +11 -0
  29. package/dist/cjs/query/compiler/order-by.cjs +89 -0
  30. package/dist/cjs/query/compiler/order-by.cjs.map +1 -0
  31. package/dist/cjs/query/compiler/order-by.d.cts +9 -0
  32. package/dist/cjs/query/compiler/select.cjs +57 -0
  33. package/dist/cjs/query/compiler/select.cjs.map +1 -0
  34. package/dist/cjs/query/compiler/select.d.cts +15 -0
  35. package/dist/cjs/query/index.d.cts +5 -5
  36. package/dist/cjs/query/ir.cjs +57 -0
  37. package/dist/cjs/query/ir.cjs.map +1 -0
  38. package/dist/cjs/query/ir.d.cts +81 -0
  39. package/dist/cjs/query/live-query-collection.cjs +224 -0
  40. package/dist/cjs/query/live-query-collection.cjs.map +1 -0
  41. package/dist/cjs/query/live-query-collection.d.cts +124 -0
  42. package/dist/cjs/transactions.cjs +20 -13
  43. package/dist/cjs/transactions.cjs.map +1 -1
  44. package/dist/cjs/transactions.d.cts +10 -1
  45. package/dist/cjs/types.d.cts +13 -0
  46. package/dist/esm/collection.d.ts +18 -21
  47. package/dist/esm/collection.js +118 -105
  48. package/dist/esm/collection.js.map +1 -1
  49. package/dist/esm/index.d.ts +0 -1
  50. package/dist/esm/index.js +30 -12
  51. package/dist/esm/query/builder/functions.d.ts +38 -0
  52. package/dist/esm/query/builder/functions.js +107 -0
  53. package/dist/esm/query/builder/functions.js.map +1 -0
  54. package/dist/esm/query/builder/index.d.ts +324 -0
  55. package/dist/esm/query/builder/index.js +499 -0
  56. package/dist/esm/query/builder/index.js.map +1 -0
  57. package/dist/esm/query/builder/ref-proxy.d.ts +28 -0
  58. package/dist/esm/query/builder/ref-proxy.js +92 -0
  59. package/dist/esm/query/builder/ref-proxy.js.map +1 -0
  60. package/dist/esm/query/builder/types.d.ts +81 -0
  61. package/dist/esm/query/compiler/evaluators.d.ts +11 -0
  62. package/dist/esm/query/compiler/evaluators.js +261 -0
  63. package/dist/esm/query/compiler/evaluators.js.map +1 -0
  64. package/dist/esm/query/compiler/group-by.d.ts +7 -0
  65. package/dist/esm/query/compiler/group-by.js +271 -0
  66. package/dist/esm/query/compiler/group-by.js.map +1 -0
  67. package/dist/esm/query/compiler/index.d.ts +15 -0
  68. package/dist/esm/query/compiler/index.js +181 -0
  69. package/dist/esm/query/compiler/index.js.map +1 -0
  70. package/dist/esm/query/compiler/joins.d.ts +11 -0
  71. package/dist/esm/query/compiler/joins.js +116 -0
  72. package/dist/esm/query/compiler/joins.js.map +1 -0
  73. package/dist/esm/query/compiler/order-by.d.ts +9 -0
  74. package/dist/esm/query/compiler/order-by.js +89 -0
  75. package/dist/esm/query/compiler/order-by.js.map +1 -0
  76. package/dist/esm/query/compiler/select.d.ts +15 -0
  77. package/dist/esm/query/compiler/select.js +57 -0
  78. package/dist/esm/query/compiler/select.js.map +1 -0
  79. package/dist/esm/query/index.d.ts +5 -5
  80. package/dist/esm/query/ir.d.ts +81 -0
  81. package/dist/esm/query/ir.js +57 -0
  82. package/dist/esm/query/ir.js.map +1 -0
  83. package/dist/esm/query/live-query-collection.d.ts +124 -0
  84. package/dist/esm/query/live-query-collection.js +224 -0
  85. package/dist/esm/query/live-query-collection.js.map +1 -0
  86. package/dist/esm/transactions.d.ts +10 -1
  87. package/dist/esm/transactions.js +20 -13
  88. package/dist/esm/transactions.js.map +1 -1
  89. package/dist/esm/types.d.ts +13 -0
  90. package/package.json +3 -4
  91. package/src/collection.ts +152 -129
  92. package/src/index.ts +0 -1
  93. package/src/query/builder/functions.ts +267 -0
  94. package/src/query/builder/index.ts +648 -0
  95. package/src/query/builder/ref-proxy.ts +156 -0
  96. package/src/query/builder/types.ts +282 -0
  97. package/src/query/compiler/evaluators.ts +315 -0
  98. package/src/query/compiler/group-by.ts +428 -0
  99. package/src/query/compiler/index.ts +276 -0
  100. package/src/query/compiler/joins.ts +228 -0
  101. package/src/query/compiler/order-by.ts +139 -0
  102. package/src/query/compiler/select.ts +173 -0
  103. package/src/query/index.ts +54 -5
  104. package/src/query/ir.ts +128 -0
  105. package/src/query/live-query-collection.ts +512 -0
  106. package/src/transactions.ts +27 -16
  107. package/src/types.ts +15 -0
  108. package/dist/cjs/query/compiled-query.cjs +0 -160
  109. package/dist/cjs/query/compiled-query.cjs.map +0 -1
  110. package/dist/cjs/query/compiled-query.d.cts +0 -20
  111. package/dist/cjs/query/evaluators.cjs +0 -161
  112. package/dist/cjs/query/evaluators.cjs.map +0 -1
  113. package/dist/cjs/query/evaluators.d.cts +0 -14
  114. package/dist/cjs/query/extractors.cjs +0 -122
  115. package/dist/cjs/query/extractors.cjs.map +0 -1
  116. package/dist/cjs/query/extractors.d.cts +0 -22
  117. package/dist/cjs/query/functions.cjs +0 -152
  118. package/dist/cjs/query/functions.cjs.map +0 -1
  119. package/dist/cjs/query/functions.d.cts +0 -21
  120. package/dist/cjs/query/group-by.cjs +0 -88
  121. package/dist/cjs/query/group-by.cjs.map +0 -1
  122. package/dist/cjs/query/group-by.d.cts +0 -40
  123. package/dist/cjs/query/joins.cjs +0 -141
  124. package/dist/cjs/query/joins.cjs.map +0 -1
  125. package/dist/cjs/query/joins.d.cts +0 -14
  126. package/dist/cjs/query/order-by.cjs +0 -185
  127. package/dist/cjs/query/order-by.cjs.map +0 -1
  128. package/dist/cjs/query/order-by.d.cts +0 -3
  129. package/dist/cjs/query/pipeline-compiler.cjs +0 -89
  130. package/dist/cjs/query/pipeline-compiler.cjs.map +0 -1
  131. package/dist/cjs/query/pipeline-compiler.d.cts +0 -10
  132. package/dist/cjs/query/query-builder.cjs +0 -307
  133. package/dist/cjs/query/query-builder.cjs.map +0 -1
  134. package/dist/cjs/query/query-builder.d.cts +0 -225
  135. package/dist/cjs/query/schema.d.cts +0 -100
  136. package/dist/cjs/query/select.cjs +0 -130
  137. package/dist/cjs/query/select.cjs.map +0 -1
  138. package/dist/cjs/query/select.d.cts +0 -3
  139. package/dist/cjs/query/types.d.cts +0 -189
  140. package/dist/cjs/query/utils.cjs +0 -154
  141. package/dist/cjs/query/utils.cjs.map +0 -1
  142. package/dist/cjs/query/utils.d.cts +0 -37
  143. package/dist/cjs/utils.cjs +0 -17
  144. package/dist/cjs/utils.cjs.map +0 -1
  145. package/dist/cjs/utils.d.cts +0 -3
  146. package/dist/esm/query/compiled-query.d.ts +0 -20
  147. package/dist/esm/query/compiled-query.js +0 -160
  148. package/dist/esm/query/compiled-query.js.map +0 -1
  149. package/dist/esm/query/evaluators.d.ts +0 -14
  150. package/dist/esm/query/evaluators.js +0 -161
  151. package/dist/esm/query/evaluators.js.map +0 -1
  152. package/dist/esm/query/extractors.d.ts +0 -22
  153. package/dist/esm/query/extractors.js +0 -122
  154. package/dist/esm/query/extractors.js.map +0 -1
  155. package/dist/esm/query/functions.d.ts +0 -21
  156. package/dist/esm/query/functions.js +0 -152
  157. package/dist/esm/query/functions.js.map +0 -1
  158. package/dist/esm/query/group-by.d.ts +0 -40
  159. package/dist/esm/query/group-by.js +0 -88
  160. package/dist/esm/query/group-by.js.map +0 -1
  161. package/dist/esm/query/joins.d.ts +0 -14
  162. package/dist/esm/query/joins.js +0 -141
  163. package/dist/esm/query/joins.js.map +0 -1
  164. package/dist/esm/query/order-by.d.ts +0 -3
  165. package/dist/esm/query/order-by.js +0 -185
  166. package/dist/esm/query/order-by.js.map +0 -1
  167. package/dist/esm/query/pipeline-compiler.d.ts +0 -10
  168. package/dist/esm/query/pipeline-compiler.js +0 -89
  169. package/dist/esm/query/pipeline-compiler.js.map +0 -1
  170. package/dist/esm/query/query-builder.d.ts +0 -225
  171. package/dist/esm/query/query-builder.js +0 -307
  172. package/dist/esm/query/query-builder.js.map +0 -1
  173. package/dist/esm/query/schema.d.ts +0 -100
  174. package/dist/esm/query/select.d.ts +0 -3
  175. package/dist/esm/query/select.js +0 -130
  176. package/dist/esm/query/select.js.map +0 -1
  177. package/dist/esm/query/types.d.ts +0 -189
  178. package/dist/esm/query/utils.d.ts +0 -37
  179. package/dist/esm/query/utils.js +0 -154
  180. package/dist/esm/query/utils.js.map +0 -1
  181. package/dist/esm/utils.d.ts +0 -3
  182. package/dist/esm/utils.js +0 -17
  183. package/dist/esm/utils.js.map +0 -1
  184. package/src/query/compiled-query.ts +0 -234
  185. package/src/query/evaluators.ts +0 -250
  186. package/src/query/extractors.ts +0 -214
  187. package/src/query/functions.ts +0 -297
  188. package/src/query/group-by.ts +0 -139
  189. package/src/query/joins.ts +0 -260
  190. package/src/query/order-by.ts +0 -264
  191. package/src/query/pipeline-compiler.ts +0 -149
  192. package/src/query/query-builder.ts +0 -902
  193. package/src/query/schema.ts +0 -268
  194. package/src/query/select.ts +0 -208
  195. package/src/query/types.ts +0 -418
  196. package/src/query/utils.ts +0 -245
  197. package/src/utils.ts +0 -15
@@ -1,268 +0,0 @@
1
- import type {
2
- Context,
3
- InputReference,
4
- PropertyReference,
5
- PropertyReferenceString,
6
- Schema,
7
- WildcardReferenceString,
8
- } from "./types.js"
9
- import type { Collection } from "../collection"
10
-
11
- // Identifiers
12
- export type ColumnName<TColumnNames extends string> = TColumnNames
13
-
14
- // JSONLike supports any JSON-compatible value plus Date objects.
15
- export type JSONLike =
16
- | string
17
- | number
18
- | boolean
19
- | Date
20
- | null
21
- | Array<JSONLike>
22
- | { [key: string]: JSONLike }
23
-
24
- // LiteralValue supports common primitives, JS Date, or undefined.
25
- // We exclude strings that start with "@" because they are property references.
26
- export type LiteralValue =
27
- | (string & {})
28
- | number
29
- | boolean
30
- | Date
31
- | null
32
- | undefined
33
-
34
- // `in` and `not in` operators require an array of values
35
- // the other operators require a single literal value
36
- export type ComparatorValue<
37
- T extends Comparator,
38
- TContext extends Context<Schema>,
39
- > = T extends `in` | `not in`
40
- ? Array<LiteralValue>
41
- : PropertyReferenceString<TContext> | LiteralValue
42
-
43
- // These versions are for use with methods on the query builder where we want to
44
- // ensure that the argument is a string that does not start with "@".
45
- // Can be combined with PropertyReference for validating references.
46
- export type SafeString<T extends string> = T extends `@${string}` ? never : T
47
- export type OptionalSafeString<T extends any> = T extends string
48
- ? SafeString<T>
49
- : never
50
- export type LiteralValueWithSafeString<T extends any> =
51
- | (OptionalSafeString<T> & {})
52
- | number
53
- | boolean
54
- | Date
55
- | null
56
- | undefined
57
-
58
- // To force a literal value (which may be arbitrary JSON or a Date), wrap it in an object with the "value" key.
59
- export interface ExplicitLiteral {
60
- value: JSONLike
61
- }
62
-
63
- // Allowed function names (common SQL functions)
64
- export type AllowedFunctionName =
65
- | `DATE`
66
- | `JSON_EXTRACT`
67
- | `JSON_EXTRACT_PATH`
68
- | `UPPER`
69
- | `LOWER`
70
- | `COALESCE`
71
- | `CONCAT`
72
- | `LENGTH`
73
- | `ORDER_INDEX`
74
-
75
- // A function call is represented as a union of objects—each having exactly one key that is one of the allowed function names.
76
- export type FunctionCall<TContext extends Context = Context> = {
77
- [K in AllowedFunctionName]: {
78
- [key in K]: ConditionOperand<TContext> | Array<ConditionOperand<TContext>>
79
- }
80
- }[AllowedFunctionName]
81
-
82
- export type AggregateFunctionName =
83
- | `SUM`
84
- | `COUNT`
85
- | `AVG`
86
- | `MIN`
87
- | `MAX`
88
- | `MEDIAN`
89
- | `MODE`
90
-
91
- export type AggregateFunctionCall<TContext extends Context = Context> = {
92
- [K in AggregateFunctionName]: {
93
- [key in K]: ConditionOperand<TContext> | Array<ConditionOperand<TContext>>
94
- }
95
- }[AggregateFunctionName]
96
-
97
- /**
98
- * An operand in a condition may be:
99
- * - A literal value (LiteralValue)
100
- * - A column reference (a string starting with "@" or an explicit { col: string } object)
101
- * - An explicit literal (to wrap arbitrary JSON or Date values) as { value: ... }
102
- * - A function call (as defined above)
103
- * - An array of operands (for example, for "in" clauses)
104
- */
105
- export type ConditionOperand<
106
- TContext extends Context = Context,
107
- T extends any = any,
108
- > =
109
- | LiteralValue
110
- | PropertyReference<TContext>
111
- | ExplicitLiteral
112
- | FunctionCall<TContext>
113
- | Array<ConditionOperand<TContext, T>>
114
-
115
- // Allowed SQL comparators.
116
- export type Comparator =
117
- | `=`
118
- | `!=`
119
- | `<`
120
- | `<=`
121
- | `>`
122
- | `>=`
123
- | `like`
124
- | `not like`
125
- | `in`
126
- | `not in`
127
- | `is`
128
- | `is not`
129
-
130
- // Logical operators.
131
- export type LogicalOperator = `and` | `or`
132
-
133
- // A simple condition is a tuple: [left operand, comparator, right operand].
134
- export type SimpleCondition<
135
- TContext extends Context = Context,
136
- T extends any = any,
137
- > = [ConditionOperand<TContext, T>, Comparator, ConditionOperand<TContext, T>]
138
-
139
- // A flat composite condition allows all elements to be at the same level:
140
- // [left1, op1, right1, 'and'/'or', left2, op2, right2, ...]
141
- export type FlatCompositeCondition<
142
- TContext extends Context = Context,
143
- T extends any = any,
144
- > = [
145
- ConditionOperand<TContext, T>,
146
- Comparator,
147
- ConditionOperand<TContext, T>,
148
- ...Array<LogicalOperator | ConditionOperand<TContext, T> | Comparator>,
149
- ]
150
-
151
- // A nested composite condition combines conditions with logical operators
152
- // The first element can be a SimpleCondition or FlatCompositeCondition
153
- // followed by logical operators and more conditions
154
- export type NestedCompositeCondition<
155
- TContext extends Context = Context,
156
- T extends any = any,
157
- > = [
158
- SimpleCondition<TContext, T> | FlatCompositeCondition<TContext, T>,
159
- ...Array<
160
- | LogicalOperator
161
- | SimpleCondition<TContext, T>
162
- | FlatCompositeCondition<TContext, T>
163
- >,
164
- ]
165
-
166
- // A condition is either a simple condition or a composite condition (flat or nested).
167
- export type Condition<
168
- TContext extends Context = Context,
169
- T extends any = any,
170
- > =
171
- | SimpleCondition<TContext, T>
172
- | FlatCompositeCondition<TContext, T>
173
- | NestedCompositeCondition<TContext, T>
174
-
175
- // A join clause includes a join type, the table to join, an optional alias,
176
- // an "on" condition, and an optional "where" clause specific to the join.
177
- export interface JoinClause<TContext extends Context = Context> {
178
- type: `inner` | `left` | `right` | `full` | `cross`
179
- from: string
180
- as?: string
181
- on: Condition<TContext>
182
- }
183
-
184
- // The orderBy clause can be a string, an object mapping a column to "asc" or "desc",
185
- // or an array of such items.
186
- export type OrderBy<TContext extends Context = Context> =
187
- | PropertyReferenceString<TContext>
188
- | { [column in PropertyReferenceString<TContext>]?: `asc` | `desc` }
189
- | Record<PropertyReferenceString<TContext>, `asc` | `desc`>
190
- | Array<
191
- | PropertyReferenceString<TContext>
192
- | { [column in PropertyReferenceString<TContext>]?: `asc` | `desc` }
193
- >
194
-
195
- export type Select<TContext extends Context = Context> =
196
- | PropertyReferenceString<TContext>
197
- | {
198
- [alias: string]:
199
- | PropertyReference<TContext>
200
- | FunctionCall<TContext>
201
- | AggregateFunctionCall<TContext>
202
- }
203
- | WildcardReferenceString<TContext>
204
- | SelectCallback<TContext>
205
-
206
- export type SelectCallback<TContext extends Context = Context> = (
207
- context: TContext extends { schema: infer S } ? S : any
208
- ) => any
209
-
210
- export type As<_TContext extends Context = Context> = string
211
-
212
- export type From<TContext extends Context = Context> = InputReference<{
213
- baseSchema: TContext[`baseSchema`]
214
- schema: TContext[`baseSchema`]
215
- }>
216
-
217
- export type WhereCallback<TContext extends Context = Context> = (
218
- context: TContext extends { schema: infer S } ? S : any
219
- ) => boolean
220
-
221
- export type Where<TContext extends Context = Context> = Array<
222
- Condition<TContext> | WhereCallback<TContext>
223
- >
224
-
225
- // Having is the same implementation as a where clause, its just run after the group by
226
- export type Having<TContext extends Context = Context> = Where<TContext>
227
-
228
- export type GroupBy<TContext extends Context = Context> =
229
- | PropertyReference<TContext>
230
- | Array<PropertyReference<TContext>>
231
-
232
- export type Limit<_TContext extends Context = Context> = number
233
-
234
- export type Offset<_TContext extends Context = Context> = number
235
-
236
- export interface BaseQuery<TContext extends Context = Context> {
237
- // The select clause is an array of either plain strings or objects mapping alias names
238
- // to expressions. Plain strings starting with "@" denote column references.
239
- // Plain string "@*" denotes all columns from all tables.
240
- // Plain string "@table.*" denotes all columns from a specific table.
241
- select?: Array<Select<TContext>>
242
- as?: As<TContext>
243
- from: From<TContext>
244
- join?: Array<JoinClause<TContext>>
245
- where?: Where<TContext>
246
- groupBy?: GroupBy<TContext>
247
- having?: Having<TContext>
248
- orderBy?: OrderBy<TContext>
249
- limit?: Limit<TContext>
250
- offset?: Offset<TContext>
251
- }
252
-
253
- // The top-level query interface.
254
- export interface Query<TContext extends Context = Context>
255
- extends BaseQuery<TContext> {
256
- with?: Array<WithQuery<TContext>>
257
- collections?: {
258
- [K: string]: Collection<any>
259
- }
260
- }
261
-
262
- // A WithQuery is a query that is used as a Common Table Expression (CTE)
263
- // It cannot be keyed and must have an alias (as)
264
- // There is no support for recursive CTEs
265
- export interface WithQuery<TContext extends Context = Context>
266
- extends BaseQuery<TContext> {
267
- as: string
268
- }
@@ -1,208 +0,0 @@
1
- import { map } from "@electric-sql/d2mini"
2
- import {
3
- evaluateOperandOnNamespacedRow,
4
- extractValueFromNamespacedRow,
5
- } from "./extractors"
6
- import type { ConditionOperand, Query, SelectCallback } from "./schema"
7
- import type { KeyedStream, NamespacedAndKeyedStream } from "../types"
8
-
9
- export function processSelect(
10
- pipeline: NamespacedAndKeyedStream,
11
- query: Query,
12
- mainTableAlias: string,
13
- inputs: Record<string, KeyedStream>
14
- ): KeyedStream {
15
- return pipeline.pipe(
16
- map(([key, namespacedRow]) => {
17
- const result: Record<string, unknown> = {}
18
-
19
- // Check if this is a grouped result (has no nested table structure)
20
- // If it's a grouped result, we need to handle it differently
21
- const isGroupedResult =
22
- query.groupBy &&
23
- Object.keys(namespacedRow).some(
24
- (namespaceKey) =>
25
- !Object.keys(inputs).includes(namespaceKey) &&
26
- typeof namespacedRow[namespaceKey] !== `object`
27
- )
28
-
29
- if (!query.select) {
30
- throw new Error(`Cannot process missing SELECT clause`)
31
- }
32
-
33
- for (const item of query.select) {
34
- // Handle callback functions
35
- if (typeof item === `function`) {
36
- const callback = item as SelectCallback
37
- const callbackResult = callback(namespacedRow)
38
-
39
- // If the callback returns an object, merge its properties into the result
40
- if (
41
- callbackResult &&
42
- typeof callbackResult === `object` &&
43
- !Array.isArray(callbackResult)
44
- ) {
45
- Object.assign(result, callbackResult)
46
- } else {
47
- // If the callback returns a primitive value, we can't merge it
48
- // This would need a specific key, but since we don't have one, we'll skip it
49
- // In practice, select callbacks should return objects with keys
50
- console.warn(
51
- `SelectCallback returned a non-object value. SelectCallbacks should return objects with key-value pairs.`
52
- )
53
- }
54
- continue
55
- }
56
-
57
- if (typeof item === `string`) {
58
- // Handle wildcard select - all columns from all tables
59
- if ((item as string) === `@*`) {
60
- // For grouped results, just return the row as is
61
- if (isGroupedResult) {
62
- Object.assign(result, namespacedRow)
63
- } else {
64
- // Extract all columns from all tables
65
- Object.assign(
66
- result,
67
- extractAllColumnsFromAllTables(namespacedRow)
68
- )
69
- }
70
- continue
71
- }
72
-
73
- // Handle @table.* syntax - all columns from a specific table
74
- if (
75
- (item as string).startsWith(`@`) &&
76
- (item as string).endsWith(`.*`)
77
- ) {
78
- const tableAlias = (item as string).slice(1, -2) // Remove the '@' and '.*' parts
79
-
80
- // For grouped results, check if we have columns from this table
81
- if (isGroupedResult) {
82
- // In grouped results, we don't have the nested structure anymore
83
- // So we can't extract by table. Just continue to the next item.
84
- continue
85
- } else {
86
- // Extract all columns from the specified table
87
- Object.assign(
88
- result,
89
- extractAllColumnsFromTable(namespacedRow, tableAlias)
90
- )
91
- }
92
- continue
93
- }
94
-
95
- // Handle simple column references like "@table.column" or "@column"
96
- if ((item as string).startsWith(`@`)) {
97
- const columnRef = (item as string).substring(1)
98
- const alias = columnRef
99
-
100
- // For grouped results, check if the column is directly in the row first
101
- if (isGroupedResult && columnRef in namespacedRow) {
102
- result[alias] = namespacedRow[columnRef]
103
- } else {
104
- // Extract the value from the nested structure
105
- result[alias] = extractValueFromNamespacedRow(
106
- namespacedRow,
107
- columnRef,
108
- mainTableAlias,
109
- undefined
110
- )
111
- }
112
-
113
- // If the alias contains a dot (table.column),
114
- // use just the column part as the field name
115
- if (alias.includes(`.`)) {
116
- const columnName = alias.split(`.`)[1]
117
- result[columnName!] = result[alias]
118
- delete result[alias]
119
- }
120
- }
121
- } else {
122
- // Handle aliased columns like { alias: "@column_name" }
123
- for (const [alias, expr] of Object.entries(item)) {
124
- if (typeof expr === `string` && (expr as string).startsWith(`@`)) {
125
- const columnRef = (expr as string).substring(1)
126
-
127
- // For grouped results, check if the column is directly in the row first
128
- if (isGroupedResult && columnRef in namespacedRow) {
129
- result[alias] = namespacedRow[columnRef]
130
- } else {
131
- // Extract the value from the nested structure
132
- result[alias] = extractValueFromNamespacedRow(
133
- namespacedRow,
134
- columnRef,
135
- mainTableAlias,
136
- undefined
137
- )
138
- }
139
- } else if (typeof expr === `object`) {
140
- // For grouped results, the aggregate results are already in the row
141
- if (isGroupedResult && alias in namespacedRow) {
142
- result[alias] = namespacedRow[alias]
143
- } else if ((expr as { ORDER_INDEX: unknown }).ORDER_INDEX) {
144
- result[alias] = namespacedRow[mainTableAlias]![alias]
145
- } else {
146
- // This might be a function call
147
- result[alias] = evaluateOperandOnNamespacedRow(
148
- namespacedRow,
149
- expr as ConditionOperand,
150
- mainTableAlias,
151
- undefined
152
- )
153
- }
154
- }
155
- }
156
- }
157
- }
158
-
159
- return [key, result] as [string, typeof result]
160
- })
161
- )
162
- }
163
-
164
- // Helper function to extract all columns from all tables in a nested row
165
- function extractAllColumnsFromAllTables(
166
- namespacedRow: Record<string, unknown>
167
- ): Record<string, unknown> {
168
- const result: Record<string, unknown> = {}
169
-
170
- // Process each table in the nested row
171
- for (const [tableAlias, tableData] of Object.entries(namespacedRow)) {
172
- if (tableData && typeof tableData === `object`) {
173
- // Add all columns from this table to the result
174
- // If there are column name conflicts, the last table's columns will overwrite previous ones
175
- Object.assign(
176
- result,
177
- extractAllColumnsFromTable(namespacedRow, tableAlias)
178
- )
179
- }
180
- }
181
-
182
- return result
183
- }
184
-
185
- // Helper function to extract all columns from a table in a nested row
186
- function extractAllColumnsFromTable(
187
- namespacedRow: Record<string, unknown>,
188
- tableAlias: string
189
- ): Record<string, unknown> {
190
- const result: Record<string, unknown> = {}
191
-
192
- // Get the table data
193
- const tableData = namespacedRow[tableAlias] as
194
- | Record<string, unknown>
195
- | null
196
- | undefined
197
-
198
- if (!tableData || typeof tableData !== `object`) {
199
- return result
200
- }
201
-
202
- // Add all columns from the table to the result
203
- for (const [columnName, value] of Object.entries(tableData)) {
204
- result[columnName] = value
205
- }
206
-
207
- return result
208
- }