typesql-cli 0.4.7 → 0.4.9
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/cli.d.ts +2 -2
- package/cli.js +228 -220
- package/cli.js.map +1 -1
- package/code-generator.d.ts +19 -19
- package/code-generator.d.ts.map +1 -1
- package/code-generator.js +269 -265
- package/code-generator.js.map +1 -1
- package/describe-query.d.ts +9 -9
- package/describe-query.js +168 -168
- package/describe-query.js.map +1 -1
- package/mysql-mapping.d.ts +18 -18
- package/mysql-mapping.d.ts.map +1 -1
- package/mysql-mapping.js +146 -146
- package/mysql-mapping.js.map +1 -1
- package/mysql-query-analyzer/collect-constraints.d.ts +50 -50
- package/mysql-query-analyzer/collect-constraints.d.ts.map +1 -1
- package/mysql-query-analyzer/collect-constraints.js +1196 -1195
- package/mysql-query-analyzer/collect-constraints.js.map +1 -1
- package/mysql-query-analyzer/infer-column-nullability.d.ts +5 -5
- package/mysql-query-analyzer/infer-column-nullability.js +307 -307
- package/mysql-query-analyzer/infer-column-nullability.js.map +1 -1
- package/mysql-query-analyzer/infer-param-nullability.d.ts +6 -6
- package/mysql-query-analyzer/infer-param-nullability.js +78 -78
- package/mysql-query-analyzer/infer-param-nullability.js.map +1 -1
- package/mysql-query-analyzer/parse.d.ts +14 -14
- package/mysql-query-analyzer/parse.d.ts.map +1 -1
- package/mysql-query-analyzer/parse.js +219 -215
- package/mysql-query-analyzer/parse.js.map +1 -1
- package/mysql-query-analyzer/select-columns.d.ts +12 -12
- package/mysql-query-analyzer/select-columns.js +373 -373
- package/mysql-query-analyzer/select-columns.js.map +1 -1
- package/mysql-query-analyzer/types.d.ts +72 -72
- package/mysql-query-analyzer/types.d.ts.map +1 -1
- package/mysql-query-analyzer/types.js +2 -2
- package/mysql-query-analyzer/unify.d.ts +4 -4
- package/mysql-query-analyzer/unify.js +157 -157
- package/mysql-query-analyzer/util.d.ts +6 -6
- package/mysql-query-analyzer/util.d.ts.map +1 -1
- package/mysql-query-analyzer/util.js +30 -30
- package/mysql-query-analyzer/verify-multiple-result.d.ts +3 -3
- package/mysql-query-analyzer/verify-multiple-result.js +47 -47
- package/mysql-query-analyzer/verify-multiple-result.js.map +1 -1
- package/package.json +4 -5
- package/queryExectutor.d.ts +15 -13
- package/queryExectutor.d.ts.map +1 -1
- package/queryExectutor.js +107 -104
- package/queryExectutor.js.map +1 -1
- package/sql-generator.d.ts +5 -5
- package/sql-generator.js +88 -88
- package/types.d.ts +89 -89
- package/types.d.ts.map +1 -1
- package/types.js +2 -2
- package/utility-types.d.ts +4 -4
- package/utility-types.d.ts.map +1 -1
- package/utility-types.js +2 -2
@@ -1,308 +1,308 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.possibleNull = exports.inferNotNull = exports.parseAndInferNotNull = void 0;
|
4
|
-
const parse_1 = require("./parse");
|
5
|
-
const ts_mysql_parser_1 = require("ts-mysql-parser");
|
6
|
-
const select_columns_1 = require("./select-columns");
|
7
|
-
const infer_param_nullability_1 = require("./infer-param-nullability");
|
8
|
-
function parseAndInferNotNull(sql, dbSchema) {
|
9
|
-
var _a;
|
10
|
-
const queryTree = parse_1.parse(sql);
|
11
|
-
const selectStatement = (_a = queryTree.simpleStatement()) === null || _a === void 0 ? void 0 : _a.selectStatement();
|
12
|
-
if (selectStatement) {
|
13
|
-
const queries = parse_1.getQuerySpecificationsFromSelectStatement(selectStatement);
|
14
|
-
const notNullAllQueries = queries.map(query => inferNotNull(query, dbSchema)); //TODO - UNION
|
15
|
-
const result = zip(notNullAllQueries).map(notNullColumn => notNullColumn.every(notNull => notNull == true));
|
16
|
-
return result;
|
17
|
-
}
|
18
|
-
}
|
19
|
-
exports.parseAndInferNotNull = parseAndInferNotNull;
|
20
|
-
function zip(arrays) {
|
21
|
-
return arrays[0].map(function (_, i) {
|
22
|
-
return arrays.map(function (array) { return array[i]; });
|
23
|
-
});
|
24
|
-
}
|
25
|
-
function inferNotNull(querySpec, dbSchema) {
|
26
|
-
const fromColumns = select_columns_1.getColumnsFrom(querySpec, dbSchema); //TODO - called twice
|
27
|
-
const notNullInference = [];
|
28
|
-
const whereClause = querySpec.whereClause();
|
29
|
-
if (querySpec.selectItemList().MULT_OPERATOR()) {
|
30
|
-
fromColumns.forEach(col => {
|
31
|
-
const field = select_columns_1.splitName(col.columnName);
|
32
|
-
const notNull = col.notNull || (whereClause && !possibleNullWhere(field, whereClause)) || false;
|
33
|
-
notNullInference.push(notNull); //TODO infernot null in where?
|
34
|
-
});
|
35
|
-
}
|
36
|
-
querySpec.selectItemList().selectItem().forEach(selectItem => {
|
37
|
-
notNullInference.push(...inferNotNullSelectItem(selectItem, dbSchema, fromColumns, whereClause));
|
38
|
-
});
|
39
|
-
return notNullInference;
|
40
|
-
}
|
41
|
-
exports.inferNotNull = inferNotNull;
|
42
|
-
function inferNotNullSelectItem(selectItem, dbSchema, fromColumns, whereClause) {
|
43
|
-
const notNullItems = [];
|
44
|
-
const tableWild = selectItem.tableWild();
|
45
|
-
if (tableWild === null || tableWild === void 0 ? void 0 : tableWild.MULT_OPERATOR()) { //TODO: DUPLICATED CODE FROM WALKER
|
46
|
-
tableWild.identifier().forEach(tabWild => {
|
47
|
-
const prefix = tabWild.text;
|
48
|
-
const columns = select_columns_1.selectAllColumns(prefix, fromColumns);
|
49
|
-
columns.forEach(col => {
|
50
|
-
const field = select_columns_1.splitName(col.columnName);
|
51
|
-
const notNull = col.notNull || (whereClause && !possibleNullWhere(field, whereClause)) || false;
|
52
|
-
notNullItems.push(notNull);
|
53
|
-
});
|
54
|
-
});
|
55
|
-
return notNullItems;
|
56
|
-
}
|
57
|
-
const expr = selectItem.expr();
|
58
|
-
if (expr) {
|
59
|
-
const notNull = inferNotNullExpr(expr, dbSchema, fromColumns);
|
60
|
-
return [notNull];
|
61
|
-
}
|
62
|
-
throw Error('Error during column null inference');
|
63
|
-
}
|
64
|
-
function inferNotNullExpr(expr, dbSchema, fromColumns) {
|
65
|
-
if (expr instanceof ts_mysql_parser_1.ExprIsContext) {
|
66
|
-
return inferNotNullExprIs(expr, dbSchema, fromColumns);
|
67
|
-
}
|
68
|
-
throw Error('Error during column null inference');
|
69
|
-
}
|
70
|
-
function inferNotNullExprIs(exprIs, dbSchema, fromColumns) {
|
71
|
-
const boolPri = exprIs.boolPri();
|
72
|
-
return inferNotNullBoolPri(boolPri, dbSchema, fromColumns);
|
73
|
-
}
|
74
|
-
function inferNotNullBoolPri(boolPri, dbSchema, fromColumns) {
|
75
|
-
if (boolPri instanceof ts_mysql_parser_1.PrimaryExprPredicateContext) {
|
76
|
-
const predicate = boolPri.predicate();
|
77
|
-
return inferNotNullPredicate(predicate, dbSchema, fromColumns);
|
78
|
-
}
|
79
|
-
if (boolPri instanceof ts_mysql_parser_1.PrimaryExprCompareContext) {
|
80
|
-
const compareLeft = boolPri.boolPri();
|
81
|
-
const compareRight = boolPri.predicate();
|
82
|
-
const notNullLeft = inferNotNullBoolPri(compareLeft, dbSchema, fromColumns);
|
83
|
-
const notNullRight = inferNotNullPredicate(compareRight, dbSchema, fromColumns);
|
84
|
-
return notNullLeft && notNullRight;
|
85
|
-
}
|
86
|
-
throw Error('Error during column null inference');
|
87
|
-
}
|
88
|
-
function inferNotNullPredicate(predicate, dbSchema, fromColumns) {
|
89
|
-
const bitExpr = predicate.bitExpr();
|
90
|
-
if (bitExpr.length == 1) {
|
91
|
-
return inferNotNullBitExpr(bitExpr[0], dbSchema, fromColumns);
|
92
|
-
}
|
93
|
-
throw Error('Error during column null inference');
|
94
|
-
}
|
95
|
-
function inferNotNullBitExpr(bitExpr, dbSchema, fromColumns) {
|
96
|
-
const simpleExpr = bitExpr.simpleExpr();
|
97
|
-
if (simpleExpr) {
|
98
|
-
return inferNotNullSimpleExpr(simpleExpr, dbSchema, fromColumns);
|
99
|
-
}
|
100
|
-
const bitExpr2 = bitExpr.bitExpr();
|
101
|
-
if (bitExpr2.length == 2) {
|
102
|
-
return inferNotNullBitExpr(bitExpr2[0], dbSchema, fromColumns) && inferNotNullBitExpr(bitExpr2[1], dbSchema, fromColumns);
|
103
|
-
}
|
104
|
-
throw Error('Error during column null inference');
|
105
|
-
}
|
106
|
-
function inferNotNullSimpleExpr(simpleExpr, dbSchema, fromColumns) {
|
107
|
-
const querySpec = infer_param_nullability_1.getParentContext(simpleExpr, ts_mysql_parser_1.QuerySpecificationContext);
|
108
|
-
const whereClause = querySpec.whereClause();
|
109
|
-
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprColumnRefContext) {
|
110
|
-
const columnName = simpleExpr.columnRef().fieldIdentifier().text;
|
111
|
-
const fieldName = select_columns_1.splitName(columnName);
|
112
|
-
const column = select_columns_1.findColumn(fieldName, fromColumns);
|
113
|
-
return column.notNull || (whereClause && !possibleNullWhere(fieldName, whereClause) || false);
|
114
|
-
}
|
115
|
-
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprRuntimeFunctionContext) {
|
116
|
-
return inferNotNullRuntimeFunctionCall(simpleExpr, dbSchema, fromColumns);
|
117
|
-
}
|
118
|
-
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprFunctionContext) {
|
119
|
-
const functionCall = simpleExpr.functionCall();
|
120
|
-
return inferNotNullFunctionCall(functionCall, dbSchema, fromColumns);
|
121
|
-
}
|
122
|
-
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprLiteralContext) {
|
123
|
-
const nullLiteral = simpleExpr.literal().nullLiteral();
|
124
|
-
if (nullLiteral) {
|
125
|
-
return false;
|
126
|
-
}
|
127
|
-
return true;
|
128
|
-
}
|
129
|
-
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprParamMarkerContext) {
|
130
|
-
const inferParam = infer_param_nullability_1.inferParameterNotNull(simpleExpr);
|
131
|
-
return inferParam;
|
132
|
-
}
|
133
|
-
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprSumContext) {
|
134
|
-
const sumExpr = simpleExpr.sumExpr();
|
135
|
-
if (sumExpr.COUNT_SYMBOL()) {
|
136
|
-
return true;
|
137
|
-
}
|
138
|
-
const inSumExpr = sumExpr.inSumExpr();
|
139
|
-
if (inSumExpr) {
|
140
|
-
return false;
|
141
|
-
}
|
142
|
-
}
|
143
|
-
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprListContext) {
|
144
|
-
const exprList = simpleExpr.exprList().expr();
|
145
|
-
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
146
|
-
}
|
147
|
-
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprSubQueryContext) {
|
148
|
-
return false;
|
149
|
-
}
|
150
|
-
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprCaseContext) {
|
151
|
-
const thenExprList = simpleExpr.thenExpression();
|
152
|
-
const elseExpr = simpleExpr.elseExpression();
|
153
|
-
if (elseExpr) {
|
154
|
-
let caseNotNull = thenExprList.every(thenExpr => inferNotNullExpr(thenExpr.expr(), dbSchema, fromColumns));
|
155
|
-
return caseNotNull && inferNotNullExpr(elseExpr.expr(), dbSchema, fromColumns);
|
156
|
-
}
|
157
|
-
else {
|
158
|
-
return false; //if doesn't have else, the not null can't be inferred
|
159
|
-
}
|
160
|
-
}
|
161
|
-
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprIntervalContext) {
|
162
|
-
const exprList = simpleExpr.expr();
|
163
|
-
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
164
|
-
}
|
165
|
-
throw Error('Error during column null inference');
|
166
|
-
}
|
167
|
-
function inferNotNullRuntimeFunctionCall(simpleExprRuntimeFunction, dbSchema, fromColumns) {
|
168
|
-
var _a, _b;
|
169
|
-
const functionCall = simpleExprRuntimeFunction.runtimeFunctionCall();
|
170
|
-
if (functionCall.NOW_SYMBOL() || functionCall.CURDATE_SYMBOL() || functionCall.CURTIME_SYMBOL()) {
|
171
|
-
return true;
|
172
|
-
}
|
173
|
-
if (functionCall.MOD_SYMBOL()) {
|
174
|
-
return false; //MOD(N,0) returns NULL.
|
175
|
-
}
|
176
|
-
if (functionCall.REPLACE_SYMBOL()) {
|
177
|
-
const exprList = functionCall.expr();
|
178
|
-
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
179
|
-
}
|
180
|
-
const trimFunction = functionCall.trimFunction();
|
181
|
-
if (trimFunction) {
|
182
|
-
const exprList = trimFunction.expr();
|
183
|
-
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
184
|
-
}
|
185
|
-
const substringFunction = functionCall.substringFunction();
|
186
|
-
if (substringFunction) {
|
187
|
-
const exprList = substringFunction.expr();
|
188
|
-
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
189
|
-
}
|
190
|
-
if (functionCall.YEAR_SYMBOL() || functionCall.MONTH_SYMBOL() || functionCall.DAY_SYMBOL()
|
191
|
-
|| functionCall.HOUR_SYMBOL() || functionCall.MINUTE_SYMBOL() || functionCall.SECOND_SYMBOL()) {
|
192
|
-
const expr = (_a = functionCall.exprWithParentheses()) === null || _a === void 0 ? void 0 : _a.expr();
|
193
|
-
return inferNotNullExpr(expr, dbSchema, fromColumns);
|
194
|
-
}
|
195
|
-
if (functionCall.ADDDATE_SYMBOL()
|
196
|
-
|| functionCall.SUBDATE_SYMBOL()
|
197
|
-
|| functionCall.DATE_ADD_SYMBOL()
|
198
|
-
|| functionCall.DATE_SUB_SYMBOL()) {
|
199
|
-
const exprList = functionCall.expr();
|
200
|
-
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
201
|
-
}
|
202
|
-
if (functionCall.COALESCE_SYMBOL()) {
|
203
|
-
const exprList = (_b = functionCall.exprListWithParentheses()) === null || _b === void 0 ? void 0 : _b.exprList().expr();
|
204
|
-
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
205
|
-
}
|
206
|
-
throw Error('Function not supported: ' + functionCall.text);
|
207
|
-
}
|
208
|
-
function inferNotNullFunctionCall(functionCall, dbSchema, fromColumns) {
|
209
|
-
var _a, _b, _c, _d;
|
210
|
-
const functionName = ((_a = functionCall.pureIdentifier()) === null || _a === void 0 ? void 0 : _a.text.toLowerCase()) || ((_b = functionCall.qualifiedIdentifier()) === null || _b === void 0 ? void 0 : _b.text.toLowerCase());
|
211
|
-
const udfExprList = (_c = functionCall.udfExprList()) === null || _c === void 0 ? void 0 : _c.udfExpr();
|
212
|
-
if (functionName == 'ifnull') {
|
213
|
-
if (udfExprList) {
|
214
|
-
const [expr1, expr2] = udfExprList;
|
215
|
-
const notNull = inferNotNullExpr(expr1.expr(), dbSchema, fromColumns) || inferNotNullExpr(expr2.expr(), dbSchema, fromColumns);
|
216
|
-
return notNull;
|
217
|
-
}
|
218
|
-
return false;
|
219
|
-
}
|
220
|
-
if (functionName == 'avg') {
|
221
|
-
return false;
|
222
|
-
}
|
223
|
-
if (functionName == 'str_to_date') {
|
224
|
-
return false; //invalid date
|
225
|
-
}
|
226
|
-
if (udfExprList) {
|
227
|
-
return udfExprList.filter((expr, paramIndex) => {
|
228
|
-
return functionName == 'timestampdiff' ? paramIndex != 0 : true; //filter the first parameter of timestampdiff function
|
229
|
-
}).every((udfExpr) => {
|
230
|
-
const expr = udfExpr.expr();
|
231
|
-
return inferNotNullExpr(expr, dbSchema, fromColumns);
|
232
|
-
});
|
233
|
-
}
|
234
|
-
const exprList = (_d = functionCall.exprList()) === null || _d === void 0 ? void 0 : _d.expr();
|
235
|
-
if (exprList) {
|
236
|
-
return exprList.every(expr => {
|
237
|
-
return inferNotNullExpr(expr, dbSchema, fromColumns);
|
238
|
-
});
|
239
|
-
}
|
240
|
-
return true;
|
241
|
-
}
|
242
|
-
function possibleNullWhere(field, whereClause) {
|
243
|
-
const expr = whereClause.expr();
|
244
|
-
return possibleNull(field, expr);
|
245
|
-
}
|
246
|
-
function possibleNull(field, exprContext) {
|
247
|
-
if (exprContext instanceof ts_mysql_parser_1.ExprIsContext) {
|
248
|
-
const boolPri = exprContext.boolPri();
|
249
|
-
if (boolPri instanceof ts_mysql_parser_1.PrimaryExprPredicateContext) {
|
250
|
-
const res = boolPri.predicate().bitExpr()[0].simpleExpr();
|
251
|
-
if (res instanceof ts_mysql_parser_1.SimpleExprListContext) {
|
252
|
-
const expr = res.exprList().expr()[0];
|
253
|
-
return possibleNull(field, expr);
|
254
|
-
}
|
255
|
-
}
|
256
|
-
if (boolPri instanceof ts_mysql_parser_1.PrimaryExprIsNullContext) {
|
257
|
-
const compare = boolPri.boolPri();
|
258
|
-
if (boolPri.notRule() && areEquals(field, compare.text)) {
|
259
|
-
return false; //possibleNull
|
260
|
-
}
|
261
|
-
}
|
262
|
-
if (boolPri instanceof ts_mysql_parser_1.PrimaryExprCompareContext) {
|
263
|
-
let compare = boolPri.boolPri().text; //value > 10;
|
264
|
-
let compare2 = boolPri.predicate().text; //10 < value
|
265
|
-
//TODO - more complex expressions. ex. (value + value2) > 10;
|
266
|
-
if (areEquals(field, compare) || areEquals(field, compare2)) {
|
267
|
-
return false; //possibleNull
|
268
|
-
}
|
269
|
-
}
|
270
|
-
return true; //possibleNull
|
271
|
-
}
|
272
|
-
if (exprContext instanceof ts_mysql_parser_1.ExprNotContext) {
|
273
|
-
const expr = exprContext.expr();
|
274
|
-
return !possibleNull(field, expr);
|
275
|
-
}
|
276
|
-
if (exprContext instanceof ts_mysql_parser_1.ExprAndContext) {
|
277
|
-
const [first, ...rest] = exprContext.expr();
|
278
|
-
let possibleNullVar = possibleNull(field, first);
|
279
|
-
rest.forEach(expr => {
|
280
|
-
possibleNullVar = possibleNullVar && possibleNull(field, expr);
|
281
|
-
});
|
282
|
-
return possibleNullVar;
|
283
|
-
}
|
284
|
-
if (exprContext instanceof ts_mysql_parser_1.ExprXorContext) {
|
285
|
-
const expressions = exprContext.expr();
|
286
|
-
}
|
287
|
-
if (exprContext instanceof ts_mysql_parser_1.ExprOrContext) {
|
288
|
-
const [first, ...rest] = exprContext.expr();
|
289
|
-
let possibleNullVar = possibleNull(field, first);
|
290
|
-
rest.forEach(expr => {
|
291
|
-
possibleNullVar = possibleNullVar || possibleNull(field, expr);
|
292
|
-
});
|
293
|
-
return possibleNullVar;
|
294
|
-
}
|
295
|
-
throw Error('Unknow type:' + exprContext.constructor.name);
|
296
|
-
}
|
297
|
-
exports.possibleNull = possibleNull;
|
298
|
-
function areEquals(field, expressionField) {
|
299
|
-
const compare = select_columns_1.splitName(expressionField); //t1.name
|
300
|
-
/*
|
301
|
-
t1.name == t1.name
|
302
|
-
t1.name == name
|
303
|
-
name == t1.name
|
304
|
-
*/
|
305
|
-
return field.name == compare.name &&
|
306
|
-
((field.prefix == compare.prefix) || (field.prefix == '' || compare.prefix == ''));
|
307
|
-
}
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.possibleNull = exports.inferNotNull = exports.parseAndInferNotNull = void 0;
|
4
|
+
const parse_1 = require("./parse");
|
5
|
+
const ts_mysql_parser_1 = require("ts-mysql-parser");
|
6
|
+
const select_columns_1 = require("./select-columns");
|
7
|
+
const infer_param_nullability_1 = require("./infer-param-nullability");
|
8
|
+
function parseAndInferNotNull(sql, dbSchema) {
|
9
|
+
var _a;
|
10
|
+
const queryTree = (0, parse_1.parse)(sql);
|
11
|
+
const selectStatement = (_a = queryTree.simpleStatement()) === null || _a === void 0 ? void 0 : _a.selectStatement();
|
12
|
+
if (selectStatement) {
|
13
|
+
const queries = (0, parse_1.getQuerySpecificationsFromSelectStatement)(selectStatement);
|
14
|
+
const notNullAllQueries = queries.map(query => inferNotNull(query, dbSchema)); //TODO - UNION
|
15
|
+
const result = zip(notNullAllQueries).map(notNullColumn => notNullColumn.every(notNull => notNull == true));
|
16
|
+
return result;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
exports.parseAndInferNotNull = parseAndInferNotNull;
|
20
|
+
function zip(arrays) {
|
21
|
+
return arrays[0].map(function (_, i) {
|
22
|
+
return arrays.map(function (array) { return array[i]; });
|
23
|
+
});
|
24
|
+
}
|
25
|
+
function inferNotNull(querySpec, dbSchema) {
|
26
|
+
const fromColumns = (0, select_columns_1.getColumnsFrom)(querySpec, dbSchema); //TODO - called twice
|
27
|
+
const notNullInference = [];
|
28
|
+
const whereClause = querySpec.whereClause();
|
29
|
+
if (querySpec.selectItemList().MULT_OPERATOR()) {
|
30
|
+
fromColumns.forEach(col => {
|
31
|
+
const field = (0, select_columns_1.splitName)(col.columnName);
|
32
|
+
const notNull = col.notNull || (whereClause && !possibleNullWhere(field, whereClause)) || false;
|
33
|
+
notNullInference.push(notNull); //TODO infernot null in where?
|
34
|
+
});
|
35
|
+
}
|
36
|
+
querySpec.selectItemList().selectItem().forEach(selectItem => {
|
37
|
+
notNullInference.push(...inferNotNullSelectItem(selectItem, dbSchema, fromColumns, whereClause));
|
38
|
+
});
|
39
|
+
return notNullInference;
|
40
|
+
}
|
41
|
+
exports.inferNotNull = inferNotNull;
|
42
|
+
function inferNotNullSelectItem(selectItem, dbSchema, fromColumns, whereClause) {
|
43
|
+
const notNullItems = [];
|
44
|
+
const tableWild = selectItem.tableWild();
|
45
|
+
if (tableWild === null || tableWild === void 0 ? void 0 : tableWild.MULT_OPERATOR()) { //TODO: DUPLICATED CODE FROM WALKER
|
46
|
+
tableWild.identifier().forEach(tabWild => {
|
47
|
+
const prefix = tabWild.text;
|
48
|
+
const columns = (0, select_columns_1.selectAllColumns)(prefix, fromColumns);
|
49
|
+
columns.forEach(col => {
|
50
|
+
const field = (0, select_columns_1.splitName)(col.columnName);
|
51
|
+
const notNull = col.notNull || (whereClause && !possibleNullWhere(field, whereClause)) || false;
|
52
|
+
notNullItems.push(notNull);
|
53
|
+
});
|
54
|
+
});
|
55
|
+
return notNullItems;
|
56
|
+
}
|
57
|
+
const expr = selectItem.expr();
|
58
|
+
if (expr) {
|
59
|
+
const notNull = inferNotNullExpr(expr, dbSchema, fromColumns);
|
60
|
+
return [notNull];
|
61
|
+
}
|
62
|
+
throw Error('Error during column null inference');
|
63
|
+
}
|
64
|
+
function inferNotNullExpr(expr, dbSchema, fromColumns) {
|
65
|
+
if (expr instanceof ts_mysql_parser_1.ExprIsContext) {
|
66
|
+
return inferNotNullExprIs(expr, dbSchema, fromColumns);
|
67
|
+
}
|
68
|
+
throw Error('Error during column null inference');
|
69
|
+
}
|
70
|
+
function inferNotNullExprIs(exprIs, dbSchema, fromColumns) {
|
71
|
+
const boolPri = exprIs.boolPri();
|
72
|
+
return inferNotNullBoolPri(boolPri, dbSchema, fromColumns);
|
73
|
+
}
|
74
|
+
function inferNotNullBoolPri(boolPri, dbSchema, fromColumns) {
|
75
|
+
if (boolPri instanceof ts_mysql_parser_1.PrimaryExprPredicateContext) {
|
76
|
+
const predicate = boolPri.predicate();
|
77
|
+
return inferNotNullPredicate(predicate, dbSchema, fromColumns);
|
78
|
+
}
|
79
|
+
if (boolPri instanceof ts_mysql_parser_1.PrimaryExprCompareContext) {
|
80
|
+
const compareLeft = boolPri.boolPri();
|
81
|
+
const compareRight = boolPri.predicate();
|
82
|
+
const notNullLeft = inferNotNullBoolPri(compareLeft, dbSchema, fromColumns);
|
83
|
+
const notNullRight = inferNotNullPredicate(compareRight, dbSchema, fromColumns);
|
84
|
+
return notNullLeft && notNullRight;
|
85
|
+
}
|
86
|
+
throw Error('Error during column null inference');
|
87
|
+
}
|
88
|
+
function inferNotNullPredicate(predicate, dbSchema, fromColumns) {
|
89
|
+
const bitExpr = predicate.bitExpr();
|
90
|
+
if (bitExpr.length == 1) {
|
91
|
+
return inferNotNullBitExpr(bitExpr[0], dbSchema, fromColumns);
|
92
|
+
}
|
93
|
+
throw Error('Error during column null inference');
|
94
|
+
}
|
95
|
+
function inferNotNullBitExpr(bitExpr, dbSchema, fromColumns) {
|
96
|
+
const simpleExpr = bitExpr.simpleExpr();
|
97
|
+
if (simpleExpr) {
|
98
|
+
return inferNotNullSimpleExpr(simpleExpr, dbSchema, fromColumns);
|
99
|
+
}
|
100
|
+
const bitExpr2 = bitExpr.bitExpr();
|
101
|
+
if (bitExpr2.length == 2) {
|
102
|
+
return inferNotNullBitExpr(bitExpr2[0], dbSchema, fromColumns) && inferNotNullBitExpr(bitExpr2[1], dbSchema, fromColumns);
|
103
|
+
}
|
104
|
+
throw Error('Error during column null inference');
|
105
|
+
}
|
106
|
+
function inferNotNullSimpleExpr(simpleExpr, dbSchema, fromColumns) {
|
107
|
+
const querySpec = (0, infer_param_nullability_1.getParentContext)(simpleExpr, ts_mysql_parser_1.QuerySpecificationContext);
|
108
|
+
const whereClause = querySpec.whereClause();
|
109
|
+
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprColumnRefContext) {
|
110
|
+
const columnName = simpleExpr.columnRef().fieldIdentifier().text;
|
111
|
+
const fieldName = (0, select_columns_1.splitName)(columnName);
|
112
|
+
const column = (0, select_columns_1.findColumn)(fieldName, fromColumns);
|
113
|
+
return column.notNull || (whereClause && !possibleNullWhere(fieldName, whereClause) || false);
|
114
|
+
}
|
115
|
+
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprRuntimeFunctionContext) {
|
116
|
+
return inferNotNullRuntimeFunctionCall(simpleExpr, dbSchema, fromColumns);
|
117
|
+
}
|
118
|
+
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprFunctionContext) {
|
119
|
+
const functionCall = simpleExpr.functionCall();
|
120
|
+
return inferNotNullFunctionCall(functionCall, dbSchema, fromColumns);
|
121
|
+
}
|
122
|
+
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprLiteralContext) {
|
123
|
+
const nullLiteral = simpleExpr.literal().nullLiteral();
|
124
|
+
if (nullLiteral) {
|
125
|
+
return false;
|
126
|
+
}
|
127
|
+
return true;
|
128
|
+
}
|
129
|
+
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprParamMarkerContext) {
|
130
|
+
const inferParam = (0, infer_param_nullability_1.inferParameterNotNull)(simpleExpr);
|
131
|
+
return inferParam;
|
132
|
+
}
|
133
|
+
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprSumContext) {
|
134
|
+
const sumExpr = simpleExpr.sumExpr();
|
135
|
+
if (sumExpr.COUNT_SYMBOL()) {
|
136
|
+
return true;
|
137
|
+
}
|
138
|
+
const inSumExpr = sumExpr.inSumExpr();
|
139
|
+
if (inSumExpr) {
|
140
|
+
return false;
|
141
|
+
}
|
142
|
+
}
|
143
|
+
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprListContext) {
|
144
|
+
const exprList = simpleExpr.exprList().expr();
|
145
|
+
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
146
|
+
}
|
147
|
+
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprSubQueryContext) {
|
148
|
+
return false;
|
149
|
+
}
|
150
|
+
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprCaseContext) {
|
151
|
+
const thenExprList = simpleExpr.thenExpression();
|
152
|
+
const elseExpr = simpleExpr.elseExpression();
|
153
|
+
if (elseExpr) {
|
154
|
+
let caseNotNull = thenExprList.every(thenExpr => inferNotNullExpr(thenExpr.expr(), dbSchema, fromColumns));
|
155
|
+
return caseNotNull && inferNotNullExpr(elseExpr.expr(), dbSchema, fromColumns);
|
156
|
+
}
|
157
|
+
else {
|
158
|
+
return false; //if doesn't have else, the not null can't be inferred
|
159
|
+
}
|
160
|
+
}
|
161
|
+
if (simpleExpr instanceof ts_mysql_parser_1.SimpleExprIntervalContext) {
|
162
|
+
const exprList = simpleExpr.expr();
|
163
|
+
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
164
|
+
}
|
165
|
+
throw Error('Error during column null inference');
|
166
|
+
}
|
167
|
+
function inferNotNullRuntimeFunctionCall(simpleExprRuntimeFunction, dbSchema, fromColumns) {
|
168
|
+
var _a, _b;
|
169
|
+
const functionCall = simpleExprRuntimeFunction.runtimeFunctionCall();
|
170
|
+
if (functionCall.NOW_SYMBOL() || functionCall.CURDATE_SYMBOL() || functionCall.CURTIME_SYMBOL()) {
|
171
|
+
return true;
|
172
|
+
}
|
173
|
+
if (functionCall.MOD_SYMBOL()) {
|
174
|
+
return false; //MOD(N,0) returns NULL.
|
175
|
+
}
|
176
|
+
if (functionCall.REPLACE_SYMBOL()) {
|
177
|
+
const exprList = functionCall.expr();
|
178
|
+
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
179
|
+
}
|
180
|
+
const trimFunction = functionCall.trimFunction();
|
181
|
+
if (trimFunction) {
|
182
|
+
const exprList = trimFunction.expr();
|
183
|
+
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
184
|
+
}
|
185
|
+
const substringFunction = functionCall.substringFunction();
|
186
|
+
if (substringFunction) {
|
187
|
+
const exprList = substringFunction.expr();
|
188
|
+
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
189
|
+
}
|
190
|
+
if (functionCall.YEAR_SYMBOL() || functionCall.MONTH_SYMBOL() || functionCall.DAY_SYMBOL()
|
191
|
+
|| functionCall.HOUR_SYMBOL() || functionCall.MINUTE_SYMBOL() || functionCall.SECOND_SYMBOL()) {
|
192
|
+
const expr = (_a = functionCall.exprWithParentheses()) === null || _a === void 0 ? void 0 : _a.expr();
|
193
|
+
return inferNotNullExpr(expr, dbSchema, fromColumns);
|
194
|
+
}
|
195
|
+
if (functionCall.ADDDATE_SYMBOL()
|
196
|
+
|| functionCall.SUBDATE_SYMBOL()
|
197
|
+
|| functionCall.DATE_ADD_SYMBOL()
|
198
|
+
|| functionCall.DATE_SUB_SYMBOL()) {
|
199
|
+
const exprList = functionCall.expr();
|
200
|
+
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
201
|
+
}
|
202
|
+
if (functionCall.COALESCE_SYMBOL()) {
|
203
|
+
const exprList = (_b = functionCall.exprListWithParentheses()) === null || _b === void 0 ? void 0 : _b.exprList().expr();
|
204
|
+
return exprList.every(expr => inferNotNullExpr(expr, dbSchema, fromColumns));
|
205
|
+
}
|
206
|
+
throw Error('Function not supported: ' + functionCall.text);
|
207
|
+
}
|
208
|
+
function inferNotNullFunctionCall(functionCall, dbSchema, fromColumns) {
|
209
|
+
var _a, _b, _c, _d;
|
210
|
+
const functionName = ((_a = functionCall.pureIdentifier()) === null || _a === void 0 ? void 0 : _a.text.toLowerCase()) || ((_b = functionCall.qualifiedIdentifier()) === null || _b === void 0 ? void 0 : _b.text.toLowerCase());
|
211
|
+
const udfExprList = (_c = functionCall.udfExprList()) === null || _c === void 0 ? void 0 : _c.udfExpr();
|
212
|
+
if (functionName == 'ifnull') {
|
213
|
+
if (udfExprList) {
|
214
|
+
const [expr1, expr2] = udfExprList;
|
215
|
+
const notNull = inferNotNullExpr(expr1.expr(), dbSchema, fromColumns) || inferNotNullExpr(expr2.expr(), dbSchema, fromColumns);
|
216
|
+
return notNull;
|
217
|
+
}
|
218
|
+
return false;
|
219
|
+
}
|
220
|
+
if (functionName == 'avg') {
|
221
|
+
return false;
|
222
|
+
}
|
223
|
+
if (functionName == 'str_to_date') {
|
224
|
+
return false; //invalid date
|
225
|
+
}
|
226
|
+
if (udfExprList) {
|
227
|
+
return udfExprList.filter((expr, paramIndex) => {
|
228
|
+
return functionName == 'timestampdiff' ? paramIndex != 0 : true; //filter the first parameter of timestampdiff function
|
229
|
+
}).every((udfExpr) => {
|
230
|
+
const expr = udfExpr.expr();
|
231
|
+
return inferNotNullExpr(expr, dbSchema, fromColumns);
|
232
|
+
});
|
233
|
+
}
|
234
|
+
const exprList = (_d = functionCall.exprList()) === null || _d === void 0 ? void 0 : _d.expr();
|
235
|
+
if (exprList) {
|
236
|
+
return exprList.every(expr => {
|
237
|
+
return inferNotNullExpr(expr, dbSchema, fromColumns);
|
238
|
+
});
|
239
|
+
}
|
240
|
+
return true;
|
241
|
+
}
|
242
|
+
function possibleNullWhere(field, whereClause) {
|
243
|
+
const expr = whereClause.expr();
|
244
|
+
return possibleNull(field, expr);
|
245
|
+
}
|
246
|
+
function possibleNull(field, exprContext) {
|
247
|
+
if (exprContext instanceof ts_mysql_parser_1.ExprIsContext) {
|
248
|
+
const boolPri = exprContext.boolPri();
|
249
|
+
if (boolPri instanceof ts_mysql_parser_1.PrimaryExprPredicateContext) {
|
250
|
+
const res = boolPri.predicate().bitExpr()[0].simpleExpr();
|
251
|
+
if (res instanceof ts_mysql_parser_1.SimpleExprListContext) {
|
252
|
+
const expr = res.exprList().expr()[0];
|
253
|
+
return possibleNull(field, expr);
|
254
|
+
}
|
255
|
+
}
|
256
|
+
if (boolPri instanceof ts_mysql_parser_1.PrimaryExprIsNullContext) {
|
257
|
+
const compare = boolPri.boolPri();
|
258
|
+
if (boolPri.notRule() && areEquals(field, compare.text)) {
|
259
|
+
return false; //possibleNull
|
260
|
+
}
|
261
|
+
}
|
262
|
+
if (boolPri instanceof ts_mysql_parser_1.PrimaryExprCompareContext) {
|
263
|
+
let compare = boolPri.boolPri().text; //value > 10;
|
264
|
+
let compare2 = boolPri.predicate().text; //10 < value
|
265
|
+
//TODO - more complex expressions. ex. (value + value2) > 10;
|
266
|
+
if (areEquals(field, compare) || areEquals(field, compare2)) {
|
267
|
+
return false; //possibleNull
|
268
|
+
}
|
269
|
+
}
|
270
|
+
return true; //possibleNull
|
271
|
+
}
|
272
|
+
if (exprContext instanceof ts_mysql_parser_1.ExprNotContext) {
|
273
|
+
const expr = exprContext.expr();
|
274
|
+
return !possibleNull(field, expr);
|
275
|
+
}
|
276
|
+
if (exprContext instanceof ts_mysql_parser_1.ExprAndContext) {
|
277
|
+
const [first, ...rest] = exprContext.expr();
|
278
|
+
let possibleNullVar = possibleNull(field, first);
|
279
|
+
rest.forEach(expr => {
|
280
|
+
possibleNullVar = possibleNullVar && possibleNull(field, expr);
|
281
|
+
});
|
282
|
+
return possibleNullVar;
|
283
|
+
}
|
284
|
+
if (exprContext instanceof ts_mysql_parser_1.ExprXorContext) {
|
285
|
+
const expressions = exprContext.expr();
|
286
|
+
}
|
287
|
+
if (exprContext instanceof ts_mysql_parser_1.ExprOrContext) {
|
288
|
+
const [first, ...rest] = exprContext.expr();
|
289
|
+
let possibleNullVar = possibleNull(field, first);
|
290
|
+
rest.forEach(expr => {
|
291
|
+
possibleNullVar = possibleNullVar || possibleNull(field, expr);
|
292
|
+
});
|
293
|
+
return possibleNullVar;
|
294
|
+
}
|
295
|
+
throw Error('Unknow type:' + exprContext.constructor.name);
|
296
|
+
}
|
297
|
+
exports.possibleNull = possibleNull;
|
298
|
+
function areEquals(field, expressionField) {
|
299
|
+
const compare = (0, select_columns_1.splitName)(expressionField); //t1.name
|
300
|
+
/*
|
301
|
+
t1.name == t1.name
|
302
|
+
t1.name == name
|
303
|
+
name == t1.name
|
304
|
+
*/
|
305
|
+
return field.name == compare.name &&
|
306
|
+
((field.prefix == compare.prefix) || (field.prefix == '' || compare.prefix == ''));
|
307
|
+
}
|
308
308
|
//# sourceMappingURL=infer-column-nullability.js.map
|