typesql-cli 0.18.5 → 0.19.0

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.
@@ -124,8 +124,12 @@ function traverse_select_no_parens(select_no_parens, context, traverseResult) {
124
124
  if (with_clause) {
125
125
  with_clause.cte_list().common_table_expr_list()
126
126
  .forEach(common_table_expr => {
127
- const withResult = traverse_common_table_expr(common_table_expr, context, traverseResult);
128
- context.withColumns.push(...withResult);
127
+ var _a, _b, _c;
128
+ const recursiveTableName = with_clause.RECURSIVE() ? common_table_expr.name().getText() : undefined;
129
+ const recursiveColumnNames = (_c = (_b = (_a = common_table_expr.name_list_()) === null || _a === void 0 ? void 0 : _a.name_list()) === null || _b === void 0 ? void 0 : _b.name_list()) === null || _c === void 0 ? void 0 : _c.map(name => name.getText());
130
+ const withResult = traverse_common_table_expr(common_table_expr, Object.assign(Object.assign({}, context), { recursiveTableName, recursiveColumnNames }), traverseResult);
131
+ const columns = recursiveColumnNames ? withResult.map((col, index) => { var _a; return (Object.assign(Object.assign({}, col), { column_name: (_a = recursiveColumnNames[index]) !== null && _a !== void 0 ? _a : col.column_name })); }) : withResult;
132
+ context.withColumns.push(...columns);
129
133
  });
130
134
  }
131
135
  const select_clause = select_no_parens.select_clause();
@@ -182,8 +186,11 @@ function traverse_select_clause(select_clause, context, traverseResult) {
182
186
  const mainSelectResult = traverse_simple_select_intersect(simple_select_intersect_list[0], context, traverseResult);
183
187
  let columns = mainSelectResult.columns;
184
188
  //union
189
+ const { recursiveTableName, recursiveColumnNames } = context;
190
+ const recursiveColumns = recursiveTableName ? mainSelectResult.columns
191
+ .map((col, index) => { var _a; return (Object.assign(Object.assign({}, col), { table_name: recursiveTableName, column_name: (_a = recursiveColumnNames === null || recursiveColumnNames === void 0 ? void 0 : recursiveColumnNames[index]) !== null && _a !== void 0 ? _a : col.column_name })); }) : [];
185
192
  for (let index = 1; index < simple_select_intersect_list.length; index++) {
186
- const unionResult = traverse_simple_select_intersect(simple_select_intersect_list[index], context, traverseResult);
193
+ const unionResult = traverse_simple_select_intersect(simple_select_intersect_list[index], Object.assign(Object.assign({}, context), { fromColumns: context.fromColumns.concat(recursiveColumns) }), traverseResult);
187
194
  columns = columns.map((value, columnIndex) => {
188
195
  const col = Object.assign({ column_name: value.column_name, is_nullable: value.is_nullable || unionResult.columns[columnIndex].is_nullable, table_name: '', table_schema: '', type: value.type }, (value.column_default && { column_default: value.column_default }));
189
196
  return col;
@@ -244,14 +251,18 @@ function traverse_simple_select_pramary(simple_select_pramary, context, traverse
244
251
  (_d = (_c = simple_select_pramary.group_clause()) === null || _c === void 0 ? void 0 : _c.group_by_list()) === null || _d === void 0 ? void 0 : _d.group_by_item_list().forEach(group_by => {
245
252
  const a_expr = group_by.a_expr();
246
253
  if (a_expr) {
254
+ newContext.groupBy = true;
255
+ /* The GROUP BY clause can reference column aliases defined in the SELECT list.
256
+ There's no need to retrieve nullability or type information from the GROUP BY expressions (findColumn(col). */
247
257
  traverse_a_expr(a_expr, newContext, traverseResult);
258
+ newContext.groupBy = false;
248
259
  }
249
260
  });
250
261
  const having_expr = (_e = simple_select_pramary.having_clause()) === null || _e === void 0 ? void 0 : _e.a_expr();
251
262
  if (having_expr) {
252
263
  traverse_a_expr(having_expr, newContext, traverseResult);
253
264
  }
254
- const filteredColumns = filterColumns_simple_select_pramary(simple_select_pramary, newContext, traverseResult);
265
+ const filteredColumns = filterColumns_simple_select_pramary(simple_select_pramary, Object.assign(Object.assign({}, context), { fromColumns: context.fromColumns.concat(fromResult.columns) }), traverseResult);
255
266
  return {
256
267
  columns: filteredColumns,
257
268
  singleRow: fromResult.singleRow
@@ -262,7 +273,7 @@ function extractRelations(a_expr) {
262
273
  const relations = columnsRef
263
274
  .map((colRefExpr) => {
264
275
  const colRef = colRefExpr;
265
- const tableName = (0, select_columns_1.splitName)(colRef.getText());
276
+ const tableName = getFieldName(colRef);
266
277
  return tableName;
267
278
  });
268
279
  const uniqueRelations = [...new Set(relations.map(relation => relation.prefix))];
@@ -340,7 +351,7 @@ function traverse_target_el(target_el, context, traverseResult) {
340
351
  const numParamsBefore = traverseResult.parameters.length;
341
352
  const exprResult = traverse_a_expr(a_expr, context, traverseResult);
342
353
  const colLabel = target_el.colLabel();
343
- const alias = colLabel != null ? colLabel.getText() : '';
354
+ const alias = colLabel != null ? get_colid_text(colLabel) : '';
344
355
  if (alias) {
345
356
  (_a = traverseResult.relations) === null || _a === void 0 ? void 0 : _a.forEach(relation => {
346
357
  if ((relation.name === exprResult.table_name || relation.alias === exprResult.table_name)
@@ -677,10 +688,16 @@ function traverse_expr_typecast(a_expr_typecast, context, traverseResult) {
677
688
  throw Error('traverse_expr_typecast - Not expected:' + a_expr_typecast.getText());
678
689
  }
679
690
  function traverseColumnRef(columnref, fromColumns) {
680
- const fieldName = (0, select_columns_1.splitName)(columnref.getText());
691
+ const fieldName = getFieldName(columnref);
681
692
  const col = findColumn(fieldName, fromColumns);
682
693
  return Object.assign(Object.assign({}, col), { is_nullable: col.is_nullable });
683
694
  }
695
+ function getFieldName(columnref) {
696
+ const colid = get_colid_text(columnref.colid());
697
+ const indirection = columnref.indirection();
698
+ let fieldName = indirection ? { name: get_indiretion_text(indirection), prefix: colid } : { name: colid, prefix: '' };
699
+ return fieldName;
700
+ }
684
701
  function getNameAndTypeIdFromAExprConst(a_expr_const) {
685
702
  var _a, _b;
686
703
  if (a_expr_const.iconst()) {
@@ -747,7 +764,7 @@ function traversec_expr(c_expr, context, traverseResult) {
747
764
  traverse_select_with_parens(select_with_parens, context, traverseResult);
748
765
  return {
749
766
  column_name: '?column?',
750
- is_nullable: true,
767
+ is_nullable: false, //empty array
751
768
  table_schema: '',
752
769
  table_name: '',
753
770
  type: 'unknown'
@@ -761,6 +778,15 @@ function traversec_expr(c_expr, context, traverseResult) {
761
778
  }
762
779
  const columnref = c_expr.columnref();
763
780
  if (columnref) {
781
+ if (context.groupBy) {
782
+ return {
783
+ column_name: columnref.getText(),
784
+ is_nullable: false,
785
+ table_name: '',
786
+ table_schema: '',
787
+ type: 'unknown'
788
+ };
789
+ }
764
790
  if (context.columnRefIsRecord) {
765
791
  const table = (0, select_columns_1.splitTableName)(columnref.getText());
766
792
  const columns = filterColumns(context.fromColumns, table);
@@ -898,11 +924,7 @@ function filterColumns(fromColumns, fieldName) {
898
924
  });
899
925
  }
900
926
  function excludeColumns(fromColumns, excludeList) {
901
- return fromColumns.filter(col => {
902
- const found = excludeList.find(excluded => (excluded.prefix === '' || col.table_name === excluded.prefix)
903
- && excluded.name == col.column_name);
904
- return !found;
905
- });
927
+ return fromColumns.filter(col => !excludeList.find(excluded => excluded == col.column_name));
906
928
  }
907
929
  function traversec_expr_case(c_expr_case, context, traverseResult) {
908
930
  var _a;
@@ -1400,18 +1422,16 @@ function checkLeftJoinIsNullable(leftJoin, subsequentJoins, fromColumns) {
1400
1422
  return true; // No INNER JOIN filtered it — remains nullable
1401
1423
  }
1402
1424
  function traverse_table_ref(table_ref, context, traverseResult) {
1403
- var _a, _b, _c, _d, _e, _f, _g;
1425
+ var _a, _b;
1404
1426
  const allColumns = [];
1405
1427
  const relation_expr = table_ref.relation_expr();
1406
1428
  const aliasClause = table_ref.alias_clause();
1407
- const aliasNameList = (_b = (_a = aliasClause === null || aliasClause === void 0 ? void 0 : aliasClause.name_list()) === null || _a === void 0 ? void 0 : _a.name_list()) === null || _b === void 0 ? void 0 : _b.map(name => name.getText());
1408
1429
  const alias = aliasClause ? aliasClause.colid().getText() : '';
1409
1430
  if (relation_expr) {
1410
1431
  const tableName = traverse_relation_expr(relation_expr);
1411
- const fromColumns = getFromColumns(tableName, context.withColumns, context.dbSchema);
1432
+ const fromColumns = getFromColumns(tableName, context.fromColumns.concat(context.withColumns), context.dbSchema);
1412
1433
  const tableNameWithAlias = alias ? alias : tableName.name;
1413
- const columnsWithAlias = fromColumns.map(col => (Object.assign(Object.assign({}, col), { table_name: tableNameWithAlias.toLowerCase() })));
1414
- const fromColumnsResult = columnsWithAlias.concat(context.parentColumns);
1434
+ const fromColumnsResult = fromColumns.map(col => (Object.assign(Object.assign({}, col), { table_name: tableNameWithAlias.toLowerCase() })));
1415
1435
  allColumns.push(...fromColumnsResult);
1416
1436
  if (context.collectNestedInfo) {
1417
1437
  const key = fromColumnsResult.filter(col => col.column_key === 'PRI');
@@ -1421,45 +1441,56 @@ function traverse_table_ref(table_ref, context, traverseResult) {
1421
1441
  alias: alias,
1422
1442
  renameAs,
1423
1443
  parentRelation: '',
1424
- joinColumn: ((_c = key[0]) === null || _c === void 0 ? void 0 : _c.column_name) || '',
1444
+ joinColumn: ((_a = key[0]) === null || _a === void 0 ? void 0 : _a.column_name) || '',
1425
1445
  cardinality: 'one',
1426
1446
  parentCardinality: 'one'
1427
1447
  };
1428
- (_d = traverseResult.relations) === null || _d === void 0 ? void 0 : _d.push(relation);
1448
+ (_b = traverseResult.relations) === null || _b === void 0 ? void 0 : _b.push(relation);
1429
1449
  }
1430
1450
  if (context.collectDynamicQueryInfo && traverseResult.dynamicQueryInfo.from.length == 0) {
1431
1451
  collectDynamicQueryInfoTableRef(table_ref, null, null, fromColumnsResult, [], traverseResult);
1432
1452
  }
1433
1453
  const joinList = extractJoins(table_ref);
1434
- const joinColumns = joinList.flatMap((join, index) => {
1454
+ joinList.forEach((join, index) => {
1435
1455
  const joinType = join.joinType; //INNER, LEFT
1436
1456
  const joinQual = join.joinQual;
1437
1457
  const numParamsBefore = traverseResult.parameters.length;
1438
- const parentColumns = join.tableRef.LATERAL_P() ? fromColumnsResult : [];
1439
- const joinTableRefResult = traverse_table_ref(join.tableRef, Object.assign(Object.assign({}, context), { parentColumns }), traverseResult);
1440
- const isLeftJoin = joinType === null || joinType === void 0 ? void 0 : joinType.LEFT();
1441
- const filteredColumns = joinQual && (joinQual === null || joinQual === void 0 ? void 0 : joinQual.USING()) ? filterUsingColumns(joinTableRefResult.columns, joinQual) : joinTableRefResult.columns;
1442
1458
  const subsequentJoints = joinList.slice(index + 1);
1443
- const checkIsNullable = isLeftJoin ? checkLeftJoinIsNullable(join, subsequentJoints, filteredColumns) : false;
1444
- ;
1445
- const resultColumns = isLeftJoin ? filteredColumns.map(col => {
1446
- const colResult = Object.assign(Object.assign({}, col), { is_nullable: checkIsNullable ? true : col.is_nullable, original_is_nullable: col.is_nullable });
1447
- return colResult;
1448
- }) : filteredColumns;
1459
+ let joinColumns = [];
1460
+ if (join.tableRef.LATERAL_P()) {
1461
+ const newContext = Object.assign(Object.assign({}, context), { parentColumns: allColumns, collectDynamicQueryInfo: false });
1462
+ const lateralJoinResult = traverse_select_with_parens_or_func_table(join.tableRef, newContext, traverseResult);
1463
+ joinColumns = lateralJoinResult.columns;
1464
+ }
1465
+ else {
1466
+ const joinTableRefResult = traverse_table_ref(join.tableRef, context, traverseResult);
1467
+ joinColumns = (joinQual === null || joinQual === void 0 ? void 0 : joinQual.USING()) ? filterUsingColumns(joinTableRefResult.columns, joinQual) : joinTableRefResult.columns;
1468
+ }
1469
+ const nullableColumns = (joinType === null || joinType === void 0 ? void 0 : joinType.LEFT())
1470
+ ? joinColumns.map(col => (Object.assign(Object.assign({}, col), { original_is_nullable: col.is_nullable, is_nullable: checkLeftJoinIsNullable(join, subsequentJoints, joinColumns) ? true : col.is_nullable })))
1471
+ : joinColumns;
1472
+ allColumns.push(...nullableColumns);
1449
1473
  if (context.collectNestedInfo && joinQual) {
1450
- collectNestedInfo(joinQual, resultColumns, traverseResult);
1474
+ collectNestedInfo(joinQual, joinColumns, traverseResult);
1451
1475
  }
1452
1476
  if (context.collectDynamicQueryInfo) {
1453
1477
  const parameters = traverseResult.parameters.slice(numParamsBefore).map((_, index) => index + numParamsBefore);
1454
- collectDynamicQueryInfoTableRef(join.tableRef, joinType, joinQual, resultColumns, parameters, traverseResult);
1478
+ collectDynamicQueryInfoTableRef(join.tableRef, joinType, joinQual, joinColumns, parameters, traverseResult);
1455
1479
  }
1456
- return resultColumns;
1457
1480
  });
1458
- allColumns.push(...joinColumns);
1481
+ return {
1482
+ columns: allColumns,
1483
+ singleRow: false
1484
+ };
1459
1485
  }
1460
- const func_table = table_ref.func_table();
1486
+ const select_with_parens_or_func_result = traverse_select_with_parens_or_func_table(table_ref, context, traverseResult);
1487
+ return select_with_parens_or_func_result;
1488
+ }
1489
+ function traverse_select_with_parens_or_func_table(tableRef, context, traverseResult) {
1490
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1491
+ const func_table = tableRef.func_table();
1461
1492
  if (func_table) {
1462
- const funcAlias = ((_g = (_f = (_e = table_ref.func_alias_clause()) === null || _e === void 0 ? void 0 : _e.alias_clause()) === null || _f === void 0 ? void 0 : _f.colid()) === null || _g === void 0 ? void 0 : _g.getText()) || '';
1493
+ const funcAlias = ((_c = (_b = (_a = tableRef.func_alias_clause()) === null || _a === void 0 ? void 0 : _a.alias_clause()) === null || _b === void 0 ? void 0 : _b.colid()) === null || _c === void 0 ? void 0 : _c.getText()) || '';
1463
1494
  const result = traverse_func_table(func_table, context, traverseResult);
1464
1495
  const resultWithAlias = result.columns.map(col => (Object.assign(Object.assign({}, col), { table_name: funcAlias || col.table_name })));
1465
1496
  return {
@@ -1467,19 +1498,18 @@ function traverse_table_ref(table_ref, context, traverseResult) {
1467
1498
  singleRow: result.singleRow
1468
1499
  };
1469
1500
  }
1470
- const select_with_parens = table_ref.select_with_parens();
1501
+ const select_with_parens = tableRef.select_with_parens();
1471
1502
  if (select_with_parens) {
1472
1503
  const columns = traverse_select_with_parens(select_with_parens, Object.assign(Object.assign({}, context), { collectDynamicQueryInfo: false }), traverseResult);
1504
+ const aliasNameList = (_f = (_e = (_d = tableRef.alias_clause()) === null || _d === void 0 ? void 0 : _d.name_list()) === null || _e === void 0 ? void 0 : _e.name_list()) === null || _f === void 0 ? void 0 : _f.map(name => name.getText());
1505
+ const alias = (_h = (_g = tableRef.alias_clause()) === null || _g === void 0 ? void 0 : _g.colid().getText()) !== null && _h !== void 0 ? _h : '';
1473
1506
  const withAlias = columns.columns.map((col, i) => (Object.assign(Object.assign({}, col), { column_name: (aliasNameList === null || aliasNameList === void 0 ? void 0 : aliasNameList[i]) || col.column_name, table_name: alias || col.table_name })));
1474
1507
  return {
1475
1508
  columns: withAlias,
1476
1509
  singleRow: false
1477
1510
  };
1478
1511
  }
1479
- return {
1480
- columns: allColumns,
1481
- singleRow: false
1482
- };
1512
+ throw Error('Stmt not expected:' + tableRef.getText());
1483
1513
  }
1484
1514
  function extractJoins(table_ref) {
1485
1515
  const joinList = [];
@@ -1528,7 +1558,7 @@ function getJoinColumns(joinQual) {
1528
1558
  const a_expr_or = a_expr_or_list[0];
1529
1559
  const a_expr_and = a_expr_or.a_expr_and_list()[0];
1530
1560
  const columnref = collectContextsOfType(a_expr_and, PostgreSQLParser_1.ColumnrefContext);
1531
- const joinColumns = columnref.map(colRef => (0, select_columns_1.splitName)(colRef.getText()));
1561
+ const joinColumns = columnref.map(colRef => getFieldName(colRef));
1532
1562
  return joinColumns;
1533
1563
  }
1534
1564
  return [];
@@ -1556,7 +1586,7 @@ function collectNestedInfo(joinQual, resultColumns, traverseResult) {
1556
1586
  });
1557
1587
  }
1558
1588
  function filterUsingColumns(fromColumns, joinQual) {
1559
- const excludeList = joinQual.name_list().name_list().map(name => (0, select_columns_1.splitName)(name.getText()));
1589
+ const excludeList = joinQual.name_list().name_list().map(name => get_colid_text(name.colid()));
1560
1590
  const filteredColumns = excludeColumns(fromColumns, excludeList);
1561
1591
  return filteredColumns;
1562
1592
  }
@@ -1649,12 +1679,12 @@ function traverse_relation_expr(relation_expr) {
1649
1679
  return name;
1650
1680
  }
1651
1681
  function traverse_qualified_name(qualified_name) {
1652
- var _a, _b;
1653
1682
  const colid_name = qualified_name.colid() ? get_colid_text(qualified_name.colid()) : '';
1654
- const indirection_el_list = (_a = qualified_name.indirection()) === null || _a === void 0 ? void 0 : _a.indirection_el_list();
1655
- if (indirection_el_list && indirection_el_list.length === 1) {
1683
+ const indirection = qualified_name.indirection();
1684
+ if (indirection) {
1685
+ const indirection_text = get_indiretion_text(indirection);
1656
1686
  return {
1657
- name: ((_b = indirection_el_list[0].attr_name()) === null || _b === void 0 ? void 0 : _b.getText()) || '',
1687
+ name: indirection_text,
1658
1688
  alias: colid_name
1659
1689
  };
1660
1690
  }
@@ -1666,7 +1696,7 @@ function traverse_qualified_name(qualified_name) {
1666
1696
  function get_colid_text(colid) {
1667
1697
  const identifier = colid.identifier();
1668
1698
  if (identifier) {
1669
- return traverse_identifier(identifier);
1699
+ return get_identifier_text(identifier);
1670
1700
  }
1671
1701
  const unreserved_keyword = colid.unreserved_keyword();
1672
1702
  if (unreserved_keyword) {
@@ -1674,8 +1704,24 @@ function get_colid_text(colid) {
1674
1704
  }
1675
1705
  return '';
1676
1706
  }
1677
- function traverse_identifier(identifier) {
1678
- const tableName = identifier.Identifier().getText();
1707
+ function get_indiretion_text(indirection) {
1708
+ var _a;
1709
+ const indirection_el_list = indirection.indirection_el_list();
1710
+ if (indirection_el_list && indirection_el_list.length === 1) {
1711
+ const colLabel = (_a = indirection_el_list[0].attr_name()) === null || _a === void 0 ? void 0 : _a.colLabel();
1712
+ if (colLabel) {
1713
+ return get_colid_text(colLabel);
1714
+ }
1715
+ }
1716
+ return '';
1717
+ }
1718
+ function get_identifier_text(identifier) {
1719
+ const quoted_identifier = identifier.QuotedIdentifier();
1720
+ if (quoted_identifier) {
1721
+ const tableName = quoted_identifier.getText().slice(1, -1);
1722
+ return tableName;
1723
+ }
1724
+ const tableName = identifier.getText();
1679
1725
  return tableName;
1680
1726
  }
1681
1727
  function traverse_unreserved_keyword(unreserved_keyword) {
@@ -2052,7 +2098,7 @@ function isNotNull_c_expr(c_expr, field) {
2052
2098
  if (c_expr instanceof PostgreSQLParser_1.C_expr_exprContext) {
2053
2099
  const columnref = c_expr.columnref();
2054
2100
  if (columnref) {
2055
- const fieldName = (0, select_columns_1.splitName)(columnref.getText());
2101
+ const fieldName = getFieldName(columnref);
2056
2102
  return (fieldName.name === field.name && (fieldName.prefix === '' || field.prefix === fieldName.prefix));
2057
2103
  }
2058
2104
  const aexprconst = c_expr.aexprconst();
@@ -2350,8 +2396,7 @@ function getCheckedUniqueColumn(a_expr_like) {
2350
2396
  if (c_expr instanceof PostgreSQLParser_1.C_expr_exprContext) {
2351
2397
  const columnref = c_expr.columnref();
2352
2398
  if (columnref) {
2353
- const fieldName = (0, select_columns_1.splitName)(columnref.getText());
2354
- // const col = traverseColumnRef(columnref, dbSchema);
2399
+ const fieldName = getFieldName(columnref);
2355
2400
  return fieldName.name;
2356
2401
  }
2357
2402
  }