typesql-cli 0.18.2 → 0.18.4

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 (32) hide show
  1. package/code-generator2.d.ts.map +1 -1
  2. package/code-generator2.js +12 -1
  3. package/code-generator2.js.map +1 -1
  4. package/dialects/postgres.d.ts.map +1 -1
  5. package/dialects/postgres.js +7 -2
  6. package/dialects/postgres.js.map +1 -1
  7. package/drivers/postgres.d.ts +2 -0
  8. package/drivers/postgres.d.ts.map +1 -1
  9. package/drivers/postgres.js +21 -0
  10. package/drivers/postgres.js.map +1 -1
  11. package/drivers/types.d.ts +2 -0
  12. package/drivers/types.d.ts.map +1 -1
  13. package/mysql-query-analyzer/select-columns.d.ts +1 -0
  14. package/mysql-query-analyzer/select-columns.d.ts.map +1 -1
  15. package/mysql-query-analyzer/select-columns.js +13 -0
  16. package/mysql-query-analyzer/select-columns.js.map +1 -1
  17. package/package.json +1 -1
  18. package/postgres-query-analyzer/describe.d.ts.map +1 -1
  19. package/postgres-query-analyzer/describe.js +6 -5
  20. package/postgres-query-analyzer/describe.js.map +1 -1
  21. package/postgres-query-analyzer/parser.d.ts +3 -2
  22. package/postgres-query-analyzer/parser.d.ts.map +1 -1
  23. package/postgres-query-analyzer/parser.js +19 -5
  24. package/postgres-query-analyzer/parser.js.map +1 -1
  25. package/postgres-query-analyzer/traverse.d.ts +18 -1
  26. package/postgres-query-analyzer/traverse.d.ts.map +1 -1
  27. package/postgres-query-analyzer/traverse.js +367 -150
  28. package/postgres-query-analyzer/traverse.js.map +1 -1
  29. package/postgres-query-analyzer/types.d.ts +8 -0
  30. package/postgres-query-analyzer/types.d.ts.map +1 -1
  31. package/sqlite-query-analyzer/types.d.ts +6 -2
  32. package/sqlite-query-analyzer/types.d.ts.map +1 -1
@@ -2,21 +2,22 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.defaultOptions = defaultOptions;
4
4
  exports.traverseSmt = traverseSmt;
5
+ exports.parseReturnType = parseReturnType;
5
6
  const PostgreSQLParser_1 = require("@wsporto/typesql-parser/postgres/PostgreSQLParser");
6
7
  const typesql_parser_1 = require("@wsporto/typesql-parser");
7
8
  const select_columns_1 = require("../mysql-query-analyzer/select-columns");
9
+ const postgres_1 = require("@wsporto/typesql-parser/postgres");
8
10
  function defaultOptions() {
9
11
  return {
10
12
  collectNestedInfo: false,
11
13
  collectDynamicQueryInfo: false
12
14
  };
13
15
  }
14
- function traverseSmt(stmt, dbSchema, checkConstraints, options) {
16
+ function traverseSmt(stmt, dbSchema, checkConstraints, userFunctions, options) {
15
17
  const { collectNestedInfo = false, collectDynamicQueryInfo = false } = options;
16
18
  const traverseResult = {
17
19
  columnsNullability: [],
18
- parameters: [],
19
- singleRow: false
20
+ parameters: []
20
21
  };
21
22
  if (collectNestedInfo) {
22
23
  traverseResult.relations = [];
@@ -35,7 +36,10 @@ function traverseSmt(stmt, dbSchema, checkConstraints, options) {
35
36
  collectNestedInfo,
36
37
  collectDynamicQueryInfo,
37
38
  fromColumns: [],
38
- checkConstraints
39
+ parentColumns: [],
40
+ withColumns: [],
41
+ checkConstraints,
42
+ userFunctions
39
43
  };
40
44
  const selectstmt = stmt.selectstmt();
41
45
  if (selectstmt) {
@@ -82,15 +86,15 @@ function getInParameterList(ctx) {
82
86
  }
83
87
  function traverseSelectstmt(selectstmt, context, traverseResult) {
84
88
  const paramIsListResult = getInParameterList(selectstmt);
85
- const columns = traverse_selectstmt(selectstmt, context, traverseResult);
89
+ const selectResult = traverse_selectstmt(selectstmt, context, traverseResult);
86
90
  //select parameters are collected after from paramters
87
91
  traverseResult.parameters.sort((param1, param2) => param1.paramIndex - param2.paramIndex);
88
- const multipleRowsResult = !isSingleRowResult(selectstmt, context.dbSchema);
92
+ const multipleRowsResult = !(selectResult.singleRow || isSingleRowResult(selectstmt, selectResult.columns));
89
93
  const limit = checkLimit(selectstmt);
90
94
  const postgresTraverseResult = {
91
95
  queryType: 'Select',
92
96
  multipleRowsResult,
93
- columns,
97
+ columns: selectResult.columns,
94
98
  parametersNullability: traverseResult.parameters.map(param => (Object.assign({ isNotNull: param.isNotNull }, addConstraintIfNotNull(param.checkConstraint)))),
95
99
  parameterList: paramIsListResult,
96
100
  limit
@@ -108,22 +112,23 @@ function traverse_selectstmt(selectstmt, context, traverseResult) {
108
112
  if (select_no_parens) {
109
113
  return traverse_select_no_parens(select_no_parens, context, traverseResult);
110
114
  }
111
- return [];
115
+ //select_with_parens
116
+ return {
117
+ columns: [],
118
+ singleRow: true
119
+ };
112
120
  }
113
121
  function traverse_select_no_parens(select_no_parens, context, traverseResult) {
114
- let withColumns = [];
115
122
  const with_clause = select_no_parens.with_clause();
116
123
  if (with_clause) {
117
124
  with_clause.cte_list().common_table_expr_list()
118
125
  .forEach(common_table_expr => {
119
- const newContext = Object.assign(Object.assign({}, context), { fromColumns: withColumns.concat(context.fromColumns) });
120
- const withResult = traverse_common_table_expr(common_table_expr, newContext, traverseResult);
121
- withColumns.push(...withResult);
126
+ const withResult = traverse_common_table_expr(common_table_expr, context, traverseResult);
127
+ context.withColumns.push(...withResult);
122
128
  });
123
129
  }
124
130
  const select_clause = select_no_parens.select_clause();
125
- const newContext = Object.assign(Object.assign({}, context), { fromColumns: withColumns.concat(context.fromColumns) });
126
- const selectResult = traverse_select_clause(select_clause, newContext, traverseResult);
131
+ const selectResult = traverse_select_clause(select_clause, context, traverseResult);
127
132
  const select_limit = select_no_parens.select_limit();
128
133
  if (select_limit) {
129
134
  const numParamsBefore = traverseResult.parameters.length;
@@ -159,8 +164,8 @@ function traverse_common_table_expr(common_table_expr, context, traverseResult)
159
164
  const tableName = common_table_expr.name().getText();
160
165
  const select_stmt = common_table_expr.preparablestmt().selectstmt();
161
166
  const numParamsBefore = traverseResult.parameters.length;
162
- const columns = traverse_selectstmt(select_stmt, Object.assign(Object.assign({}, context), { collectDynamicQueryInfo: false }), traverseResult);
163
- const columnsWithTalbeName = columns.map(col => (Object.assign(Object.assign({}, col), { table_name: tableName })));
167
+ const selectResult = traverse_selectstmt(select_stmt, Object.assign(Object.assign({}, context), { collectDynamicQueryInfo: false }), traverseResult);
168
+ const columnsWithTalbeName = selectResult.columns.map(col => (Object.assign(Object.assign({}, col), { table_name: tableName })));
164
169
  if (context.collectDynamicQueryInfo) {
165
170
  const parameters = traverseResult.parameters.slice(numParamsBefore).map((_, index) => index + numParamsBefore);
166
171
  (_a = traverseResult.dynamicQueryInfo) === null || _a === void 0 ? void 0 : _a.with.push({
@@ -173,45 +178,55 @@ function traverse_common_table_expr(common_table_expr, context, traverseResult)
173
178
  }
174
179
  function traverse_select_clause(select_clause, context, traverseResult) {
175
180
  const simple_select_intersect_list = select_clause.simple_select_intersect_list();
176
- let selectColumns = [];
177
- if (simple_select_intersect_list) {
178
- selectColumns = traverse_simple_select_intersect(simple_select_intersect_list[0], context, traverseResult);
179
- }
181
+ const mainSelectResult = traverse_simple_select_intersect(simple_select_intersect_list[0], context, traverseResult);
182
+ let columns = mainSelectResult.columns;
180
183
  //union
181
184
  for (let index = 1; index < simple_select_intersect_list.length; index++) {
182
- const unionNotNull = traverse_simple_select_intersect(simple_select_intersect_list[index], context, traverseResult);
183
- selectColumns = selectColumns.map((value, columnIndex) => {
184
- const col = Object.assign({ column_name: value.column_name, is_nullable: value.is_nullable || unionNotNull[columnIndex].is_nullable, table_name: '', table_schema: '', type: value.type }, (value.column_default && { column_default: value.column_default }));
185
+ const unionResult = traverse_simple_select_intersect(simple_select_intersect_list[index], context, traverseResult);
186
+ columns = columns.map((value, columnIndex) => {
187
+ const col = Object.assign({ column_name: value.column_name, is_nullable: value.is_nullable || unionResult.columns[columnIndex].is_nullable, table_name: '', table_schema: '', type: value.type }, (value.column_default && { column_default: value.column_default }));
185
188
  return col;
186
189
  });
187
190
  }
188
- return selectColumns;
191
+ return {
192
+ columns,
193
+ singleRow: simple_select_intersect_list.length == 1 ? mainSelectResult.singleRow : false
194
+ };
189
195
  }
190
196
  function traverse_simple_select_intersect(simple_select_intersect, context, traverseResult) {
191
197
  const simple_select_pramary = simple_select_intersect.simple_select_pramary_list()[0];
192
198
  if (simple_select_pramary) {
193
199
  return traverse_simple_select_pramary(simple_select_pramary, context, traverseResult);
194
200
  }
195
- return [];
201
+ return {
202
+ columns: [],
203
+ singleRow: true
204
+ };
196
205
  }
197
206
  function traverse_simple_select_pramary(simple_select_pramary, context, traverseResult) {
198
207
  var _a, _b, _c, _d, _e;
199
- const fromColumns = [];
208
+ let fromResult = {
209
+ columns: [],
210
+ singleRow: false
211
+ };
200
212
  const from_clause = simple_select_pramary.from_clause();
201
213
  if (from_clause) {
202
214
  const where_clause = simple_select_pramary.where_clause();
203
- const fields = traverse_from_clause(from_clause, context, traverseResult);
204
- const fieldsNotNull = where_clause != null ? fields.map(field => checkIsNullable(where_clause, field)) : fields;
205
- fromColumns.push(...fieldsNotNull);
215
+ fromResult = traverse_from_clause(from_clause, context, traverseResult);
216
+ fromResult.columns = where_clause != null ? fromResult.columns.map(field => checkIsNullable(where_clause, field)) : fromResult.columns;
206
217
  }
207
218
  const values_clause = simple_select_pramary.values_clause();
208
219
  if (values_clause) {
209
220
  const valuesColumns = traverse_values_clause(values_clause, context, traverseResult);
210
- return valuesColumns;
221
+ return {
222
+ columns: valuesColumns,
223
+ singleRow: false
224
+ };
211
225
  }
212
226
  const where_a_expr = (_a = simple_select_pramary.where_clause()) === null || _a === void 0 ? void 0 : _a.a_expr();
213
227
  //fromColumns has precedence
214
- const newContext = Object.assign(Object.assign({}, context), { fromColumns: fromColumns.concat(context.fromColumns) });
228
+ //context.fromColumns only becase of insert. update
229
+ const newContext = Object.assign(Object.assign({}, context), { fromColumns: [...context.fromColumns, ...fromResult.columns, ...context.parentColumns] });
215
230
  if (where_a_expr) {
216
231
  const numParamsBefore = traverseResult.parameters.length;
217
232
  traverse_a_expr(where_a_expr, newContext, traverseResult);
@@ -236,7 +251,10 @@ function traverse_simple_select_pramary(simple_select_pramary, context, traverse
236
251
  traverse_a_expr(having_expr, newContext, traverseResult);
237
252
  }
238
253
  const filteredColumns = filterColumns_simple_select_pramary(simple_select_pramary, newContext, traverseResult);
239
- return filteredColumns;
254
+ return {
255
+ columns: filteredColumns,
256
+ singleRow: fromResult.singleRow
257
+ };
240
258
  }
241
259
  function extractRelations(a_expr) {
242
260
  const columnsRef = collectContextsOfType(a_expr, PostgreSQLParser_1.ColumnrefContext);
@@ -340,7 +358,7 @@ function traverse_target_el(target_el, context, traverseResult) {
340
358
  parameters
341
359
  });
342
360
  }
343
- return Object.assign({ column_name: alias || exprResult.column_name, is_nullable: exprResult.is_nullable && exprResult.column_default !== true, table_name: exprResult.table_name, table_schema: exprResult.table_schema, type: exprResult.type }, (exprResult.jsonType != null && { jsonType: exprResult.jsonType }));
361
+ return Object.assign(Object.assign({ column_name: alias || exprResult.column_name, is_nullable: exprResult.is_nullable && exprResult.column_default !== true, table_name: exprResult.table_name, table_schema: exprResult.table_schema, type: exprResult.type }, (exprResult.column_key != null && { column_key: exprResult.column_key })), (exprResult.jsonType != null && { jsonType: exprResult.jsonType }));
344
362
  }
345
363
  throw Error('Column not found');
346
364
  }
@@ -355,7 +373,7 @@ function traverse_a_expr(a_expr, context, traverseResult) {
355
373
  is_nullable: true,
356
374
  table_name: '',
357
375
  table_schema: '',
358
- type: 'unknow'
376
+ type: 'unknown'
359
377
  };
360
378
  }
361
379
  function traverse_a_expr_qual(a_expr_qual, context, traverseResult) {
@@ -470,6 +488,7 @@ function traverse_expr_is_not(a_expr_is_not, context, traverseResult) {
470
488
  const result = traverse_expr_compare(a_expr_compare, context, traverseResult);
471
489
  if (a_expr_is_not.IS() && a_expr_is_not.NULL_P()) {
472
490
  checkParamterNullability(result, traverseResult);
491
+ return Object.assign(Object.assign({}, result), { is_nullable: false });
473
492
  }
474
493
  return result;
475
494
  }
@@ -518,10 +537,10 @@ function traverse_expr_compare(a_expr_compare, context, traverseResult) {
518
537
  const result = traverse_select_with_parens(select_with_parens, context, traverseResult);
519
538
  return {
520
539
  column_name: '?column?',
521
- is_nullable: result.some(col => col.is_nullable),
540
+ is_nullable: result.columns.some(col => col.is_nullable),
522
541
  table_name: '',
523
542
  table_schema: '',
524
- type: result[0].type
543
+ type: result.columns[0].type
525
544
  };
526
545
  }
527
546
  const a_expr = a_expr_compare.a_expr();
@@ -549,7 +568,7 @@ function traverse_expr_like(a_expr_like, context, traverseResult) {
549
568
  is_nullable: result.some(col => col.is_nullable),
550
569
  table_name: '',
551
570
  table_schema: '',
552
- type: 'unknow'
571
+ type: 'unknown'
553
572
  };
554
573
  }
555
574
  throw Error('traverse_expr_like - Not expected:' + a_expr_like.getText());
@@ -566,7 +585,7 @@ function traverse_expr_qual_op(a_expr_qual_op, context, traverseResult) {
566
585
  is_nullable: result.some(col => col.is_nullable),
567
586
  table_name: '',
568
587
  table_schema: '',
569
- type: 'unknow'
588
+ type: 'unknown'
570
589
  };
571
590
  }
572
591
  throw Error('traverse_expr_qual_op - Not expected:' + a_expr_qual_op.getText());
@@ -622,7 +641,7 @@ function traverse_expr_caret(a_expr_caret, context, traverseResult) {
622
641
  is_nullable: notNullInfo.some(notNullInfo => notNullInfo.is_nullable),
623
642
  table_name: '',
624
643
  table_schema: '',
625
- type: 'unknow'
644
+ type: 'unknown'
626
645
  };
627
646
  return result;
628
647
  }
@@ -710,12 +729,12 @@ function getNameAndTypeIdFromAExprConst(a_expr_const) {
710
729
  if (a_expr_const.NULL_P()) {
711
730
  return {
712
731
  name: a_expr_const.getText(),
713
- type: 'unknow'
732
+ type: 'null'
714
733
  };
715
734
  }
716
735
  return {
717
736
  name: a_expr_const.getText(),
718
- type: 'unknow'
737
+ type: 'unknown'
719
738
  };
720
739
  }
721
740
  function traversec_expr(c_expr, context, traverseResult) {
@@ -730,7 +749,7 @@ function traversec_expr(c_expr, context, traverseResult) {
730
749
  is_nullable: true,
731
750
  table_schema: '',
732
751
  table_name: '',
733
- type: 'unknow'
752
+ type: 'unknown'
734
753
  };
735
754
  }
736
755
  const array_expr = c_expr.array_expr();
@@ -741,8 +760,22 @@ function traversec_expr(c_expr, context, traverseResult) {
741
760
  }
742
761
  const columnref = c_expr.columnref();
743
762
  if (columnref) {
744
- const col = traverseColumnRef(columnref, context.fromColumns);
745
- return col;
763
+ if (context.columnRefIsRecord) {
764
+ const table = (0, select_columns_1.splitTableName)(columnref.getText());
765
+ const columns = filterColumns(context.fromColumns, table);
766
+ return {
767
+ column_name: columnref.getText(),
768
+ is_nullable: false,
769
+ table_name: '',
770
+ table_schema: '',
771
+ type: 'record',
772
+ recordTypes: columns
773
+ };
774
+ }
775
+ else {
776
+ const col = traverseColumnRef(columnref, context.fromColumns);
777
+ return col;
778
+ }
746
779
  }
747
780
  const aexprconst = c_expr.aexprconst();
748
781
  if (aexprconst) {
@@ -766,11 +799,12 @@ function traversec_expr(c_expr, context, traverseResult) {
766
799
  is_nullable: !!context.propagatesNull,
767
800
  table_name: '',
768
801
  table_schema: '',
769
- type: 'unknow'
802
+ type: 'unknown'
770
803
  };
771
804
  }
772
805
  const fun_expr = c_expr.func_expr();
773
806
  if (fun_expr) {
807
+ context.columnRefIsRecord = undefined;
774
808
  const func_application = fun_expr.func_application();
775
809
  if (func_application) {
776
810
  if (is_json_build_object_func(func_application)) {
@@ -796,14 +830,14 @@ function traversec_expr(c_expr, context, traverseResult) {
796
830
  }
797
831
  const select_with_parens = c_expr.select_with_parens();
798
832
  if (select_with_parens) {
799
- const result = traverse_select_with_parens(select_with_parens, context, traverseResult);
833
+ const result = traverse_select_with_parens(select_with_parens, Object.assign(Object.assign({}, context), { parentColumns: context.fromColumns, fromColumns: [] }), traverseResult);
800
834
  return {
801
835
  column_name: '?column?',
802
- is_nullable: true,
836
+ is_nullable: result.columns[0].jsonType ? result.columns[0].is_nullable : true,
803
837
  table_name: '',
804
838
  table_schema: '',
805
- type: result[0].type,
806
- jsonType: result[0].jsonType
839
+ type: result.columns[0].type,
840
+ jsonType: result.columns[0].jsonType
807
841
  };
808
842
  }
809
843
  const a_expr_in_parens = c_expr._a_expr_in_parens;
@@ -819,7 +853,8 @@ function traversec_expr(c_expr, context, traverseResult) {
819
853
  is_nullable: expr_list.some(col => col.is_nullable),
820
854
  table_name: '',
821
855
  table_schema: '',
822
- type: 'unknow'
856
+ type: 'record',
857
+ recordTypes: expr_list.map(expr => (Object.assign(Object.assign({}, expr), { column_name: '' })))
823
858
  };
824
859
  }
825
860
  const implicit_row = c_expr.implicit_row();
@@ -831,7 +866,7 @@ function traversec_expr(c_expr, context, traverseResult) {
831
866
  is_nullable: expr_list.some(col => col.is_nullable),
832
867
  table_name: '',
833
868
  table_schema: '',
834
- type: 'unknow'
869
+ type: 'unknown'
835
870
  };
836
871
  }
837
872
  }
@@ -855,13 +890,7 @@ function traversec_expr(c_expr, context, traverseResult) {
855
890
  function filterColumns(fromColumns, fieldName) {
856
891
  return fromColumns.filter(col => (fieldName.prefix === '' || col.table_name === fieldName.prefix)
857
892
  && (fieldName.name === '*' || col.column_name === fieldName.name)).map(col => {
858
- const result = {
859
- column_name: col.column_name,
860
- is_nullable: col.is_nullable,
861
- table_name: col.table_name,
862
- table_schema: col.table_schema,
863
- type: col.type
864
- };
893
+ const result = Object.assign(Object.assign(Object.assign({ column_name: col.column_name, is_nullable: col.is_nullable, table_name: col.table_name, table_schema: col.table_schema, type: col.type }, (col.column_key !== undefined) && { column_key: col.column_key }), (col.jsonType !== undefined) && { jsonType: col.jsonType }), (col.original_is_nullable !== undefined && { original_is_nullable: col.original_is_nullable }));
865
894
  return result;
866
895
  });
867
896
  }
@@ -878,22 +907,33 @@ function traversec_expr_case(c_expr_case, context, traverseResult) {
878
907
  const whenResult = case_expr.when_clause_list().when_clause_list().map(when_clause => traversewhen_clause(when_clause, context, traverseResult));
879
908
  const whenIsNotNull = whenResult.every(when => when);
880
909
  const elseExpr = (_a = case_expr.case_default()) === null || _a === void 0 ? void 0 : _a.a_expr();
881
- const elseIsNotNull = elseExpr ? !traverse_a_expr(elseExpr, context, traverseResult).is_nullable : false;
910
+ const elseResult = elseExpr ? traverse_a_expr(elseExpr, Object.assign({}, context), traverseResult) : null;
911
+ const elseIsNotNull = (elseResult === null || elseResult === void 0 ? void 0 : elseResult.is_nullable) === false || false;
882
912
  const notNull = elseIsNotNull && whenIsNotNull;
883
913
  return {
884
914
  column_name: '?column?',
885
915
  is_nullable: !notNull,
886
916
  table_name: '',
887
917
  table_schema: '',
888
- type: (_b = whenResult[0].type) !== null && _b !== void 0 ? _b : 'unknow'
918
+ type: (_b = whenResult[0].type) !== null && _b !== void 0 ? _b : 'unknown',
919
+ jsonType: allJsonTypesMatch(whenResult, elseResult) ? whenResult[0].jsonType : undefined
889
920
  };
890
921
  }
922
+ function allJsonTypesMatch(whenResultList, elseResult) {
923
+ var _a;
924
+ const firstType = (_a = whenResultList[0]) === null || _a === void 0 ? void 0 : _a.jsonType;
925
+ const allMatch = whenResultList.every(res => {
926
+ const match = res.jsonType == firstType;
927
+ return match;
928
+ }) && ((elseResult === null || elseResult === void 0 ? void 0 : elseResult.type) === 'null' || (elseResult === null || elseResult === void 0 ? void 0 : elseResult.jsonType) == firstType);
929
+ return allMatch;
930
+ }
891
931
  function traversewhen_clause(when_clause, context, traverseResult) {
892
932
  const a_expr_list = when_clause.a_expr_list();
893
933
  const [whenExprList, thenExprList] = partition(a_expr_list, (index) => index % 2 === 0);
894
934
  const whenExprResult = thenExprList.map((thenExpr, index) => {
895
935
  traverse_a_expr(whenExprList[index], context, traverseResult);
896
- const thenExprResult = traverse_a_expr(thenExpr, context, traverseResult);
936
+ const thenExprResult = traverse_a_expr(thenExpr, Object.assign(Object.assign({}, context), { filter_expr: whenExprList[index] }), traverseResult);
897
937
  return thenExprResult;
898
938
  });
899
939
  const notNull = whenExprResult.every(res => res);
@@ -902,7 +942,8 @@ function traversewhen_clause(when_clause, context, traverseResult) {
902
942
  is_nullable: !notNull,
903
943
  table_name: '',
904
944
  table_schema: '',
905
- type: whenExprResult[0].type
945
+ type: whenExprResult[0].type,
946
+ jsonType: whenExprResult[0].jsonType
906
947
  };
907
948
  }
908
949
  function partition(array, predicate) {
@@ -930,69 +971,113 @@ function is_json_agg(func_application) {
930
971
  return functionName === 'json_agg'
931
972
  || functionName === 'jsonb_agg';
932
973
  }
933
- function transformToJsonProperty(args, filterExpr) {
934
- const pairs = [];
935
- for (let i = 0; i < args.length; i += 2) {
936
- const key = args[i];
937
- const value = args[i + 1];
974
+ function mapJsonBuildArgsToJsonProperty(args, filterExpr) {
975
+ const keys = args.filter((_, index) => index % 2 === 0);
976
+ const values = args.filter((_, index) => index % 2 === 1);
977
+ const nullability = inferJsonNullability(values, filterExpr);
978
+ const properties = [];
979
+ for (let i = 0; i < values.length; i++) {
980
+ const key = keys[i];
981
+ const value = values[i];
938
982
  if (value !== undefined) {
939
- const isNotNull = !value.is_nullable || Boolean(filterExpr && isNotNull_a_expr(value, filterExpr));
940
- const type = value.jsonType ? value.jsonType : { name: 'json_field', type: value.type, notNull: isNotNull };
941
- pairs.push({ key: key.column_name, type });
983
+ const type = value.jsonType ? value.jsonType : { name: 'json_field', type: value.type, notNull: nullability[i] };
984
+ properties.push({ key: key.column_name, type });
942
985
  }
943
986
  }
944
- return pairs;
987
+ return properties;
988
+ }
989
+ function inferJsonNullability(columns, filterExpr) {
990
+ const tables = columns.filter(col => filterExpr && col.original_is_nullable === false && isNotNull_a_expr(col, filterExpr)).map(col => col.table_name);
991
+ const fields = columns.map(col => {
992
+ return col.original_is_nullable != null && tables.includes(col.table_name) ? !col.original_is_nullable : !col.is_nullable;
993
+ });
994
+ return fields;
995
+ }
996
+ function transformFieldsToJsonObjType(fields) {
997
+ const jsonObject = {
998
+ name: 'json',
999
+ properties: fields.map(col => mapFieldToPropertyDef(col))
1000
+ };
1001
+ return jsonObject;
1002
+ }
1003
+ function mapFieldToPropertyDef(field) {
1004
+ const prop = {
1005
+ key: field.name,
1006
+ type: transformFieldToJsonField(field)
1007
+ };
1008
+ return prop;
1009
+ }
1010
+ function transformFieldToJsonField(field) {
1011
+ const jsonField = { name: 'json_field', type: field.type, notNull: field.notNull };
1012
+ return jsonField;
945
1013
  }
946
1014
  function traverse_json_build_obj_func(func_application, context, traverseResult) {
947
1015
  var _a, _b;
948
1016
  const columnName = ((_a = func_application.func_name()) === null || _a === void 0 ? void 0 : _a.getText()) || func_application.getText();
949
1017
  const func_arg_expr_list = ((_b = func_application.func_arg_list()) === null || _b === void 0 ? void 0 : _b.func_arg_expr_list()) || [];
950
1018
  const argsResult = func_arg_expr_list.map(func_arg_expr => traversefunc_arg_expr(func_arg_expr, context, traverseResult));
951
- return {
1019
+ const result = {
952
1020
  column_name: columnName,
953
- is_nullable: true,
1021
+ is_nullable: false,
954
1022
  table_name: '',
955
1023
  table_schema: '',
956
1024
  type: 'json',
957
1025
  jsonType: {
958
1026
  name: 'json',
959
- properties: transformToJsonProperty(argsResult, context.filter_expr),
1027
+ properties: mapJsonBuildArgsToJsonProperty(argsResult, context.filter_expr),
960
1028
  }
961
1029
  };
962
- }
963
- function isNotNull_json_agg(col) {
964
- if (col.jsonType != null && col.jsonType.name == 'json') {
965
- return col.jsonType.properties.every(prop => {
966
- if (prop.type.name == 'json_field') {
967
- return !prop.type.notNull;
968
- }
969
- return false;
970
- });
971
- }
972
- return false;
1030
+ return result;
973
1031
  }
974
1032
  function traverse_json_agg(func_application, context, traverseResult) {
975
1033
  var _a, _b;
976
1034
  const columnName = ((_a = func_application.func_name()) === null || _a === void 0 ? void 0 : _a.getText()) || func_application.getText();
977
1035
  const func_arg_expr_list = ((_b = func_application.func_arg_list()) === null || _b === void 0 ? void 0 : _b.func_arg_expr_list()) || [];
978
- const argsResult = func_arg_expr_list.map(func_arg_expr => traversefunc_arg_expr(func_arg_expr, context, traverseResult));
1036
+ const argsResult = func_arg_expr_list.map(func_arg_expr => traversefunc_arg_expr(func_arg_expr, Object.assign(Object.assign({}, context), { columnRefIsRecord: true }), traverseResult));
979
1037
  const result = {
980
1038
  column_name: columnName,
981
- is_nullable: !isNotNull_json_agg(argsResult[0]),
1039
+ is_nullable: context.filter_expr != null,
982
1040
  table_name: '',
983
1041
  table_schema: '',
984
1042
  type: 'json[]',
985
1043
  jsonType: {
986
1044
  name: 'json[]',
987
- properties: argsResult.map(arg => arg.jsonType || { name: 'json_field', type: arg.type, notNull: !arg.is_nullable })
1045
+ properties: createJsonTypeForJsonAgg(argsResult[0], context.filter_expr)
988
1046
  }
989
1047
  };
990
1048
  return result;
991
1049
  }
1050
+ function createJsonTypeForJsonAgg(arg, filter_expr) {
1051
+ if (arg.recordTypes) {
1052
+ const jsonType = mapRecordsToJsonType(arg.recordTypes, filter_expr);
1053
+ return [jsonType];
1054
+ }
1055
+ return [arg.jsonType || { name: 'json_field', type: arg.type, notNull: !arg.is_nullable }];
1056
+ }
1057
+ function mapRecordsToJsonType(recordTypes, filterExpr) {
1058
+ const jsonNullability = inferJsonNullability(recordTypes, filterExpr);
1059
+ const fields = recordTypes.map((col, index) => ({ name: col.column_name ? col.column_name : `f${index + 1}`, type: col.type, notNull: jsonNullability[index] }));
1060
+ const jsonType = transformFieldsToJsonObjType(fields);
1061
+ return jsonType;
1062
+ }
992
1063
  function traversefunc_application(func_application, context, traverseResult) {
993
1064
  var _a;
994
1065
  const functionName = getFunctionName(func_application);
995
1066
  const func_arg_expr_list = ((_a = func_application.func_arg_list()) === null || _a === void 0 ? void 0 : _a.func_arg_expr_list()) || [];
1067
+ if (functionName === 'row_to_json') {
1068
+ const argResult = traversefunc_arg_expr(func_arg_expr_list[0], Object.assign(Object.assign({}, context), { columnRefIsRecord: true }), traverseResult);
1069
+ if (argResult.recordTypes) {
1070
+ const jsonType = mapRecordsToJsonType(argResult.recordTypes, context.filter_expr);
1071
+ return {
1072
+ column_name: functionName,
1073
+ is_nullable: false,
1074
+ table_name: '',
1075
+ table_schema: '',
1076
+ type: 'json',
1077
+ jsonType
1078
+ };
1079
+ }
1080
+ }
996
1081
  const argsResult = func_arg_expr_list.map(func_arg_expr => traversefunc_arg_expr(func_arg_expr, context, traverseResult));
997
1082
  if (functionName === 'count') {
998
1083
  return {
@@ -1058,7 +1143,7 @@ function traversefunc_application(func_application, context, traverseResult) {
1058
1143
  is_nullable: false,
1059
1144
  table_name: '',
1060
1145
  table_schema: '',
1061
- type: 'unknow'
1146
+ type: 'unknown'
1062
1147
  };
1063
1148
  }
1064
1149
  if (functionName === 'row_number'
@@ -1112,14 +1197,27 @@ function traversefunc_application(func_application, context, traverseResult) {
1112
1197
  };
1113
1198
  }
1114
1199
  if (functionName === 'sum') {
1115
- return Object.assign(Object.assign({}, argsResult[0]), { column_name: functionName, is_nullable: true, type: argsResult[0].type ? mapSumType(argsResult[0].type) : 'unknow' });
1200
+ return Object.assign(Object.assign({}, argsResult[0]), { column_name: functionName, is_nullable: true, type: argsResult[0].type ? mapSumType(argsResult[0].type) : 'unknown' });
1201
+ }
1202
+ if (functionName === 'json_object_agg') {
1203
+ return {
1204
+ column_name: functionName,
1205
+ is_nullable: false,
1206
+ table_name: '',
1207
+ table_schema: '',
1208
+ type: 'json',
1209
+ jsonType: {
1210
+ name: 'json_map',
1211
+ type: argsResult[1].jsonType || { name: 'json_field', type: argsResult[1].type, notNull: !argsResult[1].is_nullable }
1212
+ }
1213
+ };
1116
1214
  }
1117
1215
  return {
1118
1216
  column_name: functionName,
1119
1217
  is_nullable: true,
1120
1218
  table_name: '',
1121
1219
  table_schema: '',
1122
- type: 'unknow'
1220
+ type: 'unknown'
1123
1221
  };
1124
1222
  }
1125
1223
  function mapSumType(type) {
@@ -1162,7 +1260,7 @@ function traversefunc_expr_common_subexpr(func_expr_common_subexpr, context, tra
1162
1260
  is_nullable: true,
1163
1261
  table_name: '',
1164
1262
  table_schema: '',
1165
- type: 'unknow'
1263
+ type: 'unknown'
1166
1264
  };
1167
1265
  }
1168
1266
  function traversefunc_arg_expr(func_arg_expr, context, traverseResult) {
@@ -1185,7 +1283,7 @@ function traverse_array_expr(array_expr, context, traverseResult) {
1185
1283
  is_nullable: true,
1186
1284
  table_name: '',
1187
1285
  table_schema: '',
1188
- type: 'unknow'
1286
+ type: 'unknown'
1189
1287
  };
1190
1288
  }
1191
1289
  function traverse_array_expr_list(array_expr_list, context, traverseResult) {
@@ -1212,27 +1310,40 @@ function checkIsNullable(where_clause, field) {
1212
1310
  function traverse_from_clause(from_clause, context, traverseResult) {
1213
1311
  const from_list = from_clause.from_list();
1214
1312
  if (from_list) {
1215
- return traverse_from_list(from_list, context, traverseResult);
1313
+ const fromListResult = traverse_from_list(from_list, context, traverseResult);
1314
+ return fromListResult;
1216
1315
  }
1217
- return [];
1316
+ return {
1317
+ columns: [],
1318
+ singleRow: false
1319
+ };
1218
1320
  }
1219
1321
  function traverse_from_list(from_list, context, traverseResult) {
1220
- const newColumns = from_list.table_ref_list().flatMap(table_ref => traverse_table_ref(table_ref, context, traverseResult));
1221
- return newColumns;
1322
+ const fromListResult = from_list.table_ref_list().map(table_ref => traverse_table_ref(table_ref, context, traverseResult));
1323
+ const columns = fromListResult.flatMap(tableRes => tableRes.columns);
1324
+ return {
1325
+ columns: columns,
1326
+ singleRow: fromListResult.length === 1 ? fromListResult[0].singleRow : false
1327
+ };
1328
+ }
1329
+ function getFromColumns(tableName, withColumns, dbSchema) {
1330
+ const filteredWithColumns = withColumns.filter(col => col.table_name.toLowerCase() === tableName.name.toLowerCase());
1331
+ const filteredSchema = filteredWithColumns.length > 0 ? filteredWithColumns : dbSchema.filter(col => col.table_name.toLowerCase() === tableName.name.toLowerCase());
1332
+ return filteredSchema;
1222
1333
  }
1223
1334
  function traverse_table_ref(table_ref, context, traverseResult) {
1224
- var _a, _b, _c, _d;
1225
- const { fromColumns, dbSchema } = context;
1335
+ var _a, _b, _c, _d, _e, _f, _g;
1226
1336
  const allColumns = [];
1227
1337
  const relation_expr = table_ref.relation_expr();
1228
1338
  const aliasClause = table_ref.alias_clause();
1229
1339
  const aliasNameList = (_b = (_a = aliasClause === null || aliasClause === void 0 ? void 0 : aliasClause.name_list()) === null || _a === void 0 ? void 0 : _a.name_list()) === null || _b === void 0 ? void 0 : _b.map(name => name.getText());
1230
1340
  const alias = aliasClause ? aliasClause.colid().getText() : '';
1231
1341
  if (relation_expr) {
1232
- const tableName = traverse_relation_expr(relation_expr, dbSchema);
1342
+ const tableName = traverse_relation_expr(relation_expr);
1343
+ const fromColumns = getFromColumns(tableName, context.withColumns, context.dbSchema);
1233
1344
  const tableNameWithAlias = alias ? alias : tableName.name;
1234
- const fromColumnsResult = fromColumns.concat(dbSchema).filter(col => col.table_name.toLowerCase() === tableName.name.toLowerCase())
1235
- .map(col => (Object.assign(Object.assign({}, col), { table_name: tableNameWithAlias.toLowerCase() })));
1345
+ const columnsWithAlias = fromColumns.map(col => (Object.assign(Object.assign({}, col), { table_name: tableNameWithAlias.toLowerCase() })));
1346
+ const fromColumnsResult = columnsWithAlias.concat(context.parentColumns);
1236
1347
  allColumns.push(...fromColumnsResult);
1237
1348
  if (context.collectNestedInfo) {
1238
1349
  const key = fromColumnsResult.filter(col => col.column_key === 'PRI');
@@ -1248,47 +1359,78 @@ function traverse_table_ref(table_ref, context, traverseResult) {
1248
1359
  };
1249
1360
  (_d = traverseResult.relations) === null || _d === void 0 ? void 0 : _d.push(relation);
1250
1361
  }
1251
- const table_ref_list = table_ref.table_ref_list();
1252
- const join_type_list = table_ref.join_type_list();
1253
- const join_qual_list = table_ref.join_qual_list();
1254
1362
  if (context.collectDynamicQueryInfo && traverseResult.dynamicQueryInfo.from.length == 0) {
1255
1363
  collectDynamicQueryInfoTableRef(table_ref, null, null, fromColumnsResult, [], traverseResult);
1256
1364
  }
1257
- if (table_ref_list) {
1258
- const joinColumns = table_ref_list.flatMap((table_ref, joinIndex) => {
1259
- const joinType = join_type_list[joinIndex]; //INNER, LEFT
1260
- const joinQual = join_qual_list[joinIndex];
1261
- const numParamsBefore = traverseResult.parameters.length;
1262
- const joinColumns = traverse_table_ref(table_ref, context, traverseResult);
1263
- const isUsing = (joinQual === null || joinQual === void 0 ? void 0 : joinQual.USING()) ? true : false;
1264
- const isLeftJoin = joinType === null || joinType === void 0 ? void 0 : joinType.LEFT();
1265
- const filteredColumns = isUsing ? filterUsingColumns(joinColumns, joinQual) : joinColumns;
1266
- const resultColumns = isLeftJoin ? filteredColumns.map(col => (Object.assign(Object.assign({}, col), { is_nullable: true }))) : filteredColumns;
1267
- if (context.collectNestedInfo) {
1268
- collectNestedInfo(joinQual, resultColumns, traverseResult);
1269
- }
1270
- if (context.collectDynamicQueryInfo) {
1271
- const parameters = traverseResult.parameters.slice(numParamsBefore).map((_, index) => index + numParamsBefore);
1272
- collectDynamicQueryInfoTableRef(table_ref, joinType, joinQual, resultColumns, parameters, traverseResult);
1273
- }
1274
- return resultColumns;
1275
- });
1276
- allColumns.push(...joinColumns);
1277
- }
1365
+ const joinList = extractJoins(table_ref);
1366
+ const joinColumns = joinList.flatMap((join) => {
1367
+ const joinType = join.joinType; //INNER, LEFT
1368
+ const joinQual = join.joinQual;
1369
+ const numParamsBefore = traverseResult.parameters.length;
1370
+ const joinTableRefResult = traverse_table_ref(join.tableRef, context, traverseResult);
1371
+ const isLeftJoin = joinType === null || joinType === void 0 ? void 0 : joinType.LEFT();
1372
+ const filteredColumns = joinQual && (joinQual === null || joinQual === void 0 ? void 0 : joinQual.USING()) ? filterUsingColumns(joinTableRefResult.columns, joinQual) : joinTableRefResult.columns;
1373
+ const resultColumns = isLeftJoin ? filteredColumns.map(col => (Object.assign(Object.assign({}, col), { is_nullable: true, original_is_nullable: col.is_nullable }))) : filteredColumns;
1374
+ if (context.collectNestedInfo && joinQual) {
1375
+ collectNestedInfo(joinQual, resultColumns, traverseResult);
1376
+ }
1377
+ if (context.collectDynamicQueryInfo) {
1378
+ const parameters = traverseResult.parameters.slice(numParamsBefore).map((_, index) => index + numParamsBefore);
1379
+ collectDynamicQueryInfoTableRef(join.tableRef, joinType, joinQual, resultColumns, parameters, traverseResult);
1380
+ }
1381
+ return resultColumns;
1382
+ });
1383
+ allColumns.push(...joinColumns);
1384
+ }
1385
+ const func_table = table_ref.func_table();
1386
+ if (func_table) {
1387
+ const funcAlias = ((_g = (_f = (_e = table_ref.func_alias_clause()) === null || _e === void 0 ? void 0 : _e.alias_clause()) === null || _f === void 0 ? void 0 : _f.colid()) === null || _g === void 0 ? void 0 : _g.getText()) || '';
1388
+ const result = traverse_func_table(func_table, context, traverseResult);
1389
+ const resultWithAlias = result.columns.map(col => (Object.assign(Object.assign({}, col), { table_name: funcAlias || col.table_name })));
1390
+ return {
1391
+ columns: resultWithAlias,
1392
+ singleRow: result.singleRow
1393
+ };
1278
1394
  }
1279
1395
  const select_with_parens = table_ref.select_with_parens();
1280
1396
  if (select_with_parens) {
1281
1397
  const columns = traverse_select_with_parens(select_with_parens, Object.assign(Object.assign({}, context), { collectDynamicQueryInfo: false }), traverseResult);
1282
- const withAlias = columns.map((col, i) => ({
1398
+ const withAlias = columns.columns.map((col, i) => ({
1283
1399
  column_name: (aliasNameList === null || aliasNameList === void 0 ? void 0 : aliasNameList[i]) || col.column_name,
1284
1400
  is_nullable: col.is_nullable,
1285
1401
  table_name: alias || col.table_name,
1286
1402
  table_schema: col.table_schema,
1287
1403
  type: col.type
1288
1404
  }));
1289
- return withAlias;
1405
+ return {
1406
+ columns: withAlias,
1407
+ singleRow: false
1408
+ };
1290
1409
  }
1291
- return allColumns;
1410
+ return {
1411
+ columns: allColumns,
1412
+ singleRow: false
1413
+ };
1414
+ }
1415
+ function extractJoins(table_ref) {
1416
+ const joinList = [];
1417
+ let currentJoinType = null;
1418
+ for (const child of table_ref.children || []) {
1419
+ if (child instanceof PostgreSQLParser_1.Join_typeContext) {
1420
+ currentJoinType = child;
1421
+ }
1422
+ if (child instanceof PostgreSQLParser_1.Table_refContext) {
1423
+ joinList.push({ joinQual: null, joinType: currentJoinType, tableRef: child });
1424
+ currentJoinType = null;
1425
+ }
1426
+ if (child instanceof PostgreSQLParser_1.Join_qualContext) {
1427
+ const lastJoin = joinList.at(-1);
1428
+ if (lastJoin) {
1429
+ lastJoin.joinQual = child;
1430
+ }
1431
+ }
1432
+ }
1433
+ return joinList;
1292
1434
  }
1293
1435
  function collectDynamicQueryInfoTableRef(table_ref, joinType, joinQual, columns, parameters, traverseResult) {
1294
1436
  var _a, _b;
@@ -1358,16 +1500,88 @@ function traverse_select_with_parens(select_with_parens, context, traverseResult
1358
1500
  if (select_no_parens) {
1359
1501
  return traverse_select_no_parens(select_no_parens, context, traverseResult);
1360
1502
  }
1361
- return [];
1503
+ return {
1504
+ columns: [],
1505
+ singleRow: false
1506
+ };
1362
1507
  }
1363
- function traverse_relation_expr(relation_expr, dbSchema) {
1508
+ function traverse_func_table(func_table, context, traverseResult) {
1509
+ const func_expr_windowless = func_table.func_expr_windowless();
1510
+ if (func_expr_windowless) {
1511
+ const result = traverse_func_expr_windowless(func_expr_windowless, context, traverseResult);
1512
+ return result;
1513
+ }
1514
+ throw Error('Stmt not supported: ' + func_table.getText());
1515
+ }
1516
+ function parseReturnType(returnType) {
1517
+ const trimmed = returnType.trim();
1518
+ // Handle TABLE(...)
1519
+ if (trimmed.toLowerCase().startsWith('table(') && trimmed.endsWith(')')) {
1520
+ const inside = trimmed.slice(6, -1); // remove "TABLE(" and final ")"
1521
+ const columns = [];
1522
+ const parts = inside.split(',').map(part => part.trim());
1523
+ for (const part of parts) {
1524
+ const match = part.match(/^(\w+)\s+(.+)$/);
1525
+ if (!match) {
1526
+ throw new Error(`Invalid column definition: ${part}`);
1527
+ }
1528
+ const [, name, type] = match;
1529
+ columns.push({ name, type });
1530
+ }
1531
+ return { kind: 'table', columns };
1532
+ }
1533
+ // Handle SETOF typename
1534
+ const setofMatch = trimmed.match(/^SETOF\s+(\w+)$/i);
1535
+ if (setofMatch) {
1536
+ return { kind: 'setof', table: setofMatch[1] };
1537
+ }
1538
+ throw new Error(`Unsupported return type format: ${returnType}`);
1539
+ }
1540
+ function traverse_func_expr_windowless(func_expr_windowless, context, traverseResult) {
1541
+ const func_application = func_expr_windowless.func_application();
1542
+ if (func_application) {
1543
+ const func_name = func_application.func_name().getText().toLowerCase();
1544
+ const funcSchema = context.userFunctions.find(func => func.function_name.toLowerCase() === func_name);
1545
+ if (funcSchema) {
1546
+ const definition = funcSchema.definition;
1547
+ const returnType = parseReturnType(funcSchema.return_type);
1548
+ const functionColumns = returnType.kind === 'table' ? returnType.columns.map(col => {
1549
+ const columnInfo = {
1550
+ column_name: col.name,
1551
+ type: col.type,
1552
+ is_nullable: true,
1553
+ table_name: '',
1554
+ table_schema: ''
1555
+ };
1556
+ return columnInfo;
1557
+ }) : context.dbSchema.filter(col => col.table_name.toLowerCase() === returnType.table);
1558
+ if (funcSchema.language.toLowerCase() === 'sql') {
1559
+ const parser = (0, postgres_1.parseSql)(definition);
1560
+ const selectstmt = parser.stmt().selectstmt();
1561
+ const { columns, multipleRowsResult } = traverseSelectstmt(selectstmt, context, traverseResult);
1562
+ return {
1563
+ columns: columns.map((c) => (Object.assign(Object.assign({}, c), { table_name: funcSchema.function_name }))),
1564
+ singleRow: !multipleRowsResult
1565
+ };
1566
+ }
1567
+ else {
1568
+ return {
1569
+ columns: functionColumns,
1570
+ singleRow: false
1571
+ };
1572
+ }
1573
+ }
1574
+ }
1575
+ throw Error('Stmt not supported: ' + func_expr_windowless.getText());
1576
+ }
1577
+ function traverse_relation_expr(relation_expr) {
1364
1578
  const qualified_name = relation_expr.qualified_name();
1365
- const name = traverse_qualified_name(qualified_name, dbSchema);
1579
+ const name = traverse_qualified_name(qualified_name);
1366
1580
  return name;
1367
1581
  }
1368
- function traverse_qualified_name(qualified_name, dbSchema) {
1582
+ function traverse_qualified_name(qualified_name) {
1369
1583
  var _a, _b;
1370
- const colid_name = qualified_name.colid() ? get_colid_text(qualified_name.colid(), dbSchema) : '';
1584
+ const colid_name = qualified_name.colid() ? get_colid_text(qualified_name.colid()) : '';
1371
1585
  const indirection_el_list = (_a = qualified_name.indirection()) === null || _a === void 0 ? void 0 : _a.indirection_el_list();
1372
1586
  if (indirection_el_list && indirection_el_list.length === 1) {
1373
1587
  return {
@@ -1380,22 +1594,22 @@ function traverse_qualified_name(qualified_name, dbSchema) {
1380
1594
  alias: ''
1381
1595
  };
1382
1596
  }
1383
- function get_colid_text(colid, dbSchema) {
1597
+ function get_colid_text(colid) {
1384
1598
  const identifier = colid.identifier();
1385
1599
  if (identifier) {
1386
- return traverse_identifier(identifier, dbSchema);
1600
+ return traverse_identifier(identifier);
1387
1601
  }
1388
1602
  const unreserved_keyword = colid.unreserved_keyword();
1389
1603
  if (unreserved_keyword) {
1390
- return traverse_unreserved_keyword(unreserved_keyword, dbSchema);
1604
+ return traverse_unreserved_keyword(unreserved_keyword);
1391
1605
  }
1392
1606
  return '';
1393
1607
  }
1394
- function traverse_identifier(identifier, dbSchema) {
1608
+ function traverse_identifier(identifier) {
1395
1609
  const tableName = identifier.Identifier().getText();
1396
1610
  return tableName;
1397
1611
  }
1398
- function traverse_unreserved_keyword(unreserved_keyword, dbSchema) {
1612
+ function traverse_unreserved_keyword(unreserved_keyword) {
1399
1613
  return unreserved_keyword.getText();
1400
1614
  }
1401
1615
  function paramIsList(c_expr) {
@@ -1430,8 +1644,7 @@ function paramIsList(c_expr) {
1430
1644
  function traverseInsertstmt(insertstmt, dbSchema) {
1431
1645
  const traverseResult = {
1432
1646
  columnsNullability: [],
1433
- parameters: [],
1434
- singleRow: false
1647
+ parameters: []
1435
1648
  };
1436
1649
  const insert_target = insertstmt.insert_target();
1437
1650
  const tableName = insert_target.getText();
@@ -1443,7 +1656,10 @@ function traverseInsertstmt(insertstmt, dbSchema) {
1443
1656
  const context = {
1444
1657
  dbSchema,
1445
1658
  fromColumns: insertColumns,
1659
+ parentColumns: [],
1660
+ withColumns: [],
1446
1661
  checkConstraints: {},
1662
+ userFunctions: [],
1447
1663
  collectNestedInfo: false,
1448
1664
  collectDynamicQueryInfo: false
1449
1665
  };
@@ -1479,7 +1695,10 @@ function traverseDeletestmt(deleteStmt, dbSchema, traverseResult) {
1479
1695
  const context = {
1480
1696
  dbSchema,
1481
1697
  fromColumns: deleteColumns,
1698
+ parentColumns: [],
1699
+ withColumns: [],
1482
1700
  checkConstraints: {},
1701
+ userFunctions: [],
1483
1702
  collectNestedInfo: false,
1484
1703
  collectDynamicQueryInfo: false
1485
1704
  };
@@ -1514,12 +1733,12 @@ function traverseUpdatestmt(updatestmt, traverseContext, traverseResult) {
1514
1733
  updatestmt.set_clause_list().set_clause_list()
1515
1734
  .forEach(set_clause => traverse_set_clause(set_clause, context, traverseResult));
1516
1735
  const from_clause = updatestmt.from_clause();
1517
- const fromColumns = from_clause ? traverse_from_clause(from_clause, context, traverseResult) : [];
1736
+ const fromResult = from_clause ? traverse_from_clause(from_clause, context, traverseResult) : { columns: [], singleRow: true };
1518
1737
  const parametersBefore = traverseResult.parameters.length;
1519
1738
  const where_clause = updatestmt.where_or_current_clause();
1520
1739
  if (where_clause) {
1521
1740
  const a_expr = where_clause.a_expr();
1522
- traverse_a_expr(a_expr, Object.assign(Object.assign({}, context), { fromColumns: updateColumns.concat(fromColumns) }), traverseResult);
1741
+ traverse_a_expr(a_expr, Object.assign(Object.assign({}, context), { fromColumns: updateColumns.concat(fromResult.columns) }), traverseResult);
1523
1742
  }
1524
1743
  const whereParameters = traverseResult.parameters.slice(parametersBefore);
1525
1744
  const returning_clause = updatestmt.returning_clause();
@@ -1694,12 +1913,12 @@ function mapAddExprType(types) {
1694
1913
  };
1695
1914
  let currentType = 'int2';
1696
1915
  for (const type of types) {
1697
- if (type === 'unknow') {
1698
- return 'unknow';
1916
+ if (type === 'unknown') {
1917
+ return 'unknown';
1699
1918
  }
1700
1919
  currentType = arithmeticMatrix[currentType][type];
1701
1920
  if (!currentType) {
1702
- return 'unknow';
1921
+ return 'unknown';
1703
1922
  }
1704
1923
  }
1705
1924
  return currentType;
@@ -1784,7 +2003,7 @@ function isParameter(str) {
1784
2003
  const paramPattern = /^\$[0-9]+(::[a-zA-Z_][a-zA-Z0-9_]*)?$/;
1785
2004
  return paramPattern.test(str);
1786
2005
  }
1787
- function isSingleRowResult(selectstmt, dbSchema) {
2006
+ function isSingleRowResult(selectstmt, fromColumns) {
1788
2007
  var _a, _b;
1789
2008
  const limit = checkLimit(selectstmt);
1790
2009
  if (limit === 1) {
@@ -1817,9 +2036,7 @@ function isSingleRowResult(selectstmt, dbSchema) {
1817
2036
  }
1818
2037
  const where_clause = simple_select_pramary.where_clause();
1819
2038
  if (where_clause) {
1820
- const tableName = getTableName(table_ref_list[0]);
1821
- const uniqueKeys = dbSchema.filter(col => col.table_name.toLowerCase() === tableName.name.toLowerCase()
1822
- && (col.column_key === 'PRI' || col.column_key === 'UNI'))
2039
+ const uniqueKeys = fromColumns.filter(col => col.column_key === 'PRI' || col.column_key === 'UNI')
1823
2040
  .map(col => col.column_name);
1824
2041
  return isSingleRowResult_where(where_clause.a_expr(), uniqueKeys);
1825
2042
  }