typesql-cli 0.15.1 → 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/code-generator.d.ts +1 -1
  2. package/code-generator.d.ts.map +1 -1
  3. package/code-generator.js +2 -2
  4. package/code-generator.js.map +1 -1
  5. package/code-generator2.d.ts.map +1 -1
  6. package/code-generator2.js +71 -6
  7. package/code-generator2.js.map +1 -1
  8. package/drivers/postgres.d.ts +1 -3
  9. package/drivers/postgres.d.ts.map +1 -1
  10. package/drivers/postgres.js +0 -10
  11. package/drivers/postgres.js.map +1 -1
  12. package/drivers/sqlite.d.ts +5 -0
  13. package/drivers/sqlite.d.ts.map +1 -0
  14. package/drivers/sqlite.js +37 -0
  15. package/drivers/sqlite.js.map +1 -0
  16. package/package.json +5 -2
  17. package/postgres-query-analyzer/describe.d.ts.map +1 -1
  18. package/postgres-query-analyzer/describe.js +30 -10
  19. package/postgres-query-analyzer/describe.js.map +1 -1
  20. package/postgres-query-analyzer/parser.d.ts +2 -2
  21. package/postgres-query-analyzer/parser.d.ts.map +1 -1
  22. package/postgres-query-analyzer/parser.js +4 -4
  23. package/postgres-query-analyzer/parser.js.map +1 -1
  24. package/postgres-query-analyzer/traverse.d.ts +16 -2
  25. package/postgres-query-analyzer/traverse.d.ts.map +1 -1
  26. package/postgres-query-analyzer/traverse.js +320 -170
  27. package/postgres-query-analyzer/traverse.js.map +1 -1
  28. package/sqlite-query-analyzer/code-generator.d.ts +9 -2
  29. package/sqlite-query-analyzer/code-generator.d.ts.map +1 -1
  30. package/sqlite-query-analyzer/code-generator.js +13 -38
  31. package/sqlite-query-analyzer/code-generator.js.map +1 -1
  32. package/sqlite-query-analyzer/sqlite-describe-nested-query.d.ts +2 -0
  33. package/sqlite-query-analyzer/sqlite-describe-nested-query.d.ts.map +1 -1
  34. package/sqlite-query-analyzer/sqlite-describe-nested-query.js +12 -7
  35. package/sqlite-query-analyzer/sqlite-describe-nested-query.js.map +1 -1
  36. package/sqlite-query-analyzer/traverse.d.ts +5 -1
  37. package/sqlite-query-analyzer/traverse.d.ts.map +1 -1
  38. package/sqlite-query-analyzer/traverse.js +11 -2
  39. package/sqlite-query-analyzer/traverse.js.map +1 -1
  40. package/ts-nested-descriptor.js +1 -1
  41. package/ts-nested-descriptor.js.map +1 -1
@@ -4,15 +4,23 @@ exports.traverseSmt = traverseSmt;
4
4
  const PostgreSQLParser_1 = require("@wsporto/typesql-parser/postgres/PostgreSQLParser");
5
5
  const typesql_parser_1 = require("@wsporto/typesql-parser");
6
6
  const select_columns_1 = require("../mysql-query-analyzer/select-columns");
7
- function traverseSmt(stmt, dbSchema) {
7
+ function traverseSmt(stmt, dbSchema, generateNestedInfo) {
8
8
  const traverseResult = {
9
9
  columnsNullability: [],
10
10
  parameters: [],
11
11
  singleRow: false
12
12
  };
13
+ if (generateNestedInfo) {
14
+ traverseResult.relations = [];
15
+ }
16
+ const traverseContext = {
17
+ dbSchema,
18
+ generateNestedInfo,
19
+ fromColumns: []
20
+ };
13
21
  const selectstmt = stmt.selectstmt();
14
22
  if (selectstmt) {
15
- const result = traverseSelectstmt(selectstmt, dbSchema, [], traverseResult);
23
+ const result = traverseSelectstmt(selectstmt, traverseContext, traverseResult);
16
24
  return result;
17
25
  }
18
26
  const insertstmt = stmt.insertstmt();
@@ -42,114 +50,126 @@ function collectContextsOfType(ctx, targetType) {
42
50
  });
43
51
  return results;
44
52
  }
45
- function traverseSelectstmt(selectstmt, dbSchema, fromColumns, traverseResult) {
53
+ function traverseSelectstmt(selectstmt, context, traverseResult) {
46
54
  const result = collectContextsOfType(selectstmt, PostgreSQLParser_1.C_expr_exprContext).filter(c_expr => c_expr.PARAM());
47
55
  const paramIsListResult = result.map(param => paramIsList(param));
48
- const columns = traverse_selectstmt(selectstmt, dbSchema, fromColumns, traverseResult);
56
+ const columns = traverse_selectstmt(selectstmt, context, traverseResult);
49
57
  //select parameters are collected after from paramters
50
58
  traverseResult.parameters.sort((param1, param2) => param1.paramIndex - param2.paramIndex);
51
- const columnsNullability = columns.map(col => !col.is_nullable);
52
- const multipleRowsResult = !isSingleRowResult(selectstmt, dbSchema);
59
+ const multipleRowsResult = !isSingleRowResult(selectstmt, context.dbSchema);
53
60
  const limit = checkLimit(selectstmt);
54
- return {
61
+ const postgresTraverseResult = {
55
62
  queryType: 'Select',
56
63
  multipleRowsResult,
57
- columnsNullability,
64
+ columns,
58
65
  parametersNullability: traverseResult.parameters.map(param => param.isNotNull),
59
66
  parameterList: paramIsListResult,
60
67
  limit
61
68
  };
69
+ if (traverseResult.relations) {
70
+ postgresTraverseResult.relations = traverseResult.relations;
71
+ }
72
+ return postgresTraverseResult;
62
73
  }
63
- function traverse_selectstmt(selectstmt, dbSchema, fromColumns, traverseResult) {
74
+ function traverse_selectstmt(selectstmt, context, traverseResult) {
64
75
  const select_no_parens = selectstmt.select_no_parens();
65
76
  if (select_no_parens) {
66
- return traverse_select_no_parens(select_no_parens, dbSchema, fromColumns, traverseResult);
77
+ return traverse_select_no_parens(select_no_parens, context, traverseResult);
67
78
  }
68
79
  return [];
69
80
  }
70
- function traverse_select_no_parens(select_no_parens, dbSchema, fromColumns, traverseResult) {
81
+ function traverse_select_no_parens(select_no_parens, context, traverseResult) {
71
82
  let withColumns = [];
72
83
  const with_clause = select_no_parens.with_clause();
73
84
  if (with_clause) {
74
85
  with_clause.cte_list().common_table_expr_list()
75
86
  .forEach(common_table_expr => {
76
- const withResult = traverse_common_table_expr(common_table_expr, dbSchema, withColumns.concat(fromColumns), traverseResult);
87
+ const newContext = Object.assign(Object.assign({}, context), { fromColumns: withColumns.concat(context.fromColumns) });
88
+ const withResult = traverse_common_table_expr(common_table_expr, newContext, traverseResult);
77
89
  withColumns.push(...withResult);
78
90
  });
79
91
  }
80
92
  const select_clause = select_no_parens.select_clause();
81
93
  if (select_clause) {
82
- return traverse_select_clause(select_clause, dbSchema, withColumns.concat(fromColumns), traverseResult);
94
+ const newContext = Object.assign(Object.assign({}, context), { fromColumns: withColumns.concat(context.fromColumns) });
95
+ return traverse_select_clause(select_clause, newContext, traverseResult);
83
96
  }
84
97
  return [];
85
98
  }
86
- function traverse_common_table_expr(common_table_expr, dbSchema, fromColumns, traverseResult) {
99
+ function traverse_common_table_expr(common_table_expr, context, traverseResult) {
87
100
  const tableName = common_table_expr.name().getText();
88
101
  const select_stmt = common_table_expr.preparablestmt().selectstmt();
89
102
  if (select_stmt) {
90
- const columns = traverse_selectstmt(select_stmt, dbSchema, fromColumns, traverseResult);
103
+ const columns = traverse_selectstmt(select_stmt, context, traverseResult);
91
104
  const columnsWithTalbeName = columns.map(col => (Object.assign(Object.assign({}, col), { table_name: tableName })));
92
105
  return columnsWithTalbeName;
93
106
  }
94
107
  return [];
95
108
  }
96
- function traverse_select_clause(select_clause, dbSchema, fromColumns, traverseResult) {
109
+ function traverse_select_clause(select_clause, context, traverseResult) {
97
110
  const simple_select_intersect_list = select_clause.simple_select_intersect_list();
98
111
  let selectColumns = [];
99
112
  if (simple_select_intersect_list) {
100
- selectColumns = traverse_simple_select_intersect(simple_select_intersect_list[0], dbSchema, fromColumns, traverseResult);
113
+ selectColumns = traverse_simple_select_intersect(simple_select_intersect_list[0], context, traverseResult);
101
114
  }
102
115
  //union
103
116
  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);
117
+ const unionNotNull = traverse_simple_select_intersect(simple_select_intersect_list[index], context, traverseResult);
105
118
  selectColumns = selectColumns.map((value, columnIndex) => {
106
- const col = Object.assign(Object.assign({}, value), { is_nullable: value.is_nullable || unionNotNull[columnIndex].is_nullable });
119
+ const col = {
120
+ column_name: value.column_name,
121
+ is_nullable: value.is_nullable || unionNotNull[columnIndex].is_nullable,
122
+ table_name: '',
123
+ table_schema: ''
124
+ };
107
125
  return col;
108
126
  });
109
127
  }
110
128
  return selectColumns;
111
129
  }
112
- function traverse_simple_select_intersect(simple_select_intersect, dbSchema, fromColumns, traverseResult) {
130
+ function traverse_simple_select_intersect(simple_select_intersect, context, traverseResult) {
113
131
  const simple_select_pramary = simple_select_intersect.simple_select_pramary_list()[0];
114
132
  if (simple_select_pramary) {
115
- return traverse_simple_select_pramary(simple_select_pramary, dbSchema, fromColumns, traverseResult);
133
+ return traverse_simple_select_pramary(simple_select_pramary, context, traverseResult);
116
134
  }
117
135
  return [];
118
136
  }
119
- function traverse_simple_select_pramary(simple_select_pramary, dbSchema, parentFromColumns, traverseResult) {
137
+ function traverse_simple_select_pramary(simple_select_pramary, context, traverseResult) {
120
138
  var _a;
121
139
  const fromColumns = [];
122
140
  const from_clause = simple_select_pramary.from_clause();
123
141
  if (from_clause) {
124
142
  const where_clause = simple_select_pramary.where_clause();
125
- const fields = traverse_from_clause(from_clause, dbSchema, parentFromColumns, traverseResult);
143
+ const fields = traverse_from_clause(from_clause, context, traverseResult);
126
144
  const fieldsNotNull = where_clause != null ? fields.map(field => checkIsNullable(where_clause, field)) : fields;
127
145
  fromColumns.push(...fieldsNotNull);
128
146
  }
129
147
  const values_clause = simple_select_pramary.values_clause();
130
148
  if (values_clause) {
131
- const valuesColumns = traverse_values_clause(values_clause, dbSchema, parentFromColumns, traverseResult);
149
+ const valuesColumns = traverse_values_clause(values_clause, context, traverseResult);
132
150
  return valuesColumns;
133
151
  }
134
152
  const where_a_expr = (_a = simple_select_pramary.where_clause()) === null || _a === void 0 ? void 0 : _a.a_expr();
153
+ //fromColumns has precedence
154
+ const newContext = Object.assign(Object.assign({}, context), { fromColumns: fromColumns.concat(context.fromColumns) });
135
155
  if (where_a_expr) {
136
- traverse_a_expr(where_a_expr, dbSchema, parentFromColumns.concat(fromColumns), traverseResult);
156
+ traverse_a_expr(where_a_expr, newContext, traverseResult);
137
157
  }
138
- const filteredColumns = filterColumns_simple_select_pramary(simple_select_pramary, dbSchema, parentFromColumns.concat(fromColumns), traverseResult);
158
+ const filteredColumns = filterColumns_simple_select_pramary(simple_select_pramary, newContext, traverseResult);
139
159
  return filteredColumns;
140
160
  }
141
- function traverse_values_clause(values_clause, dbSchema, fromColumns, traverseResult) {
161
+ function traverse_values_clause(values_clause, context, traverseResult) {
142
162
  const expr_list_list = values_clause.expr_list_list();
143
163
  if (expr_list_list) {
144
- return expr_list_list.flatMap(expr_list => traverse_expr_list(expr_list, dbSchema, fromColumns, traverseResult));
164
+ return expr_list_list.flatMap(expr_list => traverse_expr_list(expr_list, context, traverseResult));
145
165
  }
146
166
  return [];
147
167
  }
148
- function traverse_expr_list(expr_list, dbSchema, fromColumns, traverseResult) {
168
+ function traverse_expr_list(expr_list, context, traverseResult) {
149
169
  const columns = expr_list.a_expr_list().map(a_expr => {
150
- const notNull = traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult);
170
+ const notNull = traverse_a_expr(a_expr, context, traverseResult);
151
171
  const result = {
152
- column_name: a_expr.getText(),
172
+ column_name: '?column?',
153
173
  is_nullable: !notNull,
154
174
  table_name: '',
155
175
  table_schema: ''
@@ -158,234 +178,279 @@ function traverse_expr_list(expr_list, dbSchema, fromColumns, traverseResult) {
158
178
  });
159
179
  return columns;
160
180
  }
161
- function filterColumns_simple_select_pramary(simple_select_pramary, dbSchema, fromColumns, traverseResult) {
181
+ function filterColumns_simple_select_pramary(simple_select_pramary, context, traverseResult) {
162
182
  const target_list_ = simple_select_pramary.target_list_();
163
183
  if (target_list_) {
164
184
  const target_list = target_list_.target_list();
165
185
  if (target_list) {
166
- return traverse_target_list(target_list, dbSchema, fromColumns, traverseResult);
186
+ return traverse_target_list(target_list, context, traverseResult);
167
187
  }
168
188
  }
169
189
  const target_list = simple_select_pramary.target_list();
170
190
  if (target_list) {
171
- return traverse_target_list(target_list, dbSchema, fromColumns, traverseResult);
191
+ return traverse_target_list(target_list, context, traverseResult);
172
192
  }
173
193
  return [];
174
194
  }
175
- function traverse_target_list(target_list, dbSchema, fromColumns, traverseResult) {
195
+ function traverse_target_list(target_list, context, traverseResult) {
176
196
  const columns = target_list.target_el_list().flatMap(target_el => {
177
197
  const fieldName = (0, select_columns_1.splitName)(target_el.getText());
178
198
  if (fieldName.name == '*') {
179
- const columns = filterColumns(fromColumns, fieldName);
199
+ const columns = filterColumns(context.fromColumns, fieldName);
180
200
  return columns;
181
201
  }
182
- const column = isNotNull_target_el(target_el, dbSchema, fromColumns, traverseResult);
202
+ const column = isNotNull_target_el(target_el, context, traverseResult);
183
203
  return [column];
184
204
  });
185
205
  return columns;
186
206
  }
187
- function isNotNull_target_el(target_el, dbSchema, fromColumns, traverseResult) {
207
+ function isNotNull_target_el(target_el, context, traverseResult) {
208
+ var _a;
188
209
  if (target_el instanceof PostgreSQLParser_1.Target_labelContext) {
189
210
  const a_expr = target_el.a_expr();
190
- const exprResult = traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult);
211
+ const exprResult = traverse_a_expr(a_expr, context, traverseResult);
191
212
  const colLabel = target_el.colLabel();
192
213
  const alias = colLabel != null ? colLabel.getText() : '';
193
- const fieldName = (0, select_columns_1.splitName)(a_expr.getText());
214
+ if (alias) {
215
+ (_a = traverseResult.relations) === null || _a === void 0 ? void 0 : _a.forEach(relation => {
216
+ if ((relation.name === exprResult.table_name || relation.alias === exprResult.table_name)
217
+ && relation.joinColumn === exprResult.column_name) {
218
+ relation.joinColumn = alias;
219
+ }
220
+ });
221
+ }
194
222
  return {
195
- column_name: alias || fieldName.name,
223
+ column_name: alias || exprResult.column_name,
196
224
  is_nullable: exprResult.is_nullable,
197
- table_name: fieldName.prefix,
198
- table_schema: ''
225
+ table_name: exprResult.table_name,
226
+ table_schema: exprResult.table_schema
199
227
  };
200
228
  }
201
229
  throw Error('Column not found');
202
230
  }
203
- function traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult) {
231
+ function traverse_a_expr(a_expr, context, traverseResult) {
204
232
  const a_expr_qual = a_expr.a_expr_qual();
205
233
  if (a_expr_qual) {
206
- const notNull = traverse_a_expr_qual(a_expr_qual, dbSchema, fromColumns, traverseResult);
234
+ const notNull = traverse_a_expr_qual(a_expr_qual, context, traverseResult);
207
235
  return notNull;
208
236
  }
209
237
  return {
210
238
  column_name: '',
211
- is_nullable: true
239
+ is_nullable: true,
240
+ table_name: '',
241
+ table_schema: ''
212
242
  };
213
243
  }
214
- function traverse_a_expr_qual(a_expr_qual, dbSchema, fromColumns, traverseResult) {
244
+ function traverse_a_expr_qual(a_expr_qual, context, traverseResult) {
215
245
  const a_expr_lessless = a_expr_qual.a_expr_lessless();
216
246
  if (a_expr_lessless) {
217
- return traverse_a_expr_lessless(a_expr_lessless, dbSchema, fromColumns, traverseResult);
247
+ return traverse_a_expr_lessless(a_expr_lessless, context, traverseResult);
218
248
  }
219
249
  throw Error('traverse_a_expr_qual - Not expected:' + a_expr_qual.getText());
220
250
  }
221
- function traverse_a_expr_lessless(a_expr_lessless, dbSchema, fromColumns, traverseResult) {
251
+ function traverse_a_expr_lessless(a_expr_lessless, context, traverseResult) {
222
252
  const a_expr_or = a_expr_lessless.a_expr_or_list()[0];
223
253
  if (a_expr_or) {
224
- return traverse_expr_or(a_expr_or, dbSchema, fromColumns, traverseResult);
254
+ return traverse_expr_or(a_expr_or, context, traverseResult);
225
255
  }
226
256
  throw Error('traverse_a_expr_lessless - Not expected:' + a_expr_lessless.getText());
227
257
  }
228
- function traverse_expr_or(a_expr_or, dbSchema, fromColumns, traverseResult) {
258
+ function traverse_expr_or(a_expr_or, context, traverseResult) {
229
259
  const a_expr_and = a_expr_or.a_expr_and_list()[0];
230
260
  if (a_expr_and) {
231
- return traverse_expr_and(a_expr_and, dbSchema, fromColumns, traverseResult);
261
+ return traverse_expr_and(a_expr_and, context, traverseResult);
232
262
  }
233
263
  throw Error('traverse_expr_or - Not expected:' + a_expr_or.getText());
234
264
  }
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));
265
+ function traverse_expr_and(a_expr_and, context, traverseResult) {
266
+ const result = a_expr_and.a_expr_between_list().map(a_expr_between => traverse_expr_between(a_expr_between, context, traverseResult));
267
+ if (result.length === 1) {
268
+ return result[0];
269
+ }
237
270
  return {
238
- column_name: a_expr_and.getText(),
239
- is_nullable: result.some(col => col.is_nullable)
271
+ column_name: '?column?',
272
+ is_nullable: result.some(col => col.is_nullable),
273
+ table_name: '',
274
+ table_schema: ''
240
275
  };
241
276
  }
242
- function traverse_expr_between(a_expr_between, dbSchema, fromColumns, traverseResult) {
277
+ function traverse_expr_between(a_expr_between, context, traverseResult) {
243
278
  const a_expr_in = a_expr_between.a_expr_in_list()[0];
244
279
  if (a_expr_in) {
245
- return traverse_expr_in(a_expr_in, dbSchema, fromColumns, traverseResult);
280
+ return traverse_expr_in(a_expr_in, context, traverseResult);
246
281
  }
247
282
  throw Error('traverse_expr_between - Not expected:' + a_expr_between.getText());
248
283
  }
249
- function traverse_expr_in(a_expr_in, dbSchema, fromColumns, traverseResult) {
284
+ function traverse_expr_in(a_expr_in, context, traverseResult) {
250
285
  const a_expr_unary = a_expr_in.a_expr_unary_not();
251
286
  let leftExprResult = undefined;
252
287
  if (a_expr_unary) {
253
- leftExprResult = traverse_expr_unary(a_expr_unary, dbSchema, fromColumns, traverseResult);
288
+ leftExprResult = traverse_expr_unary(a_expr_unary, context, traverseResult);
254
289
  }
255
290
  const in_expr = a_expr_in.in_expr();
256
291
  if (in_expr) {
257
- traverse_in_expr(in_expr, dbSchema, fromColumns, traverseResult);
292
+ traverse_in_expr(in_expr, context, traverseResult);
293
+ }
294
+ if (in_expr === null && leftExprResult != null) {
295
+ return leftExprResult;
258
296
  }
259
297
  return {
260
298
  column_name: a_expr_in.getText(),
261
299
  //id in (...) -> is_nullable: false
262
300
  // value -> is_nullable = leftExprResult.is_nullable
263
- is_nullable: in_expr != null ? false : leftExprResult.is_nullable
301
+ is_nullable: in_expr != null ? false : leftExprResult.is_nullable,
302
+ table_name: '',
303
+ table_schema: ''
264
304
  };
265
305
  }
266
- function traverse_in_expr(in_expr, dbSchema, fromColumns, traverseResult) {
306
+ function traverse_in_expr(in_expr, context, traverseResult) {
267
307
  if (in_expr instanceof PostgreSQLParser_1.In_expr_selectContext) {
268
308
  const select_with_parens = in_expr.select_with_parens();
269
- traverse_select_with_parens(select_with_parens, dbSchema, fromColumns, traverseResult);
309
+ traverse_select_with_parens(select_with_parens, context, traverseResult);
270
310
  }
271
311
  if (in_expr instanceof PostgreSQLParser_1.In_expr_listContext) {
272
312
  in_expr.expr_list().a_expr_list().forEach(a_expr => {
273
- traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult);
313
+ traverse_a_expr(a_expr, context, traverseResult);
274
314
  });
275
315
  }
276
316
  }
277
- function traverse_expr_unary(a_expr_unary, dbSchema, fromColumns, traverseResult) {
317
+ function traverse_expr_unary(a_expr_unary, context, traverseResult) {
278
318
  const a_expr_isnull = a_expr_unary.a_expr_isnull();
279
319
  if (a_expr_isnull) {
280
- return traverse_expr_isnull(a_expr_isnull, dbSchema, fromColumns, traverseResult);
320
+ return traverse_expr_isnull(a_expr_isnull, context, traverseResult);
281
321
  }
282
322
  throw Error('traverse_expr_unary - Not expected:' + a_expr_unary.getText());
283
323
  }
284
- function traverse_expr_isnull(a_expr_isnull, dbSchema, fromColumns, traverseResult) {
324
+ function traverse_expr_isnull(a_expr_isnull, context, traverseResult) {
285
325
  const a_expr_is_not = a_expr_isnull.a_expr_is_not();
286
326
  if (a_expr_is_not) {
287
- return traverse_expr_is_not(a_expr_is_not, dbSchema, fromColumns, traverseResult);
327
+ return traverse_expr_is_not(a_expr_is_not, context, traverseResult);
288
328
  }
289
329
  throw Error('traverse_expr_isnull - Not expected:' + a_expr_isnull.getText());
290
330
  }
291
- function traverse_expr_is_not(a_expr_is_not, dbSchema, fromColumns, traverseResult) {
331
+ function traverse_expr_is_not(a_expr_is_not, context, traverseResult) {
292
332
  const a_expr_compare = a_expr_is_not.a_expr_compare();
293
333
  if (a_expr_compare) {
294
- return traverse_expr_compare(a_expr_compare, dbSchema, fromColumns, traverseResult);
334
+ return traverse_expr_compare(a_expr_compare, context, traverseResult);
295
335
  }
296
336
  throw Error('traverse_expr_is_not - Not expected:' + a_expr_is_not.getText());
297
337
  }
298
- function traverse_expr_compare(a_expr_compare, dbSchema, fromColumns, traverseResult) {
338
+ function traverse_expr_compare(a_expr_compare, context, traverseResult) {
299
339
  const a_expr_like_list = a_expr_compare.a_expr_like_list();
300
340
  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));
341
+ const result = a_expr_like_list.map(a_expr_like => traverse_expr_like(a_expr_like, context, traverseResult));
342
+ if (result.length === 1) {
343
+ return result[0];
344
+ }
302
345
  return {
303
- column_name: a_expr_compare.getText(),
304
- is_nullable: result.some(col => col.is_nullable)
346
+ column_name: '?column?',
347
+ is_nullable: result.some(col => col.is_nullable),
348
+ table_name: '',
349
+ table_schema: ''
305
350
  };
306
351
  }
307
352
  throw Error('traverse_expr_compare - Not expected:' + a_expr_compare.getText());
308
353
  }
309
- function traverse_expr_like(a_expr_like, dbSchema, fromColumns, traverseResult) {
354
+ function traverse_expr_like(a_expr_like, context, traverseResult) {
310
355
  const a_expr_qual_op_list = a_expr_like.a_expr_qual_op_list();
311
356
  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));
357
+ const result = a_expr_qual_op_list.map(a_expr_qual_op => traverse_expr_qual_op(a_expr_qual_op, context, traverseResult));
358
+ if (result.length === 1) {
359
+ return result[0];
360
+ }
313
361
  return {
314
- column_name: a_expr_like.getText(),
315
- is_nullable: result.some(col => col.is_nullable)
362
+ column_name: '?column?',
363
+ is_nullable: result.some(col => col.is_nullable),
364
+ table_name: '',
365
+ table_schema: ''
316
366
  };
317
367
  }
318
368
  throw Error('traverse_expr_like - Not expected:' + a_expr_like.getText());
319
369
  }
320
- function traverse_expr_qual_op(a_expr_qual_op, dbSchema, fromColumns, traverseResult) {
370
+ function traverse_expr_qual_op(a_expr_qual_op, context, traverseResult) {
321
371
  const a_expr_unary_qualop = a_expr_qual_op.a_expr_unary_qualop_list()[0];
322
372
  if (a_expr_unary_qualop) {
323
- return traverse_expr_unary_qualop(a_expr_unary_qualop, dbSchema, fromColumns, traverseResult);
373
+ return traverse_expr_unary_qualop(a_expr_unary_qualop, context, traverseResult);
324
374
  }
325
375
  throw Error('traverse_expr_qual_op - Not expected:' + a_expr_qual_op.getText());
326
376
  }
327
- function traverse_expr_unary_qualop(a_expr_unary_qualop, dbSchema, fromColumns, traverseResult) {
377
+ function traverse_expr_unary_qualop(a_expr_unary_qualop, context, traverseResult) {
328
378
  const a_expr_add = a_expr_unary_qualop.a_expr_add();
329
379
  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));
380
+ const exprResult = a_expr_add.a_expr_mul_list().map(a_expr_mul => traverse_expr_mul(a_expr_mul, context, traverseResult));
381
+ if (exprResult.length === 1) {
382
+ return exprResult[0];
383
+ }
331
384
  const result = {
332
- column_name: a_expr_unary_qualop.getText(),
333
- is_nullable: exprResult.some(col => col.is_nullable)
385
+ column_name: '?column?',
386
+ is_nullable: exprResult.some(col => col.is_nullable),
387
+ table_name: '',
388
+ table_schema: ''
334
389
  };
335
390
  return result;
336
391
  }
337
392
  throw Error('traverse_expr_unary_qualop - Not expected:' + a_expr_unary_qualop.getText());
338
393
  }
339
- function traverse_expr_mul(a_expr_mul, dbSchema, fromColumns, traverseResult) {
394
+ function traverse_expr_mul(a_expr_mul, context, traverseResult) {
340
395
  const a_expr_mul_list = a_expr_mul.a_expr_caret_list();
341
396
  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));
397
+ const notNullInfo = a_expr_mul.a_expr_caret_list().map(a_expr_caret => traverse_expr_caret(a_expr_caret, context, traverseResult));
398
+ if (notNullInfo.length === 1) {
399
+ return notNullInfo[0];
400
+ }
343
401
  const result = {
344
- column_name: a_expr_mul.getText(),
345
- is_nullable: notNullInfo.some(notNullInfo => notNullInfo.is_nullable)
402
+ column_name: '?column?',
403
+ is_nullable: notNullInfo.some(notNullInfo => notNullInfo.is_nullable),
404
+ table_name: '',
405
+ table_schema: ''
346
406
  };
347
407
  return result;
348
408
  }
349
409
  throw Error('traverse_expr_mul - Not expected:' + a_expr_mul.getText());
350
410
  }
351
- function traverse_expr_caret(a_expr_caret, dbSchema, fromColumns, traverseResult) {
411
+ function traverse_expr_caret(a_expr_caret, context, traverseResult) {
352
412
  const a_expr_unary_sign_list = a_expr_caret.a_expr_unary_sign_list();
353
413
  if (a_expr_unary_sign_list) {
354
414
  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));
415
+ .map(a_expr_unary_sign => traverse_expr_unary_sign(a_expr_unary_sign, context, traverseResult));
416
+ if (notNullInfo.length === 1) {
417
+ return notNullInfo[0];
418
+ }
356
419
  const result = {
357
- column_name: a_expr_caret.getText(),
358
- is_nullable: notNullInfo.some(notNullInfo => notNullInfo.is_nullable)
420
+ column_name: '?column?',
421
+ is_nullable: notNullInfo.some(notNullInfo => notNullInfo.is_nullable),
422
+ table_name: '',
423
+ table_schema: ''
359
424
  };
360
425
  return result;
361
426
  }
362
427
  throw Error('traverse_expr_caret - Not expected:' + a_expr_caret.getText());
363
428
  }
364
- function traverse_expr_unary_sign(a_expr_unary_sign, dbSchema, fromColumns, traverseResult) {
429
+ function traverse_expr_unary_sign(a_expr_unary_sign, context, traverseResult) {
365
430
  const a_expr_at_time_zone = a_expr_unary_sign.a_expr_at_time_zone();
366
431
  if (a_expr_at_time_zone) {
367
- return traverse_expr_at_time_zone(a_expr_at_time_zone, dbSchema, fromColumns, traverseResult);
432
+ return traverse_expr_at_time_zone(a_expr_at_time_zone, context, traverseResult);
368
433
  }
369
434
  throw Error('traverse_expr_unary_sign - Not expected:' + a_expr_unary_sign.getText());
370
435
  }
371
- function traverse_expr_at_time_zone(a_expr_at_time_zone, dbSchema, fromColumns, traverseResult) {
436
+ function traverse_expr_at_time_zone(a_expr_at_time_zone, context, traverseResult) {
372
437
  const a_expr_collate = a_expr_at_time_zone.a_expr_collate();
373
438
  if (a_expr_collate) {
374
- return traverse_expr_collate(a_expr_collate, dbSchema, fromColumns, traverseResult);
439
+ return traverse_expr_collate(a_expr_collate, context, traverseResult);
375
440
  }
376
441
  throw Error('traverse_expr_at_time_zone - Not expected:' + a_expr_at_time_zone.getText());
377
442
  }
378
- function traverse_expr_collate(a_expr_collate, dbSchema, fromColumns, traverseResult) {
443
+ function traverse_expr_collate(a_expr_collate, context, traverseResult) {
379
444
  const a_expr_typecast = a_expr_collate.a_expr_typecast();
380
445
  if (a_expr_typecast) {
381
- return traverse_expr_typecast(a_expr_typecast, dbSchema, fromColumns, traverseResult);
446
+ return traverse_expr_typecast(a_expr_typecast, context, traverseResult);
382
447
  }
383
448
  throw Error('traverse_expr_collate - Not expected:' + a_expr_collate.getText());
384
449
  }
385
- function traverse_expr_typecast(a_expr_typecast, dbSchema, fromColumns, traverseResult) {
450
+ function traverse_expr_typecast(a_expr_typecast, context, traverseResult) {
386
451
  const c_expr = a_expr_typecast.c_expr();
387
452
  if (c_expr) {
388
- return traversec_expr(c_expr, dbSchema, fromColumns, traverseResult);
453
+ return traversec_expr(c_expr, context, traverseResult);
389
454
  }
390
455
  throw Error('traverse_expr_typecast - Not expected:' + a_expr_typecast.getText());
391
456
  }
@@ -394,12 +459,12 @@ function traverseColumnRef(columnref, fromColumns) {
394
459
  const col = findColumn(fieldName, fromColumns);
395
460
  return col;
396
461
  }
397
- function traversec_expr(c_expr, dbSchema, fromColumns, traverseResult) {
398
- var _a, _b;
462
+ function traversec_expr(c_expr, context, traverseResult) {
463
+ var _a, _b, _c, _d, _e;
399
464
  if (c_expr instanceof PostgreSQLParser_1.C_expr_exprContext) {
400
465
  const columnref = c_expr.columnref();
401
466
  if (columnref) {
402
- const col = traverseColumnRef(columnref, fromColumns);
467
+ const col = traverseColumnRef(columnref, context.fromColumns);
403
468
  return col;
404
469
  }
405
470
  const aexprconst = c_expr.aexprconst();
@@ -407,7 +472,9 @@ function traversec_expr(c_expr, dbSchema, fromColumns, traverseResult) {
407
472
  const is_nullable = aexprconst.NULL_P() != null;
408
473
  return {
409
474
  column_name: aexprconst.getText(),
410
- is_nullable
475
+ is_nullable,
476
+ table_name: '',
477
+ table_schema: ''
411
478
  };
412
479
  }
413
480
  if (c_expr.PARAM()) {
@@ -417,57 +484,77 @@ function traversec_expr(c_expr, dbSchema, fromColumns, traverseResult) {
417
484
  });
418
485
  return {
419
486
  column_name: c_expr.PARAM().getText(),
420
- is_nullable: false
487
+ is_nullable: false,
488
+ table_name: '',
489
+ table_schema: ''
421
490
  };
422
491
  }
423
492
  const func_application = (_a = c_expr.func_expr()) === null || _a === void 0 ? void 0 : _a.func_application();
424
493
  if (func_application) {
425
- const isNotNull = traversefunc_application(func_application, dbSchema, fromColumns, traverseResult);
494
+ const isNotNull = traversefunc_application(func_application, context, traverseResult);
426
495
  return {
427
- column_name: func_application.getText(),
428
- is_nullable: !isNotNull
496
+ column_name: ((_b = func_application.func_name()) === null || _b === void 0 ? void 0 : _b.getText()) || func_application.getText(),
497
+ is_nullable: !isNotNull,
498
+ table_name: '',
499
+ table_schema: ''
429
500
  };
430
501
  }
431
- const func_expr_common_subexpr = (_b = c_expr.func_expr()) === null || _b === void 0 ? void 0 : _b.func_expr_common_subexpr();
502
+ const func_expr_common_subexpr = (_c = c_expr.func_expr()) === null || _c === void 0 ? void 0 : _c.func_expr_common_subexpr();
432
503
  if (func_expr_common_subexpr) {
433
- const isNotNull = traversefunc_expr_common_subexpr(func_expr_common_subexpr, dbSchema, fromColumns, traverseResult);
504
+ const isNotNull = traversefunc_expr_common_subexpr(func_expr_common_subexpr, context, traverseResult);
434
505
  return {
435
- column_name: func_expr_common_subexpr.getText(),
436
- is_nullable: !isNotNull
506
+ 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(),
507
+ is_nullable: !isNotNull,
508
+ table_name: '',
509
+ table_schema: ''
437
510
  };
438
511
  }
439
512
  const select_with_parens = c_expr.select_with_parens();
440
513
  if (select_with_parens) {
441
- traverse_select_with_parens(select_with_parens, dbSchema, fromColumns, traverseResult);
514
+ traverse_select_with_parens(select_with_parens, context, traverseResult);
442
515
  return {
443
- column_name: select_with_parens.getText(),
444
- is_nullable: true
516
+ column_name: '?column?',
517
+ is_nullable: true,
518
+ table_name: '',
519
+ table_schema: ''
445
520
  };
446
521
  }
447
522
  const a_expr_in_parens = c_expr._a_expr_in_parens;
448
523
  if (a_expr_in_parens) {
449
- return traverse_a_expr(a_expr_in_parens, dbSchema, fromColumns, traverseResult);
524
+ return traverse_a_expr(a_expr_in_parens, context, traverseResult);
450
525
  }
451
526
  }
452
527
  if (c_expr instanceof PostgreSQLParser_1.C_expr_caseContext) {
453
- const isNotNull = traversec_expr_case(c_expr, dbSchema, fromColumns, traverseResult);
528
+ const isNotNull = traversec_expr_case(c_expr, context, traverseResult);
454
529
  return {
455
- column_name: c_expr.getText(),
456
- is_nullable: !isNotNull
530
+ column_name: '?column?',
531
+ is_nullable: !isNotNull,
532
+ table_name: '',
533
+ table_schema: ''
457
534
  };
458
535
  }
459
536
  if (c_expr instanceof PostgreSQLParser_1.C_expr_existsContext) {
460
537
  //todo - traverse
461
538
  return {
462
- column_name: c_expr.getText(),
463
- is_nullable: false
539
+ column_name: '?column?',
540
+ is_nullable: false,
541
+ table_name: '',
542
+ table_schema: ''
464
543
  };
465
544
  }
466
545
  throw Error('traversec_expr - Not expected:' + c_expr.getText());
467
546
  }
468
547
  function filterColumns(fromColumns, fieldName) {
469
548
  return fromColumns.filter(col => (fieldName.prefix === '' || col.table_name === fieldName.prefix)
470
- && (fieldName.name === '*' || col.column_name === fieldName.name));
549
+ && (fieldName.name === '*' || col.column_name === fieldName.name)).map(col => {
550
+ const result = {
551
+ column_name: col.column_name,
552
+ is_nullable: col.is_nullable,
553
+ table_name: col.table_name,
554
+ table_schema: col.table_schema
555
+ };
556
+ return result;
557
+ });
471
558
  }
472
559
  function excludeColumns(fromColumns, excludeList) {
473
560
  return fromColumns.filter(col => {
@@ -476,21 +563,21 @@ function excludeColumns(fromColumns, excludeList) {
476
563
  return !found;
477
564
  });
478
565
  }
479
- function traversec_expr_case(c_expr_case, dbSchema, fromColumns, traverseResult) {
566
+ function traversec_expr_case(c_expr_case, context, traverseResult) {
480
567
  var _a;
481
568
  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));
569
+ const whenResult = case_expr.when_clause_list().when_clause_list().map(when_clause => traversewhen_clause(when_clause, context, traverseResult));
483
570
  const whenIsNotNull = whenResult.every(when => when);
484
571
  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;
572
+ const elseIsNotNull = elseExpr ? !traverse_a_expr(elseExpr, context, traverseResult).is_nullable : false;
486
573
  return elseIsNotNull && whenIsNotNull;
487
574
  }
488
- function traversewhen_clause(when_clause, dbSchema, fromColumns, traverseResult) {
575
+ function traversewhen_clause(when_clause, context, traverseResult) {
489
576
  const a_expr_list = when_clause.a_expr_list();
490
577
  const [whenExprList, thenExprList] = partition(a_expr_list, (index) => index % 2 === 0);
491
578
  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);
579
+ traverse_a_expr(whenExprList[index], context, traverseResult);
580
+ const thenExprResult = traverse_a_expr(thenExpr, context, traverseResult);
494
581
  return thenExprResult;
495
582
  });
496
583
  return whenExprResult.every(res => res);
@@ -506,11 +593,11 @@ function partition(array, predicate) {
506
593
  return acc;
507
594
  }, [[], []]);
508
595
  }
509
- function traversefunc_application(func_application, dbSchema, fromColumns, traverseResult) {
596
+ function traversefunc_application(func_application, context, traverseResult) {
510
597
  var _a;
511
598
  const functionName = func_application.func_name().getText().toLowerCase();
512
599
  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));
600
+ const argsResult = func_arg_expr_list.map(func_arg_expr => traversefunc_arg_expr(func_arg_expr, context, traverseResult));
514
601
  if (functionName === 'count') {
515
602
  return true;
516
603
  }
@@ -528,15 +615,15 @@ function traversefunc_application(func_application, dbSchema, fromColumns, trave
528
615
  return true;
529
616
  }
530
617
  if (func_arg_expr_list) {
531
- func_arg_expr_list.forEach(func_arg_expr => traversefunc_arg_expr(func_arg_expr, dbSchema, fromColumns, traverseResult));
618
+ func_arg_expr_list.forEach(func_arg_expr => traversefunc_arg_expr(func_arg_expr, context, traverseResult));
532
619
  }
533
620
  return false;
534
621
  }
535
- function traversefunc_expr_common_subexpr(func_expr_common_subexpr, dbSchema, fromColumns, traverseResult) {
622
+ function traversefunc_expr_common_subexpr(func_expr_common_subexpr, context, traverseResult) {
536
623
  if (func_expr_common_subexpr.COALESCE()) {
537
624
  const func_arg_list = func_expr_common_subexpr.expr_list().a_expr_list();
538
625
  const result = func_arg_list.map(func_arg_expr => {
539
- const paramResult = traverse_a_expr(func_arg_expr, dbSchema, fromColumns, traverseResult);
626
+ const paramResult = traverse_a_expr(func_arg_expr, context, traverseResult);
540
627
  if (isParameter(paramResult.column_name)) {
541
628
  traverseResult.parameters[traverseResult.parameters.length - 1].isNotNull = false;
542
629
  paramResult.is_nullable = true;
@@ -547,14 +634,14 @@ function traversefunc_expr_common_subexpr(func_expr_common_subexpr, dbSchema, fr
547
634
  }
548
635
  if (func_expr_common_subexpr.EXTRACT()) {
549
636
  const a_expr = func_expr_common_subexpr.extract_list().a_expr();
550
- const result = traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult);
637
+ const result = traverse_a_expr(a_expr, context, traverseResult);
551
638
  return !result.is_nullable;
552
639
  }
553
640
  return false;
554
641
  }
555
- function traversefunc_arg_expr(func_arg_expr, dbSchema, fromColumns, traverseResult) {
642
+ function traversefunc_arg_expr(func_arg_expr, context, traverseResult) {
556
643
  const a_expr = func_arg_expr.a_expr();
557
- return !traverse_a_expr(a_expr, dbSchema, fromColumns, traverseResult).is_nullable;
644
+ return !traverse_a_expr(a_expr, context, traverseResult).is_nullable;
558
645
  }
559
646
  function findColumn(fieldName, fromColumns) {
560
647
  const col = fromColumns.find(col => (fieldName.prefix === '' || col.table_name.toLowerCase() === fieldName.prefix.toLowerCase()) && col.column_name.toLowerCase() === fieldName.name.toLowerCase());
@@ -571,18 +658,20 @@ function checkIsNullable(where_clause, field) {
571
658
  const col = Object.assign(Object.assign({}, field), { is_nullable: !isNotNullResult });
572
659
  return col;
573
660
  }
574
- function traverse_from_clause(from_clause, dbSchema, fromColumns, traverseResult) {
661
+ function traverse_from_clause(from_clause, context, traverseResult) {
575
662
  const from_list = from_clause.from_list();
576
663
  if (from_list) {
577
- return traverse_from_list(from_list, dbSchema, fromColumns, traverseResult);
664
+ return traverse_from_list(from_list, context, traverseResult);
578
665
  }
579
666
  return [];
580
667
  }
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));
668
+ function traverse_from_list(from_list, context, traverseResult) {
669
+ const newColumns = from_list.table_ref_list().flatMap(table_ref => traverse_table_ref(table_ref, context, traverseResult));
583
670
  return newColumns;
584
671
  }
585
- function traverse_table_ref(table_ref, dbSchema, fromColumns, traverseResult) {
672
+ function traverse_table_ref(table_ref, context, traverseResult) {
673
+ var _a, _b;
674
+ const { fromColumns, dbSchema } = context;
586
675
  const allColumns = [];
587
676
  const relation_expr = table_ref.relation_expr();
588
677
  const aliasClause = table_ref.alias_clause();
@@ -590,8 +679,23 @@ function traverse_table_ref(table_ref, dbSchema, fromColumns, traverseResult) {
590
679
  if (relation_expr) {
591
680
  const tableName = traverse_relation_expr(relation_expr, dbSchema);
592
681
  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 })));
682
+ const fromColumnsResult = fromColumns.concat(dbSchema).filter(col => col.table_name === tableName.name)
683
+ .map(col => (Object.assign(Object.assign({}, col), { table_name: tableNameWithAlias })));
594
684
  allColumns.push(...fromColumnsResult);
685
+ if (context.generateNestedInfo) {
686
+ const key = fromColumnsResult.filter(col => col.column_key === 'PRI');
687
+ const renameAs = (aliasClause === null || aliasClause === void 0 ? void 0 : aliasClause.AS()) != null;
688
+ const relation = {
689
+ name: tableName.name,
690
+ alias: alias || '',
691
+ renameAs,
692
+ parentRelation: '',
693
+ joinColumn: ((_a = key[0]) === null || _a === void 0 ? void 0 : _a.column_name) || '',
694
+ cardinality: 'one',
695
+ parentCardinality: 'one'
696
+ };
697
+ (_b = traverseResult.relations) === null || _b === void 0 ? void 0 : _b.push(relation);
698
+ }
595
699
  }
596
700
  const table_ref_list = table_ref.table_ref_list();
597
701
  const join_type_list = table_ref.join_type_list();
@@ -600,36 +704,67 @@ function traverse_table_ref(table_ref, dbSchema, fromColumns, traverseResult) {
600
704
  const joinColumns = table_ref_list.flatMap((table_ref, joinIndex) => {
601
705
  const joinType = join_type_list[joinIndex]; //INNER, LEFT
602
706
  const joinQual = join_qual_list[joinIndex];
603
- const joinColumns = traverse_table_ref(table_ref, dbSchema, fromColumns, traverseResult);
707
+ const joinColumns = traverse_table_ref(table_ref, context, traverseResult);
604
708
  const isUsing = (joinQual === null || joinQual === void 0 ? void 0 : joinQual.USING()) ? true : false;
605
709
  const isLeftJoin = joinType === null || joinType === void 0 ? void 0 : joinType.LEFT();
606
710
  const filteredColumns = isUsing ? filterUsingColumns(joinColumns, joinQual) : joinColumns;
607
711
  const resultColumns = isLeftJoin ? filteredColumns.map(col => (Object.assign(Object.assign({}, col), { is_nullable: true }))) : filteredColumns;
712
+ if (context.generateNestedInfo) {
713
+ collectNestedInfo(joinQual, resultColumns, traverseResult);
714
+ }
608
715
  return resultColumns;
609
716
  });
610
717
  allColumns.push(...joinColumns);
611
718
  }
612
719
  const select_with_parens = table_ref.select_with_parens();
613
720
  if (select_with_parens) {
614
- const columns = traverse_select_with_parens(select_with_parens, dbSchema, fromColumns, traverseResult);
721
+ const columns = traverse_select_with_parens(select_with_parens, context, traverseResult);
615
722
  const withAlias = columns.map(col => (Object.assign(Object.assign({}, col), { table_name: alias || col.table_name })));
616
723
  return withAlias;
617
724
  }
618
725
  return allColumns;
619
726
  }
727
+ function collectNestedInfo(joinQual, resultColumns, traverseResult) {
728
+ var _a;
729
+ const a_expr_or_list = joinQual ? collectContextsOfType(joinQual, PostgreSQLParser_1.A_expr_orContext) : [];
730
+ if (a_expr_or_list.length == 1) {
731
+ const a_expr_or = a_expr_or_list[0];
732
+ const a_expr_and = a_expr_or.a_expr_and_list()[0];
733
+ const columnref = collectContextsOfType(a_expr_and, PostgreSQLParser_1.ColumnrefContext);
734
+ const joinColumns = columnref.map(colRef => (0, select_columns_1.splitName)(colRef.getText()));
735
+ const currentRelation = (_a = traverseResult.relations) === null || _a === void 0 ? void 0 : _a.at(-1);
736
+ joinColumns.forEach(joinRef => {
737
+ if (currentRelation) {
738
+ const joinColumn = resultColumns.filter(col => col.column_name === joinRef.name)[0];
739
+ const unique = joinColumn && (joinColumn.column_key === 'PRI' || joinColumn.column_key === 'UNI');
740
+ if (joinRef.prefix === currentRelation.name || joinRef.prefix === currentRelation.alias) {
741
+ if (!unique) {
742
+ currentRelation.cardinality = 'many';
743
+ }
744
+ }
745
+ else {
746
+ currentRelation.parentRelation = joinRef.prefix;
747
+ if (!unique) {
748
+ currentRelation.parentCardinality = 'many';
749
+ }
750
+ }
751
+ }
752
+ });
753
+ }
754
+ }
620
755
  function filterUsingColumns(fromColumns, joinQual) {
621
756
  const excludeList = joinQual.name_list().name_list().map(name => (0, select_columns_1.splitName)(name.getText()));
622
757
  const filteredColumns = excludeColumns(fromColumns, excludeList);
623
758
  return filteredColumns;
624
759
  }
625
- function traverse_select_with_parens(select_with_parens, dbSchema, fromColumns, traverseResult) {
760
+ function traverse_select_with_parens(select_with_parens, context, traverseResult) {
626
761
  const select_with_parens2 = select_with_parens.select_with_parens();
627
762
  if (select_with_parens2) {
628
- return traverse_select_with_parens(select_with_parens2, dbSchema, fromColumns, traverseResult);
763
+ return traverse_select_with_parens(select_with_parens2, context, traverseResult);
629
764
  }
630
765
  const select_no_parens = select_with_parens.select_no_parens();
631
766
  if (select_no_parens) {
632
- return traverse_select_no_parens(select_no_parens, dbSchema, fromColumns, traverseResult);
767
+ return traverse_select_no_parens(select_no_parens, context, traverseResult);
633
768
  }
634
769
  return [];
635
770
  }
@@ -713,20 +848,25 @@ function traverseInsertstmt(insertstmt, dbSchema) {
713
848
  const insertColumnsList = insert_rest.insert_column_list()
714
849
  .insert_column_item_list()
715
850
  .map(insert_column_item => traverse_insert_column_item(insert_column_item, insertColumns));
851
+ const context = {
852
+ dbSchema,
853
+ fromColumns: insertColumns,
854
+ generateNestedInfo: false
855
+ };
716
856
  const selectstmt = insert_rest.selectstmt();
717
- traverse_insert_select_stmt(selectstmt, dbSchema, insertColumnsList, traverseResult);
857
+ traverse_insert_select_stmt(selectstmt, Object.assign(Object.assign({}, context), { fromColumns: insertColumnsList }), traverseResult);
718
858
  const on_conflict = insertstmt.on_conflict_();
719
859
  if (on_conflict) {
720
860
  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));
861
+ set_clause_list.forEach(set_clause => traverse_set_clause(set_clause, context, traverseResult));
722
862
  }
723
863
  const returning_clause = insertstmt.returning_clause();
724
- const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), dbSchema, insertColumns, traverseResult) : [];
864
+ const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), context, traverseResult) : [];
725
865
  const result = {
726
866
  queryType: 'Insert',
727
867
  multipleRowsResult: false,
728
868
  parametersNullability: traverseResult.parameters.map(param => param.isNotNull),
729
- columnsNullability: returninColumns.map(col => !col.is_nullable),
869
+ columns: returninColumns,
730
870
  parameterList: []
731
871
  };
732
872
  if (returning_clause) {
@@ -734,7 +874,7 @@ function traverseInsertstmt(insertstmt, dbSchema) {
734
874
  }
735
875
  return result;
736
876
  }
737
- function traverse_insert_select_stmt(selectstmt, dbSchema, insertColumnlist, traverseResult) {
877
+ function traverse_insert_select_stmt(selectstmt, context, traverseResult) {
738
878
  var _a, _b, _c, _d, _e;
739
879
  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
880
  if (simple_select) {
@@ -743,27 +883,27 @@ function traverse_insert_select_stmt(selectstmt, dbSchema, insertColumnlist, tra
743
883
  const values_clause = simple_select_pramary.values_clause();
744
884
  if (values_clause) {
745
885
  values_clause.expr_list_list()
746
- .forEach(expr_list => traverse_insert_a_expr_list(expr_list, dbSchema, insertColumnlist, traverseResult));
886
+ .forEach(expr_list => traverse_insert_a_expr_list(expr_list, context, traverseResult));
747
887
  }
748
888
  const target_list = (_e = simple_select_pramary.target_list_()) === null || _e === void 0 ? void 0 : _e.target_list();
749
889
  if (target_list) {
750
890
  const from_clause = simple_select_pramary.from_clause();
751
- const fromColumns = from_clause ? traverse_from_clause(from_clause, dbSchema, [], traverseResult) : [];
891
+ const fromColumns = from_clause ? traverse_from_clause(from_clause, Object.assign(Object.assign({}, context), { fromColumns: [] }), traverseResult) : [];
752
892
  target_list.target_el_list().forEach((target_el, index) => {
753
- const targetResult = isNotNull_target_el(target_el, dbSchema, fromColumns, traverseResult);
893
+ const targetResult = isNotNull_target_el(target_el, Object.assign(Object.assign({}, context), { fromColumns }), traverseResult);
754
894
  if (isParameter(targetResult.column_name)) {
755
- traverseResult.parameters.at(-1).isNotNull = !insertColumnlist[index].is_nullable;
895
+ traverseResult.parameters.at(-1).isNotNull = !context.fromColumns[index].is_nullable;
756
896
  }
757
897
  });
758
898
  }
759
899
  }
760
900
  }
761
901
  }
762
- function traverse_insert_a_expr_list(expr_list, dbSchema, insertColumns, traverseResult) {
902
+ function traverse_insert_a_expr_list(expr_list, context, traverseResult) {
763
903
  expr_list.a_expr_list().forEach((a_expr, index) => {
764
- const result = traverse_a_expr(a_expr, dbSchema, insertColumns, traverseResult);
904
+ const result = traverse_a_expr(a_expr, context, traverseResult);
765
905
  if (isParameter(result.column_name)) {
766
- traverseResult.parameters.at(-1).isNotNull = !insertColumns[index].is_nullable;
906
+ traverseResult.parameters.at(-1).isNotNull = !context.fromColumns[index].is_nullable;
767
907
  }
768
908
  });
769
909
  }
@@ -772,12 +912,17 @@ function traverseDeletestmt(deleteStmt, dbSchema, traverseResult) {
772
912
  const tableName = relation_expr.getText();
773
913
  const deleteColumns = dbSchema.filter(col => col.table_name === tableName);
774
914
  const returning_clause = deleteStmt.returning_clause();
775
- const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), dbSchema, deleteColumns, traverseResult) : [];
915
+ const context = {
916
+ dbSchema,
917
+ fromColumns: deleteColumns,
918
+ generateNestedInfo: false
919
+ };
920
+ const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), context, traverseResult) : [];
776
921
  const result = {
777
922
  queryType: 'Delete',
778
923
  multipleRowsResult: false,
779
924
  parametersNullability: traverseResult.parameters.map(param => param.isNotNull),
780
- columnsNullability: returninColumns.map(col => !col.is_nullable),
925
+ columns: returninColumns,
781
926
  parameterList: []
782
927
  };
783
928
  if (returning_clause) {
@@ -789,22 +934,27 @@ function traverseUpdatestmt(updatestmt, dbSchema, traverseResult) {
789
934
  const relation_expr_opt_alias = updatestmt.relation_expr_opt_alias();
790
935
  const tableName = relation_expr_opt_alias.getText();
791
936
  const updateColumns = dbSchema.filter(col => col.table_name === tableName);
937
+ const context = {
938
+ dbSchema,
939
+ fromColumns: updateColumns,
940
+ generateNestedInfo: false
941
+ };
792
942
  updatestmt.set_clause_list().set_clause_list()
793
- .forEach(set_clause => traverse_set_clause(set_clause, dbSchema, updateColumns, traverseResult));
943
+ .forEach(set_clause => traverse_set_clause(set_clause, context, traverseResult));
794
944
  const parametersBefore = traverseResult.parameters.length;
795
945
  const where_clause = updatestmt.where_or_current_clause();
796
946
  if (where_clause) {
797
947
  const a_expr = where_clause.a_expr();
798
- traverse_a_expr(a_expr, dbSchema, updateColumns, traverseResult);
948
+ traverse_a_expr(a_expr, context, traverseResult);
799
949
  }
800
950
  const whereParameters = traverseResult.parameters.slice(parametersBefore);
801
951
  const returning_clause = updatestmt.returning_clause();
802
- const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), dbSchema, updateColumns, traverseResult) : [];
952
+ const returninColumns = returning_clause ? traverse_target_list(returning_clause.target_list(), context, traverseResult) : [];
803
953
  const result = {
804
954
  queryType: 'Update',
805
955
  multipleRowsResult: false,
806
956
  parametersNullability: traverseResult.parameters.slice(0, parametersBefore).map(param => param.isNotNull),
807
- columnsNullability: returninColumns.map(col => !col.is_nullable),
957
+ columns: returninColumns,
808
958
  parameterList: [],
809
959
  whereParamtersNullability: whereParameters.map(param => param.isNotNull)
810
960
  };
@@ -813,13 +963,13 @@ function traverseUpdatestmt(updatestmt, dbSchema, traverseResult) {
813
963
  }
814
964
  return result;
815
965
  }
816
- function traverse_set_clause(set_clause, dbSchema, updateColumns, traverseResult) {
966
+ function traverse_set_clause(set_clause, context, traverseResult) {
817
967
  const set_target = set_clause.set_target();
818
968
  const columnName = (0, select_columns_1.splitName)(set_target.getText());
819
- const column = findColumn(columnName, updateColumns);
969
+ const column = findColumn(columnName, context.fromColumns);
820
970
  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);
971
+ const excludedColumns = context.fromColumns.map((col) => (Object.assign(Object.assign({}, col), { table_name: 'excluded' })));
972
+ const a_exprResult = traverse_a_expr(a_expr, Object.assign(Object.assign({}, context), { fromColumns: context.fromColumns.concat(excludedColumns) }), traverseResult);
823
973
  if (isParameter(a_exprResult.column_name)) {
824
974
  traverseResult.parameters[traverseResult.parameters.length - 1].isNotNull = !column.is_nullable;
825
975
  }