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.
Files changed (41) hide show
  1. package/README.md +5 -1
  2. package/cli.js +33 -15
  3. package/cli.js.map +1 -1
  4. package/code-generator.js +17 -7
  5. package/code-generator.js.map +1 -1
  6. package/code-generator2.d.ts +4 -1
  7. package/code-generator2.d.ts.map +1 -1
  8. package/code-generator2.js +274 -69
  9. package/code-generator2.js.map +1 -1
  10. package/drivers/postgres.d.ts +2 -0
  11. package/drivers/postgres.d.ts.map +1 -1
  12. package/drivers/postgres.js +32 -4
  13. package/drivers/postgres.js.map +1 -1
  14. package/drivers/types.d.ts +2 -0
  15. package/drivers/types.d.ts.map +1 -1
  16. package/mysql-query-analyzer/types.d.ts +2 -2
  17. package/mysql-query-analyzer/types.d.ts.map +1 -1
  18. package/package.json +53 -52
  19. package/postgres-query-analyzer/describe.d.ts.map +1 -1
  20. package/postgres-query-analyzer/describe.js +10 -41
  21. package/postgres-query-analyzer/describe.js.map +1 -1
  22. package/postgres-query-analyzer/parser.d.ts +2 -0
  23. package/postgres-query-analyzer/parser.d.ts.map +1 -1
  24. package/postgres-query-analyzer/parser.js +12 -0
  25. package/postgres-query-analyzer/parser.js.map +1 -1
  26. package/postgres-query-analyzer/traverse.d.ts +2 -0
  27. package/postgres-query-analyzer/traverse.d.ts.map +1 -1
  28. package/postgres-query-analyzer/traverse.js +378 -76
  29. package/postgres-query-analyzer/traverse.js.map +1 -1
  30. package/sqlite-query-analyzer/code-generator.d.ts +1 -0
  31. package/sqlite-query-analyzer/code-generator.d.ts.map +1 -1
  32. package/sqlite-query-analyzer/code-generator.js +1 -7
  33. package/sqlite-query-analyzer/code-generator.js.map +1 -1
  34. package/sqlite-query-analyzer/replace-list-params.js +3 -3
  35. package/sqlite-query-analyzer/replace-list-params.js.map +1 -1
  36. package/sqlite-query-analyzer/traverse.d.ts +2 -2
  37. package/sqlite-query-analyzer/traverse.d.ts.map +1 -1
  38. package/sqlite-query-analyzer/traverse.js +55 -21
  39. package/sqlite-query-analyzer/traverse.js.map +1 -1
  40. package/types.d.ts +1 -1
  41. 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
- parametersNullability: []
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.parametersNullability,
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 filterColumns_target_list(target_list, dbSchema, fromColumns, traverseResult);
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 filterColumns_target_list(target_list, dbSchema, fromColumns, traverseResult) {
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 a_expr_between = a_expr_and.a_expr_between_list()[0];
223
- if (a_expr_between) {
224
- return traverse_expr_between(a_expr_between, dbSchema, fromColumns, traverseResult);
225
- }
226
- throw Error('traverse_expr_and - Not expected:' + a_expr_and.getText());
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
- return traverse_expr_unary(a_expr_unary, dbSchema, fromColumns, traverseResult);
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 a_expr_like = a_expr_compare.a_expr_like_list()[0];
265
- if (a_expr_like) {
266
- return traverse_expr_like(a_expr_like, dbSchema, fromColumns, traverseResult);
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 a_expr_qual_op = a_expr_like.a_expr_qual_op_list()[0];
272
- if (a_expr_qual_op) {
273
- return traverse_expr_qual_op(a_expr_qual_op, dbSchema, fromColumns, traverseResult);
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 fieldName = (0, select_columns_1.splitName)(columnref.getText());
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.parametersNullability.push(true);
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 whenIsNotNull = case_expr.when_clause_list().when_clause_list().every(when_clause => traversewhen_clause(when_clause, dbSchema, fromColumns, traverseResult));
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.filter((_, index) => index % 2 == 1);
440
- return thenExprList.every(thenExpr => traverse_a_expr(thenExpr, dbSchema, fromColumns, traverseResult));
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.parametersNullability[traverseResult.parametersNullability.length - 1] = false;
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
- const colid = qualified_name.colid();
576
- if (colid) {
577
- return traverse_colid(colid, dbSchema);
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
- const parametersNullability = traverse_insert_select_stmt(selectstmt, dbSchema, insertColumnsList);
638
- return {
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
- parametersNullability,
641
- columnsNullability: [],
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
- return simple_select_pramary.values_clause().expr_list_list()
652
- .flatMap(expr_list => traverse_insert_a_expr_list(expr_list, dbSchema, insertColumnlist));
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
- parametersNullability.push(!insertColumns[index].is_nullable);
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
- return {
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
- parametersNullability: traverseResult.parametersNullability,
678
- columnsNullability: [],
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
- .map(set_clause => traverse_set_clause(set_clause, dbSchema, updateColumns, traverseResult));
688
- const dataParameters = traverseResult.parametersNullability;
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.parametersNullability.slice(dataParameters.length);
695
- return {
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
- parametersNullability: traverseResult.parametersNullability,
698
- columnsNullability: [],
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 a_exprResult = traverse_a_expr(a_expr, dbSchema, updateColumns, traverseResult);
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.parametersNullability[traverseResult.parametersNullability.length - 1] = !column.is_nullable;
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
- return +((_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());
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