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.
- package/code-generator.d.ts +3 -0
- package/code-generator.d.ts.map +1 -1
- package/code-generator.js +88 -12
- package/code-generator.js.map +1 -1
- package/describe-nested-query.d.ts +29 -0
- package/describe-nested-query.d.ts.map +1 -0
- package/describe-nested-query.js +154 -0
- package/describe-nested-query.js.map +1 -0
- package/describe-query.d.ts +2 -1
- package/describe-query.d.ts.map +1 -1
- package/describe-query.js +20 -21
- package/describe-query.js.map +1 -1
- package/mysql-mapping.d.ts +1 -1
- package/mysql-mapping.d.ts.map +1 -1
- package/mysql-mapping.js +1 -1
- package/mysql-mapping.js.map +1 -1
- package/mysql-query-analyzer/collect-constraints.d.ts +24 -50
- package/mysql-query-analyzer/collect-constraints.d.ts.map +1 -1
- package/mysql-query-analyzer/collect-constraints.js +52 -1757
- package/mysql-query-analyzer/collect-constraints.js.map +1 -1
- package/mysql-query-analyzer/infer-column-nullability.d.ts +3 -3
- package/mysql-query-analyzer/infer-column-nullability.d.ts.map +1 -1
- package/mysql-query-analyzer/infer-column-nullability.js +14 -26
- package/mysql-query-analyzer/infer-column-nullability.js.map +1 -1
- package/mysql-query-analyzer/infer-param-nullability.d.ts +3 -1
- package/mysql-query-analyzer/infer-param-nullability.d.ts.map +1 -1
- package/mysql-query-analyzer/infer-param-nullability.js +21 -3
- package/mysql-query-analyzer/infer-param-nullability.js.map +1 -1
- package/mysql-query-analyzer/parse.d.ts +10 -10
- package/mysql-query-analyzer/parse.d.ts.map +1 -1
- package/mysql-query-analyzer/parse.js +133 -181
- package/mysql-query-analyzer/parse.js.map +1 -1
- package/mysql-query-analyzer/select-columns.d.ts +9 -9
- package/mysql-query-analyzer/select-columns.d.ts.map +1 -1
- package/mysql-query-analyzer/select-columns.js +32 -226
- package/mysql-query-analyzer/select-columns.js.map +1 -1
- package/mysql-query-analyzer/traverse.d.ts +45 -0
- package/mysql-query-analyzer/traverse.d.ts.map +1 -0
- package/mysql-query-analyzer/traverse.js +1613 -0
- package/mysql-query-analyzer/traverse.js.map +1 -0
- package/mysql-query-analyzer/types.d.ts +39 -5
- package/mysql-query-analyzer/types.d.ts.map +1 -1
- package/mysql-query-analyzer/unify.d.ts +4 -3
- package/mysql-query-analyzer/unify.d.ts.map +1 -1
- package/mysql-query-analyzer/unify.js +542 -51
- package/mysql-query-analyzer/unify.js.map +1 -1
- package/mysql-query-analyzer/verify-multiple-result.js +1 -1
- package/mysql-query-analyzer/verify-multiple-result.js.map +1 -1
- package/package.json +2 -2
- package/ts-nested-descriptor.d.ts +26 -0
- package/ts-nested-descriptor.d.ts.map +1 -0
- package/ts-nested-descriptor.js +73 -0
- package/ts-nested-descriptor.js.map +1 -0
- package/types.d.ts +12 -8
- 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
|