typesql-cli 0.15.0-experimental.5 → 0.15.1
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/README.md +5 -1
- package/cli.js +33 -15
- package/cli.js.map +1 -1
- package/code-generator.js +17 -7
- package/code-generator.js.map +1 -1
- package/code-generator2.d.ts +4 -1
- package/code-generator2.d.ts.map +1 -1
- package/code-generator2.js +274 -69
- package/code-generator2.js.map +1 -1
- package/drivers/postgres.d.ts +2 -0
- package/drivers/postgres.d.ts.map +1 -1
- package/drivers/postgres.js +32 -4
- package/drivers/postgres.js.map +1 -1
- package/drivers/types.d.ts +2 -0
- package/drivers/types.d.ts.map +1 -1
- package/mysql-query-analyzer/types.d.ts +2 -2
- package/mysql-query-analyzer/types.d.ts.map +1 -1
- package/package.json +53 -52
- package/postgres-query-analyzer/describe.d.ts.map +1 -1
- package/postgres-query-analyzer/describe.js +10 -41
- package/postgres-query-analyzer/describe.js.map +1 -1
- package/postgres-query-analyzer/parser.d.ts +2 -0
- package/postgres-query-analyzer/parser.d.ts.map +1 -1
- package/postgres-query-analyzer/parser.js +12 -0
- package/postgres-query-analyzer/parser.js.map +1 -1
- package/postgres-query-analyzer/traverse.d.ts +2 -0
- package/postgres-query-analyzer/traverse.d.ts.map +1 -1
- package/postgres-query-analyzer/traverse.js +378 -76
- package/postgres-query-analyzer/traverse.js.map +1 -1
- package/sqlite-query-analyzer/code-generator.d.ts +1 -0
- package/sqlite-query-analyzer/code-generator.d.ts.map +1 -1
- package/sqlite-query-analyzer/code-generator.js +1 -7
- package/sqlite-query-analyzer/code-generator.js.map +1 -1
- package/sqlite-query-analyzer/replace-list-params.js +3 -3
- package/sqlite-query-analyzer/replace-list-params.js.map +1 -1
- package/sqlite-query-analyzer/traverse.d.ts +2 -2
- package/sqlite-query-analyzer/traverse.d.ts.map +1 -1
- package/sqlite-query-analyzer/traverse.js +55 -21
- package/sqlite-query-analyzer/traverse.js.map +1 -1
- package/types.d.ts +1 -1
- package/types.d.ts.map +1 -1
@@ -7,7 +7,8 @@ const select_columns_1 = require("../mysql-query-analyzer/select-columns");
|
|
7
7
|
function traverseSmt(stmt, dbSchema) {
|
8
8
|
const traverseResult = {
|
9
9
|
columnsNullability: [],
|
10
|
-
|
10
|
+
parameters: [],
|
11
|
+
singleRow: false
|
11
12
|
};
|
12
13
|
const selectstmt = stmt.selectstmt();
|
13
14
|
if (selectstmt) {
|
@@ -45,12 +46,16 @@ function traverseSelectstmt(selectstmt, dbSchema, fromColumns, traverseResult) {
|
|
45
46
|
const result = collectContextsOfType(selectstmt, PostgreSQLParser_1.C_expr_exprContext).filter(c_expr => c_expr.PARAM());
|
46
47
|
const paramIsListResult = result.map(param => paramIsList(param));
|
47
48
|
const columns = traverse_selectstmt(selectstmt, dbSchema, fromColumns, traverseResult);
|
49
|
+
//select parameters are collected after from paramters
|
50
|
+
traverseResult.parameters.sort((param1, param2) => param1.paramIndex - param2.paramIndex);
|
48
51
|
const columnsNullability = columns.map(col => !col.is_nullable);
|
52
|
+
const multipleRowsResult = !isSingleRowResult(selectstmt, dbSchema);
|
49
53
|
const limit = checkLimit(selectstmt);
|
50
54
|
return {
|
51
55
|
queryType: 'Select',
|
56
|
+
multipleRowsResult,
|
52
57
|
columnsNullability,
|
53
|
-
parametersNullability: traverseResult.
|
58
|
+
parametersNullability: traverseResult.parameters.map(param => param.isNotNull),
|
54
59
|
parameterList: paramIsListResult,
|
55
60
|
limit
|
56
61
|
};
|
@@ -112,6 +117,7 @@ function traverse_simple_select_intersect(simple_select_intersect, dbSchema, fro
|
|
112
117
|
return [];
|
113
118
|
}
|
114
119
|
function traverse_simple_select_pramary(simple_select_pramary, dbSchema, parentFromColumns, traverseResult) {
|
120
|
+
var _a;
|
115
121
|
const fromColumns = [];
|
116
122
|
const from_clause = simple_select_pramary.from_clause();
|
117
123
|
if (from_clause) {
|
@@ -125,6 +131,10 @@ function traverse_simple_select_pramary(simple_select_pramary, dbSchema, parentF
|
|
125
131
|
const valuesColumns = traverse_values_clause(values_clause, dbSchema, parentFromColumns, traverseResult);
|
126
132
|
return valuesColumns;
|
127
133
|
}
|
134
|
+
const where_a_expr = (_a = simple_select_pramary.where_clause()) === null || _a === void 0 ? void 0 : _a.a_expr();
|
135
|
+
if (where_a_expr) {
|
136
|
+
traverse_a_expr(where_a_expr, dbSchema, parentFromColumns.concat(fromColumns), traverseResult);
|
137
|
+
}
|
128
138
|
const filteredColumns = filterColumns_simple_select_pramary(simple_select_pramary, dbSchema, parentFromColumns.concat(fromColumns), traverseResult);
|
129
139
|
return filteredColumns;
|
130
140
|
}
|
@@ -153,12 +163,16 @@ function filterColumns_simple_select_pramary(simple_select_pramary, dbSchema, fr
|
|
153
163
|
if (target_list_) {
|
154
164
|
const target_list = target_list_.target_list();
|
155
165
|
if (target_list) {
|
156
|
-
return
|
166
|
+
return traverse_target_list(target_list, dbSchema, fromColumns, traverseResult);
|
157
167
|
}
|
158
168
|
}
|
169
|
+
const target_list = simple_select_pramary.target_list();
|
170
|
+
if (target_list) {
|
171
|
+
return traverse_target_list(target_list, dbSchema, fromColumns, traverseResult);
|
172
|
+
}
|
159
173
|
return [];
|
160
174
|
}
|
161
|
-
function
|
175
|
+
function traverse_target_list(target_list, dbSchema, fromColumns, traverseResult) {
|
162
176
|
const columns = target_list.target_el_list().flatMap(target_el => {
|
163
177
|
const fieldName = (0, select_columns_1.splitName)(target_el.getText());
|
164
178
|
if (fieldName.name == '*') {
|
@@ -219,11 +233,11 @@ function traverse_expr_or(a_expr_or, dbSchema, fromColumns, traverseResult) {
|
|
219
233
|
throw Error('traverse_expr_or - Not expected:' + a_expr_or.getText());
|
220
234
|
}
|
221
235
|
function traverse_expr_and(a_expr_and, dbSchema, fromColumns, traverseResult) {
|
222
|
-
const
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
236
|
+
const result = a_expr_and.a_expr_between_list().map(a_expr_between => traverse_expr_between(a_expr_between, dbSchema, fromColumns, traverseResult));
|
237
|
+
return {
|
238
|
+
column_name: a_expr_and.getText(),
|
239
|
+
is_nullable: result.some(col => col.is_nullable)
|
240
|
+
};
|
227
241
|
}
|
228
242
|
function traverse_expr_between(a_expr_between, dbSchema, fromColumns, traverseResult) {
|
229
243
|
const a_expr_in = a_expr_between.a_expr_in_list()[0];
|
@@ -234,10 +248,31 @@ function traverse_expr_between(a_expr_between, dbSchema, fromColumns, traverseRe
|
|
234
248
|
}
|
235
249
|
function traverse_expr_in(a_expr_in, dbSchema, fromColumns, traverseResult) {
|
236
250
|
const a_expr_unary = a_expr_in.a_expr_unary_not();
|
251
|
+
let leftExprResult = undefined;
|
237
252
|
if (a_expr_unary) {
|
238
|
-
|
253
|
+
leftExprResult = traverse_expr_unary(a_expr_unary, dbSchema, fromColumns, traverseResult);
|
254
|
+
}
|
255
|
+
const in_expr = a_expr_in.in_expr();
|
256
|
+
if (in_expr) {
|
257
|
+
traverse_in_expr(in_expr, dbSchema, fromColumns, traverseResult);
|
258
|
+
}
|
259
|
+
return {
|
260
|
+
column_name: a_expr_in.getText(),
|
261
|
+
//id in (...) -> is_nullable: false
|
262
|
+
// value -> is_nullable = leftExprResult.is_nullable
|
263
|
+
is_nullable: in_expr != null ? false : leftExprResult.is_nullable
|
264
|
+
};
|
265
|
+
}
|
266
|
+
function traverse_in_expr(in_expr, dbSchema, fromColumns, traverseResult) {
|
267
|
+
if (in_expr instanceof PostgreSQLParser_1.In_expr_selectContext) {
|
268
|
+
const select_with_parens = in_expr.select_with_parens();
|
269
|
+
traverse_select_with_parens(select_with_parens, dbSchema, fromColumns, traverseResult);
|
270
|
+
}
|
271
|
+
if (in_expr instanceof PostgreSQLParser_1.In_expr_listContext) {
|
272
|
+
in_expr.expr_list().a_expr_list().forEach(a_expr => {
|
273
|
+
traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult);
|
274
|
+
});
|
239
275
|
}
|
240
|
-
throw Error('traverse_expr_in - Not expected:' + a_expr_in.getText());
|
241
276
|
}
|
242
277
|
function traverse_expr_unary(a_expr_unary, dbSchema, fromColumns, traverseResult) {
|
243
278
|
const a_expr_isnull = a_expr_unary.a_expr_isnull();
|
@@ -261,16 +296,24 @@ function traverse_expr_is_not(a_expr_is_not, dbSchema, fromColumns, traverseResu
|
|
261
296
|
throw Error('traverse_expr_is_not - Not expected:' + a_expr_is_not.getText());
|
262
297
|
}
|
263
298
|
function traverse_expr_compare(a_expr_compare, dbSchema, fromColumns, traverseResult) {
|
264
|
-
const
|
265
|
-
if (
|
266
|
-
|
299
|
+
const a_expr_like_list = a_expr_compare.a_expr_like_list();
|
300
|
+
if (a_expr_like_list) {
|
301
|
+
const result = a_expr_like_list.map(a_expr_like => traverse_expr_like(a_expr_like, dbSchema, fromColumns, traverseResult));
|
302
|
+
return {
|
303
|
+
column_name: a_expr_compare.getText(),
|
304
|
+
is_nullable: result.some(col => col.is_nullable)
|
305
|
+
};
|
267
306
|
}
|
268
307
|
throw Error('traverse_expr_compare - Not expected:' + a_expr_compare.getText());
|
269
308
|
}
|
270
309
|
function traverse_expr_like(a_expr_like, dbSchema, fromColumns, traverseResult) {
|
271
|
-
const
|
272
|
-
if (
|
273
|
-
|
310
|
+
const a_expr_qual_op_list = a_expr_like.a_expr_qual_op_list();
|
311
|
+
if (a_expr_qual_op_list) {
|
312
|
+
const result = a_expr_qual_op_list.map(a_expr_qual_op => traverse_expr_qual_op(a_expr_qual_op, dbSchema, fromColumns, traverseResult));
|
313
|
+
return {
|
314
|
+
column_name: a_expr_like.getText(),
|
315
|
+
is_nullable: result.some(col => col.is_nullable)
|
316
|
+
};
|
274
317
|
}
|
275
318
|
throw Error('traverse_expr_like - Not expected:' + a_expr_like.getText());
|
276
319
|
}
|
@@ -346,13 +389,17 @@ function traverse_expr_typecast(a_expr_typecast, dbSchema, fromColumns, traverse
|
|
346
389
|
}
|
347
390
|
throw Error('traverse_expr_typecast - Not expected:' + a_expr_typecast.getText());
|
348
391
|
}
|
392
|
+
function traverseColumnRef(columnref, fromColumns) {
|
393
|
+
const fieldName = (0, select_columns_1.splitName)(columnref.getText());
|
394
|
+
const col = findColumn(fieldName, fromColumns);
|
395
|
+
return col;
|
396
|
+
}
|
349
397
|
function traversec_expr(c_expr, dbSchema, fromColumns, traverseResult) {
|
350
398
|
var _a, _b;
|
351
399
|
if (c_expr instanceof PostgreSQLParser_1.C_expr_exprContext) {
|
352
400
|
const columnref = c_expr.columnref();
|
353
401
|
if (columnref) {
|
354
|
-
const
|
355
|
-
const col = findColumn(fieldName, fromColumns);
|
402
|
+
const col = traverseColumnRef(columnref, fromColumns);
|
356
403
|
return col;
|
357
404
|
}
|
358
405
|
const aexprconst = c_expr.aexprconst();
|
@@ -364,7 +411,10 @@ function traversec_expr(c_expr, dbSchema, fromColumns, traverseResult) {
|
|
364
411
|
};
|
365
412
|
}
|
366
413
|
if (c_expr.PARAM()) {
|
367
|
-
traverseResult.
|
414
|
+
traverseResult.parameters.push({
|
415
|
+
paramIndex: c_expr.start.start,
|
416
|
+
isNotNull: true
|
417
|
+
});
|
368
418
|
return {
|
369
419
|
column_name: c_expr.PARAM().getText(),
|
370
420
|
is_nullable: false
|
@@ -429,15 +479,32 @@ function excludeColumns(fromColumns, excludeList) {
|
|
429
479
|
function traversec_expr_case(c_expr_case, dbSchema, fromColumns, traverseResult) {
|
430
480
|
var _a;
|
431
481
|
const case_expr = c_expr_case.case_expr();
|
432
|
-
const
|
482
|
+
const whenResult = case_expr.when_clause_list().when_clause_list().map(when_clause => traversewhen_clause(when_clause, dbSchema, fromColumns, traverseResult));
|
483
|
+
const whenIsNotNull = whenResult.every(when => when);
|
433
484
|
const elseExpr = (_a = case_expr.case_default()) === null || _a === void 0 ? void 0 : _a.a_expr();
|
434
485
|
const elseIsNotNull = elseExpr ? !traverse_a_expr(elseExpr, dbSchema, fromColumns, traverseResult).is_nullable : false;
|
435
486
|
return elseIsNotNull && whenIsNotNull;
|
436
487
|
}
|
437
488
|
function traversewhen_clause(when_clause, dbSchema, fromColumns, traverseResult) {
|
438
489
|
const a_expr_list = when_clause.a_expr_list();
|
439
|
-
const thenExprList = a_expr_list
|
440
|
-
|
490
|
+
const [whenExprList, thenExprList] = partition(a_expr_list, (index) => index % 2 === 0);
|
491
|
+
const whenExprResult = thenExprList.map((thenExpr, index) => {
|
492
|
+
traverse_a_expr(whenExprList[index], dbSchema, fromColumns, traverseResult);
|
493
|
+
const thenExprResult = traverse_a_expr(thenExpr, dbSchema, fromColumns, traverseResult);
|
494
|
+
return thenExprResult;
|
495
|
+
});
|
496
|
+
return whenExprResult.every(res => res);
|
497
|
+
}
|
498
|
+
function partition(array, predicate) {
|
499
|
+
return array.reduce((acc, curr, index) => {
|
500
|
+
if (predicate(index)) {
|
501
|
+
acc[0].push(curr);
|
502
|
+
}
|
503
|
+
else {
|
504
|
+
acc[1].push(curr);
|
505
|
+
}
|
506
|
+
return acc;
|
507
|
+
}, [[], []]);
|
441
508
|
}
|
442
509
|
function traversefunc_application(func_application, dbSchema, fromColumns, traverseResult) {
|
443
510
|
var _a;
|
@@ -471,7 +538,7 @@ function traversefunc_expr_common_subexpr(func_expr_common_subexpr, dbSchema, fr
|
|
471
538
|
const result = func_arg_list.map(func_arg_expr => {
|
472
539
|
const paramResult = traverse_a_expr(func_arg_expr, dbSchema, fromColumns, traverseResult);
|
473
540
|
if (isParameter(paramResult.column_name)) {
|
474
|
-
traverseResult.
|
541
|
+
traverseResult.parameters[traverseResult.parameters.length - 1].isNotNull = false;
|
475
542
|
paramResult.is_nullable = true;
|
476
543
|
}
|
477
544
|
return paramResult;
|
@@ -519,11 +586,11 @@ function traverse_table_ref(table_ref, dbSchema, fromColumns, traverseResult) {
|
|
519
586
|
const allColumns = [];
|
520
587
|
const relation_expr = table_ref.relation_expr();
|
521
588
|
const aliasClause = table_ref.alias_clause();
|
522
|
-
const alias = aliasClause ? aliasClause.getText() : undefined;
|
589
|
+
const alias = aliasClause ? aliasClause.colid().getText() : undefined;
|
523
590
|
if (relation_expr) {
|
524
591
|
const tableName = traverse_relation_expr(relation_expr, dbSchema);
|
525
|
-
const tableNameWithAlias = alias ? alias : tableName;
|
526
|
-
const fromColumnsResult = fromColumns.concat(dbSchema).filter(col => col.table_name === tableName).map(col => (Object.assign(Object.assign({}, col), { table_name: tableNameWithAlias })));
|
592
|
+
const tableNameWithAlias = alias ? alias : tableName.name;
|
593
|
+
const fromColumnsResult = fromColumns.concat(dbSchema).filter(col => col.table_name === tableName.name).map(col => (Object.assign(Object.assign({}, col), { table_name: tableNameWithAlias })));
|
527
594
|
allColumns.push(...fromColumnsResult);
|
528
595
|
}
|
529
596
|
const table_ref_list = table_ref.table_ref_list();
|
@@ -572,11 +639,19 @@ function traverse_relation_expr(relation_expr, dbSchema) {
|
|
572
639
|
return name;
|
573
640
|
}
|
574
641
|
function traverse_qualified_name(qualified_name, dbSchema) {
|
575
|
-
|
576
|
-
|
577
|
-
|
642
|
+
var _a, _b;
|
643
|
+
const colid_name = qualified_name.colid() ? traverse_colid(qualified_name.colid(), dbSchema) : '';
|
644
|
+
const indirection_el_list = (_a = qualified_name.indirection()) === null || _a === void 0 ? void 0 : _a.indirection_el_list();
|
645
|
+
if (indirection_el_list && indirection_el_list.length === 1) {
|
646
|
+
return {
|
647
|
+
name: ((_b = indirection_el_list[0].attr_name()) === null || _b === void 0 ? void 0 : _b.getText()) || '',
|
648
|
+
alias: colid_name
|
649
|
+
};
|
578
650
|
}
|
579
|
-
return
|
651
|
+
return {
|
652
|
+
name: colid_name,
|
653
|
+
alias: ''
|
654
|
+
};
|
580
655
|
}
|
581
656
|
function traverse_colid(colid, dbSchema) {
|
582
657
|
const identifier = colid.identifier();
|
@@ -626,6 +701,11 @@ function paramIsList(c_expr) {
|
|
626
701
|
return in_expr_list instanceof PostgreSQLParser_1.In_expr_listContext;
|
627
702
|
}
|
628
703
|
function traverseInsertstmt(insertstmt, dbSchema) {
|
704
|
+
const traverseResult = {
|
705
|
+
columnsNullability: [],
|
706
|
+
parameters: [],
|
707
|
+
singleRow: false
|
708
|
+
};
|
629
709
|
const insert_target = insertstmt.insert_target();
|
630
710
|
const tableName = insert_target.getText();
|
631
711
|
const insertColumns = dbSchema.filter(col => col.table_name === tableName);
|
@@ -634,82 +714,115 @@ function traverseInsertstmt(insertstmt, dbSchema) {
|
|
634
714
|
.insert_column_item_list()
|
635
715
|
.map(insert_column_item => traverse_insert_column_item(insert_column_item, insertColumns));
|
636
716
|
const selectstmt = insert_rest.selectstmt();
|
637
|
-
|
638
|
-
|
717
|
+
traverse_insert_select_stmt(selectstmt, dbSchema, insertColumnsList, traverseResult);
|
718
|
+
const on_conflict = insertstmt.on_conflict_();
|
719
|
+
if (on_conflict) {
|
720
|
+
const set_clause_list = on_conflict.set_clause_list().set_clause_list() || [];
|
721
|
+
set_clause_list.forEach(set_clause => traverse_set_clause(set_clause, dbSchema, insertColumns, traverseResult));
|
722
|
+
}
|
723
|
+
const returning_clause = insertstmt.returning_clause();
|
724
|
+
const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), dbSchema, insertColumns, traverseResult) : [];
|
725
|
+
const result = {
|
639
726
|
queryType: 'Insert',
|
640
|
-
|
641
|
-
|
727
|
+
multipleRowsResult: false,
|
728
|
+
parametersNullability: traverseResult.parameters.map(param => param.isNotNull),
|
729
|
+
columnsNullability: returninColumns.map(col => !col.is_nullable),
|
642
730
|
parameterList: []
|
643
731
|
};
|
732
|
+
if (returning_clause) {
|
733
|
+
result.returning = true;
|
734
|
+
}
|
735
|
+
return result;
|
644
736
|
}
|
645
|
-
function traverse_insert_select_stmt(selectstmt, dbSchema, insertColumnlist) {
|
646
|
-
var _a, _b, _c, _d;
|
737
|
+
function traverse_insert_select_stmt(selectstmt, dbSchema, insertColumnlist, traverseResult) {
|
738
|
+
var _a, _b, _c, _d, _e;
|
647
739
|
const simple_select = (_c = (_b = (_a = selectstmt.select_no_parens()) === null || _a === void 0 ? void 0 : _a.select_clause()) === null || _b === void 0 ? void 0 : _b.simple_select_intersect_list()) === null || _c === void 0 ? void 0 : _c[0];
|
648
740
|
if (simple_select) {
|
649
741
|
const simple_select_pramary = (_d = simple_select === null || simple_select === void 0 ? void 0 : simple_select.simple_select_pramary_list()) === null || _d === void 0 ? void 0 : _d[0];
|
650
742
|
if (simple_select_pramary) {
|
651
|
-
|
652
|
-
|
743
|
+
const values_clause = simple_select_pramary.values_clause();
|
744
|
+
if (values_clause) {
|
745
|
+
values_clause.expr_list_list()
|
746
|
+
.forEach(expr_list => traverse_insert_a_expr_list(expr_list, dbSchema, insertColumnlist, traverseResult));
|
747
|
+
}
|
748
|
+
const target_list = (_e = simple_select_pramary.target_list_()) === null || _e === void 0 ? void 0 : _e.target_list();
|
749
|
+
if (target_list) {
|
750
|
+
const from_clause = simple_select_pramary.from_clause();
|
751
|
+
const fromColumns = from_clause ? traverse_from_clause(from_clause, dbSchema, [], traverseResult) : [];
|
752
|
+
target_list.target_el_list().forEach((target_el, index) => {
|
753
|
+
const targetResult = isNotNull_target_el(target_el, dbSchema, fromColumns, traverseResult);
|
754
|
+
if (isParameter(targetResult.column_name)) {
|
755
|
+
traverseResult.parameters.at(-1).isNotNull = !insertColumnlist[index].is_nullable;
|
756
|
+
}
|
757
|
+
});
|
758
|
+
}
|
653
759
|
}
|
654
760
|
}
|
655
|
-
return [];
|
656
761
|
}
|
657
|
-
function traverse_insert_a_expr_list(expr_list, dbSchema, insertColumns) {
|
658
|
-
const parametersNullability = [];
|
762
|
+
function traverse_insert_a_expr_list(expr_list, dbSchema, insertColumns, traverseResult) {
|
659
763
|
expr_list.a_expr_list().forEach((a_expr, index) => {
|
660
|
-
const traverseResult = {
|
661
|
-
columnsNullability: [],
|
662
|
-
parametersNullability: []
|
663
|
-
};
|
664
764
|
const result = traverse_a_expr(a_expr, dbSchema, insertColumns, traverseResult);
|
665
765
|
if (isParameter(result.column_name)) {
|
666
|
-
|
667
|
-
}
|
668
|
-
else {
|
669
|
-
parametersNullability.push(...traverseResult.parametersNullability);
|
766
|
+
traverseResult.parameters.at(-1).isNotNull = !insertColumns[index].is_nullable;
|
670
767
|
}
|
671
768
|
});
|
672
|
-
return parametersNullability;
|
673
769
|
}
|
674
770
|
function traverseDeletestmt(deleteStmt, dbSchema, traverseResult) {
|
675
|
-
|
771
|
+
const relation_expr = deleteStmt.relation_expr_opt_alias().relation_expr();
|
772
|
+
const tableName = relation_expr.getText();
|
773
|
+
const deleteColumns = dbSchema.filter(col => col.table_name === tableName);
|
774
|
+
const returning_clause = deleteStmt.returning_clause();
|
775
|
+
const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), dbSchema, deleteColumns, traverseResult) : [];
|
776
|
+
const result = {
|
676
777
|
queryType: 'Delete',
|
677
|
-
|
678
|
-
|
778
|
+
multipleRowsResult: false,
|
779
|
+
parametersNullability: traverseResult.parameters.map(param => param.isNotNull),
|
780
|
+
columnsNullability: returninColumns.map(col => !col.is_nullable),
|
679
781
|
parameterList: []
|
680
782
|
};
|
783
|
+
if (returning_clause) {
|
784
|
+
result.returning = true;
|
785
|
+
}
|
786
|
+
return result;
|
681
787
|
}
|
682
788
|
function traverseUpdatestmt(updatestmt, dbSchema, traverseResult) {
|
683
789
|
const relation_expr_opt_alias = updatestmt.relation_expr_opt_alias();
|
684
790
|
const tableName = relation_expr_opt_alias.getText();
|
685
791
|
const updateColumns = dbSchema.filter(col => col.table_name === tableName);
|
686
792
|
updatestmt.set_clause_list().set_clause_list()
|
687
|
-
.
|
688
|
-
const
|
793
|
+
.forEach(set_clause => traverse_set_clause(set_clause, dbSchema, updateColumns, traverseResult));
|
794
|
+
const parametersBefore = traverseResult.parameters.length;
|
689
795
|
const where_clause = updatestmt.where_or_current_clause();
|
690
796
|
if (where_clause) {
|
691
797
|
const a_expr = where_clause.a_expr();
|
692
798
|
traverse_a_expr(a_expr, dbSchema, updateColumns, traverseResult);
|
693
799
|
}
|
694
|
-
const whereParameters = traverseResult.
|
695
|
-
|
800
|
+
const whereParameters = traverseResult.parameters.slice(parametersBefore);
|
801
|
+
const returning_clause = updatestmt.returning_clause();
|
802
|
+
const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), dbSchema, updateColumns, traverseResult) : [];
|
803
|
+
const result = {
|
696
804
|
queryType: 'Update',
|
697
|
-
|
698
|
-
|
805
|
+
multipleRowsResult: false,
|
806
|
+
parametersNullability: traverseResult.parameters.slice(0, parametersBefore).map(param => param.isNotNull),
|
807
|
+
columnsNullability: returninColumns.map(col => !col.is_nullable),
|
699
808
|
parameterList: [],
|
700
|
-
whereParamtersNullability: whereParameters
|
809
|
+
whereParamtersNullability: whereParameters.map(param => param.isNotNull)
|
701
810
|
};
|
811
|
+
if (returning_clause) {
|
812
|
+
result.returning = true;
|
813
|
+
}
|
814
|
+
return result;
|
702
815
|
}
|
703
816
|
function traverse_set_clause(set_clause, dbSchema, updateColumns, traverseResult) {
|
704
817
|
const set_target = set_clause.set_target();
|
705
818
|
const columnName = (0, select_columns_1.splitName)(set_target.getText());
|
706
819
|
const column = findColumn(columnName, updateColumns);
|
707
820
|
const a_expr = set_clause.a_expr();
|
708
|
-
const
|
821
|
+
const excludedColumns = updateColumns.map((col) => (Object.assign(Object.assign({}, col), { table_name: 'excluded' })));
|
822
|
+
const a_exprResult = traverse_a_expr(a_expr, dbSchema, updateColumns.concat(excludedColumns), traverseResult);
|
709
823
|
if (isParameter(a_exprResult.column_name)) {
|
710
|
-
traverseResult.
|
824
|
+
traverseResult.parameters[traverseResult.parameters.length - 1].isNotNull = !column.is_nullable;
|
711
825
|
}
|
712
|
-
return !column.is_nullable;
|
713
826
|
}
|
714
827
|
function traverse_insert_column_item(insert_column_item, dbSchema) {
|
715
828
|
const colid = insert_column_item.colid();
|
@@ -905,20 +1018,10 @@ function isNotNull_c_expr(c_expr, field) {
|
|
905
1018
|
}
|
906
1019
|
return false;
|
907
1020
|
}
|
908
|
-
function checkLimit(selectstmt) {
|
909
|
-
const select_no_parens = selectstmt.select_no_parens();
|
910
|
-
if (select_no_parens) {
|
911
|
-
return checkLimit_select_no_parens(select_no_parens);
|
912
|
-
}
|
913
|
-
const select_with_parens = selectstmt.select_with_parens();
|
914
|
-
if (select_with_parens) {
|
915
|
-
return checkLimit_select_with_parens(select_with_parens);
|
916
|
-
}
|
917
|
-
return undefined;
|
918
|
-
}
|
919
1021
|
function checkLimit_select_no_parens(select_no_parens) {
|
920
1022
|
var _a, _b, _c;
|
921
|
-
|
1023
|
+
const limitText = (_c = (_b = (_a = select_no_parens.select_limit()) === null || _a === void 0 ? void 0 : _a.limit_clause()) === null || _b === void 0 ? void 0 : _b.select_limit_value()) === null || _c === void 0 ? void 0 : _c.getText();
|
1024
|
+
return limitText ? +limitText : undefined;
|
922
1025
|
}
|
923
1026
|
function checkLimit_select_with_parens(select_with_parens) {
|
924
1027
|
return checkLimit(select_with_parens);
|
@@ -928,4 +1031,203 @@ function isParameter(str) {
|
|
928
1031
|
const paramPattern = /^\$[0-9]+(::[a-zA-Z_][a-zA-Z0-9_]*)?$/;
|
929
1032
|
return paramPattern.test(str);
|
930
1033
|
}
|
1034
|
+
function isSingleRowResult(selectstmt, dbSchema) {
|
1035
|
+
var _a;
|
1036
|
+
const limit = checkLimit(selectstmt);
|
1037
|
+
if (limit === 1) {
|
1038
|
+
return true;
|
1039
|
+
}
|
1040
|
+
const select_no_parens = selectstmt.select_no_parens();
|
1041
|
+
const simple_select_pramary_list = (_a = select_no_parens.select_clause()
|
1042
|
+
.simple_select_intersect_list()) === null || _a === void 0 ? void 0 : _a[0].simple_select_pramary_list();
|
1043
|
+
if (simple_select_pramary_list.length > 1) {
|
1044
|
+
return false;
|
1045
|
+
}
|
1046
|
+
const simple_select_pramary = simple_select_pramary_list[0];
|
1047
|
+
const from_clause = simple_select_pramary.from_clause();
|
1048
|
+
if (!from_clause) {
|
1049
|
+
const hasSetReturningFunction = simple_select_pramary.target_list_().target_list().target_el_list().some(target_el => isSetReturningFunction_target_el(target_el));
|
1050
|
+
return !hasSetReturningFunction;
|
1051
|
+
}
|
1052
|
+
if (!simple_select_pramary.group_clause()) {
|
1053
|
+
const agreegateFunction = hasAggregateFunction(simple_select_pramary);
|
1054
|
+
if (agreegateFunction) {
|
1055
|
+
return true;
|
1056
|
+
}
|
1057
|
+
}
|
1058
|
+
const table_ref_list = from_clause.from_list().table_ref_list();
|
1059
|
+
if (table_ref_list.length > 1) {
|
1060
|
+
return false;
|
1061
|
+
}
|
1062
|
+
if (table_ref_list[0].JOIN_list().length > 0 || table_ref_list[0].select_with_parens() != null) {
|
1063
|
+
return false;
|
1064
|
+
}
|
1065
|
+
const tableName = getTableName(table_ref_list[0]);
|
1066
|
+
const uniqueKeys = dbSchema.filter(col => col.table_name.toLowerCase() === tableName.name.toLowerCase()
|
1067
|
+
&& (col.column_key === 'PRI' || col.column_key === 'UNI'))
|
1068
|
+
.map(col => col.column_name);
|
1069
|
+
const where_clause = simple_select_pramary.where_clause();
|
1070
|
+
if (where_clause) {
|
1071
|
+
return isSingleRowResult_where(where_clause.a_expr(), uniqueKeys);
|
1072
|
+
}
|
1073
|
+
return false;
|
1074
|
+
}
|
1075
|
+
function hasAggregateFunction(simple_select_pramary) {
|
1076
|
+
const target_list_ = simple_select_pramary.target_list_();
|
1077
|
+
if (target_list_) {
|
1078
|
+
return target_list_.target_list().target_el_list().some(target_el => isAggregateFunction_target_el(target_el));
|
1079
|
+
}
|
1080
|
+
const target_list = simple_select_pramary.target_list();
|
1081
|
+
return target_list.target_el_list().some(target_el => isAggregateFunction_target_el(target_el));
|
1082
|
+
}
|
1083
|
+
function getTableName(table_ref) {
|
1084
|
+
const relation_expr = table_ref.relation_expr();
|
1085
|
+
const tableName = relation_expr.qualified_name().getText();
|
1086
|
+
const aliasClause = table_ref.alias_clause();
|
1087
|
+
const tableAlias = aliasClause ? aliasClause.colid().getText() : '';
|
1088
|
+
return {
|
1089
|
+
name: tableName,
|
1090
|
+
alias: tableAlias
|
1091
|
+
};
|
1092
|
+
}
|
1093
|
+
function isAggregateFunction_target_el(target_el) {
|
1094
|
+
if (target_el instanceof PostgreSQLParser_1.Target_labelContext) {
|
1095
|
+
const c_expr_list = collectContextsOfType(target_el, PostgreSQLParser_1.Func_exprContext);
|
1096
|
+
const aggrFunction = c_expr_list.some(func_expr => isAggregateFunction_c_expr(func_expr));
|
1097
|
+
return aggrFunction;
|
1098
|
+
}
|
1099
|
+
return false;
|
1100
|
+
}
|
1101
|
+
// SELECT distinct '''' || p.proname || '''' || ',' as aggregate_function
|
1102
|
+
// FROM pg_catalog.pg_proc p
|
1103
|
+
// JOIN pg_catalog.pg_aggregate a ON a.aggfnoid = p.oid
|
1104
|
+
// ORDER BY aggregate_function;
|
1105
|
+
const aggregateFunctions = new Set([
|
1106
|
+
'array_agg',
|
1107
|
+
'avg',
|
1108
|
+
'bit_and',
|
1109
|
+
'bit_or',
|
1110
|
+
'bool_and',
|
1111
|
+
'bool_or',
|
1112
|
+
'corr',
|
1113
|
+
'count',
|
1114
|
+
'covar_pop',
|
1115
|
+
'covar_samp',
|
1116
|
+
'cume_dist',
|
1117
|
+
'dense_rank',
|
1118
|
+
'every',
|
1119
|
+
'json_agg',
|
1120
|
+
'json_object_agg',
|
1121
|
+
'jsonb_agg',
|
1122
|
+
'jsonb_object_agg',
|
1123
|
+
'max',
|
1124
|
+
'min',
|
1125
|
+
'mode',
|
1126
|
+
'percent_rank',
|
1127
|
+
'percentile_cont',
|
1128
|
+
'percentile_disc',
|
1129
|
+
'rank',
|
1130
|
+
'regr_avgx',
|
1131
|
+
'regr_avgy',
|
1132
|
+
'regr_count',
|
1133
|
+
'regr_intercept',
|
1134
|
+
'regr_r2',
|
1135
|
+
'regr_slope',
|
1136
|
+
'regr_sxx',
|
1137
|
+
'regr_sxy',
|
1138
|
+
'regr_syy',
|
1139
|
+
'stddev',
|
1140
|
+
'stddev_pop',
|
1141
|
+
'stddev_samp',
|
1142
|
+
'string_agg',
|
1143
|
+
'sum',
|
1144
|
+
'var_pop',
|
1145
|
+
'var_samp',
|
1146
|
+
'variance',
|
1147
|
+
'xmlagg'
|
1148
|
+
]);
|
1149
|
+
function isAggregateFunction_c_expr(func_expr) {
|
1150
|
+
var _a, _b, _c;
|
1151
|
+
const funcName = (_c = (_b = (_a = func_expr === null || func_expr === void 0 ? void 0 : func_expr.func_application()) === null || _a === void 0 ? void 0 : _a.func_name()) === null || _b === void 0 ? void 0 : _b.getText()) === null || _c === void 0 ? void 0 : _c.toLowerCase();
|
1152
|
+
return aggregateFunctions.has(funcName);
|
1153
|
+
}
|
1154
|
+
function isSetReturningFunction_target_el(target_el) {
|
1155
|
+
if (target_el instanceof PostgreSQLParser_1.Target_labelContext) {
|
1156
|
+
const c_expr_list = collectContextsOfType(target_el, PostgreSQLParser_1.Func_exprContext);
|
1157
|
+
const setReturningFunction = c_expr_list.some(func_expr => isSetReturningFunction_c_expr(func_expr));
|
1158
|
+
return setReturningFunction;
|
1159
|
+
}
|
1160
|
+
return false;
|
1161
|
+
}
|
1162
|
+
function isSetReturningFunction_c_expr(func_expr) {
|
1163
|
+
var _a, _b, _c;
|
1164
|
+
const funcName = (_c = (_b = (_a = func_expr === null || func_expr === void 0 ? void 0 : func_expr.func_application()) === null || _a === void 0 ? void 0 : _a.func_name()) === null || _b === void 0 ? void 0 : _b.getText()) === null || _c === void 0 ? void 0 : _c.toLowerCase();
|
1165
|
+
return funcName === 'generate_series';
|
1166
|
+
}
|
1167
|
+
function isSingleRowResult_where(a_expr, uniqueKeys) {
|
1168
|
+
var _a, _b;
|
1169
|
+
const a_expr_or_list = ((_b = (_a = a_expr.a_expr_qual()) === null || _a === void 0 ? void 0 : _a.a_expr_lessless()) === null || _b === void 0 ? void 0 : _b.a_expr_or_list()) || [];
|
1170
|
+
if (a_expr_or_list.length > 1 || a_expr_or_list[0].OR_list().length > 0) {
|
1171
|
+
return false;
|
1172
|
+
}
|
1173
|
+
const someInSingleRow = a_expr_or_list[0].a_expr_and_list().some(a_expr_and => {
|
1174
|
+
const a = isSingleRowResult_a_expr_and(a_expr_and, uniqueKeys);
|
1175
|
+
return a;
|
1176
|
+
});
|
1177
|
+
return someInSingleRow;
|
1178
|
+
}
|
1179
|
+
function isSingleRowResult_a_expr_and(a_expr_and, uniqueKeys) {
|
1180
|
+
const a_expr_between_list = a_expr_and.a_expr_between_list();
|
1181
|
+
if (a_expr_between_list && a_expr_between_list.length > 0) {
|
1182
|
+
return a_expr_between_list.some(a_expr_between => isSingleRowResult_a_expr_between(a_expr_between, uniqueKeys));
|
1183
|
+
}
|
1184
|
+
return false;
|
1185
|
+
}
|
1186
|
+
function isSingleRowResult_a_expr_between(a_expr_between, uniqueKeys) {
|
1187
|
+
const isSingleRow = a_expr_between.a_expr_in_list().every(a_expr_in => isSingleRowResult_a_expr_in(a_expr_in, uniqueKeys));
|
1188
|
+
return isSingleRow;
|
1189
|
+
}
|
1190
|
+
function isSingleRowResult_a_expr_in(a_expr_in, uniqueKeys) {
|
1191
|
+
var _a, _b, _c;
|
1192
|
+
const a_expr_compare = (_c = (_b = (_a = a_expr_in.a_expr_unary_not()) === null || _a === void 0 ? void 0 : _a.a_expr_isnull()) === null || _b === void 0 ? void 0 : _b.a_expr_is_not()) === null || _c === void 0 ? void 0 : _c.a_expr_compare();
|
1193
|
+
if (a_expr_compare) {
|
1194
|
+
if (a_expr_compare.EQUAL() != null) {
|
1195
|
+
const a_expr_like_list = a_expr_compare.a_expr_like_list();
|
1196
|
+
if (a_expr_like_list && a_expr_like_list.length == 2) {
|
1197
|
+
const left = a_expr_like_list[0];
|
1198
|
+
const right = a_expr_like_list[1];
|
1199
|
+
const result = (isUniqueColumn(left, uniqueKeys) + isUniqueColumn(right, uniqueKeys));
|
1200
|
+
return result == 1;
|
1201
|
+
}
|
1202
|
+
}
|
1203
|
+
;
|
1204
|
+
}
|
1205
|
+
return false;
|
1206
|
+
}
|
1207
|
+
//1 = yes
|
1208
|
+
//0 = no
|
1209
|
+
function isUniqueColumn(a_expr_like, uniqueKeys) {
|
1210
|
+
var _a, _b;
|
1211
|
+
const c_expr = (_b = (_a = a_expr_like.a_expr_qual_op_list()) === null || _a === void 0 ? void 0 : _a[0].a_expr_unary_qualop_list()) === null || _b === void 0 ? void 0 : _b[0].a_expr_add().a_expr_mul_list()[0].a_expr_caret_list()[0].a_expr_unary_sign_list()[0].a_expr_at_time_zone().a_expr_collate().a_expr_typecast().c_expr();
|
1212
|
+
if (c_expr instanceof PostgreSQLParser_1.C_expr_exprContext) {
|
1213
|
+
const columnref = c_expr.columnref();
|
1214
|
+
if (columnref) {
|
1215
|
+
const fieldName = (0, select_columns_1.splitName)(columnref.getText());
|
1216
|
+
// const col = traverseColumnRef(columnref, dbSchema);
|
1217
|
+
return uniqueKeys.includes(fieldName.name) ? 1 : 0;
|
1218
|
+
}
|
1219
|
+
}
|
1220
|
+
return 0;
|
1221
|
+
}
|
1222
|
+
function checkLimit(selectstmt) {
|
1223
|
+
const select_no_parens = selectstmt.select_no_parens();
|
1224
|
+
if (select_no_parens) {
|
1225
|
+
return checkLimit_select_no_parens(select_no_parens);
|
1226
|
+
}
|
1227
|
+
const select_with_parens = selectstmt.select_with_parens();
|
1228
|
+
if (select_with_parens) {
|
1229
|
+
return checkLimit_select_with_parens(select_with_parens);
|
1230
|
+
}
|
1231
|
+
return undefined;
|
1232
|
+
}
|
931
1233
|
//# sourceMappingURL=traverse.js.map
|