typesql-cli 0.5.18 → 0.6.2

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 (55) hide show
  1. package/code-generator.d.ts +3 -0
  2. package/code-generator.d.ts.map +1 -1
  3. package/code-generator.js +88 -12
  4. package/code-generator.js.map +1 -1
  5. package/describe-nested-query.d.ts +29 -0
  6. package/describe-nested-query.d.ts.map +1 -0
  7. package/describe-nested-query.js +154 -0
  8. package/describe-nested-query.js.map +1 -0
  9. package/describe-query.d.ts +2 -1
  10. package/describe-query.d.ts.map +1 -1
  11. package/describe-query.js +20 -21
  12. package/describe-query.js.map +1 -1
  13. package/mysql-mapping.d.ts +1 -1
  14. package/mysql-mapping.d.ts.map +1 -1
  15. package/mysql-mapping.js +1 -1
  16. package/mysql-mapping.js.map +1 -1
  17. package/mysql-query-analyzer/collect-constraints.d.ts +24 -50
  18. package/mysql-query-analyzer/collect-constraints.d.ts.map +1 -1
  19. package/mysql-query-analyzer/collect-constraints.js +52 -1757
  20. package/mysql-query-analyzer/collect-constraints.js.map +1 -1
  21. package/mysql-query-analyzer/infer-column-nullability.d.ts +3 -3
  22. package/mysql-query-analyzer/infer-column-nullability.d.ts.map +1 -1
  23. package/mysql-query-analyzer/infer-column-nullability.js +14 -26
  24. package/mysql-query-analyzer/infer-column-nullability.js.map +1 -1
  25. package/mysql-query-analyzer/infer-param-nullability.d.ts +3 -1
  26. package/mysql-query-analyzer/infer-param-nullability.d.ts.map +1 -1
  27. package/mysql-query-analyzer/infer-param-nullability.js +21 -3
  28. package/mysql-query-analyzer/infer-param-nullability.js.map +1 -1
  29. package/mysql-query-analyzer/parse.d.ts +10 -10
  30. package/mysql-query-analyzer/parse.d.ts.map +1 -1
  31. package/mysql-query-analyzer/parse.js +133 -181
  32. package/mysql-query-analyzer/parse.js.map +1 -1
  33. package/mysql-query-analyzer/select-columns.d.ts +9 -9
  34. package/mysql-query-analyzer/select-columns.d.ts.map +1 -1
  35. package/mysql-query-analyzer/select-columns.js +32 -226
  36. package/mysql-query-analyzer/select-columns.js.map +1 -1
  37. package/mysql-query-analyzer/traverse.d.ts +45 -0
  38. package/mysql-query-analyzer/traverse.d.ts.map +1 -0
  39. package/mysql-query-analyzer/traverse.js +1613 -0
  40. package/mysql-query-analyzer/traverse.js.map +1 -0
  41. package/mysql-query-analyzer/types.d.ts +39 -5
  42. package/mysql-query-analyzer/types.d.ts.map +1 -1
  43. package/mysql-query-analyzer/unify.d.ts +4 -3
  44. package/mysql-query-analyzer/unify.d.ts.map +1 -1
  45. package/mysql-query-analyzer/unify.js +542 -51
  46. package/mysql-query-analyzer/unify.js.map +1 -1
  47. package/mysql-query-analyzer/verify-multiple-result.js +1 -1
  48. package/mysql-query-analyzer/verify-multiple-result.js.map +1 -1
  49. package/package.json +2 -2
  50. package/ts-nested-descriptor.d.ts +26 -0
  51. package/ts-nested-descriptor.d.ts.map +1 -0
  52. package/ts-nested-descriptor.js +73 -0
  53. package/ts-nested-descriptor.js.map +1 -0
  54. package/types.d.ts +12 -8
  55. package/types.d.ts.map +1 -1
@@ -0,0 +1,1613 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyMultipleResult2 = exports.isMultipleRowResult = exports.selectAllColumns = exports.filterColumns = exports.traverseWithClause = exports.traverseQuerySpecification = exports.getUpdateColumns = exports.traverseDeleteStatement = exports.traverseInsertStatement = exports.traverseQueryContext = void 0;
4
+ const ts_mysql_parser_1 = require("ts-mysql-parser");
5
+ const describe_query_1 = require("../describe-query");
6
+ const parse_1 = require("./parse");
7
+ const collect_constraints_1 = require("./collect-constraints");
8
+ const select_columns_1 = require("./select-columns");
9
+ const infer_column_nullability_1 = require("./infer-column-nullability");
10
+ const infer_param_nullability_1 = require("./infer-param-nullability");
11
+ const util_1 = require("./util");
12
+ function traverseQueryContext(queryContext, dbSchema, namedParameters) {
13
+ var _a, _b, _c, _d;
14
+ const constraints = [];
15
+ const parameters = [];
16
+ const selectStatement = (_a = queryContext.simpleStatement()) === null || _a === void 0 ? void 0 : _a.selectStatement();
17
+ if (selectStatement) {
18
+ const typeInfer = traverseSelectStatement(selectStatement, constraints, parameters, dbSchema, namedParameters);
19
+ return typeInfer;
20
+ }
21
+ const insertStatement = (_b = queryContext.simpleStatement()) === null || _b === void 0 ? void 0 : _b.insertStatement();
22
+ if (insertStatement) {
23
+ return traverseInsertStatement(insertStatement, constraints, parameters, dbSchema);
24
+ }
25
+ const updateStatement = (_c = queryContext.simpleStatement()) === null || _c === void 0 ? void 0 : _c.updateStatement();
26
+ if (updateStatement) {
27
+ const typeInfer = traverseUpdateStatement(updateStatement, constraints, parameters, dbSchema, namedParameters);
28
+ return typeInfer;
29
+ }
30
+ const deleteStatement = (_d = queryContext.simpleStatement()) === null || _d === void 0 ? void 0 : _d.deleteStatement();
31
+ if (deleteStatement) {
32
+ const typeInfer = traverseDeleteStatement(deleteStatement, constraints, parameters, dbSchema);
33
+ return typeInfer;
34
+ }
35
+ throw Error('traverseSql - not supported: ' + queryContext.constructor.name);
36
+ }
37
+ exports.traverseQueryContext = traverseQueryContext;
38
+ function traverseSelectStatement(selectStatement, constraints, parameters, dbSchema, namedParameters) {
39
+ const queryExpression = selectStatement.queryExpression();
40
+ if (queryExpression) {
41
+ const withClause = queryExpression.withClause();
42
+ const withSchema = [];
43
+ if (withClause) {
44
+ traverseWithClause(withClause, constraints, parameters, dbSchema, withSchema);
45
+ }
46
+ const queryExpressionBody = queryExpression.queryExpressionBody();
47
+ if (queryExpressionBody) {
48
+ const result = traverseQueryExpressionBody(queryExpressionBody, constraints, parameters, dbSchema, withSchema, []);
49
+ const orderByParameters = (0, parse_1.extractOrderByParameters)(selectStatement);
50
+ const limitParameters = (0, parse_1.extractLimitParameters)(selectStatement);
51
+ const paramInference = (0, infer_param_nullability_1.inferParamNullabilityQueryExpression)(queryExpression);
52
+ const allParameters = parameters
53
+ .map((param, index) => {
54
+ const param2 = {
55
+ name: param.name,
56
+ type: param,
57
+ notNull: paramInference[index],
58
+ table: ''
59
+ };
60
+ return param2;
61
+ });
62
+ const paramIndexes = (0, util_1.getParameterIndexes)(namedParameters.slice(0, allParameters.length)); //for [a, a, b, a] will return a: [0, 1, 3]; b: [2]
63
+ paramIndexes.forEach(paramIndex => {
64
+ (0, util_1.getPairWise)(paramIndex.indexes, (cur, next) => {
65
+ constraints.push({
66
+ expression: paramIndex.paramName,
67
+ type1: allParameters[cur].type,
68
+ type2: allParameters[next].type
69
+ });
70
+ });
71
+ });
72
+ const isMultiRow = isMultipleRowResult(selectStatement, result.fromColumns);
73
+ const traverseResult = {
74
+ type: 'Select',
75
+ constraints,
76
+ columns: result.columns,
77
+ parameters: allParameters,
78
+ limitParameters,
79
+ isMultiRow
80
+ };
81
+ const orderByColumns = orderByParameters.length > 0 ? getOrderByColumns(result.fromColumns, result.columns) : undefined;
82
+ if (orderByColumns) {
83
+ traverseResult.orderByColumns = orderByColumns;
84
+ }
85
+ return traverseResult;
86
+ }
87
+ }
88
+ throw Error('traverseSelectStatement - not supported: ' + selectStatement.text);
89
+ }
90
+ function traverseInsertStatement(insertStatement, constraints, parameters, dbSchema) {
91
+ var _a, _b;
92
+ const allParameters = [];
93
+ const paramsNullability = {};
94
+ let exprOrDefaultList = [];
95
+ const valuesContext = (_a = insertStatement.insertFromConstructor()) === null || _a === void 0 ? void 0 : _a.insertValues().valueList().values();
96
+ if (valuesContext) {
97
+ exprOrDefaultList = valuesContext.map(valueContext => { var _a; return ((_a = valueContext.children) === null || _a === void 0 ? void 0 : _a.filter(valueContext => valueContext instanceof ts_mysql_parser_1.ExprIsContext || valueContext.text == 'DEFAULT')) || []; });
98
+ }
99
+ const insertIntoTable = (0, collect_constraints_1.getInsertIntoTable)(insertStatement);
100
+ const fromColumns = dbSchema
101
+ .filter(c => c.table == insertIntoTable)
102
+ .map(c => {
103
+ const col = {
104
+ table: c.table,
105
+ columnName: c.column,
106
+ columnType: (0, collect_constraints_1.freshVar)(c.column, c.column_type),
107
+ columnKey: c.columnKey,
108
+ notNull: c.notNull
109
+ };
110
+ return col;
111
+ });
112
+ const insertColumns = (0, collect_constraints_1.getInsertColumns)(insertStatement, fromColumns);
113
+ exprOrDefaultList.forEach(exprOrDefault => {
114
+ exprOrDefault.forEach((expr, index) => {
115
+ const column = insertColumns[index];
116
+ if (expr instanceof ts_mysql_parser_1.ExprContext) {
117
+ const numberParamsBefore = parameters.length;
118
+ const exprType = traverseExpr(expr, constraints, parameters, dbSchema, [], fromColumns);
119
+ const paramNullabilityExpr = (0, infer_param_nullability_1.inferParamNullability)(expr);
120
+ parameters.slice(numberParamsBefore).forEach(param => {
121
+ paramsNullability[param.id] = paramNullabilityExpr.every(n => n) && column.notNull;
122
+ });
123
+ constraints.push({
124
+ expression: expr.text,
125
+ //TODO - CHANGING ORDER SHOULDN'T AFFECT THE TYPE INFERENCE
126
+ type1: exprType.kind == 'TypeOperator' ? exprType.types[0] : exprType,
127
+ type2: (0, collect_constraints_1.freshVar)(column.columnName, column.columnType.type)
128
+ });
129
+ }
130
+ else {
131
+ }
132
+ });
133
+ });
134
+ const updateList = ((_b = insertStatement.insertUpdateList()) === null || _b === void 0 ? void 0 : _b.updateList().updateElement()) || [];
135
+ updateList.forEach(updateElement => {
136
+ const columnName = updateElement.columnRef().text;
137
+ const field = (0, select_columns_1.splitName)(columnName);
138
+ const expr = updateElement.expr();
139
+ if (expr) {
140
+ const numberParamsBefore = parameters.length;
141
+ const exprType = traverseExpr(expr, constraints, parameters, dbSchema, /*withSchema*/ [], fromColumns);
142
+ const column = (0, select_columns_1.findColumn)(field, fromColumns);
143
+ parameters.slice(numberParamsBefore).forEach(param => {
144
+ paramsNullability[param.id] = column.notNull;
145
+ });
146
+ constraints.push({
147
+ expression: expr.text,
148
+ type1: exprType,
149
+ type2: (0, collect_constraints_1.freshVar)(column.columnName, column.columnType.type)
150
+ });
151
+ }
152
+ });
153
+ const insertQueryExpression = insertStatement.insertQueryExpression();
154
+ if (insertQueryExpression) {
155
+ //TODO - REMOVE numberParamsBefore (walk first insertQueryExpression)
156
+ const numberParamsBefore = parameters.length;
157
+ const exprTypes = traverseInsertQueryExpression(insertQueryExpression, constraints, parameters, dbSchema, /*withSchema*/ [], fromColumns);
158
+ exprTypes.columns.forEach((type, index) => {
159
+ const column = insertColumns[index];
160
+ if (type.type.kind == 'TypeVar') {
161
+ paramsNullability[type.type.id] = column.notNull;
162
+ }
163
+ constraints.push({
164
+ expression: insertQueryExpression.text,
165
+ type1: type.type,
166
+ type2: (0, collect_constraints_1.freshVar)(column.columnName, column.columnType.type)
167
+ });
168
+ });
169
+ const paramNullabilityExpr = (0, infer_param_nullability_1.inferParamNullabilityQuery)(insertQueryExpression);
170
+ parameters.slice(numberParamsBefore).forEach((param, index) => {
171
+ if (paramsNullability[param.id] == null) {
172
+ paramsNullability[param.id] = paramNullabilityExpr[index];
173
+ }
174
+ });
175
+ }
176
+ const typeInfo = (0, collect_constraints_1.generateTypeInfo)(parameters, constraints);
177
+ typeInfo.forEach((param, index) => {
178
+ const paramId = parameters[index].id;
179
+ allParameters.push({
180
+ name: 'param' + (allParameters.length + 1),
181
+ columnType: (0, describe_query_1.verifyNotInferred)(param),
182
+ notNull: paramsNullability[paramId]
183
+ });
184
+ });
185
+ const typeInferenceResult = {
186
+ type: 'Insert',
187
+ constraints: constraints,
188
+ parameters: allParameters
189
+ };
190
+ return typeInferenceResult;
191
+ }
192
+ exports.traverseInsertStatement = traverseInsertStatement;
193
+ function traverseUpdateStatement(updateStatement, constraints, parameters, dbSchema, namedParamters) {
194
+ var _a;
195
+ const updateElement = updateStatement.updateList().updateElement();
196
+ const withClause = updateStatement.withClause();
197
+ const withSchema = [];
198
+ if (withClause) {
199
+ traverseWithClause(withClause, constraints, parameters, dbSchema, withSchema);
200
+ }
201
+ const updateColumns = getUpdateColumns(updateStatement, constraints, parameters, dbSchema, withSchema, []);
202
+ const dataTypes = [];
203
+ const whereParameters = [];
204
+ const paramsBefore = parameters.length;
205
+ const whereExpr = (_a = updateStatement.whereClause()) === null || _a === void 0 ? void 0 : _a.expr();
206
+ const paramNullability = (0, infer_param_nullability_1.inferParamNullability)(updateStatement);
207
+ updateElement.forEach(updateElement => {
208
+ const expr = updateElement.expr();
209
+ if (expr) {
210
+ const result = traverseExpr(expr, constraints, parameters, dbSchema, withSchema, updateColumns);
211
+ const columnName = updateElement.columnRef().text;
212
+ const field = (0, select_columns_1.splitName)(columnName);
213
+ const column = (0, select_columns_1.findColumn)(field, updateColumns);
214
+ constraints.push({
215
+ expression: updateStatement.text,
216
+ type1: result,
217
+ type2: column.columnType //freshVar(column.columnName, )
218
+ });
219
+ parameters.slice(paramsBefore, parameters.length).forEach((param, index) => {
220
+ dataTypes.push({
221
+ name: namedParamters[paramsBefore + index] || field.name,
222
+ type: param,
223
+ notNull: column.notNull && !(0, infer_column_nullability_1.possibleNull)(field, expr),
224
+ table: ''
225
+ });
226
+ });
227
+ }
228
+ });
229
+ const paramsAfter = parameters.length;
230
+ if (whereExpr) {
231
+ traverseExpr(whereExpr, constraints, parameters, dbSchema, withSchema, updateColumns);
232
+ }
233
+ parameters.slice(0, paramsBefore).forEach((param, index) => {
234
+ whereParameters.push({
235
+ name: namedParamters[index] || 'param' + (whereParameters.length + 1),
236
+ type: param,
237
+ notNull: paramNullability[index],
238
+ table: ''
239
+ });
240
+ });
241
+ parameters.slice(paramsAfter).forEach((param, index) => {
242
+ whereParameters.push({
243
+ name: namedParamters[paramsAfter + index] || 'param' + (whereParameters.length + 1),
244
+ type: param,
245
+ notNull: paramNullability[paramsAfter + index],
246
+ table: ''
247
+ });
248
+ });
249
+ const typeInferenceResult = {
250
+ type: 'Update',
251
+ constraints,
252
+ data: dataTypes,
253
+ parameters: whereParameters
254
+ };
255
+ return typeInferenceResult;
256
+ }
257
+ function traverseDeleteStatement(deleteStatement, constraints, parameters, dbSchema) {
258
+ var _a;
259
+ const whereExpr = (_a = deleteStatement.whereClause()) === null || _a === void 0 ? void 0 : _a.expr();
260
+ const deleteColumns = (0, collect_constraints_1.getDeleteColumns)(deleteStatement, dbSchema);
261
+ const allParameters = [];
262
+ if (whereExpr) {
263
+ traverseExpr(whereExpr, constraints, parameters, dbSchema, [], deleteColumns);
264
+ const typeInfo = (0, collect_constraints_1.generateTypeInfo)(parameters, constraints);
265
+ const paramNullability = (0, infer_param_nullability_1.inferParamNullability)(whereExpr);
266
+ typeInfo.forEach((param, paramIndex) => {
267
+ allParameters.push({
268
+ name: 'param' + (allParameters.length + 1),
269
+ columnType: (0, describe_query_1.verifyNotInferred)(param),
270
+ notNull: paramNullability[paramIndex]
271
+ });
272
+ });
273
+ }
274
+ const typeInferenceResult = {
275
+ type: 'Delete',
276
+ constraints,
277
+ parameters: allParameters
278
+ };
279
+ return typeInferenceResult;
280
+ }
281
+ exports.traverseDeleteStatement = traverseDeleteStatement;
282
+ function getUpdateColumns(updateStatement, constraints, parameters, dbSchema, withSchema, fromColumns) {
283
+ const tableReferences = updateStatement.tableReferenceList().tableReference();
284
+ const columns = traverseTableReferenceList(tableReferences, constraints, parameters, dbSchema, withSchema, fromColumns);
285
+ return columns;
286
+ }
287
+ exports.getUpdateColumns = getUpdateColumns;
288
+ function traverseInsertQueryExpression(insertQueryExpression, constraints, parameters, dbSchema, withSchema, fromColumns) {
289
+ const queryExpressionOrParens = insertQueryExpression.queryExpressionOrParens();
290
+ return traverseQueryExpressionOrParens(queryExpressionOrParens, constraints, parameters, dbSchema, withSchema, fromColumns);
291
+ }
292
+ function traverseQueryExpressionOrParens(queryExpressionOrParens, constraints, parameters, dbSchema, withSchema, fromColumns) {
293
+ const queryExpression = queryExpressionOrParens.queryExpression();
294
+ if (queryExpression) {
295
+ return traverseQueryExpression(queryExpression, constraints, parameters, dbSchema, withSchema, fromColumns);
296
+ }
297
+ const queryEpressionParens = queryExpressionOrParens.queryExpressionParens();
298
+ if (queryEpressionParens) {
299
+ return traverseQueryExpressionParens(queryEpressionParens, constraints, parameters, dbSchema, withSchema, fromColumns);
300
+ }
301
+ throw Error("walkQueryExpressionOrParens");
302
+ }
303
+ function traverseQueryExpression(queryExpression, constraints, parameters, dbSchema, withSchema, fromColumns, recursive = false) {
304
+ const queryExpressionBody = queryExpression.queryExpressionBody();
305
+ if (queryExpressionBody) {
306
+ return traverseQueryExpressionBody(queryExpressionBody, constraints, parameters, dbSchema, withSchema, fromColumns);
307
+ }
308
+ const queryExpressionParens = queryExpression.queryExpressionParens();
309
+ if (queryExpressionParens) {
310
+ return traverseQueryExpressionParens(queryExpressionParens, constraints, parameters, dbSchema, withSchema, fromColumns, recursive);
311
+ }
312
+ throw Error("walkQueryExpression");
313
+ }
314
+ function traverseQueryExpressionParens(queryExpressionParens, constraints, parameters, dbSchema, withSchema, fromColumns, recursive = false) {
315
+ const queryExpression = queryExpressionParens.queryExpression();
316
+ if (queryExpression) {
317
+ return traverseQueryExpression(queryExpression, constraints, parameters, dbSchema, withSchema, fromColumns, recursive);
318
+ }
319
+ const queryExpressionParens2 = queryExpressionParens.queryExpressionParens();
320
+ if (queryExpressionParens2) {
321
+ return traverseQueryExpressionParens(queryExpressionParens, constraints, parameters, dbSchema, withSchema, fromColumns, recursive);
322
+ }
323
+ throw Error("walkQueryExpressionParens");
324
+ }
325
+ function traverseQueryExpressionBody(queryExpressionBody, constraints, parameters, dbSchema, withSchema, fromColumns, recursiveNames) {
326
+ const subQuery = queryExpressionBody instanceof ts_mysql_parser_1.SubqueryContext ? true : false;
327
+ const allQueries = (0, parse_1.getAllQuerySpecificationsFromSelectStatement)(queryExpressionBody);
328
+ const [first, ...unionQuerySpec] = allQueries;
329
+ const mainQueryResult = traverseQuerySpecification(first, constraints, parameters, dbSchema, withSchema, fromColumns, subQuery);
330
+ const resultTypes = mainQueryResult.columns.map((t, index) => unionQuerySpec.length == 0 ? t.type : (0, collect_constraints_1.freshVar)(recursiveNames && recursiveNames.length > 0 ? recursiveNames[index] : t.name, t.type.type)); //TODO mover para traversequeryspecificat?
331
+ for (let queryIndex = 0; queryIndex < unionQuerySpec.length; queryIndex++) {
332
+ const columnNames = recursiveNames && recursiveNames.length > 0 ? recursiveNames : mainQueryResult.columns.map(col => col.name);
333
+ const newFromColumns = recursiveNames ? renameFromColumns(mainQueryResult.columns, columnNames) : mainQueryResult.fromColumns;
334
+ const unionQuery = unionQuerySpec[queryIndex];
335
+ const unionResult = traverseQuerySpecification(unionQuery, constraints, parameters, dbSchema, withSchema, newFromColumns, subQuery);
336
+ resultTypes.forEach((t2, index) => {
337
+ mainQueryResult.columns[index].notNull = mainQueryResult.columns[index].notNull && unionResult.columns[index].notNull;
338
+ constraints.push({
339
+ expression: 'union',
340
+ coercionType: 'Union',
341
+ mostGeneralType: true,
342
+ type1: t2,
343
+ type2: unionResult.columns[index].type
344
+ });
345
+ });
346
+ }
347
+ const resultTypeAndNotNull = resultTypes.map((c, index) => {
348
+ const col = {
349
+ name: resultTypes[index].name,
350
+ type: resultTypes[index],
351
+ notNull: mainQueryResult.columns[index].notNull,
352
+ table: c.table || ''
353
+ };
354
+ return col;
355
+ });
356
+ const result = {
357
+ columns: resultTypeAndNotNull,
358
+ fromColumns: mainQueryResult.fromColumns
359
+ };
360
+ return result;
361
+ }
362
+ function renameFromColumns(fromColumns, recursiveNames) {
363
+ const newFromColumns = fromColumns.map((col, index) => {
364
+ const newCol = {
365
+ table: "",
366
+ columnName: recursiveNames[index],
367
+ columnType: col.type,
368
+ columnKey: "",
369
+ notNull: col.notNull
370
+ };
371
+ return newCol;
372
+ });
373
+ return newFromColumns;
374
+ }
375
+ function traverseQuerySpecification(querySpec, constraints, parameters, dbSchema, withSchema, fromColumnsParent, subQuery = false) {
376
+ const fromClause = querySpec.fromClause();
377
+ const fromColumns = fromClause ? traverseFromClause(fromClause, constraints, parameters, dbSchema, withSchema, fromColumnsParent) : [];
378
+ const allColumns = subQuery ? fromColumnsParent.concat(fromColumns) : fromColumns; //(... where id = t1.id)
379
+ const selectItemListResult = traverseSelectItemList(querySpec.selectItemList(), constraints, parameters, dbSchema, withSchema, allColumns);
380
+ const whereClause = querySpec.whereClause();
381
+ //TODO - HAVING, BLAH
382
+ if (whereClause) {
383
+ const whereExpr = whereClause === null || whereClause === void 0 ? void 0 : whereClause.expr();
384
+ traverseExpr(whereExpr, constraints, parameters, dbSchema, withSchema, allColumns);
385
+ }
386
+ const columnNullability = (0, infer_column_nullability_1.inferNotNull)(querySpec, dbSchema, allColumns);
387
+ const columns = selectItemListResult.types.map((t, index) => {
388
+ const resultType = {
389
+ name: t.name,
390
+ type: t,
391
+ notNull: columnNullability[index],
392
+ table: t.table || ''
393
+ };
394
+ return resultType;
395
+ });
396
+ const havingClause = querySpec.havingClause();
397
+ if (havingClause) {
398
+ const selectColumns = columns.map(c => {
399
+ const col = {
400
+ table: "",
401
+ columnName: c.name,
402
+ columnType: c.type,
403
+ columnKey: "",
404
+ notNull: c.notNull
405
+ };
406
+ return col;
407
+ });
408
+ traverseHavingClause(havingClause, constraints, parameters, dbSchema, withSchema, selectColumns.concat(fromColumns));
409
+ }
410
+ return {
411
+ columns,
412
+ fromColumns
413
+ };
414
+ }
415
+ exports.traverseQuerySpecification = traverseQuerySpecification;
416
+ function traverseWithClause(withClause, constraints, parameters, dbSchema, withSchema) {
417
+ //result1, result2
418
+ withClause.commonTableExpression().forEach(commonTableExpression => {
419
+ var _a;
420
+ const identifier = commonTableExpression.identifier().text;
421
+ const recursiveNames = withClause.RECURSIVE_SYMBOL() ? ((_a = commonTableExpression.columnInternalRefList()) === null || _a === void 0 ? void 0 : _a.columnInternalRef().map(t => t.text)) || [] : undefined;
422
+ const subQuery = commonTableExpression.subquery();
423
+ const subqueryResult = traverseSubquery(subQuery, constraints, parameters, dbSchema, withSchema, [], recursiveNames); //recursive= true??
424
+ subqueryResult.columns.forEach(col => {
425
+ const withCol = {
426
+ table: identifier,
427
+ columnName: col.name,
428
+ columnType: col.type,
429
+ columnKey: "",
430
+ notNull: col.notNull
431
+ };
432
+ withSchema.push(withCol);
433
+ });
434
+ });
435
+ }
436
+ exports.traverseWithClause = traverseWithClause;
437
+ function traverseFromClause(fromClause, constraints, parameters, dbSchema, withSchema, fromColumnsParent) {
438
+ var _a;
439
+ const tableReferenceList = (_a = fromClause.tableReferenceList()) === null || _a === void 0 ? void 0 : _a.tableReference();
440
+ const fromColumns = tableReferenceList ? traverseTableReferenceList(tableReferenceList, constraints, parameters, dbSchema, withSchema, fromColumnsParent) : [];
441
+ return fromColumns;
442
+ }
443
+ function traverseTableReferenceList(tableReferenceList, constraints, parameters, dbSchema, withSchema, fromColumns) {
444
+ const result = [];
445
+ tableReferenceList.forEach(tab => {
446
+ const tableFactor = tab.tableFactor();
447
+ if (tableFactor) {
448
+ const fields = traverseTableFactor(tableFactor, constraints, parameters, dbSchema, withSchema, fromColumns);
449
+ result.push(...fields);
450
+ }
451
+ const allJoinedColumns = [];
452
+ let firstLeftJoinIndex = -1;
453
+ tab.joinedTable().forEach((joined, index) => {
454
+ var _a, _b;
455
+ if (((_a = joined.innerJoinType()) === null || _a === void 0 ? void 0 : _a.INNER_SYMBOL()) || ((_b = joined.innerJoinType()) === null || _b === void 0 ? void 0 : _b.JOIN_SYMBOL())) {
456
+ firstLeftJoinIndex = -1; //dont need to add notNull = false to joins
457
+ }
458
+ else if (firstLeftJoinIndex == -1) {
459
+ firstLeftJoinIndex = index; //add notNull = false to all joins after the first left join
460
+ }
461
+ const tableReferences = joined.tableReference();
462
+ if (tableReferences) {
463
+ const usingFields = (0, select_columns_1.extractFieldsFromUsingClause)(joined);
464
+ const joinedFields = traverseTableReferenceList([tableReferences], constraints, parameters, dbSchema, withSchema, fromColumns);
465
+ //doesn't duplicate the fields of the USING clause. Ex. INNER JOIN mytable2 USING(id);
466
+ const joinedFieldsFiltered = usingFields.length > 0 ? filterUsingFields(joinedFields, usingFields) : joinedFields;
467
+ allJoinedColumns.push(joinedFieldsFiltered);
468
+ const onClause = joined.expr(); //ON expr
469
+ if (onClause) {
470
+ joinedFieldsFiltered.forEach(field => {
471
+ const fieldName = {
472
+ name: field.columnName,
473
+ prefix: field.tableAlias || ''
474
+ };
475
+ field.notNull = field.notNull || !(0, infer_column_nullability_1.possibleNull)(fieldName, onClause);
476
+ });
477
+ //apply inference to the parent join too
478
+ result.forEach(field => {
479
+ const fieldName = {
480
+ name: field.columnName,
481
+ prefix: field.tableAlias || ''
482
+ };
483
+ field.notNull = field.notNull || !(0, infer_column_nullability_1.possibleNull)(fieldName, onClause);
484
+ });
485
+ traverseExpr(onClause, constraints, parameters, dbSchema, withSchema, allJoinedColumns.flatMap(c => c).concat(result));
486
+ }
487
+ }
488
+ });
489
+ allJoinedColumns.forEach((joinedColumns, index) => {
490
+ joinedColumns.forEach(field => {
491
+ if (firstLeftJoinIndex != -1 && index >= firstLeftJoinIndex) {
492
+ const newField = Object.assign(Object.assign({}, field), { notNull: false });
493
+ result.push(newField);
494
+ }
495
+ else {
496
+ result.push(field);
497
+ }
498
+ });
499
+ });
500
+ });
501
+ return result;
502
+ }
503
+ function traverseTableFactor(tableFactor, constraints, parameters, dbSchema, withSchema, fromColumns) {
504
+ var _a;
505
+ const singleTable = tableFactor.singleTable();
506
+ if (singleTable) {
507
+ return traverseSingleTable(singleTable, constraints, parameters, dbSchema, withSchema);
508
+ }
509
+ const derivadTable = tableFactor.derivedTable();
510
+ if (derivadTable) {
511
+ const tableAlias = (_a = derivadTable.tableAlias()) === null || _a === void 0 ? void 0 : _a.identifier().text;
512
+ const subQuery = derivadTable.subquery();
513
+ if (subQuery) {
514
+ const subQueryResult = traverseSubquery(subQuery, constraints, parameters, dbSchema, withSchema, fromColumns);
515
+ const result = subQueryResult.columns.map(t => {
516
+ const colDef = {
517
+ table: tableAlias || '',
518
+ columnName: t.name,
519
+ columnType: t.type,
520
+ columnKey: "",
521
+ notNull: t.notNull,
522
+ tableAlias: tableAlias
523
+ };
524
+ return colDef;
525
+ });
526
+ return result;
527
+ }
528
+ }
529
+ const tableReferenceListParens = tableFactor.tableReferenceListParens();
530
+ if (tableReferenceListParens) {
531
+ const listParens = traverseTableReferenceListParens(tableReferenceListParens, constraints, parameters, dbSchema, withSchema, fromColumns);
532
+ return listParens;
533
+ }
534
+ throw Error('traverseTableFactor - not supported: ' + tableFactor.constructor.name);
535
+ }
536
+ //tableReferenceList | tableReferenceListParens
537
+ function traverseTableReferenceListParens(ctx, constraints, parameters, dbSchema, withSchema, fromColumns) {
538
+ const tableReferenceList = ctx.tableReferenceList();
539
+ if (tableReferenceList) {
540
+ return traverseTableReferenceList(tableReferenceList.tableReference(), constraints, parameters, dbSchema, withSchema, fromColumns);
541
+ }
542
+ const tableReferenceListParens = ctx.tableReferenceListParens();
543
+ if (tableReferenceListParens) {
544
+ return traverseTableReferenceListParens(tableReferenceListParens, constraints, parameters, dbSchema, withSchema, fromColumns);
545
+ }
546
+ throw Error('traverseTableReferenceListParens - not supported: ' + ctx.constructor.name);
547
+ }
548
+ function traverseSingleTable(singleTable, constraints, parameters, dbSchema, withSchema) {
549
+ var _a;
550
+ const table = singleTable === null || singleTable === void 0 ? void 0 : singleTable.tableRef().text;
551
+ const tableAlias = (_a = singleTable === null || singleTable === void 0 ? void 0 : singleTable.tableAlias()) === null || _a === void 0 ? void 0 : _a.identifier().text;
552
+ const tableName = (0, select_columns_1.splitName)(table);
553
+ const fields = filterColumns(dbSchema, withSchema, tableAlias, tableName);
554
+ return fields;
555
+ }
556
+ function traverseSubquery(subQuery, constraints, parameters, dbSchema, fromColumns, withSchema, recursiveNames) {
557
+ const result = traverseQueryExpressionBody(subQuery, constraints, parameters, dbSchema, fromColumns, withSchema, recursiveNames);
558
+ return result;
559
+ }
560
+ function traverseSelectItemList(selectItemList, constraints, parameters, dbSchema, withSchema, fromColumns) {
561
+ const listType = [];
562
+ if (selectItemList.MULT_OPERATOR()) {
563
+ fromColumns.forEach(col => {
564
+ const columnType = (0, collect_constraints_1.createColumnType)(col);
565
+ listType.push(columnType);
566
+ });
567
+ }
568
+ selectItemList.selectItem().forEach(selectItem => {
569
+ const tableWild = selectItem.tableWild();
570
+ if (tableWild) {
571
+ if (tableWild.MULT_OPERATOR()) {
572
+ const itemName = (0, select_columns_1.splitName)(selectItem.text);
573
+ const allColumns = selectAllColumns(itemName.prefix, fromColumns);
574
+ allColumns.forEach(col => {
575
+ const columnType = (0, collect_constraints_1.createColumnType)(col);
576
+ listType.push(columnType);
577
+ });
578
+ }
579
+ }
580
+ const expr = selectItem.expr();
581
+ if (expr) {
582
+ const exprType = traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
583
+ if (exprType.kind == 'TypeOperator') {
584
+ const subqueryType = exprType.types[0];
585
+ subqueryType.name = (0, select_columns_1.getColumnName)(selectItem);
586
+ listType.push(subqueryType);
587
+ }
588
+ else if (exprType.kind == 'TypeVar') {
589
+ exprType.name = (0, select_columns_1.getColumnName)(selectItem);
590
+ listType.push(Object.assign({}, exprType)); //clone
591
+ }
592
+ }
593
+ });
594
+ const result = {
595
+ kind: 'TypeOperator',
596
+ types: listType
597
+ };
598
+ return result;
599
+ }
600
+ function traverseHavingClause(havingClause, constraints, parameters, dbSchema, withSchema, fromColumns) {
601
+ const havingExpr = havingClause.expr();
602
+ traverseExpr(havingExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
603
+ }
604
+ function traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns) {
605
+ if (expr instanceof ts_mysql_parser_1.ExprIsContext) {
606
+ const boolPri = expr.boolPri();
607
+ const boolPriType = traverseBoolPri(boolPri, constraints, parameters, dbSchema, withSchema, fromColumns);
608
+ return boolPriType;
609
+ }
610
+ if (expr instanceof ts_mysql_parser_1.ExprNotContext) {
611
+ return (0, collect_constraints_1.freshVar)(expr.text, 'tinyint');
612
+ ;
613
+ }
614
+ if (expr instanceof ts_mysql_parser_1.ExprAndContext || expr instanceof ts_mysql_parser_1.ExprXorContext || expr instanceof ts_mysql_parser_1.ExprOrContext) {
615
+ const exprLeft = expr.expr()[0];
616
+ traverseExpr(exprLeft, constraints, parameters, dbSchema, withSchema, fromColumns);
617
+ const exprRight = expr.expr()[1];
618
+ traverseExpr(exprRight, constraints, parameters, dbSchema, withSchema, fromColumns);
619
+ return (0, collect_constraints_1.freshVar)(expr.text, 'tinyint');
620
+ }
621
+ throw Error('traverseExpr - not supported: ' + expr.text);
622
+ }
623
+ function traverseBoolPri(boolPri, constraints, parameters, dbSchema, withSchema, fromColumns) {
624
+ if (boolPri instanceof ts_mysql_parser_1.PrimaryExprPredicateContext) {
625
+ const predicate = boolPri.predicate();
626
+ const predicateType = traversePredicate(predicate, constraints, parameters, dbSchema, withSchema, fromColumns);
627
+ return predicateType;
628
+ }
629
+ if (boolPri instanceof ts_mysql_parser_1.PrimaryExprIsNullContext) {
630
+ const boolPri2 = boolPri.boolPri();
631
+ traverseBoolPri(boolPri2, constraints, parameters, dbSchema, withSchema, fromColumns);
632
+ return (0, collect_constraints_1.freshVar)(boolPri.text, '?');
633
+ }
634
+ if (boolPri instanceof ts_mysql_parser_1.PrimaryExprCompareContext) {
635
+ const compareLeft = boolPri.boolPri();
636
+ const compareRight = boolPri.predicate();
637
+ const typeLeft = traverseBoolPri(compareLeft, constraints, parameters, dbSchema, withSchema, fromColumns);
638
+ const typeRight = traversePredicate(compareRight, constraints, parameters, dbSchema, withSchema, fromColumns);
639
+ constraints.push({
640
+ expression: boolPri.text,
641
+ type1: typeLeft,
642
+ type2: typeRight
643
+ });
644
+ return (0, collect_constraints_1.freshVar)(boolPri.text, 'tinyint');
645
+ }
646
+ if (boolPri instanceof ts_mysql_parser_1.PrimaryExprAllAnyContext) {
647
+ const compareLeft = boolPri.boolPri();
648
+ const compareRight = boolPri.subquery();
649
+ const typeLeft = traverseBoolPri(compareLeft, constraints, parameters, dbSchema, withSchema, fromColumns);
650
+ const subQueryResult = traverseSubquery(compareRight, constraints, parameters, dbSchema, withSchema, fromColumns);
651
+ constraints.push({
652
+ expression: boolPri.text,
653
+ type1: typeLeft,
654
+ type2: {
655
+ kind: 'TypeOperator',
656
+ types: subQueryResult.columns.map(t => t.type)
657
+ }
658
+ });
659
+ return (0, collect_constraints_1.freshVar)(boolPri.text, 'tinyint');
660
+ }
661
+ throw Error('traverseExpr - not supported: ' + boolPri.constructor.name);
662
+ }
663
+ function traversePredicate(predicate, constraints, parameters, dbSchema, withSchema, fromColumns) {
664
+ const bitExpr = predicate.bitExpr()[0]; //TODO - predicate length = 2? [1] == predicateOperations
665
+ const bitExprType = traverseBitExpr(bitExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
666
+ const predicateOperations = predicate.predicateOperations();
667
+ if (predicateOperations) {
668
+ const rightType = traversePredicateOperations(predicateOperations, bitExprType, constraints, parameters, fromColumns, dbSchema, withSchema);
669
+ if (bitExprType.kind == 'TypeOperator' && rightType.kind == 'TypeOperator') {
670
+ rightType.types.forEach((t, i) => {
671
+ constraints.push({
672
+ expression: predicateOperations.text,
673
+ type1: t,
674
+ type2: bitExprType.types[i],
675
+ mostGeneralType: true
676
+ });
677
+ });
678
+ }
679
+ if (bitExprType.kind == 'TypeVar' && rightType.kind == 'TypeOperator') {
680
+ rightType.types.forEach((t, i) => {
681
+ constraints.push({
682
+ expression: predicateOperations.text,
683
+ type1: bitExprType,
684
+ type2: Object.assign(Object.assign({}, t), { list: true }),
685
+ mostGeneralType: true
686
+ });
687
+ });
688
+ // return rightType.types[0];
689
+ }
690
+ return bitExprType;
691
+ }
692
+ return bitExprType;
693
+ }
694
+ function traverseExprList(exprList, constraints, parameters, dbSchema, withSchema, fromColumns) {
695
+ const listType = exprList.expr().map(item => {
696
+ const exprType = traverseExpr(item, constraints, parameters, dbSchema, withSchema, fromColumns);
697
+ return exprType;
698
+ });
699
+ const type = {
700
+ kind: 'TypeOperator',
701
+ types: listType
702
+ };
703
+ return type;
704
+ }
705
+ function traverseBitExpr(bitExpr, constraints, parameters, dbSchema, withSchema, fromColumns) {
706
+ const simpleExpr = bitExpr.simpleExpr();
707
+ if (simpleExpr) {
708
+ return traverseSimpleExpr(simpleExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
709
+ }
710
+ if (bitExpr.bitExpr().length == 2) {
711
+ const bitExprLeft = bitExpr.bitExpr()[0];
712
+ const typeLeftTemp = traverseBitExpr(bitExprLeft, constraints, parameters, dbSchema, withSchema, fromColumns);
713
+ const typeLeft = typeLeftTemp.kind == 'TypeOperator' ? typeLeftTemp.types[0] : typeLeftTemp;
714
+ //const newTypeLeft = typeLeft.name == '?'? freshVar('?', 'bigint') : typeLeft;
715
+ const bitExprRight = bitExpr.bitExpr()[1];
716
+ const typeRightTemp = traverseBitExpr(bitExprRight, constraints, parameters, dbSchema, withSchema, fromColumns);
717
+ //In the expression 'id + (value + 2) + ?' the '(value+2)' is treated as a SimpleExprListContext and return a TypeOperator
718
+ const typeRight = typeRightTemp.kind == 'TypeOperator' ? typeRightTemp.types[0] : typeRightTemp;
719
+ //const newTypeRight = typeRight.name == '?'? freshVar('?', 'bigint') : typeRight;
720
+ const bitExprType = (0, collect_constraints_1.freshVar)(bitExpr.text, '?');
721
+ if (typeLeftTemp.kind == 'TypeVar' && typeRightTemp.kind == 'TypeVar' && typeLeftTemp.table == typeRightTemp.table) {
722
+ bitExprType.table = typeLeftTemp.table;
723
+ }
724
+ //PRECISA?
725
+ // constraints.push({
726
+ // expression: bitExpr.text,
727
+ // type1: typeLeft,
728
+ // type2: typeRight,
729
+ // mostGeneralType: true,
730
+ // coercionType: 'Sum'
731
+ // })
732
+ // constraints.push({
733
+ // expression: bitExpr.text,
734
+ // type1: typeLeft,
735
+ // type2: typeRight,
736
+ // mostGeneralType: true,
737
+ // coercionType: 'Sum'
738
+ // })
739
+ // constraints.push({
740
+ // expression: bitExpr.text,
741
+ // type1: bitExprType,
742
+ // type2: typeRight,
743
+ // mostGeneralType: true,
744
+ // coercionType: 'Sum'
745
+ // })
746
+ constraints.push({
747
+ expression: bitExprLeft.text,
748
+ type1: bitExprType,
749
+ type2: typeLeft,
750
+ mostGeneralType: true,
751
+ coercionType: 'Sum'
752
+ });
753
+ constraints.push({
754
+ expression: bitExprRight.text,
755
+ type1: bitExprType,
756
+ type2: typeRight,
757
+ mostGeneralType: true,
758
+ coercionType: 'Sum'
759
+ });
760
+ // const resultType = freshVar(bitExprRight.text, 'number');
761
+ // constraints.push({
762
+ // expression: bitExprRight.text,
763
+ // type1: resultType,
764
+ // type2: freshVar(bitExprRight.text, 'number'),
765
+ // mostGeneralType: true,
766
+ // coercionType: 'Sum'
767
+ // })
768
+ return bitExprType;
769
+ }
770
+ if (bitExpr.INTERVAL_SYMBOL()) {
771
+ const bitExpr2 = bitExpr.bitExpr()[0];
772
+ const leftType = traverseBitExpr(bitExpr2, constraints, parameters, dbSchema, withSchema, fromColumns);
773
+ const expr = bitExpr.expr(); //expr interval
774
+ traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
775
+ constraints.push({
776
+ expression: bitExpr.text,
777
+ type1: leftType,
778
+ type2: (0, collect_constraints_1.freshVar)('datetime', 'datetime')
779
+ });
780
+ return (0, collect_constraints_1.freshVar)('datetime', 'datetime');
781
+ }
782
+ throw Error('traverseBitExpr - not supported: ' + bitExpr.constructor.name);
783
+ }
784
+ function traversePredicateOperations(predicateOperations, parentType, constraints, parameters, fromColumns, dbSchema, withSchema) {
785
+ if (predicateOperations instanceof ts_mysql_parser_1.PredicateExprInContext) {
786
+ const subquery = predicateOperations.subquery();
787
+ if (subquery) {
788
+ const subQueryResult = traverseSubquery(subquery, constraints, parameters, dbSchema, withSchema, fromColumns);
789
+ return { kind: 'TypeOperator', types: subQueryResult.columns.map(t => t.type) };
790
+ }
791
+ const exprList = predicateOperations.exprList();
792
+ if (exprList) {
793
+ const rightType = traverseExprList(exprList, constraints, parameters, dbSchema, withSchema, fromColumns);
794
+ return rightType;
795
+ }
796
+ }
797
+ if (predicateOperations instanceof ts_mysql_parser_1.PredicateExprLikeContext) {
798
+ const simpleExpr = predicateOperations.simpleExpr()[0];
799
+ const rightType = traverseSimpleExpr(simpleExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
800
+ constraints.push({
801
+ expression: simpleExpr.text,
802
+ type1: parentType,
803
+ type2: rightType
804
+ });
805
+ return rightType;
806
+ }
807
+ throw Error("Not expected");
808
+ }
809
+ function traverseSimpleExpr(simpleExpr, constraints, parameters, dbSchema, withSchema, fromColumns) {
810
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
811
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprColumnRefContext) {
812
+ const fieldName = (0, select_columns_1.splitName)(simpleExpr.text);
813
+ const column = (0, select_columns_1.findColumn)(fieldName, fromColumns.concat(withSchema));
814
+ const typeVar = (0, collect_constraints_1.freshVar)(column.columnName, column.columnType.type, column.tableAlias || column.table);
815
+ constraints.push({
816
+ expression: simpleExpr.text,
817
+ type1: typeVar,
818
+ type2: column.columnType,
819
+ mostGeneralType: true
820
+ });
821
+ return typeVar;
822
+ }
823
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprParamMarkerContext) {
824
+ const param = (0, collect_constraints_1.freshVar)('?', '?');
825
+ parameters.push(param);
826
+ return param;
827
+ }
828
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprLiteralContext) {
829
+ const literal = simpleExpr.literal();
830
+ if (literal.textLiteral()) {
831
+ const text = ((_a = literal.textLiteral()) === null || _a === void 0 ? void 0 : _a.text.slice(1, -1)) || ''; //remove quotes
832
+ return (0, collect_constraints_1.freshVar)(text, 'varchar');
833
+ }
834
+ const numLiteral = literal.numLiteral();
835
+ if (numLiteral) {
836
+ return (0, collect_constraints_1.freshVar)(numLiteral.text, 'int');
837
+ // addNamedNode(simpleExpr, freshVar('bigint', 'bigint'), namedNodes)
838
+ // if(numLiteral.INT_NUMBER()) {
839
+ // const typeInt = freshVar('int', 'int');
840
+ // addNamedNode(simpleExpr, typeInt, namedNodes)
841
+ // }
842
+ // if(numLiteral.DECIMAL_NUMBER()) {
843
+ // const typeDecimal = freshVar('decimal', 'decimal');
844
+ // addNamedNode(simpleExpr, typeDecimal, namedNodes)
845
+ // }
846
+ // if(numLiteral.FLOAT_NUMBER()) {
847
+ // const typeFloat = freshVar('float', 'float');
848
+ // addNamedNode(simpleExpr, typeFloat, namedNodes)
849
+ // }
850
+ ;
851
+ }
852
+ const boolLiteral = literal.boolLiteral();
853
+ if (boolLiteral) {
854
+ return (0, collect_constraints_1.freshVar)(boolLiteral.text, 'bit');
855
+ }
856
+ const nullLiteral = literal.nullLiteral();
857
+ if (nullLiteral) {
858
+ return (0, collect_constraints_1.freshVar)(nullLiteral.text, '?');
859
+ }
860
+ throw Error('literal not supported:' + literal.text);
861
+ //...
862
+ }
863
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprListContext) {
864
+ const exprList = simpleExpr.exprList();
865
+ const listType = exprList.expr().map(item => {
866
+ const exprType = traverseExpr(item, constraints, parameters, dbSchema, withSchema, fromColumns);
867
+ return exprType;
868
+ });
869
+ const resultType = {
870
+ kind: 'TypeOperator',
871
+ types: listType
872
+ };
873
+ return resultType;
874
+ }
875
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprSubQueryContext) {
876
+ const subquery = simpleExpr.subquery();
877
+ const subqueryResult = traverseSubquery(subquery, constraints, parameters, dbSchema, withSchema, fromColumns);
878
+ return {
879
+ kind: 'TypeOperator',
880
+ types: subqueryResult.columns.map(t => (Object.assign(Object.assign({}, t.type), { table: '' })))
881
+ };
882
+ }
883
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprCaseContext) {
884
+ //case when expr then expr else expr
885
+ const caseType = (0, collect_constraints_1.freshVar)(simpleExpr.text, '?');
886
+ simpleExpr.whenExpression().forEach(whenExprCont => {
887
+ const whenExpr = whenExprCont.expr();
888
+ const whenType = traverseExpr(whenExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
889
+ constraints.push({
890
+ expression: whenExpr.text,
891
+ type1: whenType.kind == 'TypeOperator' ? whenType.types[0] : whenType,
892
+ type2: (0, collect_constraints_1.freshVar)('tinyint', 'tinyint') //bool
893
+ });
894
+ });
895
+ const thenTypes = simpleExpr.thenExpression().map(thenExprCtx => {
896
+ const thenExpr = thenExprCtx.expr();
897
+ const thenType = traverseExpr(thenExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
898
+ constraints.push({
899
+ expression: thenExprCtx.text,
900
+ type1: caseType,
901
+ type2: thenType.kind == 'TypeOperator' ? thenType.types[0] : thenType,
902
+ mostGeneralType: true,
903
+ });
904
+ return thenType;
905
+ });
906
+ const elseExpr = (_b = simpleExpr.elseExpression()) === null || _b === void 0 ? void 0 : _b.expr();
907
+ if (elseExpr) {
908
+ const elseType = traverseExpr(elseExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
909
+ constraints.push({
910
+ expression: (_c = simpleExpr.elseExpression()) === null || _c === void 0 ? void 0 : _c.text,
911
+ type1: caseType,
912
+ type2: elseType.kind == 'TypeOperator' ? elseType.types[0] : elseType,
913
+ mostGeneralType: true
914
+ });
915
+ thenTypes.forEach(thenType => {
916
+ var _a;
917
+ constraints.push({
918
+ expression: (_a = simpleExpr.elseExpression()) === null || _a === void 0 ? void 0 : _a.text,
919
+ type1: thenType,
920
+ type2: elseType.kind == 'TypeOperator' ? elseType.types[0] : elseType,
921
+ mostGeneralType: true
922
+ });
923
+ });
924
+ }
925
+ return caseType;
926
+ }
927
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprIntervalContext) {
928
+ const exprList = simpleExpr.expr();
929
+ const exprLeft = exprList[0];
930
+ const exprRight = exprList[1];
931
+ const typeLeft = traverseExpr(exprLeft, constraints, parameters, dbSchema, withSchema, fromColumns);
932
+ const typeRight = traverseExpr(exprRight, constraints, parameters, dbSchema, withSchema, fromColumns);
933
+ constraints.push({
934
+ expression: exprLeft.text,
935
+ type1: typeLeft,
936
+ type2: (0, collect_constraints_1.freshVar)('bigint', 'bigint')
937
+ });
938
+ if (typeRight.kind == 'TypeVar' && ((0, collect_constraints_1.isDateLiteral)(typeRight.name) || (0, collect_constraints_1.isDateTimeLiteral)(typeRight.name))) {
939
+ typeRight.type = 'datetime';
940
+ }
941
+ constraints.push({
942
+ expression: exprRight.text,
943
+ type1: typeRight,
944
+ type2: (0, collect_constraints_1.freshVar)('datetime', 'datetime')
945
+ });
946
+ return (0, collect_constraints_1.freshVar)('datetime', 'datetime');
947
+ }
948
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprSumContext) {
949
+ const sumExpr = simpleExpr.sumExpr();
950
+ if (sumExpr.MAX_SYMBOL() || sumExpr.MIN_SYMBOL()) {
951
+ const functionType = (0, collect_constraints_1.freshVar)(simpleExpr.text, '?');
952
+ const inSumExpr = (_d = sumExpr.inSumExpr()) === null || _d === void 0 ? void 0 : _d.expr();
953
+ if (inSumExpr) {
954
+ const inSumExprType = traverseExpr(inSumExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
955
+ constraints.push({
956
+ expression: simpleExpr.text,
957
+ type1: functionType,
958
+ type2: inSumExprType,
959
+ mostGeneralType: true
960
+ });
961
+ }
962
+ return functionType;
963
+ }
964
+ if (sumExpr.COUNT_SYMBOL()) {
965
+ const functionType = (0, collect_constraints_1.freshVar)(simpleExpr.text, 'bigint');
966
+ const inSumExpr = (_e = sumExpr.inSumExpr()) === null || _e === void 0 ? void 0 : _e.expr();
967
+ if (inSumExpr) {
968
+ traverseExpr(inSumExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
969
+ }
970
+ return functionType;
971
+ }
972
+ if (sumExpr.SUM_SYMBOL() || sumExpr.AVG_SYMBOL()) {
973
+ const functionType = (0, collect_constraints_1.freshVar)(simpleExpr.text, '?');
974
+ const inSumExpr = (_f = sumExpr.inSumExpr()) === null || _f === void 0 ? void 0 : _f.expr();
975
+ if (inSumExpr) {
976
+ const inSumExprType = traverseExpr(inSumExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
977
+ constraints.push({
978
+ expression: simpleExpr.text,
979
+ type1: functionType,
980
+ type2: inSumExprType,
981
+ mostGeneralType: true,
982
+ coercionType: 'SumFunction'
983
+ });
984
+ if (inSumExprType.kind == 'TypeVar') {
985
+ functionType.table = inSumExprType.table;
986
+ }
987
+ }
988
+ return functionType;
989
+ }
990
+ if (sumExpr.GROUP_CONCAT_SYMBOL()) {
991
+ const exprList = sumExpr.exprList();
992
+ if (exprList) {
993
+ exprList.expr().map(item => {
994
+ const exprType = traverseExpr(item, constraints, parameters, dbSchema, withSchema, fromColumns);
995
+ return exprType;
996
+ });
997
+ /*
998
+ The result type is TEXT or BLOB unless group_concat_max_len is less than or equal to 512,
999
+ in which case the result type is VARCHAR or VARBINARY.
1000
+ */
1001
+ //TODO - Infer TEXT/BLOB or VARCHAR/VARBINARY
1002
+ return (0, collect_constraints_1.freshVar)(sumExpr.text, 'varchar');
1003
+ ;
1004
+ }
1005
+ }
1006
+ throw Error('Expression not supported: ' + sumExpr.constructor.name);
1007
+ }
1008
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprRuntimeFunctionContext) {
1009
+ const runtimeFunctionCall = simpleExpr.runtimeFunctionCall();
1010
+ if (runtimeFunctionCall.NOW_SYMBOL()) {
1011
+ return (0, collect_constraints_1.freshVar)(simpleExpr.text, 'datetime');
1012
+ }
1013
+ if (runtimeFunctionCall.CURDATE_SYMBOL()) {
1014
+ return (0, collect_constraints_1.freshVar)(simpleExpr.text, 'date');
1015
+ }
1016
+ if (runtimeFunctionCall.CURTIME_SYMBOL()) {
1017
+ return (0, collect_constraints_1.freshVar)(simpleExpr.text, 'time');
1018
+ }
1019
+ if (runtimeFunctionCall.REPLACE_SYMBOL()) {
1020
+ const exprList = runtimeFunctionCall.expr();
1021
+ exprList.forEach(expr => {
1022
+ const exprType = traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
1023
+ constraints.push({
1024
+ expression: expr.text,
1025
+ type1: exprType,
1026
+ type2: (0, collect_constraints_1.freshVar)('varchar', 'varchar')
1027
+ });
1028
+ });
1029
+ return (0, collect_constraints_1.freshVar)('varchar', 'varchar');
1030
+ }
1031
+ if (runtimeFunctionCall.YEAR_SYMBOL() || runtimeFunctionCall.MONTH_SYMBOL() || runtimeFunctionCall.DAY_SYMBOL()) {
1032
+ const expr = (_g = runtimeFunctionCall.exprWithParentheses()) === null || _g === void 0 ? void 0 : _g.expr();
1033
+ if (expr) {
1034
+ const paramType = traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
1035
+ if (paramType.kind == 'TypeVar' && (0, collect_constraints_1.isDateTimeLiteral)(paramType.name)) {
1036
+ paramType.type = 'datetime';
1037
+ }
1038
+ if (paramType.kind == 'TypeVar' && (0, collect_constraints_1.isDateLiteral)(paramType.name)) {
1039
+ paramType.type = 'date';
1040
+ }
1041
+ constraints.push({
1042
+ expression: expr.text,
1043
+ type1: paramType,
1044
+ type2: (0, collect_constraints_1.freshVar)(simpleExpr.text, 'date')
1045
+ });
1046
+ }
1047
+ const returnType = runtimeFunctionCall.YEAR_SYMBOL() ? 'year' : 'tinyint';
1048
+ return (0, collect_constraints_1.freshVar)(simpleExpr.text, returnType);
1049
+ }
1050
+ if (runtimeFunctionCall.HOUR_SYMBOL() || runtimeFunctionCall.MINUTE_SYMBOL() || runtimeFunctionCall.SECOND_SYMBOL()) {
1051
+ const expr = (_h = runtimeFunctionCall.exprWithParentheses()) === null || _h === void 0 ? void 0 : _h.expr();
1052
+ if (expr) {
1053
+ const paramType = traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
1054
+ if (paramType.kind == 'TypeVar' && (0, collect_constraints_1.isTimeLiteral)(paramType.name)) {
1055
+ paramType.type = 'time';
1056
+ }
1057
+ if (paramType.kind == 'TypeVar' && (0, collect_constraints_1.isDateLiteral)(paramType.name)) {
1058
+ paramType.type = 'date';
1059
+ }
1060
+ if (paramType.kind == 'TypeVar' && (0, collect_constraints_1.isDateTimeLiteral)(paramType.name)) {
1061
+ paramType.type = 'datetime';
1062
+ }
1063
+ constraints.push({
1064
+ expression: expr.text,
1065
+ type1: paramType,
1066
+ type2: (0, collect_constraints_1.freshVar)(simpleExpr.text, 'time')
1067
+ });
1068
+ }
1069
+ //HOUR can return values greater than 23. Ex.: SELECT HOUR('272:59:59');
1070
+ //https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_hour
1071
+ const returnType = runtimeFunctionCall.HOUR_SYMBOL() ? 'int' : 'tinyint';
1072
+ return (0, collect_constraints_1.freshVar)(simpleExpr.text, returnType);
1073
+ }
1074
+ const trimFunction = runtimeFunctionCall.trimFunction();
1075
+ if (trimFunction) {
1076
+ const exprList = trimFunction.expr();
1077
+ if (exprList.length == 1) {
1078
+ const exprType = traverseExpr(exprList[0], constraints, parameters, dbSchema, withSchema, fromColumns);
1079
+ constraints.push({
1080
+ expression: exprList[0].text,
1081
+ type1: exprType,
1082
+ type2: (0, collect_constraints_1.freshVar)('varchar', 'varchar')
1083
+ });
1084
+ }
1085
+ if (exprList.length == 2) {
1086
+ const exprType = traverseExpr(exprList[0], constraints, parameters, dbSchema, withSchema, fromColumns);
1087
+ const expr2Type = traverseExpr(exprList[1], constraints, parameters, dbSchema, withSchema, fromColumns);
1088
+ constraints.push({
1089
+ expression: exprList[0].text,
1090
+ type1: exprType,
1091
+ type2: (0, collect_constraints_1.freshVar)('varchar', 'varchar')
1092
+ });
1093
+ constraints.push({
1094
+ expression: exprList[1].text,
1095
+ type1: expr2Type,
1096
+ type2: (0, collect_constraints_1.freshVar)('varchar', 'varchar')
1097
+ });
1098
+ }
1099
+ return (0, collect_constraints_1.freshVar)('varchar', 'varchar');
1100
+ }
1101
+ const substringFunction = runtimeFunctionCall.substringFunction();
1102
+ if (substringFunction) {
1103
+ const exprList = substringFunction.expr();
1104
+ const varcharParam = (0, collect_constraints_1.freshVar)('varchar', 'varchar');
1105
+ const intParam = (0, collect_constraints_1.freshVar)('int', 'int');
1106
+ const params = {
1107
+ kind: 'FixedLengthParams',
1108
+ paramsType: [varcharParam, intParam, intParam]
1109
+ };
1110
+ traverseExprListParameters(exprList, params, constraints, parameters, dbSchema, withSchema, fromColumns);
1111
+ return varcharParam;
1112
+ }
1113
+ if (runtimeFunctionCall.ADDDATE_SYMBOL()
1114
+ || runtimeFunctionCall.DATE_ADD_SYMBOL()
1115
+ || runtimeFunctionCall.SUBDATE_SYMBOL()
1116
+ || runtimeFunctionCall.DATE_SUB_SYMBOL()) {
1117
+ //SELECT ADDDATE('2008-01-02', INTERVAL 31 DAY)
1118
+ //SELECT ADDDATE('2008-01-02', 31)
1119
+ const expr1 = runtimeFunctionCall.expr()[0];
1120
+ const expr2 = runtimeFunctionCall.expr()[1];
1121
+ const typeExpr1 = traverseExpr(expr1, constraints, parameters, dbSchema, withSchema, fromColumns);
1122
+ const typeExpr2 = traverseExpr(expr2, constraints, parameters, dbSchema, withSchema, fromColumns);
1123
+ if (typeExpr1.kind == 'TypeVar' && ((0, collect_constraints_1.isDateLiteral)(typeExpr1.name) || (0, collect_constraints_1.isDateTimeLiteral)(typeExpr1.name))) {
1124
+ typeExpr1.type = 'datetime';
1125
+ }
1126
+ constraints.push({
1127
+ expression: expr1.text,
1128
+ type1: typeExpr1,
1129
+ type2: (0, collect_constraints_1.freshVar)('datetime', 'datetime')
1130
+ });
1131
+ constraints.push({
1132
+ expression: expr2.text,
1133
+ type1: typeExpr2,
1134
+ type2: (0, collect_constraints_1.freshVar)('bigint', 'bigint')
1135
+ });
1136
+ return (0, collect_constraints_1.freshVar)('datetime', 'datetime');
1137
+ }
1138
+ if (runtimeFunctionCall.COALESCE_SYMBOL()) {
1139
+ const exprList = (_j = runtimeFunctionCall.exprListWithParentheses()) === null || _j === void 0 ? void 0 : _j.exprList().expr();
1140
+ if (exprList) {
1141
+ const paramType = (0, collect_constraints_1.freshVar)('COALESCE', 'any');
1142
+ const params = {
1143
+ kind: 'VariableLengthParams',
1144
+ paramType: '?'
1145
+ };
1146
+ const paramsTypeList = traverseExprListParameters(exprList, params, constraints, parameters, dbSchema, withSchema, fromColumns);
1147
+ paramsTypeList.forEach((typeVar, paramIndex) => {
1148
+ constraints.push({
1149
+ expression: runtimeFunctionCall.text + '_param' + (paramIndex + 1),
1150
+ type1: paramType,
1151
+ type2: typeVar,
1152
+ mostGeneralType: true,
1153
+ coercionType: 'Coalesce'
1154
+ });
1155
+ });
1156
+ return paramType;
1157
+ }
1158
+ }
1159
+ //MOD (number, number): number
1160
+ if (runtimeFunctionCall.MOD_SYMBOL()) {
1161
+ const functionType = (0, collect_constraints_1.freshVar)('number', 'number');
1162
+ const exprList = runtimeFunctionCall.expr();
1163
+ const param1 = traverseExpr(exprList[0], constraints, parameters, dbSchema, withSchema, fromColumns);
1164
+ const param2 = traverseExpr(exprList[1], constraints, parameters, dbSchema, withSchema, fromColumns);
1165
+ constraints.push({
1166
+ expression: simpleExpr.text,
1167
+ type1: (0, collect_constraints_1.freshVar)('number', 'number'),
1168
+ type2: param1,
1169
+ mostGeneralType: true,
1170
+ coercionType: 'Numeric'
1171
+ });
1172
+ constraints.push({
1173
+ expression: simpleExpr.text,
1174
+ type1: (0, collect_constraints_1.freshVar)('number', 'number'),
1175
+ type2: param2,
1176
+ mostGeneralType: true,
1177
+ coercionType: 'Numeric'
1178
+ });
1179
+ constraints.push({
1180
+ expression: simpleExpr.text,
1181
+ type1: functionType,
1182
+ type2: param1,
1183
+ mostGeneralType: true
1184
+ });
1185
+ constraints.push({
1186
+ expression: simpleExpr.text,
1187
+ type1: functionType,
1188
+ type2: param2,
1189
+ mostGeneralType: true
1190
+ });
1191
+ return functionType;
1192
+ }
1193
+ if (runtimeFunctionCall.IF_SYMBOL()) {
1194
+ const exprList = runtimeFunctionCall.expr();
1195
+ const expr1 = exprList[0];
1196
+ const expr2 = exprList[1];
1197
+ const expr3 = exprList[2];
1198
+ traverseExpr(expr1, constraints, parameters, dbSchema, withSchema, fromColumns);
1199
+ const expr2Type = traverseExpr(expr2, constraints, parameters, dbSchema, withSchema, fromColumns);
1200
+ const expr3Type = traverseExpr(expr3, constraints, parameters, dbSchema, withSchema, fromColumns);
1201
+ constraints.push({
1202
+ expression: runtimeFunctionCall.text,
1203
+ type1: expr2Type,
1204
+ type2: expr3Type,
1205
+ mostGeneralType: true
1206
+ });
1207
+ return expr2Type;
1208
+ }
1209
+ throw Error('Function not supported: ' + runtimeFunctionCall.text);
1210
+ }
1211
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprFunctionContext) {
1212
+ const functionIdentifier = (0, collect_constraints_1.getFunctionName)(simpleExpr);
1213
+ if (functionIdentifier === 'concat_ws' || (functionIdentifier === null || functionIdentifier === void 0 ? void 0 : functionIdentifier.toLowerCase()) === 'concat') {
1214
+ const varcharType = (0, collect_constraints_1.freshVar)(simpleExpr.text, 'varchar');
1215
+ const params = {
1216
+ kind: 'VariableLengthParams',
1217
+ paramType: 'varchar'
1218
+ };
1219
+ walkFunctionParameters(simpleExpr, params, constraints, parameters, dbSchema, withSchema, fromColumns);
1220
+ return varcharType;
1221
+ }
1222
+ if (functionIdentifier === 'avg') {
1223
+ const functionType = (0, collect_constraints_1.freshVar)(simpleExpr.text, '?');
1224
+ constraints.push({
1225
+ expression: simpleExpr.text,
1226
+ type1: functionType,
1227
+ type2: (0, collect_constraints_1.freshVar)('decimal', 'decimal'),
1228
+ mostGeneralType: true
1229
+ });
1230
+ const params = {
1231
+ kind: 'FixedLengthParams',
1232
+ paramsType: [functionType]
1233
+ };
1234
+ walkFunctionParameters(simpleExpr, params, constraints, parameters, dbSchema, withSchema, fromColumns);
1235
+ return functionType;
1236
+ }
1237
+ if (functionIdentifier === 'round') {
1238
+ const functionType = (0, collect_constraints_1.freshVar)(simpleExpr.text, '?');
1239
+ const params = {
1240
+ kind: 'FixedLengthParams',
1241
+ paramsType: [functionType]
1242
+ };
1243
+ const paramsType = walkFunctionParameters(simpleExpr, params, constraints, parameters, dbSchema, withSchema, fromColumns);
1244
+ //The return value has the same type as the first argument
1245
+ constraints.push({
1246
+ expression: simpleExpr.text,
1247
+ type1: functionType,
1248
+ type2: paramsType[0],
1249
+ mostGeneralType: true
1250
+ });
1251
+ return functionType;
1252
+ }
1253
+ if (functionIdentifier === 'floor') {
1254
+ const doubleParam = (0, collect_constraints_1.freshVar)('double', 'double');
1255
+ const params = {
1256
+ kind: 'FixedLengthParams',
1257
+ paramsType: [doubleParam, doubleParam]
1258
+ };
1259
+ walkFunctionParameters(simpleExpr, params, constraints, parameters, dbSchema, withSchema, fromColumns);
1260
+ return (0, collect_constraints_1.freshVar)(simpleExpr.text, 'bigint');
1261
+ }
1262
+ if (functionIdentifier === 'str_to_date') {
1263
+ const varcharParam = (0, collect_constraints_1.freshVar)('varchar', 'varchar');
1264
+ const params = {
1265
+ kind: 'FixedLengthParams',
1266
+ paramsType: [varcharParam, varcharParam]
1267
+ };
1268
+ walkFunctionParameters(simpleExpr, params, constraints, parameters, dbSchema, withSchema, fromColumns);
1269
+ return (0, collect_constraints_1.freshVar)(simpleExpr.text, 'date');
1270
+ }
1271
+ if (functionIdentifier === 'datediff') {
1272
+ const udfExprList = (_k = simpleExpr.functionCall().udfExprList()) === null || _k === void 0 ? void 0 : _k.udfExpr();
1273
+ if (udfExprList) {
1274
+ udfExprList.forEach((inExpr) => {
1275
+ const expr = inExpr.expr();
1276
+ const exprType = traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
1277
+ const newType = (0, collect_constraints_1.verifyDateTypesCoercion)(exprType);
1278
+ constraints.push({
1279
+ expression: expr.text,
1280
+ type1: newType,
1281
+ type2: (0, collect_constraints_1.freshVar)('date', 'date'),
1282
+ mostGeneralType: true
1283
+ });
1284
+ });
1285
+ }
1286
+ return (0, collect_constraints_1.freshVar)(simpleExpr.text, 'bigint');
1287
+ }
1288
+ if (functionIdentifier === 'lpad' || functionIdentifier == 'rpad') {
1289
+ const varcharParam = (0, collect_constraints_1.freshVar)('varchar', 'varchar');
1290
+ const intParam = (0, collect_constraints_1.freshVar)('int', 'int');
1291
+ const params = {
1292
+ kind: 'FixedLengthParams',
1293
+ paramsType: [varcharParam, intParam, varcharParam]
1294
+ };
1295
+ walkFunctionParameters(simpleExpr, params, constraints, parameters, dbSchema, withSchema, fromColumns);
1296
+ return varcharParam;
1297
+ }
1298
+ if (functionIdentifier === 'lower'
1299
+ || functionIdentifier === 'lcase'
1300
+ || functionIdentifier === 'upper'
1301
+ || functionIdentifier === 'ucase'
1302
+ || functionIdentifier === 'trim'
1303
+ || functionIdentifier === 'ltrim'
1304
+ || functionIdentifier === 'rtrim') {
1305
+ const varcharParam = (0, collect_constraints_1.freshVar)('varchar', 'varchar');
1306
+ const params = {
1307
+ kind: 'FixedLengthParams',
1308
+ paramsType: [varcharParam]
1309
+ };
1310
+ walkFunctionParameters(simpleExpr, params, constraints, parameters, dbSchema, withSchema, fromColumns);
1311
+ return varcharParam;
1312
+ }
1313
+ if (functionIdentifier === 'length' || functionIdentifier == 'char_length') {
1314
+ const varcharParam = (0, collect_constraints_1.freshVar)('varchar', 'varchar');
1315
+ const params = {
1316
+ kind: 'FixedLengthParams',
1317
+ paramsType: [varcharParam]
1318
+ };
1319
+ walkFunctionParameters(simpleExpr, params, constraints, parameters, dbSchema, withSchema, fromColumns);
1320
+ return (0, collect_constraints_1.freshVar)('int', 'int');
1321
+ }
1322
+ if (functionIdentifier === 'abs') {
1323
+ const functionType = (0, collect_constraints_1.freshVar)('number', 'number');
1324
+ const udfExprList = (_l = simpleExpr.functionCall().udfExprList()) === null || _l === void 0 ? void 0 : _l.udfExpr();
1325
+ udfExprList === null || udfExprList === void 0 ? void 0 : udfExprList.forEach(expr => {
1326
+ const param1 = traverseExpr(expr.expr(), constraints, parameters, dbSchema, withSchema, fromColumns);
1327
+ constraints.push({
1328
+ expression: simpleExpr.text,
1329
+ type1: functionType,
1330
+ type2: param1,
1331
+ mostGeneralType: true,
1332
+ coercionType: 'Numeric'
1333
+ });
1334
+ });
1335
+ return functionType;
1336
+ }
1337
+ if (functionIdentifier == 'ceiling' || functionIdentifier == 'ceil') {
1338
+ const functionType = (0, collect_constraints_1.freshVar)('number', 'number');
1339
+ const udfExprList = (_m = simpleExpr.functionCall().udfExprList()) === null || _m === void 0 ? void 0 : _m.udfExpr();
1340
+ udfExprList === null || udfExprList === void 0 ? void 0 : udfExprList.forEach(expr => {
1341
+ const param1 = traverseExpr(expr.expr(), constraints, parameters, dbSchema, withSchema, fromColumns);
1342
+ constraints.push({
1343
+ expression: simpleExpr.text,
1344
+ type1: functionType,
1345
+ type2: param1,
1346
+ mostGeneralType: true,
1347
+ coercionType: 'Ceiling'
1348
+ });
1349
+ });
1350
+ return functionType;
1351
+ }
1352
+ if (functionIdentifier == 'timestampdiff') {
1353
+ const udfExprList = (_o = simpleExpr.functionCall().udfExprList()) === null || _o === void 0 ? void 0 : _o.udfExpr();
1354
+ if (udfExprList) {
1355
+ const [first, ...rest] = udfExprList;
1356
+ const unit = first.text.trim().toLowerCase();
1357
+ rest.forEach((inExpr, paramIndex) => {
1358
+ const expr = inExpr.expr();
1359
+ const exprType = traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
1360
+ const newType = (0, collect_constraints_1.verifyDateTypesCoercion)(exprType);
1361
+ //const expectedType = ['hour', 'minute', 'second'].includes(unit)? 'time' : 'datetime'
1362
+ constraints.push({
1363
+ expression: expr.text,
1364
+ type1: newType,
1365
+ type2: (0, collect_constraints_1.freshVar)('datetime', 'datetime'),
1366
+ mostGeneralType: true
1367
+ });
1368
+ });
1369
+ }
1370
+ return (0, collect_constraints_1.freshVar)('int', 'int');
1371
+ }
1372
+ if (functionIdentifier == 'ifnull' || functionIdentifier == 'nullif') {
1373
+ const functionType = (0, collect_constraints_1.freshVar)(simpleExpr.text, '?');
1374
+ const udfExprList = (_p = simpleExpr.functionCall().udfExprList()) === null || _p === void 0 ? void 0 : _p.udfExpr();
1375
+ if (udfExprList) {
1376
+ const [expr1, expr2] = udfExprList;
1377
+ const expr1Type = traverseExpr(expr1.expr(), constraints, parameters, dbSchema, withSchema, fromColumns);
1378
+ constraints.push({
1379
+ expression: expr1.text,
1380
+ type1: functionType,
1381
+ type2: expr1Type
1382
+ });
1383
+ const expr2Type = traverseExpr(expr2.expr(), constraints, parameters, dbSchema, withSchema, fromColumns);
1384
+ constraints.push({
1385
+ expression: expr2.text,
1386
+ type1: functionType,
1387
+ type2: expr2Type
1388
+ });
1389
+ }
1390
+ return functionType;
1391
+ }
1392
+ if (functionIdentifier == 'md5' //md5(str) - TODO - have input constraint = string
1393
+ || functionIdentifier == 'hex' //md5(n or str)
1394
+ || functionIdentifier == 'unhex') { //unhex (str) - TODO - have input constraint = string
1395
+ const functionType = (0, collect_constraints_1.freshVar)(simpleExpr.text, 'char');
1396
+ const udfExprList = (_q = simpleExpr.functionCall().udfExprList()) === null || _q === void 0 ? void 0 : _q.udfExpr();
1397
+ if (udfExprList) {
1398
+ const [expr1] = udfExprList;
1399
+ const paramType = traverseExpr(expr1.expr(), constraints, parameters, dbSchema, withSchema, fromColumns);
1400
+ constraints.push({
1401
+ expression: expr1.text,
1402
+ type1: paramType,
1403
+ type2: (0, collect_constraints_1.freshVar)(expr1.text, 'varchar')
1404
+ });
1405
+ }
1406
+ return functionType;
1407
+ }
1408
+ throw Error('Function not supported: ' + functionIdentifier);
1409
+ }
1410
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprWindowingFunctionContext) {
1411
+ const windowFunctionCall = simpleExpr.windowFunctionCall();
1412
+ return traverseWindowFunctionCall(windowFunctionCall, constraints, parameters, dbSchema, withSchema, fromColumns);
1413
+ }
1414
+ if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprCastContext) {
1415
+ const castType = simpleExpr.castType();
1416
+ if (castType.CHAR_SYMBOL()) {
1417
+ return (0, collect_constraints_1.freshVar)(castType.text, 'char');
1418
+ }
1419
+ }
1420
+ throw Error('traverseSimpleExpr - not supported: ' + simpleExpr.constructor.name);
1421
+ }
1422
+ function traverseWindowFunctionCall(windowFunctionCall, constraints, parameters, dbSchema, withSchema, fromColumns) {
1423
+ if (windowFunctionCall.ROW_NUMBER_SYMBOL()
1424
+ || windowFunctionCall.RANK_SYMBOL()
1425
+ || windowFunctionCall.DENSE_RANK_SYMBOL()
1426
+ || windowFunctionCall.CUME_DIST_SYMBOL()
1427
+ || windowFunctionCall.PERCENT_RANK_SYMBOL()) {
1428
+ return (0, collect_constraints_1.freshVar)(windowFunctionCall.text, 'bigint');
1429
+ }
1430
+ const expr = windowFunctionCall.expr();
1431
+ if (expr) {
1432
+ return traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
1433
+ }
1434
+ const exprWithParentheses = windowFunctionCall.exprWithParentheses();
1435
+ if (exprWithParentheses) {
1436
+ const expr = exprWithParentheses.expr();
1437
+ return traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
1438
+ }
1439
+ throw Error('No support for expression' + windowFunctionCall.constructor.name);
1440
+ }
1441
+ function traverseExprListParameters(exprList, params, constraints, parameters, dbSchema, withSchema, fromColumns) {
1442
+ return exprList.map((expr, paramIndex) => {
1443
+ const exprType = traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
1444
+ const paramType = params.kind == 'FixedLengthParams' ? params.paramsType[paramIndex] : (0, collect_constraints_1.freshVar)(params.paramType, params.paramType);
1445
+ constraints.push({
1446
+ expression: expr.text,
1447
+ type1: exprType,
1448
+ type2: paramType,
1449
+ mostGeneralType: true
1450
+ });
1451
+ return paramType;
1452
+ });
1453
+ }
1454
+ function walkFunctionParameters(simpleExprFunction, params, constraints, parameters, dbSchema, withSchema, fromColumns) {
1455
+ var _a, _b;
1456
+ const functionName = (0, collect_constraints_1.getFunctionName)(simpleExprFunction);
1457
+ const udfExprList = (_a = simpleExprFunction.functionCall().udfExprList()) === null || _a === void 0 ? void 0 : _a.udfExpr();
1458
+ if (udfExprList) {
1459
+ const paramTypes = udfExprList
1460
+ .filter((undefined, paramIndex) => {
1461
+ return functionName == 'timestampdiff' ? paramIndex != 0 : true; //filter the first parameter of timestampdiff function
1462
+ })
1463
+ .map((inExpr, paramIndex) => {
1464
+ const expr = inExpr.expr();
1465
+ const exprType = traverseExpr(expr, constraints, parameters, dbSchema, withSchema, fromColumns);
1466
+ constraints.push({
1467
+ expression: expr.text,
1468
+ type1: exprType,
1469
+ type2: params.kind == 'FixedLengthParams' ? params.paramsType[paramIndex] : (0, collect_constraints_1.freshVar)(params.paramType, params.paramType),
1470
+ });
1471
+ return exprType;
1472
+ });
1473
+ return paramTypes;
1474
+ }
1475
+ const exprList = (_b = simpleExprFunction.functionCall().exprList()) === null || _b === void 0 ? void 0 : _b.expr();
1476
+ if (exprList) {
1477
+ const paramTypes = exprList.map((inExpr, paramIndex) => {
1478
+ const inSumExprType = traverseExpr(inExpr, constraints, parameters, dbSchema, withSchema, fromColumns);
1479
+ constraints.push({
1480
+ expression: inExpr.text,
1481
+ type1: params.kind == 'FixedLengthParams' ? params.paramsType[paramIndex] : (0, collect_constraints_1.freshVar)(params.paramType, params.paramType),
1482
+ type2: inSumExprType,
1483
+ mostGeneralType: true
1484
+ });
1485
+ return inSumExprType;
1486
+ });
1487
+ return paramTypes;
1488
+ }
1489
+ throw Error('Error in walkFunctionParameters');
1490
+ }
1491
+ function filterColumns(dbSchema, withSchema, tableAlias, table) {
1492
+ const withResult = withSchema.filter(t => t.table.toLowerCase() == table.name.toLowerCase()).map(s => (Object.assign(Object.assign({}, s), { tableAlias: tableAlias })));
1493
+ const tableColumns1 = dbSchema
1494
+ .filter(schema => schema.table.toLowerCase() == table.name.toLowerCase() && (schema.schema == table.prefix || table.prefix == ''))
1495
+ .map(tableColumn => {
1496
+ //name and colum are the same on the leaf table
1497
+ const r = {
1498
+ columnName: tableColumn.column, columnType: (0, collect_constraints_1.createColumnTypeFomColumnSchema)(tableColumn),
1499
+ notNull: tableColumn.notNull, table: table.name, tableAlias: tableAlias || '', columnKey: tableColumn.columnKey
1500
+ };
1501
+ return r;
1502
+ });
1503
+ const result = tableColumns1.concat(withResult);
1504
+ return result;
1505
+ }
1506
+ exports.filterColumns = filterColumns;
1507
+ function selectAllColumns(tablePrefix, fromColumns) {
1508
+ return fromColumns.filter(column => {
1509
+ if (tablePrefix == '' || tablePrefix == column.tableAlias || tablePrefix == column.table) {
1510
+ return true;
1511
+ }
1512
+ return false;
1513
+ });
1514
+ }
1515
+ exports.selectAllColumns = selectAllColumns;
1516
+ function filterUsingFields(joinedFields, usingFields) {
1517
+ return joinedFields.filter(joinedField => {
1518
+ const isUsing = usingFields.includes(joinedField.columnName);
1519
+ if (!isUsing) {
1520
+ return true;
1521
+ }
1522
+ return false;
1523
+ });
1524
+ }
1525
+ function isMultipleRowResult(selectStatement, fromColumns) {
1526
+ var _a, _b;
1527
+ const querySpecs = (0, parse_1.getAllQuerySpecificationsFromSelectStatement)(selectStatement);
1528
+ if (querySpecs.length == 1) { //UNION queries are multipleRowsResult = true
1529
+ const fromClause = querySpecs[0].fromClause();
1530
+ if (!fromClause) {
1531
+ return false;
1532
+ }
1533
+ if (querySpecs[0].selectItemList().childCount == 1) {
1534
+ const selectItem = querySpecs[0].selectItemList().getChild(0);
1535
+ //if selectItem = * (TerminalNode) childCount = 0; selectItem.expr() throws exception
1536
+ const expr = selectItem.childCount > 0 ? selectItem.expr() : null;
1537
+ if (expr) {
1538
+ //SUM, MAX... WITHOUT GROUP BY are multipleRowsResult = false
1539
+ const groupBy = querySpecs[0].groupByClause();
1540
+ if (!groupBy && (0, parse_1.isSumExpressContext)(expr)) {
1541
+ return false;
1542
+ }
1543
+ }
1544
+ }
1545
+ const joinedTable = (_a = fromClause.tableReferenceList()) === null || _a === void 0 ? void 0 : _a.tableReference()[0].joinedTable();
1546
+ if (joinedTable && joinedTable.length > 0) {
1547
+ return true;
1548
+ }
1549
+ const whereClauseExpr = (_b = querySpecs[0].whereClause()) === null || _b === void 0 ? void 0 : _b.expr();
1550
+ const isMultipleRowResult = whereClauseExpr && verifyMultipleResult2(whereClauseExpr, fromColumns);
1551
+ if (isMultipleRowResult == false) {
1552
+ return false;
1553
+ }
1554
+ }
1555
+ const limitOptions = (0, parse_1.getLimitOptions)(selectStatement);
1556
+ if (limitOptions.length == 1 && limitOptions[0].text == '1') {
1557
+ return false;
1558
+ }
1559
+ if (limitOptions.length == 2 && limitOptions[1].text == '1') {
1560
+ return false;
1561
+ }
1562
+ return true;
1563
+ }
1564
+ exports.isMultipleRowResult = isMultipleRowResult;
1565
+ function verifyMultipleResult2(exprContext, fromColumns) {
1566
+ if (exprContext instanceof ts_mysql_parser_1.ExprIsContext) {
1567
+ const boolPri = exprContext.boolPri();
1568
+ if (boolPri instanceof ts_mysql_parser_1.PrimaryExprCompareContext) {
1569
+ if (boolPri.compOp().EQUAL_OPERATOR()) {
1570
+ let compareLeft = boolPri.boolPri();
1571
+ let compareRight = boolPri.predicate();
1572
+ if (isUniqueKeyComparation(compareLeft, fromColumns) || isUniqueKeyComparation(compareRight, fromColumns)) {
1573
+ return false; //multipleRow = false
1574
+ }
1575
+ }
1576
+ return true; //multipleRow = true
1577
+ }
1578
+ return true; //multipleRow
1579
+ }
1580
+ if (exprContext instanceof ts_mysql_parser_1.ExprNotContext) {
1581
+ return true;
1582
+ }
1583
+ if (exprContext instanceof ts_mysql_parser_1.ExprAndContext) {
1584
+ const oneIsSingleResult = exprContext.expr().some(expr => verifyMultipleResult2(expr, fromColumns) == false);
1585
+ return oneIsSingleResult == false;
1586
+ }
1587
+ // if (exprContext instanceof ExprXorContext) {
1588
+ // const expressions = exprContext.expr();
1589
+ // }
1590
+ if (exprContext instanceof ts_mysql_parser_1.ExprOrContext) {
1591
+ return true; //multipleRow = true
1592
+ }
1593
+ throw Error('Unknow type:' + exprContext.constructor.name);
1594
+ }
1595
+ exports.verifyMultipleResult2 = verifyMultipleResult2;
1596
+ function isUniqueKeyComparation(compare, fromColumns) {
1597
+ const tokens = (0, select_columns_1.getSimpleExpressions)(compare);
1598
+ if (tokens.length == 1 && tokens[0] instanceof ts_mysql_parser_1.SimpleExprColumnRefContext) {
1599
+ const fieldName = (0, select_columns_1.splitName)(tokens[0].text);
1600
+ const col = (0, select_columns_1.findColumn)(fieldName, fromColumns);
1601
+ if (col.columnKey == 'PRI' || col.columnKey == 'UNI') { //TODO - UNIQUE
1602
+ return true; //isUniqueKeyComparation = true
1603
+ }
1604
+ }
1605
+ return false; //isUniqueKeyComparation = false
1606
+ }
1607
+ function getOrderByColumns(fromColumns, selectColumns) {
1608
+ const fromColumnsNames = fromColumns.map(col => col.columnName); //TODO - loading twice
1609
+ const selectColumnsNames = selectColumns.map(col => col.name);
1610
+ const allOrderByColumns = Array.from(new Set(fromColumnsNames.concat(selectColumnsNames)));
1611
+ return allOrderByColumns;
1612
+ }
1613
+ //# sourceMappingURL=traverse.js.map