@checkdigit/eslint-athena-plugin 1.0.0-PR.2-dcdf

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 (66) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.md +17 -0
  3. package/SECURITY.md +13 -0
  4. package/dist-mjs/athena/api-locator.mjs +66 -0
  5. package/dist-mjs/athena/api-matcher.mjs +206 -0
  6. package/dist-mjs/athena/athena.mjs +165 -0
  7. package/dist-mjs/athena/column.mjs +1 -0
  8. package/dist-mjs/athena/context.mjs +21 -0
  9. package/dist-mjs/athena/index.mjs +1 -0
  10. package/dist-mjs/athena/service-table.mjs +45 -0
  11. package/dist-mjs/athena/sql-file.mjs +123 -0
  12. package/dist-mjs/athena/types.mjs +1 -0
  13. package/dist-mjs/athena/validate.mjs +619 -0
  14. package/dist-mjs/athena/visitor.mjs +291 -0
  15. package/dist-mjs/get-documentation-url.mjs +9 -0
  16. package/dist-mjs/index.mjs +56 -0
  17. package/dist-mjs/openapi/deref-schema.mjs +20 -0
  18. package/dist-mjs/openapi/generate-schema.mjs +375 -0
  19. package/dist-mjs/openapi/service-schema-generator.mjs +176 -0
  20. package/dist-mjs/peggy/athena-peggy.mjs +20700 -0
  21. package/dist-mjs/service.mjs +9 -0
  22. package/dist-mjs/sql-parser.mjs +28 -0
  23. package/dist-types/athena/api-locator.d.ts +2 -0
  24. package/dist-types/athena/api-matcher.d.ts +14 -0
  25. package/dist-types/athena/athena.d.ts +5 -0
  26. package/dist-types/athena/column.d.ts +1 -0
  27. package/dist-types/athena/context.d.ts +21 -0
  28. package/dist-types/athena/index.d.ts +8 -0
  29. package/dist-types/athena/service-table.d.ts +8 -0
  30. package/dist-types/athena/sql-file.d.ts +5 -0
  31. package/dist-types/athena/types.d.ts +493 -0
  32. package/dist-types/athena/validate.d.ts +14 -0
  33. package/dist-types/athena/visitor.d.ts +75 -0
  34. package/dist-types/get-documentation-url.d.ts +1 -0
  35. package/dist-types/index.d.ts +5 -0
  36. package/dist-types/openapi/deref-schema.d.ts +1 -0
  37. package/dist-types/openapi/generate-schema.d.ts +33 -0
  38. package/dist-types/openapi/service-schema-generator.d.ts +5 -0
  39. package/dist-types/peggy/athena-peggy.d.ts +13 -0
  40. package/dist-types/service.d.ts +2 -0
  41. package/dist-types/sql-parser.d.ts +25 -0
  42. package/package.json +1 -0
  43. package/src/api/v1/swagger.yml +619 -0
  44. package/src/api/v2/swagger.yml +477 -0
  45. package/src/athena/api-locator.ts +78 -0
  46. package/src/athena/api-matcher.ts +323 -0
  47. package/src/athena/athena.ts +224 -0
  48. package/src/athena/column.ts +4 -0
  49. package/src/athena/context.ts +47 -0
  50. package/src/athena/index.ts +13 -0
  51. package/src/athena/service-table.ts +78 -0
  52. package/src/athena/sql-file.ts +161 -0
  53. package/src/athena/types.ts +568 -0
  54. package/src/athena/validate.ts +902 -0
  55. package/src/athena/visitor.ts +406 -0
  56. package/src/get-documentation-url.ts +7 -0
  57. package/src/index.ts +67 -0
  58. package/src/openapi/deref-schema.ts +20 -0
  59. package/src/openapi/generate-schema.ts +553 -0
  60. package/src/openapi/service-schema-generator.ts +241 -0
  61. package/src/peggy/athena-peggy.ts +22149 -0
  62. package/src/peggy/athena.peggy +2971 -0
  63. package/src/service.ts +11 -0
  64. package/src/services/eslintAthenaPlugin/v1/swagger.schema.deref.json +1931 -0
  65. package/src/services/eslintAthenaPlugin/v2/swagger.schema.deref.json +978 -0
  66. package/src/sql-parser.ts +53 -0
@@ -0,0 +1,619 @@
1
+ // src/athena/validate.ts
2
+ import { strict as assert } from "node:assert";
3
+ import debug from "debug";
4
+ import { JSONPath } from "jsonpath-plus";
5
+ import { matchApi } from "./api-matcher.mjs";
6
+ import { locateApi } from "./api-locator.mjs";
7
+ import {
8
+ createChildContext
9
+ } from "./context.mjs";
10
+ import { buildServiceTables } from "./service-table.mjs";
11
+ import {
12
+ containsCastToArray,
13
+ containsCastToMap,
14
+ containsLambda,
15
+ extractBracketAccessorPath,
16
+ extractColumnRefs,
17
+ extractJsonExtractCalls,
18
+ extractJsonExtractPath,
19
+ fromClauseItems,
20
+ hasFunctionCalls,
21
+ isBaseFrom,
22
+ isJoin,
23
+ isTableExpr,
24
+ isUnnestFrom,
25
+ isValuesFrom
26
+ } from "./visitor.mjs";
27
+ var SYNTAXT_ERROR = "SyntaxError";
28
+ var ATHENA_ERROR = "AthenaError";
29
+ var AthenaError = class extends Error {
30
+ code;
31
+ ast;
32
+ constructor(code, message, ast) {
33
+ super(message);
34
+ this.code = code;
35
+ this.name = "AthenaError";
36
+ if (ast !== void 0) {
37
+ this.ast = ast;
38
+ }
39
+ }
40
+ };
41
+ function offsetToLoc(text, offset) {
42
+ const prefix = text.slice(0, offset);
43
+ const lines = prefix.split("\n");
44
+ return { line: lines.length, column: lines[lines.length - 1]?.length ?? 0 };
45
+ }
46
+ var log = debug("eslint-athena-plugin:athena");
47
+ var ANONYMOUS_TABLE = "<anonymous>";
48
+ var SUBQUERY_TABLE = "<subquery>";
49
+ function resolvedCol(name, schema, ast) {
50
+ return ast !== void 0 ? { name, schema, ast } : { name, schema };
51
+ }
52
+ function getApiSchemas(serviceName, ctx) {
53
+ let schemas = ctx.apiSchemas.get(serviceName);
54
+ if (schemas === void 0) {
55
+ schemas = locateApi(serviceName);
56
+ ctx.apiSchemas.set(serviceName, schemas);
57
+ }
58
+ return schemas;
59
+ }
60
+ function lookupTables(nameOrAlias, ctx) {
61
+ const canonical = ctx.aliases.get(nameOrAlias) ?? nameOrAlias;
62
+ return ctx.tables.get(nameOrAlias) ?? ctx.tables.get(canonical) ?? [];
63
+ }
64
+ function flattenTables(ctx) {
65
+ return [...ctx.tables.values()].flat();
66
+ }
67
+ function resolveReferencedTables(tableRef, allTables, ctx) {
68
+ return tableRef !== void 0 ? lookupTables(tableRef, ctx) : allTables;
69
+ }
70
+ function resolveColumnRefParts(ref) {
71
+ return {
72
+ tableRef: ref.table ?? void 0,
73
+ colRef: typeof ref.column === "string" ? ref.column : void 0
74
+ };
75
+ }
76
+ function resolveServiceTable(select, item, ctx, storageKey) {
77
+ const { table: tableName } = item;
78
+ const key = storageKey ?? tableName;
79
+ try {
80
+ const apiSchemas = getApiSchemas(tableName, ctx);
81
+ if (apiSchemas.length === 0) {
82
+ throw new AthenaError(
83
+ ATHENA_ERROR,
84
+ `service not found: "${tableName}" (no swagger schema located)`,
85
+ item
86
+ );
87
+ }
88
+ const operations = matchApi(select, item, apiSchemas) ?? [];
89
+ ctx.tables.set(key, buildServiceTables(tableName, operations));
90
+ } catch (error) {
91
+ if (error instanceof AthenaError) {
92
+ throw error;
93
+ }
94
+ throw new AthenaError(
95
+ ATHENA_ERROR,
96
+ error instanceof Error ? error.message : String(error),
97
+ item
98
+ );
99
+ }
100
+ }
101
+ function getFunctionAliasName(as) {
102
+ return as?.name.name[0]?.value;
103
+ }
104
+ function extractColumnAliasName(arg) {
105
+ const colRef = arg;
106
+ if (typeof colRef.column === "string") {
107
+ return colRef.column;
108
+ }
109
+ const fnNode = arg;
110
+ if (fnNode.type === "function" && fnNode.args?.value?.length === 0) {
111
+ return fnNode.name?.name?.[0]?.value?.toLowerCase();
112
+ }
113
+ return void 0;
114
+ }
115
+ function isStandaloneUnnest(node) {
116
+ return isUnnestFrom(node) && typeof node.expr.column !== "string";
117
+ }
118
+ function aliasAsSingleton(alias) {
119
+ return alias !== void 0 ? [alias] : [];
120
+ }
121
+ function fromItemTableNames(item) {
122
+ if (isBaseFrom(item) || isJoin(item)) {
123
+ return item.as !== null ? [item.as, item.table] : [item.table];
124
+ }
125
+ if (isTableExpr(item)) {
126
+ return [typeof item.as === "string" ? item.as : SUBQUERY_TABLE];
127
+ }
128
+ if (isValuesFrom(item)) {
129
+ return aliasAsSingleton(getFunctionAliasName(item.as));
130
+ }
131
+ const unknownItem = item;
132
+ if (isStandaloneUnnest(unknownItem)) {
133
+ return aliasAsSingleton(getFunctionAliasName(unknownItem.as ?? void 0));
134
+ }
135
+ return [];
136
+ }
137
+ function restrictToFromClause(select, ctx) {
138
+ const fromNames = new Set(
139
+ fromClauseItems(select).flatMap(fromItemTableNames)
140
+ );
141
+ for (const name of [...ctx.tables.keys()]) {
142
+ if (!fromNames.has(name)) {
143
+ ctx.tables.delete(name);
144
+ }
145
+ }
146
+ }
147
+ function tableIsResolved(tableName, storageKey, ctx) {
148
+ return ctx.tables.has(storageKey) || ctx.tables.has(tableName);
149
+ }
150
+ function registerAliasedTable(tableAlias, columns, ctx) {
151
+ ctx.tables.set(tableAlias, [{ name: tableAlias, columns }]);
152
+ }
153
+ function resolveTableOrJoinItem(select, item, ctx) {
154
+ const { table: tableName, as: alias } = item;
155
+ if (alias !== null) {
156
+ ctx.aliases.set(alias, tableName);
157
+ }
158
+ const storageKey = alias ?? tableName;
159
+ if (!tableIsResolved(tableName, storageKey, ctx)) {
160
+ resolveServiceTable(select, item, ctx, alias ?? void 0);
161
+ }
162
+ }
163
+ function resolveFromClause(select, ctx) {
164
+ for (const item of fromClauseItems(select)) {
165
+ const unknownItem = item;
166
+ if (isStandaloneUnnest(unknownItem)) {
167
+ const tableAlias = getFunctionAliasName(unknownItem.as ?? void 0);
168
+ if (tableAlias !== void 0) {
169
+ const columns = new Map(
170
+ (unknownItem.as?.args.value ?? []).map((columnRef) => {
171
+ const colName = extractColumnAliasName(columnRef) ?? "";
172
+ return [colName, [resolvedCol(colName, {})]];
173
+ })
174
+ );
175
+ registerAliasedTable(tableAlias, columns, ctx);
176
+ }
177
+ } else if (isUnnestFrom(unknownItem)) {
178
+ } else if (isValuesFrom(item)) {
179
+ const tableAlias = getFunctionAliasName(item.as);
180
+ if (tableAlias !== void 0) {
181
+ const columns = new Map(
182
+ item.as.args.value.map((columnRef) => [
183
+ columnRef.column,
184
+ [resolvedCol(columnRef.column, {})]
185
+ ])
186
+ );
187
+ registerAliasedTable(tableAlias, columns, ctx);
188
+ }
189
+ } else if (isTableExpr(item)) {
190
+ const alias = typeof item.as === "string" ? item.as : SUBQUERY_TABLE;
191
+ checkSelect(item.expr.ast, ctx, alias);
192
+ } else if (isJoin(item) || isBaseFrom(item)) {
193
+ resolveTableOrJoinItem(select, item, ctx);
194
+ }
195
+ }
196
+ }
197
+ function extractUnnestMappings(select) {
198
+ const mappings = [];
199
+ for (const item of fromClauseItems(select)) {
200
+ if (!isUnnestFrom(item)) {
201
+ continue;
202
+ }
203
+ const fromColumn = typeof item.expr.column === "string" ? item.expr.column : void 0;
204
+ if (fromColumn === void 0) {
205
+ continue;
206
+ }
207
+ const aliasArgs = item.as?.args.value ?? [];
208
+ const toColumns = [];
209
+ for (const col of aliasArgs) {
210
+ const colName = extractColumnAliasName(col);
211
+ if (colName !== void 0) {
212
+ toColumns.push(colName);
213
+ }
214
+ }
215
+ assert.ok(
216
+ toColumns.length > 0,
217
+ "UNNEST alias must have at least one column name"
218
+ );
219
+ const tableAlias = getFunctionAliasName(item.as ?? void 0);
220
+ mappings.push({
221
+ fromColumn,
222
+ toColumns,
223
+ ...tableAlias !== void 0 ? { tableAlias } : {},
224
+ ast: item.expr
225
+ });
226
+ }
227
+ return mappings;
228
+ }
229
+ function buildUnnestColumnMap(fromColumn, toColumns, sourceSchema, sourceAst, ast, hasKnownApiOperation) {
230
+ if (sourceSchema?.type === "array") {
231
+ const [toColumn] = toColumns;
232
+ assert.ok(toColumn !== void 0);
233
+ return /* @__PURE__ */ new Map([
234
+ [toColumn, [resolvedCol(toColumn, sourceSchema.items, sourceAst)]]
235
+ ]);
236
+ }
237
+ if (sourceSchema?.type === "object") {
238
+ const [keyColumn, valueColumn] = toColumns;
239
+ assert.ok(
240
+ keyColumn !== void 0 && valueColumn !== void 0,
241
+ `UNNEST of map column '${fromColumn}' requires exactly two alias columns (key, value)`
242
+ );
243
+ const addlProps = sourceSchema["additionalProperties"];
244
+ const valueSchema = typeof addlProps === "object" && addlProps !== null ? addlProps : { type: "string" };
245
+ return /* @__PURE__ */ new Map([
246
+ [keyColumn, [resolvedCol(keyColumn, { type: "string" }, sourceAst)]],
247
+ [valueColumn, [resolvedCol(valueColumn, valueSchema, sourceAst)]]
248
+ ]);
249
+ }
250
+ if (!hasKnownApiOperation) {
251
+ return new Map(
252
+ toColumns.map((toColumn) => [toColumn, [resolvedCol(toColumn, {})]])
253
+ );
254
+ }
255
+ throw new AthenaError(
256
+ ATHENA_ERROR,
257
+ `UNNEST source column '${fromColumn}' must resolve to an array or map schema`,
258
+ ast
259
+ );
260
+ }
261
+ function applyUnnestPre(mappings, ctx) {
262
+ const deferred = [];
263
+ for (const { fromColumn, toColumns, tableAlias, ast } of mappings) {
264
+ const ownerTable = flattenTables(ctx).find(
265
+ (table) => table.columns.has(fromColumn)
266
+ );
267
+ if (ownerTable === void 0) {
268
+ deferred.push({
269
+ fromColumn,
270
+ toColumns,
271
+ ...tableAlias !== void 0 ? { tableAlias } : {},
272
+ ast
273
+ });
274
+ continue;
275
+ }
276
+ const sourceColumns = ownerTable.columns.get(fromColumn) ?? [];
277
+ const unnestTableName = `${ownerTable.name ?? ANONYMOUS_TABLE}:<unnested>`;
278
+ const apiOperation = ownerTable.apiOperation !== void 0 ? { apiOperation: ownerTable.apiOperation } : {};
279
+ const unnestColumns = buildUnnestColumnMap(
280
+ fromColumn,
281
+ toColumns,
282
+ sourceColumns[0]?.schema,
283
+ sourceColumns[0]?.ast,
284
+ ast,
285
+ ownerTable.apiOperation !== void 0
286
+ );
287
+ const unnestEntry = [
288
+ { name: unnestTableName, ...apiOperation, columns: unnestColumns }
289
+ ];
290
+ ctx.tables.set(unnestTableName, unnestEntry);
291
+ if (tableAlias !== void 0) {
292
+ ctx.tables.set(tableAlias, unnestEntry);
293
+ }
294
+ }
295
+ return deferred;
296
+ }
297
+ function applyUnnestPost(mappings, columns) {
298
+ for (const { fromColumn, toColumns, ast } of mappings) {
299
+ const sourceColumns = columns.get(fromColumn);
300
+ if (sourceColumns === void 0) {
301
+ throw new AthenaError(
302
+ ATHENA_ERROR,
303
+ `UNNEST source column '${fromColumn}' not found in SELECT`,
304
+ ast
305
+ );
306
+ }
307
+ const unnestColumns = buildUnnestColumnMap(
308
+ fromColumn,
309
+ toColumns,
310
+ sourceColumns[0]?.schema,
311
+ sourceColumns[0]?.ast,
312
+ ast,
313
+ true
314
+ );
315
+ for (const [key, value] of unnestColumns) {
316
+ columns.set(key, value);
317
+ }
318
+ }
319
+ }
320
+ function resolveDefaultSchemaColumn(columnAlias, indexedName, columnAST, columns) {
321
+ const name = columnAlias ?? indexedName;
322
+ columns.set(name, [
323
+ resolvedCol(name, { type: "string" }, columnAST)
324
+ ]);
325
+ }
326
+ function expandWildcard(referencedTables, columns) {
327
+ for (const table of referencedTables) {
328
+ for (const [colName, cols] of table.columns) {
329
+ columns.set(colName, cols);
330
+ }
331
+ }
332
+ }
333
+ function schemaPropertyHint(resolvedColumns) {
334
+ if (resolvedColumns.length === 0) {
335
+ return "";
336
+ }
337
+ const firstSchema = resolvedColumns[0]?.schema;
338
+ if (!resolvedColumns.every(
339
+ (col) => JSON.stringify(col.schema) === JSON.stringify(firstSchema)
340
+ )) {
341
+ return "";
342
+ }
343
+ if (firstSchema?.type !== "object" || firstSchema.properties === void 0) {
344
+ return "";
345
+ }
346
+ const propNames = Object.keys(firstSchema.properties);
347
+ return propNames.length > 0 ? `; available properties: ${propNames.join(", ")}` : "";
348
+ }
349
+ function resolveSchemaAtPath(colRef, propertyAccessor, resolvedColumns, ast) {
350
+ const adjustedPath = `$.${propertyAccessor.substring(1).replace(/(?<sep>\.|\[)/gu, "..properties$<sep>")}`;
351
+ log("adjusted path", adjustedPath);
352
+ const extractedSchemas = resolvedColumns.flatMap(
353
+ (col) => JSONPath({ json: col.schema, path: adjustedPath })
354
+ );
355
+ log("extracted schemas", extractedSchemas);
356
+ if (extractedSchemas.length === 0) {
357
+ throw new AthenaError(
358
+ ATHENA_ERROR,
359
+ `Column "${colRef}" has no property at path "${propertyAccessor}"${schemaPropertyHint(resolvedColumns)}`,
360
+ ast
361
+ );
362
+ }
363
+ return extractedSchemas;
364
+ }
365
+ function navigateSchemaPath(colRef, propertyAccessor, resolvedColumns, colName, columnAST, columns) {
366
+ const errorAst = extractJsonExtractCalls(columnAST)[0]?.fnNode ?? columnAST;
367
+ const extractedSchemas = resolveSchemaAtPath(
368
+ colRef,
369
+ propertyAccessor,
370
+ resolvedColumns,
371
+ errorAst
372
+ );
373
+ columns.set(
374
+ colName,
375
+ extractedSchemas.map(
376
+ (schema) => resolvedCol(colName, schema, columnAST)
377
+ )
378
+ );
379
+ }
380
+ function throwUnknownTableError(tableRef, colRef, ctx, ref) {
381
+ throw new AthenaError(
382
+ ATHENA_ERROR,
383
+ `Table or alias "${tableRef ?? colRef}" does not exist. Known tables: ${[...ctx.tables.keys()].join(", ")}`,
384
+ ref
385
+ );
386
+ }
387
+ function resolveReferencedTablesOrThrow(tableRef, colRef, allTables, ctx, ref) {
388
+ const referencedTables = resolveReferencedTables(tableRef, allTables, ctx);
389
+ if (referencedTables.length === 0) {
390
+ throwUnknownTableError(tableRef, colRef, ctx, ref);
391
+ }
392
+ return referencedTables;
393
+ }
394
+ function lookupColumnOrThrow(colRef, ref, referencedTables) {
395
+ const resolvedColumns = referencedTables.flatMap(
396
+ (table) => table.columns.get(colRef) ?? []
397
+ );
398
+ if (resolvedColumns.length === 0) {
399
+ const tableNames = [
400
+ ...new Set(
401
+ referencedTables.map(
402
+ (referenceTable) => referenceTable.name ?? ANONYMOUS_TABLE
403
+ )
404
+ )
405
+ ].join(", ");
406
+ const availableCols = [
407
+ ...new Set(
408
+ referencedTables.flatMap((table) => [...table.columns.keys()])
409
+ )
410
+ ].join(", ");
411
+ throw new AthenaError(
412
+ ATHENA_ERROR,
413
+ `Column "${colRef}" does not exist in table(s) ${tableNames}. Available columns: ${availableCols}`,
414
+ ref
415
+ );
416
+ }
417
+ return resolvedColumns;
418
+ }
419
+ function checkColumnRefsExist(ast, allTables, ctx, selectColumns) {
420
+ if (containsLambda(ast)) {
421
+ return;
422
+ }
423
+ for (const ref of extractColumnRefs(ast)) {
424
+ const { tableRef, colRef } = resolveColumnRefParts(ref);
425
+ if (colRef === void 0 || colRef === "*") {
426
+ continue;
427
+ }
428
+ if (tableRef === void 0 && selectColumns?.has(colRef) === true) {
429
+ continue;
430
+ }
431
+ const referencedTables = resolveReferencedTablesOrThrow(
432
+ tableRef,
433
+ colRef,
434
+ allTables,
435
+ ctx,
436
+ ref
437
+ );
438
+ lookupColumnOrThrow(colRef, ref, referencedTables);
439
+ }
440
+ }
441
+ function validateComplexColumnExpression(columnAST, allTables, ctx) {
442
+ for (const { ref, path, fnNode } of extractJsonExtractCalls(columnAST)) {
443
+ const { tableRef, colRef } = resolveColumnRefParts(ref);
444
+ if (colRef === void 0) {
445
+ continue;
446
+ }
447
+ const referencedTables = resolveReferencedTables(tableRef, allTables, ctx);
448
+ const resolvedColumns = referencedTables.flatMap(
449
+ (table) => table.columns.get(colRef) ?? []
450
+ );
451
+ if (resolvedColumns.length > 0) {
452
+ resolveSchemaAtPath(colRef, path, resolvedColumns, fnNode);
453
+ }
454
+ }
455
+ }
456
+ function resolveSingleColumnRef(columnAST, columnAlias, indexedName, ref, allTables, ctx, columns) {
457
+ const { tableRef, colRef } = resolveColumnRefParts(ref);
458
+ assert.ok(colRef !== void 0, "column_ref must have a string column name");
459
+ const referencedTables = resolveReferencedTablesOrThrow(
460
+ tableRef,
461
+ colRef,
462
+ allTables,
463
+ ctx,
464
+ ref
465
+ );
466
+ if (colRef === "*") {
467
+ expandWildcard(referencedTables, columns);
468
+ return;
469
+ }
470
+ const withFunctions = hasFunctionCalls(columnAST);
471
+ const colName = columnAlias ?? (withFunctions ? indexedName : colRef);
472
+ const resolvedColumns = lookupColumnOrThrow(colRef, ref, referencedTables);
473
+ const propertyAccessor = extractJsonExtractPath(columnAST) ?? extractBracketAccessorPath(columnAST);
474
+ if (propertyAccessor !== void 0) {
475
+ navigateSchemaPath(
476
+ colRef,
477
+ propertyAccessor,
478
+ resolvedColumns,
479
+ colName,
480
+ columnAST,
481
+ columns
482
+ );
483
+ return;
484
+ }
485
+ columns.set(
486
+ colName,
487
+ resolvedColumns.map(
488
+ (col) => resolvedCol(colName, col.schema, columnAST)
489
+ )
490
+ );
491
+ }
492
+ function applySchemaTypeOverride(columnAST, columnAlias, indexedName, columns, predicate, schemaType) {
493
+ if (!predicate(columnAST)) {
494
+ return;
495
+ }
496
+ const colName = columnAlias ?? indexedName;
497
+ const existing = columns.get(colName);
498
+ if (existing !== void 0 && existing[0]?.schema.type !== schemaType) {
499
+ columns.set(
500
+ colName,
501
+ existing.map(
502
+ (col) => resolvedCol(col.name, { type: schemaType }, col.ast)
503
+ )
504
+ );
505
+ }
506
+ }
507
+ function validateClauseExpression(expression, allTables, ctx, selectColumns) {
508
+ checkColumnRefsExist(expression, allTables, ctx, selectColumns);
509
+ validateComplexColumnExpression(expression, allTables, ctx);
510
+ }
511
+ function resolveSelectColumns(select, ctx) {
512
+ const allTables = flattenTables(ctx);
513
+ const columns = /* @__PURE__ */ new Map();
514
+ for (const [index, columnAST] of select.columns.entries()) {
515
+ log("resolving column", columnAST);
516
+ const columnAlias = columnAST.as ?? void 0;
517
+ const indexedName = `_col${String(index)}`;
518
+ const columnRefs = extractColumnRefs(columnAST);
519
+ if (columnRefs.length !== 1) {
520
+ validateClauseExpression(columnAST, allTables, ctx);
521
+ resolveDefaultSchemaColumn(columnAlias, indexedName, columnAST, columns);
522
+ } else {
523
+ const [ref] = columnRefs;
524
+ assert.ok(ref !== void 0);
525
+ resolveSingleColumnRef(
526
+ columnAST,
527
+ columnAlias,
528
+ indexedName,
529
+ ref,
530
+ allTables,
531
+ ctx,
532
+ columns
533
+ );
534
+ }
535
+ applySchemaTypeOverride(
536
+ columnAST,
537
+ columnAlias,
538
+ indexedName,
539
+ columns,
540
+ containsCastToArray,
541
+ "array"
542
+ );
543
+ applySchemaTypeOverride(
544
+ columnAST,
545
+ columnAlias,
546
+ indexedName,
547
+ columns,
548
+ containsCastToMap,
549
+ "object"
550
+ );
551
+ }
552
+ return columns;
553
+ }
554
+ function checkSelect(selectAST, ctx, withTableName) {
555
+ const select = "stmt" in selectAST ? selectAST.stmt.ast : selectAST;
556
+ const selectCtx = createChildContext(ctx);
557
+ resolveFromClause(select, selectCtx);
558
+ restrictToFromClause(select, selectCtx);
559
+ const unnestMappings = extractUnnestMappings(select);
560
+ const deferredUnnest = applyUnnestPre(unnestMappings, selectCtx);
561
+ const columns = resolveSelectColumns(select, selectCtx);
562
+ applyUnnestPost(deferredUnnest, columns);
563
+ log("resolved columns", [...columns.keys()]);
564
+ const allTables = flattenTables(selectCtx);
565
+ for (const item of fromClauseItems(select)) {
566
+ const onExpr = item.on;
567
+ if (onExpr !== void 0) {
568
+ validateClauseExpression(onExpr, allTables, selectCtx);
569
+ }
570
+ }
571
+ if (select.where !== null) {
572
+ validateClauseExpression(select.where, allTables, selectCtx);
573
+ }
574
+ if (select.having !== null) {
575
+ validateClauseExpression(select.having, allTables, selectCtx, columns);
576
+ }
577
+ for (const orderItem of select.orderby ?? []) {
578
+ validateClauseExpression(orderItem.expr, allTables, selectCtx, columns);
579
+ }
580
+ if (select.groupby?.columns !== void 0) {
581
+ for (const groupCol of select.groupby.columns) {
582
+ validateClauseExpression(groupCol, allTables, selectCtx, columns);
583
+ }
584
+ }
585
+ if (select._next !== void 0) {
586
+ const nextColumns = checkSelect(select._next, ctx, withTableName);
587
+ if (columns.size !== nextColumns.size) {
588
+ throw new AthenaError(
589
+ ATHENA_ERROR,
590
+ `UNION ALL parts have different number of columns: ${columns.size.toString()} vs ${nextColumns.size.toString()}`,
591
+ select._next
592
+ );
593
+ }
594
+ }
595
+ if (withTableName !== void 0) {
596
+ const resolvedTable = { name: withTableName, columns };
597
+ ctx.tables.set(withTableName, [resolvedTable]);
598
+ }
599
+ return columns;
600
+ }
601
+ function checkAthenaAst(ast, ctx) {
602
+ assert.ok(ast.type === "select");
603
+ const select = ast;
604
+ if (select.with !== null) {
605
+ for (const withItem of select.with) {
606
+ checkSelect(withItem.stmt.ast, ctx, withItem.name.value);
607
+ }
608
+ select.with = null;
609
+ }
610
+ checkSelect(select, ctx);
611
+ }
612
+ export {
613
+ ATHENA_ERROR,
614
+ AthenaError,
615
+ SYNTAXT_ERROR,
616
+ checkAthenaAst,
617
+ offsetToLoc
618
+ };
619
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2F0aGVuYS92YWxpZGF0ZS50cyJdLAogICJtYXBwaW5ncyI6ICI7QUFVQSxTQUFTLFVBQVUsY0FBYztBQUVqQyxPQUFPLFdBQVc7QUFDbEIsU0FBUyxnQkFBZ0I7QUFJekIsU0FBUyxnQkFBZ0I7QUFDekIsU0FBUyxpQkFBaUI7QUFDMUI7QUFBQSxFQUNFO0FBQUEsT0FJSztBQUNQLFNBQVMsMEJBQTBCO0FBQ25DO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxPQUVLO0FBRUEsSUFBTSxnQkFBZ0I7QUFDdEIsSUFBTSxlQUFlO0FBRXJCLElBQU0sY0FBTixjQUEwQixNQUFNO0FBQUEsRUFDOUI7QUFBQSxFQUNBO0FBQUEsRUFDUCxZQUFZLE1BQWMsU0FBaUIsS0FBYztBQUN2RCxVQUFNLE9BQU87QUFDYixTQUFLLE9BQU87QUFDWixTQUFLLE9BQU87QUFDWixRQUFJLFFBQVEsUUFBVztBQUNyQixXQUFLLE1BQU07QUFBQSxJQUNiO0FBQUEsRUFDRjtBQUNGO0FBR08sU0FBUyxZQUNkLE1BQ0EsUUFDa0M7QUFDbEMsUUFBTSxTQUFTLEtBQUssTUFBTSxHQUFHLE1BQU07QUFDbkMsUUFBTSxRQUFRLE9BQU8sTUFBTSxJQUFJO0FBQy9CLFNBQU8sRUFBRSxNQUFNLE1BQU0sUUFBUSxRQUFRLE1BQU0sTUFBTSxTQUFTLENBQUMsR0FBRyxVQUFVLEVBQUU7QUFDNUU7QUFFQSxJQUFNLE1BQU0sTUFBTSw2QkFBNkI7QUFDL0MsSUFBTSxrQkFBa0I7QUFDeEIsSUFBTSxpQkFBaUI7QUFNdkIsU0FBUyxZQUNQLE1BQ0EsUUFDQSxLQUNnQjtBQUNoQixTQUFPLFFBQVEsU0FBWSxFQUFFLE1BQU0sUUFBUSxJQUFJLElBQUks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