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,374 +1,374 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.getSimpleExpressions = exports.findColumn2 = exports.findColumn = exports.splitName = exports.getColumnsFrom = exports.getColumnNames = exports.selectAllColumns = exports.filterColumns = void 0;
|
4
|
-
const antlr4ts_1 = require("antlr4ts");
|
5
|
-
const Interval_1 = require("antlr4ts/misc/Interval");
|
6
|
-
const ts_mysql_parser_1 = require("ts-mysql-parser");
|
7
|
-
const parse_1 = require("./parse");
|
8
|
-
const infer_column_nullability_1 = require("./infer-column-nullability");
|
9
|
-
function filterColumns(dbSchema, tablePrefix, table) {
|
10
|
-
const tableColumns = dbSchema.filter(schema => schema.table.toLowerCase() == table.name.toLowerCase() && (schema.schema == table.prefix || table.prefix == ''));
|
11
|
-
return tableColumns.map(tableColumn => {
|
12
|
-
//name and colum are the same on the leaf table
|
13
|
-
const r = {
|
14
|
-
columnName: tableColumn.column, column: tableColumn.column, columnType: tableColumn.column_type,
|
15
|
-
notNull: tableColumn.notNull, table: table.name, tableAlias: tablePrefix || '', columnKey: tableColumn.columnKey
|
16
|
-
};
|
17
|
-
return r;
|
18
|
-
});
|
19
|
-
}
|
20
|
-
exports.filterColumns = filterColumns;
|
21
|
-
function selectAllColumns(tablePrefix, fromColumns) {
|
22
|
-
const allColumns = [];
|
23
|
-
fromColumns.forEach(column => {
|
24
|
-
if (tablePrefix == '' || tablePrefix == column.tableAlias) {
|
25
|
-
allColumns.push(column);
|
26
|
-
}
|
27
|
-
});
|
28
|
-
return allColumns;
|
29
|
-
}
|
30
|
-
exports.selectAllColumns = selectAllColumns;
|
31
|
-
function getColumnNames(querySpec, fromColumns) {
|
32
|
-
const allColumns = [];
|
33
|
-
if (querySpec.selectItemList().MULT_OPERATOR()) {
|
34
|
-
allColumns.push(...selectAllColumns('', fromColumns).map(col => col.columnName));
|
35
|
-
}
|
36
|
-
const ctx = querySpec.selectItemList();
|
37
|
-
ctx.selectItem().forEach(selectItem => {
|
38
|
-
var _a, _b;
|
39
|
-
const tableWild = selectItem.tableWild();
|
40
|
-
if (tableWild) {
|
41
|
-
if (tableWild.MULT_OPERATOR()) {
|
42
|
-
const itemName = splitName(selectItem.text);
|
43
|
-
allColumns.push(...selectAllColumns(itemName.prefix, fromColumns).map(col => col.columnName));
|
44
|
-
}
|
45
|
-
}
|
46
|
-
else {
|
47
|
-
const alias = (_b = (_a = selectItem.selectAlias()) === null || _a === void 0 ? void 0 : _a.identifier()) === null || _b === void 0 ? void 0 : _b.text;
|
48
|
-
const tokens = getSimpleExpressions(selectItem);
|
49
|
-
let columnName = extractOriginalSql(selectItem.expr()); //TODO VERIFICAR NULL
|
50
|
-
if (tokens.length == 1 && tokens[0] instanceof ts_mysql_parser_1.SimpleExprColumnRefContext) {
|
51
|
-
columnName = splitName(tokens[0].text).name;
|
52
|
-
}
|
53
|
-
allColumns.push(alias || columnName);
|
54
|
-
}
|
55
|
-
});
|
56
|
-
return allColumns;
|
57
|
-
}
|
58
|
-
exports.getColumnNames = getColumnNames;
|
59
|
-
function getColumnsFrom(ctx, dbSchema) {
|
60
|
-
var _a, _b;
|
61
|
-
const tableReferences = (_b = (_a = ctx.fromClause()) === null || _a === void 0 ? void 0 : _a.tableReferenceList()) === null || _b === void 0 ? void 0 : _b.tableReference();
|
62
|
-
const fromColumns = tableReferences ? extractColumnsFromTableReferences(tableReferences, dbSchema) : [];
|
63
|
-
return fromColumns;
|
64
|
-
}
|
65
|
-
exports.getColumnsFrom = getColumnsFrom;
|
66
|
-
//rule: tableReference
|
67
|
-
function extractColumnsFromTableReferences(tablesReferences, dbSchema) {
|
68
|
-
const result = [];
|
69
|
-
tablesReferences.forEach(tab => {
|
70
|
-
const tableFactor = tab.tableFactor();
|
71
|
-
if (tableFactor) {
|
72
|
-
const fields = extractFieldsFromTableFactor(tableFactor, dbSchema);
|
73
|
-
result.push(...fields);
|
74
|
-
}
|
75
|
-
const allJoinedColumns = [];
|
76
|
-
let firstLeftJoinIndex = -1;
|
77
|
-
tab.joinedTable().forEach((joined, index) => {
|
78
|
-
var _a, _b;
|
79
|
-
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())) {
|
80
|
-
firstLeftJoinIndex = -1; //dont need to add notNull = false to joins
|
81
|
-
}
|
82
|
-
else if (firstLeftJoinIndex == -1) {
|
83
|
-
firstLeftJoinIndex = index; //add notNull = false to all joins after the first left join
|
84
|
-
}
|
85
|
-
const tableReferences = joined.tableReference();
|
86
|
-
const onClause = joined.expr(); //ON expr
|
87
|
-
if (tableReferences) {
|
88
|
-
const usingFields = extractFieldsFromUsingClause(joined);
|
89
|
-
const joinedFields = extractColumnsFromTableReferences([tableReferences], dbSchema);
|
90
|
-
//doesn't duplicate the fields of the USING clause. Ex. INNER JOIN mytable2 USING(id);
|
91
|
-
const joinedFieldsFiltered = usingFields.length > 0 ? filterUsingFields(joinedFields, usingFields) : joinedFields;
|
92
|
-
if (onClause) {
|
93
|
-
joinedFieldsFiltered.forEach(field => {
|
94
|
-
const fieldName = {
|
95
|
-
name: field.columnName,
|
96
|
-
prefix: field.tableAlias || ''
|
97
|
-
};
|
98
|
-
field.notNull = field.notNull || !infer_column_nullability_1.possibleNull(fieldName, onClause);
|
99
|
-
});
|
100
|
-
//apply inference to the parent join too
|
101
|
-
result.forEach(field => {
|
102
|
-
const fieldName = {
|
103
|
-
name: field.columnName,
|
104
|
-
prefix: field.tableAlias || ''
|
105
|
-
};
|
106
|
-
field.notNull = field.notNull || !infer_column_nullability_1.possibleNull(fieldName, onClause);
|
107
|
-
});
|
108
|
-
}
|
109
|
-
allJoinedColumns.push(joinedFieldsFiltered);
|
110
|
-
}
|
111
|
-
});
|
112
|
-
allJoinedColumns.forEach((joinedColumns, index) => {
|
113
|
-
joinedColumns.forEach(field => {
|
114
|
-
if (firstLeftJoinIndex != -1 && index >= firstLeftJoinIndex) {
|
115
|
-
const newField = Object.assign(Object.assign({}, field), { notNull: false });
|
116
|
-
result.push(newField);
|
117
|
-
}
|
118
|
-
else {
|
119
|
-
result.push(field);
|
120
|
-
}
|
121
|
-
});
|
122
|
-
});
|
123
|
-
});
|
124
|
-
return result;
|
125
|
-
}
|
126
|
-
function extractFieldsFromUsingClause(joinedTableContext) {
|
127
|
-
var _a;
|
128
|
-
const usingFieldsClause = (_a = joinedTableContext.identifierListWithParentheses()) === null || _a === void 0 ? void 0 : _a.identifierList();
|
129
|
-
if (usingFieldsClause) {
|
130
|
-
return usingFieldsClause.text.split(',').map(field => field.trim());
|
131
|
-
}
|
132
|
-
return [];
|
133
|
-
}
|
134
|
-
function filterUsingFields(joinedFields, usingFields) {
|
135
|
-
return joinedFields.filter(joinedField => {
|
136
|
-
const isUsing = usingFields.includes(joinedField.columnName);
|
137
|
-
if (!isUsing) {
|
138
|
-
return joinedField;
|
139
|
-
}
|
140
|
-
});
|
141
|
-
}
|
142
|
-
//rule: singleTable
|
143
|
-
function extractFieldsFromSingleTable(dbSchema, ctx) {
|
144
|
-
var _a;
|
145
|
-
const table = ctx === null || ctx === void 0 ? void 0 : ctx.tableRef().text;
|
146
|
-
const tableAlias = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.tableAlias()) === null || _a === void 0 ? void 0 : _a.text;
|
147
|
-
const tableName = splitName(table);
|
148
|
-
const fields = filterColumns(dbSchema, tableAlias, tableName);
|
149
|
-
return fields;
|
150
|
-
}
|
151
|
-
//rule: singleTableParens
|
152
|
-
function extractFieldsFromSingleTableParens(dbSchema, ctx) {
|
153
|
-
let fields = [];
|
154
|
-
//singleTable | singleTableParens
|
155
|
-
const singleTable = ctx.singleTable();
|
156
|
-
if (singleTable) {
|
157
|
-
fields = extractFieldsFromSingleTable(dbSchema, singleTable);
|
158
|
-
}
|
159
|
-
const singleTableParens = ctx.singleTableParens();
|
160
|
-
if (singleTableParens) {
|
161
|
-
fields = extractFieldsFromSingleTableParens(dbSchema, singleTableParens);
|
162
|
-
}
|
163
|
-
return fields;
|
164
|
-
}
|
165
|
-
/*rule:
|
166
|
-
tableFactor:
|
167
|
-
singleTable
|
168
|
-
| singleTableParens
|
169
|
-
| derivedTable
|
170
|
-
| tableReferenceListParens
|
171
|
-
| {serverVersion >= 80004}? tableFunction
|
172
|
-
*/
|
173
|
-
function extractFieldsFromTableFactor(tableFactor, dbSchema) {
|
174
|
-
var _a;
|
175
|
-
const singleTable = tableFactor.singleTable();
|
176
|
-
if (singleTable) {
|
177
|
-
return extractFieldsFromSingleTable(dbSchema, singleTable);
|
178
|
-
}
|
179
|
-
const singleTableParens = tableFactor.singleTableParens();
|
180
|
-
if (singleTableParens) {
|
181
|
-
return extractFieldsFromSingleTableParens(dbSchema, singleTableParens);
|
182
|
-
}
|
183
|
-
const derivadTable = tableFactor.derivedTable();
|
184
|
-
if (derivadTable) {
|
185
|
-
//walkQueryExpressionParens(queryExpressionParens, namedNodes, constraints, dbSchema);
|
186
|
-
//TODO - WALKSUBQUERY
|
187
|
-
const subQuery = derivadTable.subquery();
|
188
|
-
if (subQuery) {
|
189
|
-
//subquery=true only for select (subquery); not for from(subquery)
|
190
|
-
// const fromColumns
|
191
|
-
const queries = parse_1.getQuerySpecificationsFromSelectStatement(subQuery);
|
192
|
-
const queryResult = parse_1.analiseQuery(queries, dbSchema, []); //TODO - WHY []?
|
193
|
-
// console.log("queryResult=", queryResult);
|
194
|
-
const tableAlias = (_a = derivadTable.tableAlias()) === null || _a === void 0 ? void 0 : _a.text;
|
195
|
-
return queryResult.columns.map(col => {
|
196
|
-
const newCol = {
|
197
|
-
column: col.name,
|
198
|
-
columnName: col.name,
|
199
|
-
columnType: col.type,
|
200
|
-
columnKey: '',
|
201
|
-
notNull: col.notNull,
|
202
|
-
table: tableAlias || '',
|
203
|
-
tableAlias: tableAlias
|
204
|
-
};
|
205
|
-
return newCol;
|
206
|
-
});
|
207
|
-
}
|
208
|
-
}
|
209
|
-
const tableReferenceListParens = tableFactor.tableReferenceListParens();
|
210
|
-
if (tableReferenceListParens) {
|
211
|
-
const listParens = extractColumnsFromTableListParens(tableReferenceListParens, dbSchema);
|
212
|
-
return listParens;
|
213
|
-
}
|
214
|
-
return [];
|
215
|
-
}
|
216
|
-
//tableReferenceList | tableReferenceListParens
|
217
|
-
function extractColumnsFromTableListParens(ctx, dbSchema) {
|
218
|
-
const tableReferenceList = ctx.tableReferenceList();
|
219
|
-
if (tableReferenceList) {
|
220
|
-
return extractColumnsFromTableReferences(tableReferenceList.tableReference(), dbSchema);
|
221
|
-
}
|
222
|
-
const tableReferenceListParens = ctx.tableReferenceListParens();
|
223
|
-
if (tableReferenceListParens) {
|
224
|
-
return extractColumnsFromTableListParens(tableReferenceListParens, dbSchema);
|
225
|
-
}
|
226
|
-
return [];
|
227
|
-
}
|
228
|
-
function splitName(fieldName) {
|
229
|
-
const fieldNameSplit = fieldName.split('.');
|
230
|
-
const result = {
|
231
|
-
name: fieldNameSplit.length == 2 ? fieldNameSplit[1] : fieldNameSplit[0],
|
232
|
-
prefix: fieldNameSplit.length == 2 ? fieldNameSplit[0] : ''
|
233
|
-
};
|
234
|
-
const withoutStick = {
|
235
|
-
name: removeBackStick(result.name),
|
236
|
-
prefix: result.prefix
|
237
|
-
};
|
238
|
-
return withoutStick;
|
239
|
-
}
|
240
|
-
exports.splitName = splitName;
|
241
|
-
function removeBackStick(name) {
|
242
|
-
const withoutBackStick = name.startsWith("`") && name.endsWith("`") ? name.slice(1, -1) : name;
|
243
|
-
return withoutBackStick;
|
244
|
-
}
|
245
|
-
const functionAlias = [
|
246
|
-
{
|
247
|
-
column: 'CURRENT_DATE',
|
248
|
-
column_type: 'date',
|
249
|
-
columnKey: '',
|
250
|
-
notNull: true,
|
251
|
-
schema: '',
|
252
|
-
table: ''
|
253
|
-
},
|
254
|
-
{
|
255
|
-
column: 'CURRENT_TIME',
|
256
|
-
column_type: 'time',
|
257
|
-
columnKey: '',
|
258
|
-
notNull: true,
|
259
|
-
schema: '',
|
260
|
-
table: ''
|
261
|
-
},
|
262
|
-
{
|
263
|
-
column: 'CURRENT_TIMESTAMP',
|
264
|
-
column_type: 'timestamp',
|
265
|
-
columnKey: '',
|
266
|
-
notNull: true,
|
267
|
-
schema: '',
|
268
|
-
table: ''
|
269
|
-
},
|
270
|
-
{
|
271
|
-
column: 'LOCALTIME',
|
272
|
-
column_type: 'datetime',
|
273
|
-
columnKey: '',
|
274
|
-
notNull: true,
|
275
|
-
schema: '',
|
276
|
-
table: ''
|
277
|
-
},
|
278
|
-
{
|
279
|
-
column: 'LOCALTIMESTAMP',
|
280
|
-
column_type: 'datetime',
|
281
|
-
columnKey: '',
|
282
|
-
notNull: true,
|
283
|
-
schema: '',
|
284
|
-
table: ''
|
285
|
-
}
|
286
|
-
];
|
287
|
-
function findColumn(fieldName, columns) {
|
288
|
-
//TODO - Put tableAlias always ''
|
289
|
-
const functionType = functionAlias.find(col => col.column.toLowerCase() == fieldName.name.toLowerCase());
|
290
|
-
if (functionType) {
|
291
|
-
const colDef = {
|
292
|
-
column: functionType.column,
|
293
|
-
columnName: functionType.column,
|
294
|
-
columnType: functionType.column_type,
|
295
|
-
columnKey: functionType.columnKey,
|
296
|
-
notNull: functionType.notNull,
|
297
|
-
table: ''
|
298
|
-
};
|
299
|
-
return colDef;
|
300
|
-
}
|
301
|
-
const found = columns.find(col => col.columnName.toLowerCase() == fieldName.name.toLowerCase() &&
|
302
|
-
(fieldName.prefix == '' || fieldName.prefix == col.tableAlias || fieldName.prefix == col.table));
|
303
|
-
if (!found) {
|
304
|
-
throw Error('column not found:' + JSON.stringify(fieldName));
|
305
|
-
}
|
306
|
-
return found;
|
307
|
-
}
|
308
|
-
exports.findColumn = findColumn;
|
309
|
-
function findColumn2(fieldName, table, columns) {
|
310
|
-
//TODO - Put tableAlias always ''
|
311
|
-
const functionType = functionAlias.find(col => col.column == fieldName.name);
|
312
|
-
if (functionType) {
|
313
|
-
return functionType;
|
314
|
-
}
|
315
|
-
const found = columns.find(col => col.column.toLowerCase() === fieldName.name.toLowerCase() && table === col.table);
|
316
|
-
if (!found) {
|
317
|
-
throw Error('column not found:' + JSON.stringify(fieldName));
|
318
|
-
}
|
319
|
-
return found;
|
320
|
-
}
|
321
|
-
exports.findColumn2 = findColumn2;
|
322
|
-
function extractOriginalSql(rule) {
|
323
|
-
var _a, _b;
|
324
|
-
const startIndex = rule.start.startIndex;
|
325
|
-
const stopIndex = ((_a = rule.stop) === null || _a === void 0 ? void 0 : _a.stopIndex) || startIndex;
|
326
|
-
const interval = new Interval_1.Interval(startIndex, stopIndex);
|
327
|
-
const result = (_b = rule.start.inputStream) === null || _b === void 0 ? void 0 : _b.getText(interval);
|
328
|
-
return result;
|
329
|
-
}
|
330
|
-
function getSimpleExpressions(ctx) {
|
331
|
-
const tokens = [];
|
332
|
-
collectSimpleExpr(tokens, ctx);
|
333
|
-
return tokens;
|
334
|
-
}
|
335
|
-
exports.getSimpleExpressions = getSimpleExpressions;
|
336
|
-
function collectSimpleExpr(tokens, parent) {
|
337
|
-
if (isSimpleExpression(parent)) {
|
338
|
-
tokens.push(parent);
|
339
|
-
}
|
340
|
-
for (let i = 0; i < parent.childCount; i++) {
|
341
|
-
const child = parent.getChild(i);
|
342
|
-
if (child instanceof antlr4ts_1.RuleContext) {
|
343
|
-
collectSimpleExpr(tokens, child);
|
344
|
-
}
|
345
|
-
}
|
346
|
-
}
|
347
|
-
function isSimpleExpression(ctx) {
|
348
|
-
return ctx instanceof ts_mysql_parser_1.SimpleExprVariableContext
|
349
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprColumnRefContext
|
350
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprRuntimeFunctionContext
|
351
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprFunctionContext
|
352
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprCollateContext
|
353
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprLiteralContext
|
354
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprParamMarkerContext
|
355
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprSumContext
|
356
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprGroupingOperationContext
|
357
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprWindowingFunctionContext
|
358
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprConcatContext
|
359
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprUnaryContext
|
360
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprNotContext
|
361
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprListContext
|
362
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprSubQueryContext
|
363
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprOdbcContext
|
364
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprMatchContext
|
365
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprBinaryContext
|
366
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprCastContext
|
367
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprCaseContext
|
368
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprConvertContext
|
369
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprConvertUsingContext
|
370
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprDefaultContext
|
371
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprValuesContext
|
372
|
-
|| ctx instanceof ts_mysql_parser_1.SimpleExprIntervalContext;
|
373
|
-
}
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.getSimpleExpressions = exports.findColumn2 = exports.findColumn = exports.splitName = exports.getColumnsFrom = exports.getColumnNames = exports.selectAllColumns = exports.filterColumns = void 0;
|
4
|
+
const antlr4ts_1 = require("antlr4ts");
|
5
|
+
const Interval_1 = require("antlr4ts/misc/Interval");
|
6
|
+
const ts_mysql_parser_1 = require("ts-mysql-parser");
|
7
|
+
const parse_1 = require("./parse");
|
8
|
+
const infer_column_nullability_1 = require("./infer-column-nullability");
|
9
|
+
function filterColumns(dbSchema, tablePrefix, table) {
|
10
|
+
const tableColumns = dbSchema.filter(schema => schema.table.toLowerCase() == table.name.toLowerCase() && (schema.schema == table.prefix || table.prefix == ''));
|
11
|
+
return tableColumns.map(tableColumn => {
|
12
|
+
//name and colum are the same on the leaf table
|
13
|
+
const r = {
|
14
|
+
columnName: tableColumn.column, column: tableColumn.column, columnType: tableColumn.column_type,
|
15
|
+
notNull: tableColumn.notNull, table: table.name, tableAlias: tablePrefix || '', columnKey: tableColumn.columnKey
|
16
|
+
};
|
17
|
+
return r;
|
18
|
+
});
|
19
|
+
}
|
20
|
+
exports.filterColumns = filterColumns;
|
21
|
+
function selectAllColumns(tablePrefix, fromColumns) {
|
22
|
+
const allColumns = [];
|
23
|
+
fromColumns.forEach(column => {
|
24
|
+
if (tablePrefix == '' || tablePrefix == column.tableAlias) {
|
25
|
+
allColumns.push(column);
|
26
|
+
}
|
27
|
+
});
|
28
|
+
return allColumns;
|
29
|
+
}
|
30
|
+
exports.selectAllColumns = selectAllColumns;
|
31
|
+
function getColumnNames(querySpec, fromColumns) {
|
32
|
+
const allColumns = [];
|
33
|
+
if (querySpec.selectItemList().MULT_OPERATOR()) {
|
34
|
+
allColumns.push(...selectAllColumns('', fromColumns).map(col => col.columnName));
|
35
|
+
}
|
36
|
+
const ctx = querySpec.selectItemList();
|
37
|
+
ctx.selectItem().forEach(selectItem => {
|
38
|
+
var _a, _b;
|
39
|
+
const tableWild = selectItem.tableWild();
|
40
|
+
if (tableWild) {
|
41
|
+
if (tableWild.MULT_OPERATOR()) {
|
42
|
+
const itemName = splitName(selectItem.text);
|
43
|
+
allColumns.push(...selectAllColumns(itemName.prefix, fromColumns).map(col => col.columnName));
|
44
|
+
}
|
45
|
+
}
|
46
|
+
else {
|
47
|
+
const alias = (_b = (_a = selectItem.selectAlias()) === null || _a === void 0 ? void 0 : _a.identifier()) === null || _b === void 0 ? void 0 : _b.text;
|
48
|
+
const tokens = getSimpleExpressions(selectItem);
|
49
|
+
let columnName = extractOriginalSql(selectItem.expr()); //TODO VERIFICAR NULL
|
50
|
+
if (tokens.length == 1 && tokens[0] instanceof ts_mysql_parser_1.SimpleExprColumnRefContext) {
|
51
|
+
columnName = splitName(tokens[0].text).name;
|
52
|
+
}
|
53
|
+
allColumns.push(alias || columnName);
|
54
|
+
}
|
55
|
+
});
|
56
|
+
return allColumns;
|
57
|
+
}
|
58
|
+
exports.getColumnNames = getColumnNames;
|
59
|
+
function getColumnsFrom(ctx, dbSchema) {
|
60
|
+
var _a, _b;
|
61
|
+
const tableReferences = (_b = (_a = ctx.fromClause()) === null || _a === void 0 ? void 0 : _a.tableReferenceList()) === null || _b === void 0 ? void 0 : _b.tableReference();
|
62
|
+
const fromColumns = tableReferences ? extractColumnsFromTableReferences(tableReferences, dbSchema) : [];
|
63
|
+
return fromColumns;
|
64
|
+
}
|
65
|
+
exports.getColumnsFrom = getColumnsFrom;
|
66
|
+
//rule: tableReference
|
67
|
+
function extractColumnsFromTableReferences(tablesReferences, dbSchema) {
|
68
|
+
const result = [];
|
69
|
+
tablesReferences.forEach(tab => {
|
70
|
+
const tableFactor = tab.tableFactor();
|
71
|
+
if (tableFactor) {
|
72
|
+
const fields = extractFieldsFromTableFactor(tableFactor, dbSchema);
|
73
|
+
result.push(...fields);
|
74
|
+
}
|
75
|
+
const allJoinedColumns = [];
|
76
|
+
let firstLeftJoinIndex = -1;
|
77
|
+
tab.joinedTable().forEach((joined, index) => {
|
78
|
+
var _a, _b;
|
79
|
+
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())) {
|
80
|
+
firstLeftJoinIndex = -1; //dont need to add notNull = false to joins
|
81
|
+
}
|
82
|
+
else if (firstLeftJoinIndex == -1) {
|
83
|
+
firstLeftJoinIndex = index; //add notNull = false to all joins after the first left join
|
84
|
+
}
|
85
|
+
const tableReferences = joined.tableReference();
|
86
|
+
const onClause = joined.expr(); //ON expr
|
87
|
+
if (tableReferences) {
|
88
|
+
const usingFields = extractFieldsFromUsingClause(joined);
|
89
|
+
const joinedFields = extractColumnsFromTableReferences([tableReferences], dbSchema);
|
90
|
+
//doesn't duplicate the fields of the USING clause. Ex. INNER JOIN mytable2 USING(id);
|
91
|
+
const joinedFieldsFiltered = usingFields.length > 0 ? filterUsingFields(joinedFields, usingFields) : joinedFields;
|
92
|
+
if (onClause) {
|
93
|
+
joinedFieldsFiltered.forEach(field => {
|
94
|
+
const fieldName = {
|
95
|
+
name: field.columnName,
|
96
|
+
prefix: field.tableAlias || ''
|
97
|
+
};
|
98
|
+
field.notNull = field.notNull || !(0, infer_column_nullability_1.possibleNull)(fieldName, onClause);
|
99
|
+
});
|
100
|
+
//apply inference to the parent join too
|
101
|
+
result.forEach(field => {
|
102
|
+
const fieldName = {
|
103
|
+
name: field.columnName,
|
104
|
+
prefix: field.tableAlias || ''
|
105
|
+
};
|
106
|
+
field.notNull = field.notNull || !(0, infer_column_nullability_1.possibleNull)(fieldName, onClause);
|
107
|
+
});
|
108
|
+
}
|
109
|
+
allJoinedColumns.push(joinedFieldsFiltered);
|
110
|
+
}
|
111
|
+
});
|
112
|
+
allJoinedColumns.forEach((joinedColumns, index) => {
|
113
|
+
joinedColumns.forEach(field => {
|
114
|
+
if (firstLeftJoinIndex != -1 && index >= firstLeftJoinIndex) {
|
115
|
+
const newField = Object.assign(Object.assign({}, field), { notNull: false });
|
116
|
+
result.push(newField);
|
117
|
+
}
|
118
|
+
else {
|
119
|
+
result.push(field);
|
120
|
+
}
|
121
|
+
});
|
122
|
+
});
|
123
|
+
});
|
124
|
+
return result;
|
125
|
+
}
|
126
|
+
function extractFieldsFromUsingClause(joinedTableContext) {
|
127
|
+
var _a;
|
128
|
+
const usingFieldsClause = (_a = joinedTableContext.identifierListWithParentheses()) === null || _a === void 0 ? void 0 : _a.identifierList();
|
129
|
+
if (usingFieldsClause) {
|
130
|
+
return usingFieldsClause.text.split(',').map(field => field.trim());
|
131
|
+
}
|
132
|
+
return [];
|
133
|
+
}
|
134
|
+
function filterUsingFields(joinedFields, usingFields) {
|
135
|
+
return joinedFields.filter(joinedField => {
|
136
|
+
const isUsing = usingFields.includes(joinedField.columnName);
|
137
|
+
if (!isUsing) {
|
138
|
+
return joinedField;
|
139
|
+
}
|
140
|
+
});
|
141
|
+
}
|
142
|
+
//rule: singleTable
|
143
|
+
function extractFieldsFromSingleTable(dbSchema, ctx) {
|
144
|
+
var _a;
|
145
|
+
const table = ctx === null || ctx === void 0 ? void 0 : ctx.tableRef().text;
|
146
|
+
const tableAlias = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.tableAlias()) === null || _a === void 0 ? void 0 : _a.text;
|
147
|
+
const tableName = splitName(table);
|
148
|
+
const fields = filterColumns(dbSchema, tableAlias, tableName);
|
149
|
+
return fields;
|
150
|
+
}
|
151
|
+
//rule: singleTableParens
|
152
|
+
function extractFieldsFromSingleTableParens(dbSchema, ctx) {
|
153
|
+
let fields = [];
|
154
|
+
//singleTable | singleTableParens
|
155
|
+
const singleTable = ctx.singleTable();
|
156
|
+
if (singleTable) {
|
157
|
+
fields = extractFieldsFromSingleTable(dbSchema, singleTable);
|
158
|
+
}
|
159
|
+
const singleTableParens = ctx.singleTableParens();
|
160
|
+
if (singleTableParens) {
|
161
|
+
fields = extractFieldsFromSingleTableParens(dbSchema, singleTableParens);
|
162
|
+
}
|
163
|
+
return fields;
|
164
|
+
}
|
165
|
+
/*rule:
|
166
|
+
tableFactor:
|
167
|
+
singleTable
|
168
|
+
| singleTableParens
|
169
|
+
| derivedTable
|
170
|
+
| tableReferenceListParens
|
171
|
+
| {serverVersion >= 80004}? tableFunction
|
172
|
+
*/
|
173
|
+
function extractFieldsFromTableFactor(tableFactor, dbSchema) {
|
174
|
+
var _a;
|
175
|
+
const singleTable = tableFactor.singleTable();
|
176
|
+
if (singleTable) {
|
177
|
+
return extractFieldsFromSingleTable(dbSchema, singleTable);
|
178
|
+
}
|
179
|
+
const singleTableParens = tableFactor.singleTableParens();
|
180
|
+
if (singleTableParens) {
|
181
|
+
return extractFieldsFromSingleTableParens(dbSchema, singleTableParens);
|
182
|
+
}
|
183
|
+
const derivadTable = tableFactor.derivedTable();
|
184
|
+
if (derivadTable) {
|
185
|
+
//walkQueryExpressionParens(queryExpressionParens, namedNodes, constraints, dbSchema);
|
186
|
+
//TODO - WALKSUBQUERY
|
187
|
+
const subQuery = derivadTable.subquery();
|
188
|
+
if (subQuery) {
|
189
|
+
//subquery=true only for select (subquery); not for from(subquery)
|
190
|
+
// const fromColumns
|
191
|
+
const queries = (0, parse_1.getQuerySpecificationsFromSelectStatement)(subQuery);
|
192
|
+
const queryResult = (0, parse_1.analiseQuery)(queries, dbSchema, []); //TODO - WHY []?
|
193
|
+
// console.log("queryResult=", queryResult);
|
194
|
+
const tableAlias = (_a = derivadTable.tableAlias()) === null || _a === void 0 ? void 0 : _a.text;
|
195
|
+
return queryResult.columns.map(col => {
|
196
|
+
const newCol = {
|
197
|
+
column: col.name,
|
198
|
+
columnName: col.name,
|
199
|
+
columnType: col.type,
|
200
|
+
columnKey: '',
|
201
|
+
notNull: col.notNull,
|
202
|
+
table: tableAlias || '',
|
203
|
+
tableAlias: tableAlias
|
204
|
+
};
|
205
|
+
return newCol;
|
206
|
+
});
|
207
|
+
}
|
208
|
+
}
|
209
|
+
const tableReferenceListParens = tableFactor.tableReferenceListParens();
|
210
|
+
if (tableReferenceListParens) {
|
211
|
+
const listParens = extractColumnsFromTableListParens(tableReferenceListParens, dbSchema);
|
212
|
+
return listParens;
|
213
|
+
}
|
214
|
+
return [];
|
215
|
+
}
|
216
|
+
//tableReferenceList | tableReferenceListParens
|
217
|
+
function extractColumnsFromTableListParens(ctx, dbSchema) {
|
218
|
+
const tableReferenceList = ctx.tableReferenceList();
|
219
|
+
if (tableReferenceList) {
|
220
|
+
return extractColumnsFromTableReferences(tableReferenceList.tableReference(), dbSchema);
|
221
|
+
}
|
222
|
+
const tableReferenceListParens = ctx.tableReferenceListParens();
|
223
|
+
if (tableReferenceListParens) {
|
224
|
+
return extractColumnsFromTableListParens(tableReferenceListParens, dbSchema);
|
225
|
+
}
|
226
|
+
return [];
|
227
|
+
}
|
228
|
+
function splitName(fieldName) {
|
229
|
+
const fieldNameSplit = fieldName.split('.');
|
230
|
+
const result = {
|
231
|
+
name: fieldNameSplit.length == 2 ? fieldNameSplit[1] : fieldNameSplit[0],
|
232
|
+
prefix: fieldNameSplit.length == 2 ? fieldNameSplit[0] : ''
|
233
|
+
};
|
234
|
+
const withoutStick = {
|
235
|
+
name: removeBackStick(result.name),
|
236
|
+
prefix: result.prefix
|
237
|
+
};
|
238
|
+
return withoutStick;
|
239
|
+
}
|
240
|
+
exports.splitName = splitName;
|
241
|
+
function removeBackStick(name) {
|
242
|
+
const withoutBackStick = name.startsWith("`") && name.endsWith("`") ? name.slice(1, -1) : name;
|
243
|
+
return withoutBackStick;
|
244
|
+
}
|
245
|
+
const functionAlias = [
|
246
|
+
{
|
247
|
+
column: 'CURRENT_DATE',
|
248
|
+
column_type: 'date',
|
249
|
+
columnKey: '',
|
250
|
+
notNull: true,
|
251
|
+
schema: '',
|
252
|
+
table: ''
|
253
|
+
},
|
254
|
+
{
|
255
|
+
column: 'CURRENT_TIME',
|
256
|
+
column_type: 'time',
|
257
|
+
columnKey: '',
|
258
|
+
notNull: true,
|
259
|
+
schema: '',
|
260
|
+
table: ''
|
261
|
+
},
|
262
|
+
{
|
263
|
+
column: 'CURRENT_TIMESTAMP',
|
264
|
+
column_type: 'timestamp',
|
265
|
+
columnKey: '',
|
266
|
+
notNull: true,
|
267
|
+
schema: '',
|
268
|
+
table: ''
|
269
|
+
},
|
270
|
+
{
|
271
|
+
column: 'LOCALTIME',
|
272
|
+
column_type: 'datetime',
|
273
|
+
columnKey: '',
|
274
|
+
notNull: true,
|
275
|
+
schema: '',
|
276
|
+
table: ''
|
277
|
+
},
|
278
|
+
{
|
279
|
+
column: 'LOCALTIMESTAMP',
|
280
|
+
column_type: 'datetime',
|
281
|
+
columnKey: '',
|
282
|
+
notNull: true,
|
283
|
+
schema: '',
|
284
|
+
table: ''
|
285
|
+
}
|
286
|
+
];
|
287
|
+
function findColumn(fieldName, columns) {
|
288
|
+
//TODO - Put tableAlias always ''
|
289
|
+
const functionType = functionAlias.find(col => col.column.toLowerCase() == fieldName.name.toLowerCase());
|
290
|
+
if (functionType) {
|
291
|
+
const colDef = {
|
292
|
+
column: functionType.column,
|
293
|
+
columnName: functionType.column,
|
294
|
+
columnType: functionType.column_type,
|
295
|
+
columnKey: functionType.columnKey,
|
296
|
+
notNull: functionType.notNull,
|
297
|
+
table: ''
|
298
|
+
};
|
299
|
+
return colDef;
|
300
|
+
}
|
301
|
+
const found = columns.find(col => col.columnName.toLowerCase() == fieldName.name.toLowerCase() &&
|
302
|
+
(fieldName.prefix == '' || fieldName.prefix == col.tableAlias || fieldName.prefix == col.table));
|
303
|
+
if (!found) {
|
304
|
+
throw Error('column not found:' + JSON.stringify(fieldName));
|
305
|
+
}
|
306
|
+
return found;
|
307
|
+
}
|
308
|
+
exports.findColumn = findColumn;
|
309
|
+
function findColumn2(fieldName, table, columns) {
|
310
|
+
//TODO - Put tableAlias always ''
|
311
|
+
const functionType = functionAlias.find(col => col.column == fieldName.name);
|
312
|
+
if (functionType) {
|
313
|
+
return functionType;
|
314
|
+
}
|
315
|
+
const found = columns.find(col => col.column.toLowerCase() === fieldName.name.toLowerCase() && table === col.table);
|
316
|
+
if (!found) {
|
317
|
+
throw Error('column not found:' + JSON.stringify(fieldName));
|
318
|
+
}
|
319
|
+
return found;
|
320
|
+
}
|
321
|
+
exports.findColumn2 = findColumn2;
|
322
|
+
function extractOriginalSql(rule) {
|
323
|
+
var _a, _b;
|
324
|
+
const startIndex = rule.start.startIndex;
|
325
|
+
const stopIndex = ((_a = rule.stop) === null || _a === void 0 ? void 0 : _a.stopIndex) || startIndex;
|
326
|
+
const interval = new Interval_1.Interval(startIndex, stopIndex);
|
327
|
+
const result = (_b = rule.start.inputStream) === null || _b === void 0 ? void 0 : _b.getText(interval);
|
328
|
+
return result;
|
329
|
+
}
|
330
|
+
function getSimpleExpressions(ctx) {
|
331
|
+
const tokens = [];
|
332
|
+
collectSimpleExpr(tokens, ctx);
|
333
|
+
return tokens;
|
334
|
+
}
|
335
|
+
exports.getSimpleExpressions = getSimpleExpressions;
|
336
|
+
function collectSimpleExpr(tokens, parent) {
|
337
|
+
if (isSimpleExpression(parent)) {
|
338
|
+
tokens.push(parent);
|
339
|
+
}
|
340
|
+
for (let i = 0; i < parent.childCount; i++) {
|
341
|
+
const child = parent.getChild(i);
|
342
|
+
if (child instanceof antlr4ts_1.RuleContext) {
|
343
|
+
collectSimpleExpr(tokens, child);
|
344
|
+
}
|
345
|
+
}
|
346
|
+
}
|
347
|
+
function isSimpleExpression(ctx) {
|
348
|
+
return ctx instanceof ts_mysql_parser_1.SimpleExprVariableContext
|
349
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprColumnRefContext
|
350
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprRuntimeFunctionContext
|
351
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprFunctionContext
|
352
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprCollateContext
|
353
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprLiteralContext
|
354
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprParamMarkerContext
|
355
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprSumContext
|
356
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprGroupingOperationContext
|
357
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprWindowingFunctionContext
|
358
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprConcatContext
|
359
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprUnaryContext
|
360
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprNotContext
|
361
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprListContext
|
362
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprSubQueryContext
|
363
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprOdbcContext
|
364
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprMatchContext
|
365
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprBinaryContext
|
366
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprCastContext
|
367
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprCaseContext
|
368
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprConvertContext
|
369
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprConvertUsingContext
|
370
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprDefaultContext
|
371
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprValuesContext
|
372
|
+
|| ctx instanceof ts_mysql_parser_1.SimpleExprIntervalContext;
|
373
|
+
}
|
374
374
|
//# sourceMappingURL=select-columns.js.map
|