typesql-cli 0.15.1 → 0.15.3

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 (42) hide show
  1. package/README.md +1 -1
  2. package/code-generator.d.ts +1 -1
  3. package/code-generator.d.ts.map +1 -1
  4. package/code-generator.js +2 -2
  5. package/code-generator.js.map +1 -1
  6. package/code-generator2.d.ts.map +1 -1
  7. package/code-generator2.js +354 -26
  8. package/code-generator2.js.map +1 -1
  9. package/drivers/postgres.d.ts +1 -3
  10. package/drivers/postgres.d.ts.map +1 -1
  11. package/drivers/postgres.js +0 -10
  12. package/drivers/postgres.js.map +1 -1
  13. package/drivers/sqlite.d.ts +5 -0
  14. package/drivers/sqlite.d.ts.map +1 -0
  15. package/drivers/sqlite.js +37 -0
  16. package/drivers/sqlite.js.map +1 -0
  17. package/package.json +5 -2
  18. package/postgres-query-analyzer/describe.d.ts.map +1 -1
  19. package/postgres-query-analyzer/describe.js +35 -10
  20. package/postgres-query-analyzer/describe.js.map +1 -1
  21. package/postgres-query-analyzer/parser.d.ts +2 -2
  22. package/postgres-query-analyzer/parser.d.ts.map +1 -1
  23. package/postgres-query-analyzer/parser.js +4 -4
  24. package/postgres-query-analyzer/parser.js.map +1 -1
  25. package/postgres-query-analyzer/traverse.d.ts +23 -2
  26. package/postgres-query-analyzer/traverse.d.ts.map +1 -1
  27. package/postgres-query-analyzer/traverse.js +509 -204
  28. package/postgres-query-analyzer/traverse.js.map +1 -1
  29. package/sqlite-query-analyzer/code-generator.d.ts +9 -2
  30. package/sqlite-query-analyzer/code-generator.d.ts.map +1 -1
  31. package/sqlite-query-analyzer/code-generator.js +13 -38
  32. package/sqlite-query-analyzer/code-generator.js.map +1 -1
  33. package/sqlite-query-analyzer/sqlite-describe-nested-query.d.ts +2 -0
  34. package/sqlite-query-analyzer/sqlite-describe-nested-query.d.ts.map +1 -1
  35. package/sqlite-query-analyzer/sqlite-describe-nested-query.js +12 -7
  36. package/sqlite-query-analyzer/sqlite-describe-nested-query.js.map +1 -1
  37. package/sqlite-query-analyzer/traverse.d.ts +5 -1
  38. package/sqlite-query-analyzer/traverse.d.ts.map +1 -1
  39. package/sqlite-query-analyzer/traverse.js +11 -2
  40. package/sqlite-query-analyzer/traverse.js.map +1 -1
  41. package/ts-nested-descriptor.js +1 -1
  42. package/ts-nested-descriptor.js.map +1 -1
@@ -1,18 +1,44 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultOptions = defaultOptions;
3
4
  exports.traverseSmt = traverseSmt;
4
5
  const PostgreSQLParser_1 = require("@wsporto/typesql-parser/postgres/PostgreSQLParser");
5
6
  const typesql_parser_1 = require("@wsporto/typesql-parser");
6
7
  const select_columns_1 = require("../mysql-query-analyzer/select-columns");
7
- function traverseSmt(stmt, dbSchema) {
8
+ function defaultOptions() {
9
+ return {
10
+ collectNestedInfo: false,
11
+ collectDynamicQueryInfo: false
12
+ };
13
+ }
14
+ function traverseSmt(stmt, dbSchema, options) {
15
+ const { collectNestedInfo = false, collectDynamicQueryInfo = false } = options;
8
16
  const traverseResult = {
9
17
  columnsNullability: [],
10
18
  parameters: [],
11
19
  singleRow: false
12
20
  };
21
+ if (collectNestedInfo) {
22
+ traverseResult.relations = [];
23
+ }
24
+ if (collectDynamicQueryInfo) {
25
+ const dynamicQueryInfo = {
26
+ with: [],
27
+ select: [],
28
+ from: [],
29
+ where: []
30
+ };
31
+ traverseResult.dynamicQueryInfo = dynamicQueryInfo;
32
+ }
33
+ const traverseContext = {
34
+ dbSchema,
35
+ collectNestedInfo,
36
+ collectDynamicQueryInfo,
37
+ fromColumns: []
38
+ };
13
39
  const selectstmt = stmt.selectstmt();
14
40
  if (selectstmt) {
15
- const result = traverseSelectstmt(selectstmt, dbSchema, [], traverseResult);
41
+ const result = traverseSelectstmt(selectstmt, traverseContext, traverseResult);
16
42
  return result;
17
43
  }
18
44
  const insertstmt = stmt.insertstmt();
@@ -42,114 +68,183 @@ function collectContextsOfType(ctx, targetType) {
42
68
  });
43
69
  return results;
44
70
  }
45
- function traverseSelectstmt(selectstmt, dbSchema, fromColumns, traverseResult) {
71
+ function traverseSelectstmt(selectstmt, context, traverseResult) {
46
72
  const result = collectContextsOfType(selectstmt, PostgreSQLParser_1.C_expr_exprContext).filter(c_expr => c_expr.PARAM());
47
73
  const paramIsListResult = result.map(param => paramIsList(param));
48
- const columns = traverse_selectstmt(selectstmt, dbSchema, fromColumns, traverseResult);
74
+ const columns = traverse_selectstmt(selectstmt, context, traverseResult);
49
75
  //select parameters are collected after from paramters
50
76
  traverseResult.parameters.sort((param1, param2) => param1.paramIndex - param2.paramIndex);
51
- const columnsNullability = columns.map(col => !col.is_nullable);
52
- const multipleRowsResult = !isSingleRowResult(selectstmt, dbSchema);
77
+ const multipleRowsResult = !isSingleRowResult(selectstmt, context.dbSchema);
53
78
  const limit = checkLimit(selectstmt);
54
- return {
79
+ const postgresTraverseResult = {
55
80
  queryType: 'Select',
56
81
  multipleRowsResult,
57
- columnsNullability,
82
+ columns,
58
83
  parametersNullability: traverseResult.parameters.map(param => param.isNotNull),
59
84
  parameterList: paramIsListResult,
60
85
  limit
61
86
  };
87
+ if (traverseResult.relations) {
88
+ postgresTraverseResult.relations = traverseResult.relations;
89
+ }
90
+ if (traverseResult.dynamicQueryInfo) {
91
+ postgresTraverseResult.dynamicQueryInfo = traverseResult.dynamicQueryInfo;
92
+ }
93
+ return postgresTraverseResult;
62
94
  }
63
- function traverse_selectstmt(selectstmt, dbSchema, fromColumns, traverseResult) {
95
+ function traverse_selectstmt(selectstmt, context, traverseResult) {
64
96
  const select_no_parens = selectstmt.select_no_parens();
65
97
  if (select_no_parens) {
66
- return traverse_select_no_parens(select_no_parens, dbSchema, fromColumns, traverseResult);
98
+ return traverse_select_no_parens(select_no_parens, context, traverseResult);
67
99
  }
68
100
  return [];
69
101
  }
70
- function traverse_select_no_parens(select_no_parens, dbSchema, fromColumns, traverseResult) {
102
+ function traverse_select_no_parens(select_no_parens, context, traverseResult) {
71
103
  let withColumns = [];
72
104
  const with_clause = select_no_parens.with_clause();
73
105
  if (with_clause) {
74
106
  with_clause.cte_list().common_table_expr_list()
75
107
  .forEach(common_table_expr => {
76
- const withResult = traverse_common_table_expr(common_table_expr, dbSchema, withColumns.concat(fromColumns), traverseResult);
108
+ const newContext = Object.assign(Object.assign({}, context), { fromColumns: withColumns.concat(context.fromColumns) });
109
+ const withResult = traverse_common_table_expr(common_table_expr, newContext, traverseResult);
77
110
  withColumns.push(...withResult);
78
111
  });
79
112
  }
80
113
  const select_clause = select_no_parens.select_clause();
81
- if (select_clause) {
82
- return traverse_select_clause(select_clause, dbSchema, withColumns.concat(fromColumns), traverseResult);
114
+ const newContext = Object.assign(Object.assign({}, context), { fromColumns: withColumns.concat(context.fromColumns) });
115
+ const selectResult = traverse_select_clause(select_clause, newContext, traverseResult);
116
+ const select_limit = select_no_parens.select_limit();
117
+ if (select_limit) {
118
+ const numParamsBefore = traverseResult.parameters.length;
119
+ const limit_clause = select_limit.limit_clause();
120
+ const limit_a_expr = limit_clause.select_limit_value().a_expr();
121
+ traverse_a_expr(limit_a_expr, context, traverseResult);
122
+ let fragment = '';
123
+ if (limit_clause) {
124
+ if (context.collectDynamicQueryInfo) {
125
+ fragment += (0, select_columns_1.extractOriginalSql)(limit_clause);
126
+ }
127
+ }
128
+ const offset_clause = select_limit.offset_clause();
129
+ if (offset_clause) {
130
+ const offset_a_expr = offset_clause.select_offset_value().a_expr();
131
+ traverse_a_expr(offset_a_expr, context, traverseResult);
132
+ if (context.collectDynamicQueryInfo) {
133
+ fragment += ' ' + (0, select_columns_1.extractOriginalSql)(offset_clause);
134
+ }
135
+ }
136
+ if (fragment) {
137
+ const parameters = traverseResult.parameters.slice(numParamsBefore).map((_, index) => index + numParamsBefore);
138
+ traverseResult.dynamicQueryInfo.limitOffset = {
139
+ fragment,
140
+ parameters
141
+ };
142
+ }
83
143
  }
84
- return [];
144
+ return selectResult;
85
145
  }
86
- function traverse_common_table_expr(common_table_expr, dbSchema, fromColumns, traverseResult) {
146
+ function traverse_common_table_expr(common_table_expr, context, traverseResult) {
147
+ var _a;
87
148
  const tableName = common_table_expr.name().getText();
88
149
  const select_stmt = common_table_expr.preparablestmt().selectstmt();
89
- if (select_stmt) {
90
- const columns = traverse_selectstmt(select_stmt, dbSchema, fromColumns, traverseResult);
91
- const columnsWithTalbeName = columns.map(col => (Object.assign(Object.assign({}, col), { table_name: tableName })));
92
- return columnsWithTalbeName;
150
+ const numParamsBefore = traverseResult.parameters.length;
151
+ const columns = traverse_selectstmt(select_stmt, Object.assign(Object.assign({}, context), { collectDynamicQueryInfo: false }), traverseResult);
152
+ const columnsWithTalbeName = columns.map(col => (Object.assign(Object.assign({}, col), { table_name: tableName })));
153
+ if (context.collectDynamicQueryInfo) {
154
+ const parameters = traverseResult.parameters.slice(numParamsBefore).map((_, index) => index + numParamsBefore);
155
+ (_a = traverseResult.dynamicQueryInfo) === null || _a === void 0 ? void 0 : _a.with.push({
156
+ fragment: (0, select_columns_1.extractOriginalSql)(common_table_expr),
157
+ relationName: tableName,
158
+ parameters
159
+ });
93
160
  }
94
- return [];
161
+ return columnsWithTalbeName;
95
162
  }
96
- function traverse_select_clause(select_clause, dbSchema, fromColumns, traverseResult) {
163
+ function traverse_select_clause(select_clause, context, traverseResult) {
97
164
  const simple_select_intersect_list = select_clause.simple_select_intersect_list();
98
165
  let selectColumns = [];
99
166
  if (simple_select_intersect_list) {
100
- selectColumns = traverse_simple_select_intersect(simple_select_intersect_list[0], dbSchema, fromColumns, traverseResult);
167
+ selectColumns = traverse_simple_select_intersect(simple_select_intersect_list[0], context, traverseResult);
101
168
  }
102
169
  //union
103
170
  for (let index = 1; index < simple_select_intersect_list.length; index++) {
104
- const unionNotNull = traverse_simple_select_intersect(simple_select_intersect_list[index], dbSchema, fromColumns, traverseResult);
171
+ const unionNotNull = traverse_simple_select_intersect(simple_select_intersect_list[index], context, traverseResult);
105
172
  selectColumns = selectColumns.map((value, columnIndex) => {
106
- const col = Object.assign(Object.assign({}, value), { is_nullable: value.is_nullable || unionNotNull[columnIndex].is_nullable });
173
+ const col = {
174
+ column_name: value.column_name,
175
+ is_nullable: value.is_nullable || unionNotNull[columnIndex].is_nullable,
176
+ table_name: '',
177
+ table_schema: ''
178
+ };
107
179
  return col;
108
180
  });
109
181
  }
110
182
  return selectColumns;
111
183
  }
112
- function traverse_simple_select_intersect(simple_select_intersect, dbSchema, fromColumns, traverseResult) {
184
+ function traverse_simple_select_intersect(simple_select_intersect, context, traverseResult) {
113
185
  const simple_select_pramary = simple_select_intersect.simple_select_pramary_list()[0];
114
186
  if (simple_select_pramary) {
115
- return traverse_simple_select_pramary(simple_select_pramary, dbSchema, fromColumns, traverseResult);
187
+ return traverse_simple_select_pramary(simple_select_pramary, context, traverseResult);
116
188
  }
117
189
  return [];
118
190
  }
119
- function traverse_simple_select_pramary(simple_select_pramary, dbSchema, parentFromColumns, traverseResult) {
120
- var _a;
191
+ function traverse_simple_select_pramary(simple_select_pramary, context, traverseResult) {
192
+ var _a, _b;
121
193
  const fromColumns = [];
122
194
  const from_clause = simple_select_pramary.from_clause();
123
195
  if (from_clause) {
124
196
  const where_clause = simple_select_pramary.where_clause();
125
- const fields = traverse_from_clause(from_clause, dbSchema, parentFromColumns, traverseResult);
197
+ const fields = traverse_from_clause(from_clause, context, traverseResult);
126
198
  const fieldsNotNull = where_clause != null ? fields.map(field => checkIsNullable(where_clause, field)) : fields;
127
199
  fromColumns.push(...fieldsNotNull);
128
200
  }
129
201
  const values_clause = simple_select_pramary.values_clause();
130
202
  if (values_clause) {
131
- const valuesColumns = traverse_values_clause(values_clause, dbSchema, parentFromColumns, traverseResult);
203
+ const valuesColumns = traverse_values_clause(values_clause, context, traverseResult);
132
204
  return valuesColumns;
133
205
  }
134
206
  const where_a_expr = (_a = simple_select_pramary.where_clause()) === null || _a === void 0 ? void 0 : _a.a_expr();
207
+ //fromColumns has precedence
208
+ const newContext = Object.assign(Object.assign({}, context), { fromColumns: fromColumns.concat(context.fromColumns) });
135
209
  if (where_a_expr) {
136
- traverse_a_expr(where_a_expr, dbSchema, parentFromColumns.concat(fromColumns), traverseResult);
210
+ const numParamsBefore = traverseResult.parameters.length;
211
+ traverse_a_expr(where_a_expr, newContext, traverseResult);
212
+ if (context.collectDynamicQueryInfo) {
213
+ const parameters = traverseResult.parameters.slice(numParamsBefore).map((_, index) => index + numParamsBefore);
214
+ const relations = extractRelations(where_a_expr);
215
+ (_b = traverseResult.dynamicQueryInfo) === null || _b === void 0 ? void 0 : _b.where.push({
216
+ fragment: `AND ${(0, select_columns_1.extractOriginalSql)(where_a_expr)}`,
217
+ parameters,
218
+ dependOnRelations: relations
219
+ });
220
+ }
137
221
  }
138
- const filteredColumns = filterColumns_simple_select_pramary(simple_select_pramary, dbSchema, parentFromColumns.concat(fromColumns), traverseResult);
222
+ const filteredColumns = filterColumns_simple_select_pramary(simple_select_pramary, newContext, traverseResult);
139
223
  return filteredColumns;
140
224
  }
141
- function traverse_values_clause(values_clause, dbSchema, fromColumns, traverseResult) {
225
+ function extractRelations(a_expr) {
226
+ const columnsRef = collectContextsOfType(a_expr, PostgreSQLParser_1.ColumnrefContext);
227
+ const relations = columnsRef
228
+ .map((colRefExpr) => {
229
+ const colRef = colRefExpr;
230
+ const tableName = (0, select_columns_1.splitName)(colRef.getText());
231
+ return tableName;
232
+ });
233
+ const uniqueRelations = [...new Set(relations.map(relation => relation.prefix))];
234
+ return uniqueRelations;
235
+ }
236
+ function traverse_values_clause(values_clause, context, traverseResult) {
142
237
  const expr_list_list = values_clause.expr_list_list();
143
238
  if (expr_list_list) {
144
- return expr_list_list.flatMap(expr_list => traverse_expr_list(expr_list, dbSchema, fromColumns, traverseResult));
239
+ return expr_list_list.flatMap(expr_list => traverse_expr_list(expr_list, context, traverseResult));
145
240
  }
146
241
  return [];
147
242
  }
148
- function traverse_expr_list(expr_list, dbSchema, fromColumns, traverseResult) {
243
+ function traverse_expr_list(expr_list, context, traverseResult) {
149
244
  const columns = expr_list.a_expr_list().map(a_expr => {
150
- const notNull = traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult);
245
+ const notNull = traverse_a_expr(a_expr, context, traverseResult);
151
246
  const result = {
152
- column_name: a_expr.getText(),
247
+ column_name: '?column?',
153
248
  is_nullable: !notNull,
154
249
  table_name: '',
155
250
  table_schema: ''
@@ -158,234 +253,307 @@ function traverse_expr_list(expr_list, dbSchema, fromColumns, traverseResult) {
158
253
  });
159
254
  return columns;
160
255
  }
161
- function filterColumns_simple_select_pramary(simple_select_pramary, dbSchema, fromColumns, traverseResult) {
256
+ function filterColumns_simple_select_pramary(simple_select_pramary, context, traverseResult) {
162
257
  const target_list_ = simple_select_pramary.target_list_();
163
258
  if (target_list_) {
164
259
  const target_list = target_list_.target_list();
165
260
  if (target_list) {
166
- return traverse_target_list(target_list, dbSchema, fromColumns, traverseResult);
261
+ return traverse_target_list(target_list, context, traverseResult);
167
262
  }
168
263
  }
169
264
  const target_list = simple_select_pramary.target_list();
170
265
  if (target_list) {
171
- return traverse_target_list(target_list, dbSchema, fromColumns, traverseResult);
266
+ return traverse_target_list(target_list, context, traverseResult);
172
267
  }
173
268
  return [];
174
269
  }
175
- function traverse_target_list(target_list, dbSchema, fromColumns, traverseResult) {
270
+ function traverse_target_list(target_list, context, traverseResult) {
176
271
  const columns = target_list.target_el_list().flatMap(target_el => {
177
272
  const fieldName = (0, select_columns_1.splitName)(target_el.getText());
178
273
  if (fieldName.name == '*') {
179
- const columns = filterColumns(fromColumns, fieldName);
274
+ const columns = filterColumns(context.fromColumns, fieldName);
275
+ if (context.collectDynamicQueryInfo) {
276
+ columns.forEach(col => {
277
+ var _a;
278
+ (_a = traverseResult.dynamicQueryInfo) === null || _a === void 0 ? void 0 : _a.select.push({
279
+ fragment: `${col.table_name}.${col.column_name}`,
280
+ fragmentWitoutAlias: `${col.table_name}.${col.column_name}`,
281
+ dependOnRelations: [col.table_name],
282
+ parameters: []
283
+ });
284
+ });
285
+ }
180
286
  return columns;
181
287
  }
182
- const column = isNotNull_target_el(target_el, dbSchema, fromColumns, traverseResult);
288
+ const column = traverse_target_el(target_el, context, traverseResult);
183
289
  return [column];
184
290
  });
185
291
  return columns;
186
292
  }
187
- function isNotNull_target_el(target_el, dbSchema, fromColumns, traverseResult) {
293
+ function traverse_target_el(target_el, context, traverseResult) {
294
+ var _a, _b;
188
295
  if (target_el instanceof PostgreSQLParser_1.Target_labelContext) {
189
296
  const a_expr = target_el.a_expr();
190
- const exprResult = traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult);
297
+ const numParamsBefore = traverseResult.parameters.length;
298
+ const exprResult = traverse_a_expr(a_expr, context, traverseResult);
191
299
  const colLabel = target_el.colLabel();
192
300
  const alias = colLabel != null ? colLabel.getText() : '';
193
- const fieldName = (0, select_columns_1.splitName)(a_expr.getText());
301
+ if (alias) {
302
+ (_a = traverseResult.relations) === null || _a === void 0 ? void 0 : _a.forEach(relation => {
303
+ if ((relation.name === exprResult.table_name || relation.alias === exprResult.table_name)
304
+ && relation.joinColumn === exprResult.column_name) {
305
+ relation.joinColumn = alias;
306
+ }
307
+ });
308
+ }
309
+ if (context.collectDynamicQueryInfo) {
310
+ const parameters = traverseResult.parameters.slice(numParamsBefore).map((_, index) => index + numParamsBefore);
311
+ const relations = extractRelations(target_el.a_expr());
312
+ (_b = traverseResult.dynamicQueryInfo) === null || _b === void 0 ? void 0 : _b.select.push({
313
+ fragment: (0, select_columns_1.extractOriginalSql)(target_el),
314
+ fragmentWitoutAlias: (0, select_columns_1.extractOriginalSql)(target_el.a_expr()),
315
+ dependOnRelations: relations,
316
+ parameters
317
+ });
318
+ }
194
319
  return {
195
- column_name: alias || fieldName.name,
320
+ column_name: alias || exprResult.column_name,
196
321
  is_nullable: exprResult.is_nullable,
197
- table_name: fieldName.prefix,
198
- table_schema: ''
322
+ table_name: exprResult.table_name,
323
+ table_schema: exprResult.table_schema
199
324
  };
200
325
  }
201
326
  throw Error('Column not found');
202
327
  }
203
- function traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult) {
328
+ function traverse_a_expr(a_expr, context, traverseResult) {
204
329
  const a_expr_qual = a_expr.a_expr_qual();
205
330
  if (a_expr_qual) {
206
- const notNull = traverse_a_expr_qual(a_expr_qual, dbSchema, fromColumns, traverseResult);
331
+ const notNull = traverse_a_expr_qual(a_expr_qual, context, traverseResult);
207
332
  return notNull;
208
333
  }
209
334
  return {
210
335
  column_name: '',
211
- is_nullable: true
336
+ is_nullable: true,
337
+ table_name: '',
338
+ table_schema: ''
212
339
  };
213
340
  }
214
- function traverse_a_expr_qual(a_expr_qual, dbSchema, fromColumns, traverseResult) {
341
+ function traverse_a_expr_qual(a_expr_qual, context, traverseResult) {
215
342
  const a_expr_lessless = a_expr_qual.a_expr_lessless();
216
343
  if (a_expr_lessless) {
217
- return traverse_a_expr_lessless(a_expr_lessless, dbSchema, fromColumns, traverseResult);
344
+ return traverse_a_expr_lessless(a_expr_lessless, context, traverseResult);
218
345
  }
219
346
  throw Error('traverse_a_expr_qual - Not expected:' + a_expr_qual.getText());
220
347
  }
221
- function traverse_a_expr_lessless(a_expr_lessless, dbSchema, fromColumns, traverseResult) {
348
+ function traverse_a_expr_lessless(a_expr_lessless, context, traverseResult) {
222
349
  const a_expr_or = a_expr_lessless.a_expr_or_list()[0];
223
350
  if (a_expr_or) {
224
- return traverse_expr_or(a_expr_or, dbSchema, fromColumns, traverseResult);
351
+ return traverse_expr_or(a_expr_or, context, traverseResult);
225
352
  }
226
353
  throw Error('traverse_a_expr_lessless - Not expected:' + a_expr_lessless.getText());
227
354
  }
228
- function traverse_expr_or(a_expr_or, dbSchema, fromColumns, traverseResult) {
229
- const a_expr_and = a_expr_or.a_expr_and_list()[0];
230
- if (a_expr_and) {
231
- return traverse_expr_and(a_expr_and, dbSchema, fromColumns, traverseResult);
355
+ function traverse_expr_or(a_expr_or, context, traverseResult) {
356
+ // expr1 OR expr2
357
+ const result = a_expr_or.a_expr_and_list().map(a_expr_and => traverse_expr_and(a_expr_and, context, traverseResult));
358
+ if (result.length === 1) {
359
+ return result[0];
232
360
  }
233
- throw Error('traverse_expr_or - Not expected:' + a_expr_or.getText());
361
+ return {
362
+ column_name: '?column?',
363
+ is_nullable: result.some(col => col.is_nullable),
364
+ table_name: '',
365
+ table_schema: ''
366
+ };
234
367
  }
235
- function traverse_expr_and(a_expr_and, dbSchema, fromColumns, traverseResult) {
236
- const result = a_expr_and.a_expr_between_list().map(a_expr_between => traverse_expr_between(a_expr_between, dbSchema, fromColumns, traverseResult));
368
+ function traverse_expr_and(a_expr_and, context, traverseResult) {
369
+ const result = a_expr_and.a_expr_between_list().map(a_expr_between => traverse_expr_between(a_expr_between, context, traverseResult));
370
+ if (result.length === 1) {
371
+ return result[0];
372
+ }
237
373
  return {
238
- column_name: a_expr_and.getText(),
239
- is_nullable: result.some(col => col.is_nullable)
374
+ column_name: '?column?',
375
+ is_nullable: result.some(col => col.is_nullable),
376
+ table_name: '',
377
+ table_schema: ''
240
378
  };
241
379
  }
242
- function traverse_expr_between(a_expr_between, dbSchema, fromColumns, traverseResult) {
380
+ function traverse_expr_between(a_expr_between, context, traverseResult) {
243
381
  const a_expr_in = a_expr_between.a_expr_in_list()[0];
244
382
  if (a_expr_in) {
245
- return traverse_expr_in(a_expr_in, dbSchema, fromColumns, traverseResult);
383
+ return traverse_expr_in(a_expr_in, context, traverseResult);
246
384
  }
247
385
  throw Error('traverse_expr_between - Not expected:' + a_expr_between.getText());
248
386
  }
249
- function traverse_expr_in(a_expr_in, dbSchema, fromColumns, traverseResult) {
387
+ function traverse_expr_in(a_expr_in, context, traverseResult) {
250
388
  const a_expr_unary = a_expr_in.a_expr_unary_not();
251
389
  let leftExprResult = undefined;
252
390
  if (a_expr_unary) {
253
- leftExprResult = traverse_expr_unary(a_expr_unary, dbSchema, fromColumns, traverseResult);
391
+ leftExprResult = traverse_expr_unary(a_expr_unary, context, traverseResult);
254
392
  }
255
393
  const in_expr = a_expr_in.in_expr();
256
394
  if (in_expr) {
257
- traverse_in_expr(in_expr, dbSchema, fromColumns, traverseResult);
395
+ traverse_in_expr(in_expr, context, traverseResult);
396
+ }
397
+ if (in_expr === null && leftExprResult != null) {
398
+ return leftExprResult;
258
399
  }
259
400
  return {
260
401
  column_name: a_expr_in.getText(),
261
402
  //id in (...) -> is_nullable: false
262
403
  // value -> is_nullable = leftExprResult.is_nullable
263
- is_nullable: in_expr != null ? false : leftExprResult.is_nullable
404
+ is_nullable: in_expr != null ? false : leftExprResult.is_nullable,
405
+ table_name: '',
406
+ table_schema: ''
264
407
  };
265
408
  }
266
- function traverse_in_expr(in_expr, dbSchema, fromColumns, traverseResult) {
409
+ function traverse_in_expr(in_expr, context, traverseResult) {
267
410
  if (in_expr instanceof PostgreSQLParser_1.In_expr_selectContext) {
268
411
  const select_with_parens = in_expr.select_with_parens();
269
- traverse_select_with_parens(select_with_parens, dbSchema, fromColumns, traverseResult);
412
+ traverse_select_with_parens(select_with_parens, context, traverseResult);
270
413
  }
271
414
  if (in_expr instanceof PostgreSQLParser_1.In_expr_listContext) {
272
415
  in_expr.expr_list().a_expr_list().forEach(a_expr => {
273
- traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult);
416
+ traverse_a_expr(a_expr, context, traverseResult);
274
417
  });
275
418
  }
276
419
  }
277
- function traverse_expr_unary(a_expr_unary, dbSchema, fromColumns, traverseResult) {
420
+ function traverse_expr_unary(a_expr_unary, context, traverseResult) {
278
421
  const a_expr_isnull = a_expr_unary.a_expr_isnull();
279
422
  if (a_expr_isnull) {
280
- return traverse_expr_isnull(a_expr_isnull, dbSchema, fromColumns, traverseResult);
423
+ return traverse_expr_isnull(a_expr_isnull, context, traverseResult);
281
424
  }
282
425
  throw Error('traverse_expr_unary - Not expected:' + a_expr_unary.getText());
283
426
  }
284
- function traverse_expr_isnull(a_expr_isnull, dbSchema, fromColumns, traverseResult) {
427
+ function traverse_expr_isnull(a_expr_isnull, context, traverseResult) {
285
428
  const a_expr_is_not = a_expr_isnull.a_expr_is_not();
286
429
  if (a_expr_is_not) {
287
- return traverse_expr_is_not(a_expr_is_not, dbSchema, fromColumns, traverseResult);
430
+ return traverse_expr_is_not(a_expr_is_not, context, traverseResult);
288
431
  }
289
432
  throw Error('traverse_expr_isnull - Not expected:' + a_expr_isnull.getText());
290
433
  }
291
- function traverse_expr_is_not(a_expr_is_not, dbSchema, fromColumns, traverseResult) {
434
+ function traverse_expr_is_not(a_expr_is_not, context, traverseResult) {
292
435
  const a_expr_compare = a_expr_is_not.a_expr_compare();
293
436
  if (a_expr_compare) {
294
- return traverse_expr_compare(a_expr_compare, dbSchema, fromColumns, traverseResult);
437
+ return traverse_expr_compare(a_expr_compare, context, traverseResult);
295
438
  }
296
439
  throw Error('traverse_expr_is_not - Not expected:' + a_expr_is_not.getText());
297
440
  }
298
- function traverse_expr_compare(a_expr_compare, dbSchema, fromColumns, traverseResult) {
441
+ function traverse_expr_compare(a_expr_compare, context, traverseResult) {
299
442
  const a_expr_like_list = a_expr_compare.a_expr_like_list();
300
443
  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));
444
+ const result = a_expr_like_list.map(a_expr_like => traverse_expr_like(a_expr_like, context, traverseResult));
445
+ if (result.length === 1) {
446
+ return result[0];
447
+ }
302
448
  return {
303
- column_name: a_expr_compare.getText(),
304
- is_nullable: result.some(col => col.is_nullable)
449
+ column_name: '?column?',
450
+ is_nullable: result.some(col => col.is_nullable),
451
+ table_name: '',
452
+ table_schema: ''
305
453
  };
306
454
  }
307
455
  throw Error('traverse_expr_compare - Not expected:' + a_expr_compare.getText());
308
456
  }
309
- function traverse_expr_like(a_expr_like, dbSchema, fromColumns, traverseResult) {
457
+ function traverse_expr_like(a_expr_like, context, traverseResult) {
310
458
  const a_expr_qual_op_list = a_expr_like.a_expr_qual_op_list();
311
459
  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));
460
+ const result = a_expr_qual_op_list.map(a_expr_qual_op => traverse_expr_qual_op(a_expr_qual_op, context, traverseResult));
461
+ if (result.length === 1) {
462
+ return result[0];
463
+ }
313
464
  return {
314
- column_name: a_expr_like.getText(),
315
- is_nullable: result.some(col => col.is_nullable)
465
+ column_name: '?column?',
466
+ is_nullable: result.some(col => col.is_nullable),
467
+ table_name: '',
468
+ table_schema: ''
316
469
  };
317
470
  }
318
471
  throw Error('traverse_expr_like - Not expected:' + a_expr_like.getText());
319
472
  }
320
- function traverse_expr_qual_op(a_expr_qual_op, dbSchema, fromColumns, traverseResult) {
473
+ function traverse_expr_qual_op(a_expr_qual_op, context, traverseResult) {
321
474
  const a_expr_unary_qualop = a_expr_qual_op.a_expr_unary_qualop_list()[0];
322
475
  if (a_expr_unary_qualop) {
323
- return traverse_expr_unary_qualop(a_expr_unary_qualop, dbSchema, fromColumns, traverseResult);
476
+ return traverse_expr_unary_qualop(a_expr_unary_qualop, context, traverseResult);
324
477
  }
325
478
  throw Error('traverse_expr_qual_op - Not expected:' + a_expr_qual_op.getText());
326
479
  }
327
- function traverse_expr_unary_qualop(a_expr_unary_qualop, dbSchema, fromColumns, traverseResult) {
480
+ function traverse_expr_unary_qualop(a_expr_unary_qualop, context, traverseResult) {
328
481
  const a_expr_add = a_expr_unary_qualop.a_expr_add();
329
482
  if (a_expr_add) {
330
- const exprResult = a_expr_add.a_expr_mul_list().map(a_expr_mul => traverse_expr_mul(a_expr_mul, dbSchema, fromColumns, traverseResult));
483
+ const exprResult = a_expr_add.a_expr_mul_list().map(a_expr_mul => traverse_expr_mul(a_expr_mul, context, traverseResult));
484
+ if (exprResult.length === 1) {
485
+ return exprResult[0];
486
+ }
331
487
  const result = {
332
- column_name: a_expr_unary_qualop.getText(),
333
- is_nullable: exprResult.some(col => col.is_nullable)
488
+ column_name: '?column?',
489
+ is_nullable: exprResult.some(col => col.is_nullable),
490
+ table_name: '',
491
+ table_schema: ''
334
492
  };
335
493
  return result;
336
494
  }
337
495
  throw Error('traverse_expr_unary_qualop - Not expected:' + a_expr_unary_qualop.getText());
338
496
  }
339
- function traverse_expr_mul(a_expr_mul, dbSchema, fromColumns, traverseResult) {
497
+ function traverse_expr_mul(a_expr_mul, context, traverseResult) {
340
498
  const a_expr_mul_list = a_expr_mul.a_expr_caret_list();
341
499
  if (a_expr_mul_list) {
342
- const notNullInfo = a_expr_mul.a_expr_caret_list().map(a_expr_caret => traverse_expr_caret(a_expr_caret, dbSchema, fromColumns, traverseResult));
500
+ const notNullInfo = a_expr_mul.a_expr_caret_list().map(a_expr_caret => traverse_expr_caret(a_expr_caret, context, traverseResult));
501
+ if (notNullInfo.length === 1) {
502
+ return notNullInfo[0];
503
+ }
343
504
  const result = {
344
- column_name: a_expr_mul.getText(),
345
- is_nullable: notNullInfo.some(notNullInfo => notNullInfo.is_nullable)
505
+ column_name: '?column?',
506
+ is_nullable: notNullInfo.some(notNullInfo => notNullInfo.is_nullable),
507
+ table_name: '',
508
+ table_schema: ''
346
509
  };
347
510
  return result;
348
511
  }
349
512
  throw Error('traverse_expr_mul - Not expected:' + a_expr_mul.getText());
350
513
  }
351
- function traverse_expr_caret(a_expr_caret, dbSchema, fromColumns, traverseResult) {
514
+ function traverse_expr_caret(a_expr_caret, context, traverseResult) {
352
515
  const a_expr_unary_sign_list = a_expr_caret.a_expr_unary_sign_list();
353
516
  if (a_expr_unary_sign_list) {
354
517
  const notNullInfo = a_expr_caret.a_expr_unary_sign_list()
355
- .map(a_expr_unary_sign => traverse_expr_unary_sign(a_expr_unary_sign, dbSchema, fromColumns, traverseResult));
518
+ .map(a_expr_unary_sign => traverse_expr_unary_sign(a_expr_unary_sign, context, traverseResult));
519
+ if (notNullInfo.length === 1) {
520
+ return notNullInfo[0];
521
+ }
356
522
  const result = {
357
- column_name: a_expr_caret.getText(),
358
- is_nullable: notNullInfo.some(notNullInfo => notNullInfo.is_nullable)
523
+ column_name: '?column?',
524
+ is_nullable: notNullInfo.some(notNullInfo => notNullInfo.is_nullable),
525
+ table_name: '',
526
+ table_schema: ''
359
527
  };
360
528
  return result;
361
529
  }
362
530
  throw Error('traverse_expr_caret - Not expected:' + a_expr_caret.getText());
363
531
  }
364
- function traverse_expr_unary_sign(a_expr_unary_sign, dbSchema, fromColumns, traverseResult) {
532
+ function traverse_expr_unary_sign(a_expr_unary_sign, context, traverseResult) {
365
533
  const a_expr_at_time_zone = a_expr_unary_sign.a_expr_at_time_zone();
366
534
  if (a_expr_at_time_zone) {
367
- return traverse_expr_at_time_zone(a_expr_at_time_zone, dbSchema, fromColumns, traverseResult);
535
+ return traverse_expr_at_time_zone(a_expr_at_time_zone, context, traverseResult);
368
536
  }
369
537
  throw Error('traverse_expr_unary_sign - Not expected:' + a_expr_unary_sign.getText());
370
538
  }
371
- function traverse_expr_at_time_zone(a_expr_at_time_zone, dbSchema, fromColumns, traverseResult) {
539
+ function traverse_expr_at_time_zone(a_expr_at_time_zone, context, traverseResult) {
372
540
  const a_expr_collate = a_expr_at_time_zone.a_expr_collate();
373
541
  if (a_expr_collate) {
374
- return traverse_expr_collate(a_expr_collate, dbSchema, fromColumns, traverseResult);
542
+ return traverse_expr_collate(a_expr_collate, context, traverseResult);
375
543
  }
376
544
  throw Error('traverse_expr_at_time_zone - Not expected:' + a_expr_at_time_zone.getText());
377
545
  }
378
- function traverse_expr_collate(a_expr_collate, dbSchema, fromColumns, traverseResult) {
546
+ function traverse_expr_collate(a_expr_collate, context, traverseResult) {
379
547
  const a_expr_typecast = a_expr_collate.a_expr_typecast();
380
548
  if (a_expr_typecast) {
381
- return traverse_expr_typecast(a_expr_typecast, dbSchema, fromColumns, traverseResult);
549
+ return traverse_expr_typecast(a_expr_typecast, context, traverseResult);
382
550
  }
383
551
  throw Error('traverse_expr_collate - Not expected:' + a_expr_collate.getText());
384
552
  }
385
- function traverse_expr_typecast(a_expr_typecast, dbSchema, fromColumns, traverseResult) {
553
+ function traverse_expr_typecast(a_expr_typecast, context, traverseResult) {
386
554
  const c_expr = a_expr_typecast.c_expr();
387
555
  if (c_expr) {
388
- return traversec_expr(c_expr, dbSchema, fromColumns, traverseResult);
556
+ return traversec_expr(c_expr, context, traverseResult);
389
557
  }
390
558
  throw Error('traverse_expr_typecast - Not expected:' + a_expr_typecast.getText());
391
559
  }
@@ -394,12 +562,12 @@ function traverseColumnRef(columnref, fromColumns) {
394
562
  const col = findColumn(fieldName, fromColumns);
395
563
  return col;
396
564
  }
397
- function traversec_expr(c_expr, dbSchema, fromColumns, traverseResult) {
398
- var _a, _b;
565
+ function traversec_expr(c_expr, context, traverseResult) {
566
+ var _a, _b, _c, _d, _e;
399
567
  if (c_expr instanceof PostgreSQLParser_1.C_expr_exprContext) {
400
568
  const columnref = c_expr.columnref();
401
569
  if (columnref) {
402
- const col = traverseColumnRef(columnref, fromColumns);
570
+ const col = traverseColumnRef(columnref, context.fromColumns);
403
571
  return col;
404
572
  }
405
573
  const aexprconst = c_expr.aexprconst();
@@ -407,67 +575,111 @@ function traversec_expr(c_expr, dbSchema, fromColumns, traverseResult) {
407
575
  const is_nullable = aexprconst.NULL_P() != null;
408
576
  return {
409
577
  column_name: aexprconst.getText(),
410
- is_nullable
578
+ is_nullable,
579
+ table_name: '',
580
+ table_schema: ''
411
581
  };
412
582
  }
413
583
  if (c_expr.PARAM()) {
414
584
  traverseResult.parameters.push({
415
585
  paramIndex: c_expr.start.start,
416
- isNotNull: true
586
+ isNotNull: !context.propagatesNull
417
587
  });
418
588
  return {
419
589
  column_name: c_expr.PARAM().getText(),
420
- is_nullable: false
590
+ is_nullable: !!context.propagatesNull,
591
+ table_name: '',
592
+ table_schema: ''
421
593
  };
422
594
  }
423
595
  const func_application = (_a = c_expr.func_expr()) === null || _a === void 0 ? void 0 : _a.func_application();
424
596
  if (func_application) {
425
- const isNotNull = traversefunc_application(func_application, dbSchema, fromColumns, traverseResult);
597
+ const isNotNull = traversefunc_application(func_application, context, traverseResult);
426
598
  return {
427
- column_name: func_application.getText(),
428
- is_nullable: !isNotNull
599
+ column_name: ((_b = func_application.func_name()) === null || _b === void 0 ? void 0 : _b.getText()) || func_application.getText(),
600
+ is_nullable: !isNotNull,
601
+ table_name: '',
602
+ table_schema: ''
429
603
  };
430
604
  }
431
- const func_expr_common_subexpr = (_b = c_expr.func_expr()) === null || _b === void 0 ? void 0 : _b.func_expr_common_subexpr();
605
+ const func_expr_common_subexpr = (_c = c_expr.func_expr()) === null || _c === void 0 ? void 0 : _c.func_expr_common_subexpr();
432
606
  if (func_expr_common_subexpr) {
433
- const isNotNull = traversefunc_expr_common_subexpr(func_expr_common_subexpr, dbSchema, fromColumns, traverseResult);
607
+ const isNotNull = traversefunc_expr_common_subexpr(func_expr_common_subexpr, context, traverseResult);
434
608
  return {
435
- column_name: func_expr_common_subexpr.getText(),
436
- is_nullable: !isNotNull
609
+ column_name: ((_e = (_d = func_expr_common_subexpr.getText().split('(')) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.trim()) || func_expr_common_subexpr.getText(),
610
+ is_nullable: !isNotNull,
611
+ table_name: '',
612
+ table_schema: ''
437
613
  };
438
614
  }
439
615
  const select_with_parens = c_expr.select_with_parens();
440
616
  if (select_with_parens) {
441
- traverse_select_with_parens(select_with_parens, dbSchema, fromColumns, traverseResult);
617
+ traverse_select_with_parens(select_with_parens, context, traverseResult);
442
618
  return {
443
- column_name: select_with_parens.getText(),
444
- is_nullable: true
619
+ column_name: '?column?',
620
+ is_nullable: true,
621
+ table_name: '',
622
+ table_schema: ''
445
623
  };
446
624
  }
447
625
  const a_expr_in_parens = c_expr._a_expr_in_parens;
448
626
  if (a_expr_in_parens) {
449
- return traverse_a_expr(a_expr_in_parens, dbSchema, fromColumns, traverseResult);
627
+ return traverse_a_expr(a_expr_in_parens, context, traverseResult);
628
+ }
629
+ const explicit_row = c_expr.explicit_row();
630
+ if (explicit_row) {
631
+ const expr_list = explicit_row.expr_list().a_expr_list()
632
+ .map(a_expr => traverse_a_expr(a_expr, context, traverseResult));
633
+ return {
634
+ column_name: '?column?',
635
+ is_nullable: expr_list.some(col => col.is_nullable),
636
+ table_name: '',
637
+ table_schema: ''
638
+ };
639
+ }
640
+ const implicit_row = c_expr.implicit_row();
641
+ if (implicit_row) {
642
+ const expr_list = implicit_row.expr_list().a_expr_list().concat(implicit_row.a_expr())
643
+ .map(a_expr => traverse_a_expr(a_expr, context, traverseResult));
644
+ return {
645
+ column_name: '?column?',
646
+ is_nullable: expr_list.some(col => col.is_nullable),
647
+ table_name: '',
648
+ table_schema: ''
649
+ };
450
650
  }
451
651
  }
452
652
  if (c_expr instanceof PostgreSQLParser_1.C_expr_caseContext) {
453
- const isNotNull = traversec_expr_case(c_expr, dbSchema, fromColumns, traverseResult);
653
+ const isNotNull = traversec_expr_case(c_expr, context, traverseResult);
454
654
  return {
455
- column_name: c_expr.getText(),
456
- is_nullable: !isNotNull
655
+ column_name: '?column?',
656
+ is_nullable: !isNotNull,
657
+ table_name: '',
658
+ table_schema: ''
457
659
  };
458
660
  }
459
661
  if (c_expr instanceof PostgreSQLParser_1.C_expr_existsContext) {
460
662
  //todo - traverse
461
663
  return {
462
- column_name: c_expr.getText(),
463
- is_nullable: false
664
+ column_name: '?column?',
665
+ is_nullable: false,
666
+ table_name: '',
667
+ table_schema: ''
464
668
  };
465
669
  }
466
670
  throw Error('traversec_expr - Not expected:' + c_expr.getText());
467
671
  }
468
672
  function filterColumns(fromColumns, fieldName) {
469
673
  return fromColumns.filter(col => (fieldName.prefix === '' || col.table_name === fieldName.prefix)
470
- && (fieldName.name === '*' || col.column_name === fieldName.name));
674
+ && (fieldName.name === '*' || col.column_name === fieldName.name)).map(col => {
675
+ const result = {
676
+ column_name: col.column_name,
677
+ is_nullable: col.is_nullable,
678
+ table_name: col.table_name,
679
+ table_schema: col.table_schema
680
+ };
681
+ return result;
682
+ });
471
683
  }
472
684
  function excludeColumns(fromColumns, excludeList) {
473
685
  return fromColumns.filter(col => {
@@ -476,21 +688,21 @@ function excludeColumns(fromColumns, excludeList) {
476
688
  return !found;
477
689
  });
478
690
  }
479
- function traversec_expr_case(c_expr_case, dbSchema, fromColumns, traverseResult) {
691
+ function traversec_expr_case(c_expr_case, context, traverseResult) {
480
692
  var _a;
481
693
  const case_expr = c_expr_case.case_expr();
482
- const whenResult = case_expr.when_clause_list().when_clause_list().map(when_clause => traversewhen_clause(when_clause, dbSchema, fromColumns, traverseResult));
694
+ const whenResult = case_expr.when_clause_list().when_clause_list().map(when_clause => traversewhen_clause(when_clause, context, traverseResult));
483
695
  const whenIsNotNull = whenResult.every(when => when);
484
696
  const elseExpr = (_a = case_expr.case_default()) === null || _a === void 0 ? void 0 : _a.a_expr();
485
- const elseIsNotNull = elseExpr ? !traverse_a_expr(elseExpr, dbSchema, fromColumns, traverseResult).is_nullable : false;
697
+ const elseIsNotNull = elseExpr ? !traverse_a_expr(elseExpr, context, traverseResult).is_nullable : false;
486
698
  return elseIsNotNull && whenIsNotNull;
487
699
  }
488
- function traversewhen_clause(when_clause, dbSchema, fromColumns, traverseResult) {
700
+ function traversewhen_clause(when_clause, context, traverseResult) {
489
701
  const a_expr_list = when_clause.a_expr_list();
490
702
  const [whenExprList, thenExprList] = partition(a_expr_list, (index) => index % 2 === 0);
491
703
  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);
704
+ traverse_a_expr(whenExprList[index], context, traverseResult);
705
+ const thenExprResult = traverse_a_expr(thenExpr, context, traverseResult);
494
706
  return thenExprResult;
495
707
  });
496
708
  return whenExprResult.every(res => res);
@@ -506,11 +718,11 @@ function partition(array, predicate) {
506
718
  return acc;
507
719
  }, [[], []]);
508
720
  }
509
- function traversefunc_application(func_application, dbSchema, fromColumns, traverseResult) {
721
+ function traversefunc_application(func_application, context, traverseResult) {
510
722
  var _a;
511
723
  const functionName = func_application.func_name().getText().toLowerCase();
512
724
  const func_arg_expr_list = ((_a = func_application.func_arg_list()) === null || _a === void 0 ? void 0 : _a.func_arg_expr_list()) || [];
513
- const argsResult = func_arg_expr_list.map(func_arg_expr => traversefunc_arg_expr(func_arg_expr, dbSchema, fromColumns, traverseResult));
725
+ const argsResult = func_arg_expr_list.map(func_arg_expr => traversefunc_arg_expr(func_arg_expr, context, traverseResult));
514
726
  if (functionName === 'count') {
515
727
  return true;
516
728
  }
@@ -527,34 +739,27 @@ function traversefunc_application(func_application, dbSchema, fromColumns, trave
527
739
  if (functionName === 'generate_series') {
528
740
  return true;
529
741
  }
530
- if (func_arg_expr_list) {
531
- func_arg_expr_list.forEach(func_arg_expr => traversefunc_arg_expr(func_arg_expr, dbSchema, fromColumns, traverseResult));
532
- }
533
742
  return false;
534
743
  }
535
- function traversefunc_expr_common_subexpr(func_expr_common_subexpr, dbSchema, fromColumns, traverseResult) {
536
- if (func_expr_common_subexpr.COALESCE()) {
744
+ function traversefunc_expr_common_subexpr(func_expr_common_subexpr, context, traverseResult) {
745
+ if (func_expr_common_subexpr.COALESCE() || func_expr_common_subexpr.GREATEST() || func_expr_common_subexpr.LEAST()) {
537
746
  const func_arg_list = func_expr_common_subexpr.expr_list().a_expr_list();
538
747
  const result = func_arg_list.map(func_arg_expr => {
539
- const paramResult = traverse_a_expr(func_arg_expr, dbSchema, fromColumns, traverseResult);
540
- if (isParameter(paramResult.column_name)) {
541
- traverseResult.parameters[traverseResult.parameters.length - 1].isNotNull = false;
542
- paramResult.is_nullable = true;
543
- }
748
+ const paramResult = traverse_a_expr(func_arg_expr, Object.assign(Object.assign({}, context), { propagatesNull: true }), traverseResult);
544
749
  return paramResult;
545
750
  });
546
751
  return result.some(col => !col.is_nullable);
547
752
  }
548
753
  if (func_expr_common_subexpr.EXTRACT()) {
549
754
  const a_expr = func_expr_common_subexpr.extract_list().a_expr();
550
- const result = traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult);
755
+ const result = traverse_a_expr(a_expr, context, traverseResult);
551
756
  return !result.is_nullable;
552
757
  }
553
758
  return false;
554
759
  }
555
- function traversefunc_arg_expr(func_arg_expr, dbSchema, fromColumns, traverseResult) {
760
+ function traversefunc_arg_expr(func_arg_expr, context, traverseResult) {
556
761
  const a_expr = func_arg_expr.a_expr();
557
- return !traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult).is_nullable;
762
+ return !traverse_a_expr(a_expr, context, traverseResult).is_nullable;
558
763
  }
559
764
  function findColumn(fieldName, fromColumns) {
560
765
  const col = fromColumns.find(col => (fieldName.prefix === '' || col.table_name.toLowerCase() === fieldName.prefix.toLowerCase()) && col.column_name.toLowerCase() === fieldName.name.toLowerCase());
@@ -571,65 +776,147 @@ function checkIsNullable(where_clause, field) {
571
776
  const col = Object.assign(Object.assign({}, field), { is_nullable: !isNotNullResult });
572
777
  return col;
573
778
  }
574
- function traverse_from_clause(from_clause, dbSchema, fromColumns, traverseResult) {
779
+ function traverse_from_clause(from_clause, context, traverseResult) {
575
780
  const from_list = from_clause.from_list();
576
781
  if (from_list) {
577
- return traverse_from_list(from_list, dbSchema, fromColumns, traverseResult);
782
+ return traverse_from_list(from_list, context, traverseResult);
578
783
  }
579
784
  return [];
580
785
  }
581
- function traverse_from_list(from_list, dbSchema, fromColumns, traverseResult) {
582
- const newColumns = from_list.table_ref_list().flatMap(table_ref => traverse_table_ref(table_ref, dbSchema, fromColumns, traverseResult));
786
+ function traverse_from_list(from_list, context, traverseResult) {
787
+ const newColumns = from_list.table_ref_list().flatMap(table_ref => traverse_table_ref(table_ref, context, traverseResult));
583
788
  return newColumns;
584
789
  }
585
- function traverse_table_ref(table_ref, dbSchema, fromColumns, traverseResult) {
790
+ function traverse_table_ref(table_ref, context, traverseResult) {
791
+ var _a, _b;
792
+ const { fromColumns, dbSchema } = context;
586
793
  const allColumns = [];
587
794
  const relation_expr = table_ref.relation_expr();
588
795
  const aliasClause = table_ref.alias_clause();
589
- const alias = aliasClause ? aliasClause.colid().getText() : undefined;
796
+ const alias = aliasClause ? aliasClause.colid().getText() : '';
590
797
  if (relation_expr) {
591
798
  const tableName = traverse_relation_expr(relation_expr, dbSchema);
592
799
  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 })));
800
+ const fromColumnsResult = fromColumns.concat(dbSchema).filter(col => col.table_name === tableName.name)
801
+ .map(col => (Object.assign(Object.assign({}, col), { table_name: tableNameWithAlias })));
594
802
  allColumns.push(...fromColumnsResult);
595
- }
596
- const table_ref_list = table_ref.table_ref_list();
597
- const join_type_list = table_ref.join_type_list();
598
- const join_qual_list = table_ref.join_qual_list();
599
- if (table_ref_list) {
600
- const joinColumns = table_ref_list.flatMap((table_ref, joinIndex) => {
601
- const joinType = join_type_list[joinIndex]; //INNER, LEFT
602
- const joinQual = join_qual_list[joinIndex];
603
- const joinColumns = traverse_table_ref(table_ref, dbSchema, fromColumns, traverseResult);
604
- const isUsing = (joinQual === null || joinQual === void 0 ? void 0 : joinQual.USING()) ? true : false;
605
- const isLeftJoin = joinType === null || joinType === void 0 ? void 0 : joinType.LEFT();
606
- const filteredColumns = isUsing ? filterUsingColumns(joinColumns, joinQual) : joinColumns;
607
- const resultColumns = isLeftJoin ? filteredColumns.map(col => (Object.assign(Object.assign({}, col), { is_nullable: true }))) : filteredColumns;
608
- return resultColumns;
609
- });
610
- allColumns.push(...joinColumns);
803
+ if (context.collectNestedInfo) {
804
+ const key = fromColumnsResult.filter(col => col.column_key === 'PRI');
805
+ const renameAs = (aliasClause === null || aliasClause === void 0 ? void 0 : aliasClause.AS()) != null;
806
+ const relation = {
807
+ name: tableName.name,
808
+ alias: alias,
809
+ renameAs,
810
+ parentRelation: '',
811
+ joinColumn: ((_a = key[0]) === null || _a === void 0 ? void 0 : _a.column_name) || '',
812
+ cardinality: 'one',
813
+ parentCardinality: 'one'
814
+ };
815
+ (_b = traverseResult.relations) === null || _b === void 0 ? void 0 : _b.push(relation);
816
+ }
817
+ const table_ref_list = table_ref.table_ref_list();
818
+ const join_type_list = table_ref.join_type_list();
819
+ const join_qual_list = table_ref.join_qual_list();
820
+ if (context.collectDynamicQueryInfo && traverseResult.dynamicQueryInfo.from.length == 0) {
821
+ collectDynamicQueryInfoTableRef(table_ref, null, null, fromColumnsResult, [], traverseResult);
822
+ }
823
+ if (table_ref_list) {
824
+ const joinColumns = table_ref_list.flatMap((table_ref, joinIndex) => {
825
+ const joinType = join_type_list[joinIndex]; //INNER, LEFT
826
+ const joinQual = join_qual_list[joinIndex];
827
+ const numParamsBefore = traverseResult.parameters.length;
828
+ const joinColumns = traverse_table_ref(table_ref, context, traverseResult);
829
+ const isUsing = (joinQual === null || joinQual === void 0 ? void 0 : joinQual.USING()) ? true : false;
830
+ const isLeftJoin = joinType === null || joinType === void 0 ? void 0 : joinType.LEFT();
831
+ const filteredColumns = isUsing ? filterUsingColumns(joinColumns, joinQual) : joinColumns;
832
+ const resultColumns = isLeftJoin ? filteredColumns.map(col => (Object.assign(Object.assign({}, col), { is_nullable: true }))) : filteredColumns;
833
+ if (context.collectNestedInfo) {
834
+ collectNestedInfo(joinQual, resultColumns, traverseResult);
835
+ }
836
+ if (context.collectDynamicQueryInfo) {
837
+ const parameters = traverseResult.parameters.slice(numParamsBefore).map((_, index) => index + numParamsBefore);
838
+ collectDynamicQueryInfoTableRef(table_ref, joinType, joinQual, resultColumns, parameters, traverseResult);
839
+ }
840
+ return resultColumns;
841
+ });
842
+ allColumns.push(...joinColumns);
843
+ }
611
844
  }
612
845
  const select_with_parens = table_ref.select_with_parens();
613
846
  if (select_with_parens) {
614
- const columns = traverse_select_with_parens(select_with_parens, dbSchema, fromColumns, traverseResult);
847
+ const columns = traverse_select_with_parens(select_with_parens, Object.assign(Object.assign({}, context), { collectDynamicQueryInfo: false }), traverseResult);
615
848
  const withAlias = columns.map(col => (Object.assign(Object.assign({}, col), { table_name: alias || col.table_name })));
616
849
  return withAlias;
617
850
  }
618
851
  return allColumns;
619
852
  }
853
+ function collectDynamicQueryInfoTableRef(table_ref, joinType, joinQual, columns, parameters, traverseResult) {
854
+ var _a, _b;
855
+ const alias = table_ref.alias_clause() ? (0, select_columns_1.extractOriginalSql)(table_ref.alias_clause()) : '';
856
+ const fromExpr = (0, select_columns_1.extractOriginalSql)(table_ref.relation_expr() || table_ref.select_with_parens());
857
+ const tableName = ((_a = table_ref.relation_expr()) === null || _a === void 0 ? void 0 : _a.getText()) || alias;
858
+ const fromOrJoin = joinType ? `${(0, select_columns_1.extractOriginalSql)(joinType)} JOIN` : 'FROM';
859
+ const join = joinQual ? ` ${(0, select_columns_1.extractOriginalSql)(joinQual)}` : '';
860
+ const fromFragment = `${fromOrJoin} ${fromExpr} ${alias}${join}`;
861
+ const fields = columns.map(col => col.column_name);
862
+ const joinColumns = joinQual ? getJoinColumns(joinQual) : [];
863
+ const parentList = joinColumns.filter(joinRef => joinRef.prefix !== tableName && joinRef.prefix !== alias);
864
+ const parentRelation = parentList.length === 1 ? parentList[0].prefix : '';
865
+ (_b = traverseResult.dynamicQueryInfo) === null || _b === void 0 ? void 0 : _b.from.push({
866
+ fragment: fromFragment,
867
+ fields,
868
+ parameters,
869
+ relationName: tableName,
870
+ relationAlias: alias,
871
+ parentRelation
872
+ });
873
+ }
874
+ function getJoinColumns(joinQual) {
875
+ const a_expr_or_list = joinQual ? collectContextsOfType(joinQual, PostgreSQLParser_1.A_expr_orContext) : [];
876
+ if (a_expr_or_list.length == 1) {
877
+ const a_expr_or = a_expr_or_list[0];
878
+ const a_expr_and = a_expr_or.a_expr_and_list()[0];
879
+ const columnref = collectContextsOfType(a_expr_and, PostgreSQLParser_1.ColumnrefContext);
880
+ const joinColumns = columnref.map(colRef => (0, select_columns_1.splitName)(colRef.getText()));
881
+ return joinColumns;
882
+ }
883
+ return [];
884
+ }
885
+ function collectNestedInfo(joinQual, resultColumns, traverseResult) {
886
+ var _a;
887
+ const joinColumns = getJoinColumns(joinQual);
888
+ const currentRelation = (_a = traverseResult.relations) === null || _a === void 0 ? void 0 : _a.at(-1);
889
+ joinColumns.forEach(joinRef => {
890
+ if (currentRelation) {
891
+ const joinColumn = resultColumns.filter(col => col.column_name === joinRef.name)[0];
892
+ const unique = joinColumn && (joinColumn.column_key === 'PRI' || joinColumn.column_key === 'UNI');
893
+ if (joinRef.prefix === currentRelation.name || joinRef.prefix === currentRelation.alias) {
894
+ if (!unique) {
895
+ currentRelation.cardinality = 'many';
896
+ }
897
+ }
898
+ else {
899
+ currentRelation.parentRelation = joinRef.prefix;
900
+ if (!unique) {
901
+ currentRelation.parentCardinality = 'many';
902
+ }
903
+ }
904
+ }
905
+ });
906
+ }
620
907
  function filterUsingColumns(fromColumns, joinQual) {
621
908
  const excludeList = joinQual.name_list().name_list().map(name => (0, select_columns_1.splitName)(name.getText()));
622
909
  const filteredColumns = excludeColumns(fromColumns, excludeList);
623
910
  return filteredColumns;
624
911
  }
625
- function traverse_select_with_parens(select_with_parens, dbSchema, fromColumns, traverseResult) {
912
+ function traverse_select_with_parens(select_with_parens, context, traverseResult) {
626
913
  const select_with_parens2 = select_with_parens.select_with_parens();
627
914
  if (select_with_parens2) {
628
- return traverse_select_with_parens(select_with_parens2, dbSchema, fromColumns, traverseResult);
915
+ return traverse_select_with_parens(select_with_parens2, context, traverseResult);
629
916
  }
630
917
  const select_no_parens = select_with_parens.select_no_parens();
631
918
  if (select_no_parens) {
632
- return traverse_select_no_parens(select_no_parens, dbSchema, fromColumns, traverseResult);
919
+ return traverse_select_no_parens(select_no_parens, context, traverseResult);
633
920
  }
634
921
  return [];
635
922
  }
@@ -713,20 +1000,26 @@ function traverseInsertstmt(insertstmt, dbSchema) {
713
1000
  const insertColumnsList = insert_rest.insert_column_list()
714
1001
  .insert_column_item_list()
715
1002
  .map(insert_column_item => traverse_insert_column_item(insert_column_item, insertColumns));
1003
+ const context = {
1004
+ dbSchema,
1005
+ fromColumns: insertColumns,
1006
+ collectNestedInfo: false,
1007
+ collectDynamicQueryInfo: false
1008
+ };
716
1009
  const selectstmt = insert_rest.selectstmt();
717
- traverse_insert_select_stmt(selectstmt, dbSchema, insertColumnsList, traverseResult);
1010
+ traverse_insert_select_stmt(selectstmt, Object.assign(Object.assign({}, context), { fromColumns: insertColumnsList }), traverseResult);
718
1011
  const on_conflict = insertstmt.on_conflict_();
719
1012
  if (on_conflict) {
720
1013
  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));
1014
+ set_clause_list.forEach(set_clause => traverse_set_clause(set_clause, context, traverseResult));
722
1015
  }
723
1016
  const returning_clause = insertstmt.returning_clause();
724
- const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), dbSchema, insertColumns, traverseResult) : [];
1017
+ const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), context, traverseResult) : [];
725
1018
  const result = {
726
1019
  queryType: 'Insert',
727
1020
  multipleRowsResult: false,
728
1021
  parametersNullability: traverseResult.parameters.map(param => param.isNotNull),
729
- columnsNullability: returninColumns.map(col => !col.is_nullable),
1022
+ columns: returninColumns,
730
1023
  parameterList: []
731
1024
  };
732
1025
  if (returning_clause) {
@@ -734,7 +1027,7 @@ function traverseInsertstmt(insertstmt, dbSchema) {
734
1027
  }
735
1028
  return result;
736
1029
  }
737
- function traverse_insert_select_stmt(selectstmt, dbSchema, insertColumnlist, traverseResult) {
1030
+ function traverse_insert_select_stmt(selectstmt, context, traverseResult) {
738
1031
  var _a, _b, _c, _d, _e;
739
1032
  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];
740
1033
  if (simple_select) {
@@ -743,27 +1036,27 @@ function traverse_insert_select_stmt(selectstmt, dbSchema, insertColumnlist, tra
743
1036
  const values_clause = simple_select_pramary.values_clause();
744
1037
  if (values_clause) {
745
1038
  values_clause.expr_list_list()
746
- .forEach(expr_list => traverse_insert_a_expr_list(expr_list, dbSchema, insertColumnlist, traverseResult));
1039
+ .forEach(expr_list => traverse_insert_a_expr_list(expr_list, context, traverseResult));
747
1040
  }
748
1041
  const target_list = (_e = simple_select_pramary.target_list_()) === null || _e === void 0 ? void 0 : _e.target_list();
749
1042
  if (target_list) {
750
1043
  const from_clause = simple_select_pramary.from_clause();
751
- const fromColumns = from_clause ? traverse_from_clause(from_clause, dbSchema, [], traverseResult) : [];
1044
+ const fromColumns = from_clause ? traverse_from_clause(from_clause, Object.assign(Object.assign({}, context), { fromColumns: [] }), traverseResult) : [];
752
1045
  target_list.target_el_list().forEach((target_el, index) => {
753
- const targetResult = isNotNull_target_el(target_el, dbSchema, fromColumns, traverseResult);
1046
+ const targetResult = traverse_target_el(target_el, Object.assign(Object.assign({}, context), { fromColumns }), traverseResult);
754
1047
  if (isParameter(targetResult.column_name)) {
755
- traverseResult.parameters.at(-1).isNotNull = !insertColumnlist[index].is_nullable;
1048
+ traverseResult.parameters.at(-1).isNotNull = !context.fromColumns[index].is_nullable;
756
1049
  }
757
1050
  });
758
1051
  }
759
1052
  }
760
1053
  }
761
1054
  }
762
- function traverse_insert_a_expr_list(expr_list, dbSchema, insertColumns, traverseResult) {
1055
+ function traverse_insert_a_expr_list(expr_list, context, traverseResult) {
763
1056
  expr_list.a_expr_list().forEach((a_expr, index) => {
764
- const result = traverse_a_expr(a_expr, dbSchema, insertColumns, traverseResult);
1057
+ const result = traverse_a_expr(a_expr, context, traverseResult);
765
1058
  if (isParameter(result.column_name)) {
766
- traverseResult.parameters.at(-1).isNotNull = !insertColumns[index].is_nullable;
1059
+ traverseResult.parameters.at(-1).isNotNull = !context.fromColumns[index].is_nullable;
767
1060
  }
768
1061
  });
769
1062
  }
@@ -772,12 +1065,18 @@ function traverseDeletestmt(deleteStmt, dbSchema, traverseResult) {
772
1065
  const tableName = relation_expr.getText();
773
1066
  const deleteColumns = dbSchema.filter(col => col.table_name === tableName);
774
1067
  const returning_clause = deleteStmt.returning_clause();
775
- const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), dbSchema, deleteColumns, traverseResult) : [];
1068
+ const context = {
1069
+ dbSchema,
1070
+ fromColumns: deleteColumns,
1071
+ collectNestedInfo: false,
1072
+ collectDynamicQueryInfo: false
1073
+ };
1074
+ const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), context, traverseResult) : [];
776
1075
  const result = {
777
1076
  queryType: 'Delete',
778
1077
  multipleRowsResult: false,
779
1078
  parametersNullability: traverseResult.parameters.map(param => param.isNotNull),
780
- columnsNullability: returninColumns.map(col => !col.is_nullable),
1079
+ columns: returninColumns,
781
1080
  parameterList: []
782
1081
  };
783
1082
  if (returning_clause) {
@@ -789,22 +1088,28 @@ function traverseUpdatestmt(updatestmt, dbSchema, traverseResult) {
789
1088
  const relation_expr_opt_alias = updatestmt.relation_expr_opt_alias();
790
1089
  const tableName = relation_expr_opt_alias.getText();
791
1090
  const updateColumns = dbSchema.filter(col => col.table_name === tableName);
1091
+ const context = {
1092
+ dbSchema,
1093
+ fromColumns: updateColumns,
1094
+ collectNestedInfo: false,
1095
+ collectDynamicQueryInfo: false
1096
+ };
792
1097
  updatestmt.set_clause_list().set_clause_list()
793
- .forEach(set_clause => traverse_set_clause(set_clause, dbSchema, updateColumns, traverseResult));
1098
+ .forEach(set_clause => traverse_set_clause(set_clause, context, traverseResult));
794
1099
  const parametersBefore = traverseResult.parameters.length;
795
1100
  const where_clause = updatestmt.where_or_current_clause();
796
1101
  if (where_clause) {
797
1102
  const a_expr = where_clause.a_expr();
798
- traverse_a_expr(a_expr, dbSchema, updateColumns, traverseResult);
1103
+ traverse_a_expr(a_expr, context, traverseResult);
799
1104
  }
800
1105
  const whereParameters = traverseResult.parameters.slice(parametersBefore);
801
1106
  const returning_clause = updatestmt.returning_clause();
802
- const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), dbSchema, updateColumns, traverseResult) : [];
1107
+ const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), context, traverseResult) : [];
803
1108
  const result = {
804
1109
  queryType: 'Update',
805
1110
  multipleRowsResult: false,
806
1111
  parametersNullability: traverseResult.parameters.slice(0, parametersBefore).map(param => param.isNotNull),
807
- columnsNullability: returninColumns.map(col => !col.is_nullable),
1112
+ columns: returninColumns,
808
1113
  parameterList: [],
809
1114
  whereParamtersNullability: whereParameters.map(param => param.isNotNull)
810
1115
  };
@@ -813,13 +1118,13 @@ function traverseUpdatestmt(updatestmt, dbSchema, traverseResult) {
813
1118
  }
814
1119
  return result;
815
1120
  }
816
- function traverse_set_clause(set_clause, dbSchema, updateColumns, traverseResult) {
1121
+ function traverse_set_clause(set_clause, context, traverseResult) {
817
1122
  const set_target = set_clause.set_target();
818
1123
  const columnName = (0, select_columns_1.splitName)(set_target.getText());
819
- const column = findColumn(columnName, updateColumns);
1124
+ const column = findColumn(columnName, context.fromColumns);
820
1125
  const a_expr = set_clause.a_expr();
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);
1126
+ const excludedColumns = context.fromColumns.map((col) => (Object.assign(Object.assign({}, col), { table_name: 'excluded' })));
1127
+ const a_exprResult = traverse_a_expr(a_expr, Object.assign(Object.assign({}, context), { fromColumns: context.fromColumns.concat(excludedColumns) }), traverseResult);
823
1128
  if (isParameter(a_exprResult.column_name)) {
824
1129
  traverseResult.parameters[traverseResult.parameters.length - 1].isNotNull = !column.is_nullable;
825
1130
  }