typesql-cli 0.18.4 → 0.18.5

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 (37) hide show
  1. package/code-generator2.d.ts.map +1 -1
  2. package/code-generator2.js +2 -1
  3. package/code-generator2.js.map +1 -1
  4. package/dialects/postgres.d.ts +2 -1
  5. package/dialects/postgres.d.ts.map +1 -1
  6. package/dialects/postgres.js +13 -1
  7. package/dialects/postgres.js.map +1 -1
  8. package/drivers/postgres.d.ts +2 -1
  9. package/drivers/postgres.d.ts.map +1 -1
  10. package/drivers/postgres.js.map +1 -1
  11. package/drivers/types.d.ts +2 -2
  12. package/drivers/types.d.ts.map +1 -1
  13. package/package.json +1 -1
  14. package/postgres-query-analyzer/case-nullability-checker.d.ts +3 -0
  15. package/postgres-query-analyzer/case-nullability-checker.d.ts.map +1 -0
  16. package/postgres-query-analyzer/case-nullability-checker.js +110 -0
  17. package/postgres-query-analyzer/case-nullability-checker.js.map +1 -0
  18. package/postgres-query-analyzer/describe.d.ts.map +1 -1
  19. package/postgres-query-analyzer/describe.js +4 -4
  20. package/postgres-query-analyzer/describe.js.map +1 -1
  21. package/postgres-query-analyzer/enum-parser.d.ts +2 -1
  22. package/postgres-query-analyzer/enum-parser.d.ts.map +1 -1
  23. package/postgres-query-analyzer/enum-parser.js.map +1 -1
  24. package/postgres-query-analyzer/nullability-checker.d.ts +3 -0
  25. package/postgres-query-analyzer/nullability-checker.d.ts.map +1 -0
  26. package/postgres-query-analyzer/nullability-checker.js +110 -0
  27. package/postgres-query-analyzer/nullability-checker.js.map +1 -0
  28. package/postgres-query-analyzer/traverse.d.ts +2 -2
  29. package/postgres-query-analyzer/traverse.d.ts.map +1 -1
  30. package/postgres-query-analyzer/traverse.js +213 -60
  31. package/postgres-query-analyzer/traverse.js.map +1 -1
  32. package/sqlite-query-analyzer/replace-list-params.d.ts +0 -1
  33. package/sqlite-query-analyzer/replace-list-params.d.ts.map +1 -1
  34. package/sqlite-query-analyzer/replace-list-params.js +0 -57
  35. package/sqlite-query-analyzer/replace-list-params.js.map +1 -1
  36. package/sqlite-query-analyzer/types.d.ts +3 -1
  37. package/sqlite-query-analyzer/types.d.ts.map +1 -1
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.evaluatesTrueIfNull = evaluatesTrueIfNull;
4
+ const PostgreSQLParser_1 = require("@wsporto/typesql-parser/postgres/PostgreSQLParser");
5
+ const select_columns_1 = require("../mysql-query-analyzer/select-columns");
6
+ const typesql_parser_1 = require("@wsporto/typesql-parser");
7
+ function getSingleColumnRefOrNull(elseExpr) {
8
+ var _a;
9
+ if (((_a = elseExpr.children) === null || _a === void 0 ? void 0 : _a.length) != 1) {
10
+ return null;
11
+ }
12
+ const child = elseExpr.children[0];
13
+ if (child instanceof PostgreSQLParser_1.ColumnrefContext) {
14
+ return child;
15
+ }
16
+ if (child instanceof typesql_parser_1.ParserRuleContext) { //composite
17
+ return getSingleColumnRefOrNull(child);
18
+ }
19
+ return null;
20
+ }
21
+ function evaluatesTrueIfNull(elseExpr, a_expr) {
22
+ // Can only infer if the elseExpr is a single column;
23
+ const columnRef = getSingleColumnRefOrNull(elseExpr.a_expr());
24
+ if (!columnRef) {
25
+ return false;
26
+ }
27
+ const a_expr_qual = a_expr.a_expr_qual();
28
+ if (a_expr_qual) {
29
+ return evaluatesTrueIfNull_a_expr_qual(a_expr_qual, (0, select_columns_1.splitName)(columnRef.getText()));
30
+ }
31
+ return false;
32
+ }
33
+ function evaluatesTrueIfNull_a_expr_qual(a_expr_qual, field) {
34
+ const a_expr_lessless = a_expr_qual.a_expr_lessless();
35
+ if (a_expr_lessless) {
36
+ return evaluatesTrueIfNull_a_expr_lessless(a_expr_lessless, field);
37
+ }
38
+ return false;
39
+ }
40
+ function evaluatesTrueIfNull_a_expr_lessless(a_expr_lessless, field) {
41
+ const a_expr_or = a_expr_lessless.a_expr_or_list()[0];
42
+ if (a_expr_or) {
43
+ return evaluatesTrueIfNull_a_expr_or(a_expr_or, field);
44
+ }
45
+ return false;
46
+ }
47
+ //a_expr_or: "valueisnotnulland(id>0orvalueisnotnull)"
48
+ //a_expr_or: "valueisnotnullor(id>0orvalueisnotnull)"
49
+ function evaluatesTrueIfNull_a_expr_or(a_expr_or, field) {
50
+ const a_expr_and = a_expr_or.a_expr_and_list();
51
+ if (a_expr_and) {
52
+ //1. valueisnotnull
53
+ //2. (id>0orvalueisnotnull)
54
+ const result = a_expr_and.some(a_expr_and => evaluatesTrueIfNull_a_expr_and(a_expr_and, field));
55
+ return result;
56
+ }
57
+ return false;
58
+ }
59
+ function evaluatesTrueIfNull_a_expr_and(a_expr_and, field) {
60
+ const a_expr_between_list = a_expr_and.a_expr_between_list();
61
+ if (a_expr_between_list) {
62
+ return a_expr_between_list.every(a_expr_between => evaluatesTrueIfNull_a_expr_between(a_expr_between, field));
63
+ }
64
+ return false;
65
+ }
66
+ function evaluatesTrueIfNull_a_expr_between(a_expr_between, field) {
67
+ const a_expr_in = a_expr_between.a_expr_in_list()[0];
68
+ if (a_expr_in) {
69
+ return evaluatesTrueIfNull_a_expr_in(a_expr_in, field);
70
+ }
71
+ return false;
72
+ }
73
+ function evaluatesTrueIfNull_a_expr_in(a_expr_in, field) {
74
+ const a_expr_unary_not = a_expr_in.a_expr_unary_not();
75
+ if (a_expr_unary_not) {
76
+ return evaluatesTrueIfNull_a_expr_unary_not(a_expr_unary_not, field);
77
+ }
78
+ return false;
79
+ }
80
+ function evaluatesTrueIfNull_a_expr_unary_not(a_expr_unary_not, field) {
81
+ const a_expr_isnull = a_expr_unary_not.a_expr_isnull();
82
+ if (a_expr_isnull) {
83
+ return evaluatesTrueIfNull_a_expr_isnull(a_expr_isnull, field);
84
+ }
85
+ return false;
86
+ }
87
+ function evaluatesTrueIfNull_a_expr_isnull(a_expr_isnull, field) {
88
+ const a_expr_is_not = a_expr_isnull.a_expr_is_not();
89
+ if (a_expr_is_not) {
90
+ const a_expr_compare = a_expr_is_not.a_expr_compare();
91
+ if (!a_expr_compare) {
92
+ return false;
93
+ }
94
+ const columnRef = getSingleColumnRefOrNull(a_expr_compare);
95
+ if (!columnRef) {
96
+ return false;
97
+ }
98
+ const fieldName = (0, select_columns_1.splitName)(columnRef.getText());
99
+ if (fieldName.name === field.name && (field.prefix === fieldName.prefix || fieldName.prefix === '' || field.prefix === '')
100
+ && a_expr_is_not.IS() && a_expr_is_not.NULL_P()) {
101
+ if (a_expr_is_not.NOT()) {
102
+ return false;
103
+ }
104
+ return true;
105
+ }
106
+ return false;
107
+ }
108
+ return false;
109
+ }
110
+ //# sourceMappingURL=nullability-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nullability-checker.js","sourceRoot":"","sources":["../../../src/postgres-query-analyzer/nullability-checker.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import { DynamicSqlInfo2 } from '../mysql-query-analyzer/types';
4
4
  import { QueryType } from '../types';
5
5
  import { Relation2 } from '../sqlite-query-analyzer/sqlite-describe-nested-query';
6
6
  import { CheckConstraintResult } from '../drivers/postgres';
7
- import { JsonType, PostgresSimpleType } from '../sqlite-query-analyzer/types';
7
+ import { JsonType, PostgresEnumType, PostgresSimpleType } from '../sqlite-query-analyzer/types';
8
8
  import { UserFunctionSchema } from './types';
9
9
  export type NotNullInfo = {
10
10
  table_schema: string;
@@ -32,7 +32,7 @@ export type PostgresTraverseResult = {
32
32
  };
33
33
  export type ParamInfo = {
34
34
  isNotNull: boolean;
35
- checkConstraint?: string;
35
+ checkConstraint?: PostgresEnumType;
36
36
  };
37
37
  export type Relation3 = {
38
38
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../../src/postgres-query-analyzer/traverse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgxC,WAAW,EAA4L,MAAM,mDAAmD,CAAC;AAExhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAa,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,uDAAuD,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAA+C,QAAQ,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAE3H,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,MAAM,WAAW,GAAG;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,EAAE,CAAC;IAChC,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC5B,CAAA;AAGD,MAAM,MAAM,sBAAsB,GAAG;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,qBAAqB,EAAE,SAAS,EAAE,CAAC;IACnC,yBAAyB,CAAC,EAAE,SAAS,EAAE,CAAC;IACxC,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;IACxB,gBAAgB,CAAC,EAAE,eAAe,CAAC;CACnC,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB,CAAA;AA2BD,MAAM,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAA;AAED,wBAAgB,cAAc,IAAI,eAAe,CAKhD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,oBAAoB,EAAE,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,aAAa,EAAE,kBAAkB,EAAE,EAAE,OAAO,EAAE,eAAe,GAAG,sBAAsB,CAmD/M;AA2lDD,MAAM,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd,CAAC;AAWF,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEnE,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,CA6BtE"}
1
+ {"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../../src/postgres-query-analyzer/traverse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqyC,WAAW,EAA4L,MAAM,mDAAmD,CAAC;AAE7iD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAa,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,uDAAuD,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAA8D,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAE5J,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAG7C,MAAM,MAAM,WAAW,GAAG;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,cAAc,CAAC,EAAE,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,EAAE,CAAC;IAChC,IAAI,EAAE,kBAAkB,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,WAAW,CAAC,EAAE,WAAW,EAAE,CAAC;CAC5B,CAAA;AAGD,MAAM,MAAM,sBAAsB,GAAG;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,qBAAqB,EAAE,SAAS,EAAE,CAAC;IACnC,yBAAyB,CAAC,EAAE,SAAS,EAAE,CAAC;IACxC,aAAa,EAAE,OAAO,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC;IACxB,gBAAgB,CAAC,EAAE,eAAe,CAAC;CACnC,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,gBAAgB,CAAC;CACnC,CAAA;AA2BD,MAAM,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC7B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAClC,CAAA;AAED,wBAAgB,cAAc,IAAI,eAAe,CAKhD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,oBAAoB,EAAE,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,aAAa,EAAE,kBAAkB,EAAE,EAAE,OAAO,EAAE,eAAe,GAAG,sBAAsB,CAmD/M;AA2rDD,MAAM,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd,CAAC;AAWF,MAAM,MAAM,kBAAkB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEnE,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,kBAAkB,CA6BtE"}
@@ -7,6 +7,7 @@ const PostgreSQLParser_1 = require("@wsporto/typesql-parser/postgres/PostgreSQLP
7
7
  const typesql_parser_1 = require("@wsporto/typesql-parser");
8
8
  const select_columns_1 = require("../mysql-query-analyzer/select-columns");
9
9
  const postgres_1 = require("@wsporto/typesql-parser/postgres");
10
+ const case_nullability_checker_1 = require("./case-nullability-checker");
10
11
  function defaultOptions() {
11
12
  return {
12
13
  collectNestedInfo: false,
@@ -358,7 +359,7 @@ function traverse_target_el(target_el, context, traverseResult) {
358
359
  parameters
359
360
  });
360
361
  }
361
- return Object.assign(Object.assign({ column_name: alias || exprResult.column_name, is_nullable: exprResult.is_nullable && exprResult.column_default !== true, table_name: exprResult.table_name, table_schema: exprResult.table_schema, type: exprResult.type }, (exprResult.column_key != null && { column_key: exprResult.column_key })), (exprResult.jsonType != null && { jsonType: exprResult.jsonType }));
362
+ return Object.assign(Object.assign(Object.assign({ column_name: alias || exprResult.column_name, is_nullable: exprResult.is_nullable, table_name: exprResult.table_name, table_schema: exprResult.table_schema, type: exprResult.type }, (exprResult.column_default != null) && { column_default: exprResult.column_default }), (exprResult.column_key != null && { column_key: exprResult.column_key })), (exprResult.jsonType != null && { jsonType: exprResult.jsonType }));
362
363
  }
363
364
  throw Error('Column not found');
364
365
  }
@@ -831,13 +832,15 @@ function traversec_expr(c_expr, context, traverseResult) {
831
832
  const select_with_parens = c_expr.select_with_parens();
832
833
  if (select_with_parens) {
833
834
  const result = traverse_select_with_parens(select_with_parens, Object.assign(Object.assign({}, context), { parentColumns: context.fromColumns, fromColumns: [] }), traverseResult);
835
+ const jsonType = result.columns[0].jsonType;
836
+ const is_nullable = jsonType == null ? true : jsonType.name !== 'json[]' && jsonType.name !== 'json_map'; //json[], json_map are not nullable
834
837
  return {
835
838
  column_name: '?column?',
836
- is_nullable: result.columns[0].jsonType ? result.columns[0].is_nullable : true,
839
+ is_nullable,
837
840
  table_name: '',
838
841
  table_schema: '',
839
842
  type: result.columns[0].type,
840
- jsonType: result.columns[0].jsonType
843
+ jsonType: jsonType != null && jsonType.name === 'json' ? Object.assign(Object.assign({}, jsonType), { notNull: !is_nullable }) : jsonType
841
844
  };
842
845
  }
843
846
  const a_expr_in_parens = c_expr._a_expr_in_parens;
@@ -902,23 +905,37 @@ function excludeColumns(fromColumns, excludeList) {
902
905
  });
903
906
  }
904
907
  function traversec_expr_case(c_expr_case, context, traverseResult) {
905
- var _a, _b;
908
+ var _a;
906
909
  const case_expr = c_expr_case.case_expr();
907
- const whenResult = case_expr.when_clause_list().when_clause_list().map(when_clause => traversewhen_clause(when_clause, context, traverseResult));
908
- const whenIsNotNull = whenResult.every(when => when);
909
- const elseExpr = (_a = case_expr.case_default()) === null || _a === void 0 ? void 0 : _a.a_expr();
910
- const elseResult = elseExpr ? traverse_a_expr(elseExpr, Object.assign({}, context), traverseResult) : null;
911
- const elseIsNotNull = (elseResult === null || elseResult === void 0 ? void 0 : elseResult.is_nullable) === false || false;
910
+ const whenClauseList = case_expr.when_clause_list().when_clause_list();
911
+ const whenResult = whenClauseList.map(when_clause => traversewhen_clause(when_clause, context, traverseResult));
912
+ const whenIsNotNull = whenResult.every(when => !when.is_nullable);
913
+ const elseExpr = case_expr.case_default();
914
+ const elseResult = elseExpr ? traverse_a_expr(elseExpr.a_expr(), Object.assign({}, context), traverseResult) : null;
915
+ const branchNotNull = elseResult ? evaluateBranches(whenClauseList, elseExpr, whenResult.map(col => !col.is_nullable)) : false;
916
+ const elseIsNotNull = (elseResult === null || elseResult === void 0 ? void 0 : elseResult.is_nullable) === false || branchNotNull;
912
917
  const notNull = elseIsNotNull && whenIsNotNull;
913
918
  return {
914
919
  column_name: '?column?',
915
920
  is_nullable: !notNull,
916
921
  table_name: '',
917
922
  table_schema: '',
918
- type: (_b = whenResult[0].type) !== null && _b !== void 0 ? _b : 'unknown',
923
+ type: (_a = whenResult[0].type) !== null && _a !== void 0 ? _a : 'unknown',
919
924
  jsonType: allJsonTypesMatch(whenResult, elseResult) ? whenResult[0].jsonType : undefined
920
925
  };
921
926
  }
927
+ function evaluateBranches(whenClauseList, elseExpr, whenIsNotNull) {
928
+ const exprIndex = whenClauseList.findIndex(when => {
929
+ const whenExpr = when.a_expr(0);
930
+ const evaluatesIfNull = (0, case_nullability_checker_1.evaluatesTrueIfNull)(elseExpr, whenExpr);
931
+ if (evaluatesIfNull) {
932
+ return true;
933
+ }
934
+ return false;
935
+ });
936
+ const result = exprIndex !== -1 ? whenIsNotNull[exprIndex] : false;
937
+ return result;
938
+ }
922
939
  function allJsonTypesMatch(whenResultList, elseResult) {
923
940
  var _a;
924
941
  const firstType = (_a = whenResultList[0]) === null || _a === void 0 ? void 0 : _a.jsonType;
@@ -936,7 +953,7 @@ function traversewhen_clause(when_clause, context, traverseResult) {
936
953
  const thenExprResult = traverse_a_expr(thenExpr, Object.assign(Object.assign({}, context), { filter_expr: whenExprList[index] }), traverseResult);
937
954
  return thenExprResult;
938
955
  });
939
- const notNull = whenExprResult.every(res => res);
956
+ const notNull = whenExprResult.every(res => !res.is_nullable);
940
957
  return {
941
958
  column_name: '?column?',
942
959
  is_nullable: !notNull,
@@ -987,7 +1004,9 @@ function mapJsonBuildArgsToJsonProperty(args, filterExpr) {
987
1004
  return properties;
988
1005
  }
989
1006
  function inferJsonNullability(columns, filterExpr) {
990
- const tables = columns.filter(col => filterExpr && col.original_is_nullable === false && isNotNull_a_expr(col, filterExpr)).map(col => col.table_name);
1007
+ const tables = columns.filter(col => filterExpr && col.original_is_nullable === false
1008
+ && isNotNull_a_expr({ name: col.column_name, prefix: col.table_name }, filterExpr))
1009
+ .map(col => col.table_name);
991
1010
  const fields = columns.map(col => {
992
1011
  return col.original_is_nullable != null && tables.includes(col.table_name) ? !col.original_is_nullable : !col.is_nullable;
993
1012
  });
@@ -996,19 +1015,20 @@ function inferJsonNullability(columns, filterExpr) {
996
1015
  function transformFieldsToJsonObjType(fields) {
997
1016
  const jsonObject = {
998
1017
  name: 'json',
1018
+ notNull: true,
999
1019
  properties: fields.map(col => mapFieldToPropertyDef(col))
1000
1020
  };
1001
1021
  return jsonObject;
1002
1022
  }
1003
1023
  function mapFieldToPropertyDef(field) {
1004
1024
  const prop = {
1005
- key: field.name,
1025
+ key: field.column_name,
1006
1026
  type: transformFieldToJsonField(field)
1007
1027
  };
1008
1028
  return prop;
1009
1029
  }
1010
1030
  function transformFieldToJsonField(field) {
1011
- const jsonField = { name: 'json_field', type: field.type, notNull: field.notNull };
1031
+ const jsonField = field.jsonType ? field.jsonType : { name: 'json_field', type: field.type, notNull: !field.is_nullable };
1012
1032
  return jsonField;
1013
1033
  }
1014
1034
  function traverse_json_build_obj_func(func_application, context, traverseResult) {
@@ -1024,6 +1044,7 @@ function traverse_json_build_obj_func(func_application, context, traverseResult)
1024
1044
  type: 'json',
1025
1045
  jsonType: {
1026
1046
  name: 'json',
1047
+ notNull: true,
1027
1048
  properties: mapJsonBuildArgsToJsonProperty(argsResult, context.filter_expr),
1028
1049
  }
1029
1050
  };
@@ -1040,23 +1061,26 @@ function traverse_json_agg(func_application, context, traverseResult) {
1040
1061
  table_name: '',
1041
1062
  table_schema: '',
1042
1063
  type: 'json[]',
1043
- jsonType: {
1044
- name: 'json[]',
1045
- properties: createJsonTypeForJsonAgg(argsResult[0], context.filter_expr)
1046
- }
1064
+ jsonType: createJsonTypeForJsonAgg(argsResult[0], context.filter_expr)
1047
1065
  };
1048
1066
  return result;
1049
1067
  }
1050
1068
  function createJsonTypeForJsonAgg(arg, filter_expr) {
1051
1069
  if (arg.recordTypes) {
1052
1070
  const jsonType = mapRecordsToJsonType(arg.recordTypes, filter_expr);
1053
- return [jsonType];
1071
+ return {
1072
+ name: 'json[]',
1073
+ properties: [jsonType]
1074
+ };
1054
1075
  }
1055
- return [arg.jsonType || { name: 'json_field', type: arg.type, notNull: !arg.is_nullable }];
1076
+ const jsonType = arg.jsonType ? { name: 'json[]', properties: [arg.jsonType] } : undefined;
1077
+ const fieldType = { name: 'json[]', properties: [{ name: 'json_field', type: arg.type, notNull: !arg.is_nullable }] };
1078
+ const result = jsonType || fieldType;
1079
+ return result;
1056
1080
  }
1057
1081
  function mapRecordsToJsonType(recordTypes, filterExpr) {
1058
1082
  const jsonNullability = inferJsonNullability(recordTypes, filterExpr);
1059
- const fields = recordTypes.map((col, index) => ({ name: col.column_name ? col.column_name : `f${index + 1}`, type: col.type, notNull: jsonNullability[index] }));
1083
+ const fields = recordTypes.map((col, index) => (Object.assign(Object.assign({}, col), { column_name: col.column_name ? col.column_name : `f${index + 1}`, is_nullable: !jsonNullability[index] })));
1060
1084
  const jsonType = transformFieldsToJsonObjType(fields);
1061
1085
  return jsonType;
1062
1086
  }
@@ -1212,6 +1236,15 @@ function traversefunc_application(func_application, context, traverseResult) {
1212
1236
  }
1213
1237
  };
1214
1238
  }
1239
+ if (functionName === 'unnest') {
1240
+ return {
1241
+ column_name: functionName,
1242
+ is_nullable: argsResult[0].is_nullable,
1243
+ type: argsResult[0].type,
1244
+ table_name: '',
1245
+ table_schema: ''
1246
+ };
1247
+ }
1215
1248
  return {
1216
1249
  column_name: functionName,
1217
1250
  is_nullable: true,
@@ -1271,7 +1304,7 @@ function traverse_array_expr(array_expr, context, traverseResult) {
1271
1304
  const expr_list = array_expr.expr_list();
1272
1305
  if (expr_list) {
1273
1306
  const traverse_expr_list_result = traverse_expr_list(expr_list, context, traverseResult);
1274
- return Object.assign(Object.assign({}, traverse_expr_list_result[0]), { column_name: '?column?', table_name: '', table_schema: '' });
1307
+ return Object.assign(Object.assign({}, traverse_expr_list_result[0]), { is_nullable: traverse_expr_list_result.some(expr => expr.is_nullable), column_name: '?column?', table_name: '', table_schema: '' });
1275
1308
  }
1276
1309
  const array_expr_list = array_expr.array_expr_list();
1277
1310
  if (array_expr_list) {
@@ -1293,17 +1326,21 @@ function traverse_array_expr_list(array_expr_list, context, traverseResult) {
1293
1326
  return result;
1294
1327
  }
1295
1328
  function findColumn(fieldName, fromColumns) {
1296
- const col = fromColumns.find(col => (fieldName.prefix === '' || col.table_name.toLowerCase() === fieldName.prefix.toLowerCase()) && col.column_name.toLowerCase() === fieldName.name.toLowerCase());
1329
+ const col = findColumnOrNull(fieldName, fromColumns);
1297
1330
  if (col == null) {
1298
1331
  throw Error('Column not found: ' + fieldNameToString(fieldName));
1299
1332
  }
1300
1333
  return col;
1301
1334
  }
1335
+ function findColumnOrNull(fieldName, fromColumns) {
1336
+ const col = fromColumns.find(col => (fieldName.prefix === '' || col.table_name.toLowerCase() === fieldName.prefix.toLowerCase()) && col.column_name.toLowerCase() === fieldName.name.toLowerCase());
1337
+ return col;
1338
+ }
1302
1339
  function fieldNameToString(fieldName) {
1303
1340
  return fieldName.prefix !== '' ? `${fieldName.prefix}.${fieldName.name}` : fieldName.name;
1304
1341
  }
1305
1342
  function checkIsNullable(where_clause, field) {
1306
- const isNotNullResult = !field.is_nullable || isNotNull(field, where_clause);
1343
+ const isNotNullResult = !field.is_nullable || isNotNull({ name: field.column_name, prefix: field.table_name }, where_clause);
1307
1344
  const col = Object.assign(Object.assign({}, field), { is_nullable: !isNotNullResult });
1308
1345
  return col;
1309
1346
  }
@@ -1331,6 +1368,37 @@ function getFromColumns(tableName, withColumns, dbSchema) {
1331
1368
  const filteredSchema = filteredWithColumns.length > 0 ? filteredWithColumns : dbSchema.filter(col => col.table_name.toLowerCase() === tableName.name.toLowerCase());
1332
1369
  return filteredSchema;
1333
1370
  }
1371
+ function checkLeftJoinIsNullable(leftJoin, subsequentJoins, fromColumns) {
1372
+ if (!leftJoin.joinQual) {
1373
+ return true; // No condition = always nullable
1374
+ }
1375
+ const leftTable = getTableName(leftJoin.tableRef);
1376
+ const leftJoinColumns = getJoinColumns(leftJoin.joinQual)
1377
+ .filter(col => {
1378
+ if (col.prefix === leftTable.name && col.prefix === leftTable.alias) {
1379
+ return true;
1380
+ }
1381
+ if (findColumnOrNull(col, fromColumns)) { //column without table reference (ex: fk_user)
1382
+ return true;
1383
+ }
1384
+ return false;
1385
+ });
1386
+ for (const join of subsequentJoins) {
1387
+ // Only INNER JOINs can cancel nullability
1388
+ if (!(join.joinType === null || join.joinType.INNER_P())) {
1389
+ continue;
1390
+ }
1391
+ const joinConditionColumns = getJoinColumns(join.joinQual);
1392
+ const filteredJoinColumnsFromLeft = joinConditionColumns.filter(col => leftJoinColumns.some(lc => lc.prefix === col.prefix));
1393
+ // Are *all* columns from the left join used in not-null filtering?
1394
+ const referencesLeftJoin = filteredJoinColumnsFromLeft.length > 0 &&
1395
+ filteredJoinColumnsFromLeft.every(col => { var _a; return isNotNull_a_expr(col, (_a = join.joinQual) === null || _a === void 0 ? void 0 : _a.a_expr()); });
1396
+ if (referencesLeftJoin) {
1397
+ return false; // LEFT JOIN is effectively filtered by INNER JOIN — not nullable
1398
+ }
1399
+ }
1400
+ return true; // No INNER JOIN filtered it — remains nullable
1401
+ }
1334
1402
  function traverse_table_ref(table_ref, context, traverseResult) {
1335
1403
  var _a, _b, _c, _d, _e, _f, _g;
1336
1404
  const allColumns = [];
@@ -1363,14 +1431,21 @@ function traverse_table_ref(table_ref, context, traverseResult) {
1363
1431
  collectDynamicQueryInfoTableRef(table_ref, null, null, fromColumnsResult, [], traverseResult);
1364
1432
  }
1365
1433
  const joinList = extractJoins(table_ref);
1366
- const joinColumns = joinList.flatMap((join) => {
1434
+ const joinColumns = joinList.flatMap((join, index) => {
1367
1435
  const joinType = join.joinType; //INNER, LEFT
1368
1436
  const joinQual = join.joinQual;
1369
1437
  const numParamsBefore = traverseResult.parameters.length;
1370
- const joinTableRefResult = traverse_table_ref(join.tableRef, context, traverseResult);
1438
+ const parentColumns = join.tableRef.LATERAL_P() ? fromColumnsResult : [];
1439
+ const joinTableRefResult = traverse_table_ref(join.tableRef, Object.assign(Object.assign({}, context), { parentColumns }), traverseResult);
1371
1440
  const isLeftJoin = joinType === null || joinType === void 0 ? void 0 : joinType.LEFT();
1372
1441
  const filteredColumns = joinQual && (joinQual === null || joinQual === void 0 ? void 0 : joinQual.USING()) ? filterUsingColumns(joinTableRefResult.columns, joinQual) : joinTableRefResult.columns;
1373
- const resultColumns = isLeftJoin ? filteredColumns.map(col => (Object.assign(Object.assign({}, col), { is_nullable: true, original_is_nullable: col.is_nullable }))) : filteredColumns;
1442
+ 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;
1374
1449
  if (context.collectNestedInfo && joinQual) {
1375
1450
  collectNestedInfo(joinQual, resultColumns, traverseResult);
1376
1451
  }
@@ -1395,13 +1470,7 @@ function traverse_table_ref(table_ref, context, traverseResult) {
1395
1470
  const select_with_parens = table_ref.select_with_parens();
1396
1471
  if (select_with_parens) {
1397
1472
  const columns = traverse_select_with_parens(select_with_parens, Object.assign(Object.assign({}, context), { collectDynamicQueryInfo: false }), traverseResult);
1398
- const withAlias = columns.columns.map((col, i) => ({
1399
- column_name: (aliasNameList === null || aliasNameList === void 0 ? void 0 : aliasNameList[i]) || col.column_name,
1400
- is_nullable: col.is_nullable,
1401
- table_name: alias || col.table_name,
1402
- table_schema: col.table_schema,
1403
- type: col.type
1404
- }));
1473
+ 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 })));
1405
1474
  return {
1406
1475
  columns: withAlias,
1407
1476
  singleRow: false
@@ -1720,7 +1789,7 @@ function traverseDeletestmt(deleteStmt, dbSchema, traverseResult) {
1720
1789
  return result;
1721
1790
  }
1722
1791
  function addConstraintIfNotNull(checkConstraint) {
1723
- return checkConstraint !== undefined ? { checkConstraint } : {};
1792
+ return checkConstraint !== undefined ? { checkConstraint } : undefined;
1724
1793
  }
1725
1794
  function traverseUpdatestmt(updatestmt, traverseContext, traverseResult) {
1726
1795
  var _a;
@@ -1853,7 +1922,14 @@ function isNotNull_a_expr_unary_not(a_expr_unary_not, field) {
1853
1922
  function isNotNull_a_expr_isnull(a_expr_isnull, field) {
1854
1923
  const a_expr_is_not = a_expr_isnull.a_expr_is_not();
1855
1924
  if (a_expr_is_not) {
1856
- return isNotNull_a_expr_is_not(a_expr_is_not, field);
1925
+ const isNotNull = isNotNull_a_expr_is_not(a_expr_is_not, field);
1926
+ if (isNotNull && a_expr_is_not.IS() && a_expr_is_not.NOT() && a_expr_is_not.NULL_P()) {
1927
+ return true;
1928
+ }
1929
+ if (a_expr_is_not.IS() && a_expr_is_not.NULL_P()) {
1930
+ return false;
1931
+ }
1932
+ return isNotNull;
1857
1933
  }
1858
1934
  return false;
1859
1935
  }
@@ -1977,7 +2053,7 @@ function isNotNull_c_expr(c_expr, field) {
1977
2053
  const columnref = c_expr.columnref();
1978
2054
  if (columnref) {
1979
2055
  const fieldName = (0, select_columns_1.splitName)(columnref.getText());
1980
- return (fieldName.name === field.column_name && (fieldName.prefix === '' || field.table_name === fieldName.prefix));
2056
+ return (fieldName.name === field.name && (fieldName.prefix === '' || field.prefix === fieldName.prefix));
1981
2057
  }
1982
2058
  const aexprconst = c_expr.aexprconst();
1983
2059
  if (aexprconst) {
@@ -2004,7 +2080,7 @@ function isParameter(str) {
2004
2080
  return paramPattern.test(str);
2005
2081
  }
2006
2082
  function isSingleRowResult(selectstmt, fromColumns) {
2007
- var _a, _b;
2083
+ var _a;
2008
2084
  const limit = checkLimit(selectstmt);
2009
2085
  if (limit === 1) {
2010
2086
  return true;
@@ -2018,11 +2094,11 @@ function isSingleRowResult(selectstmt, fromColumns) {
2018
2094
  const simple_select_pramary = simple_select_pramary_list[0];
2019
2095
  const from_clause = simple_select_pramary.from_clause();
2020
2096
  if (!from_clause) {
2021
- const hasSetReturningFunction = (_b = simple_select_pramary.target_list_()) === null || _b === void 0 ? void 0 : _b.target_list().target_el_list().some(target_el => isSetReturningFunction_target_el(target_el));
2097
+ const hasSetReturningFunction = hasFunction(simple_select_pramary, fun => isSetReturningFunction(fun));
2022
2098
  return !hasSetReturningFunction;
2023
2099
  }
2024
2100
  if (!simple_select_pramary.group_clause()) {
2025
- const agreegateFunction = hasAggregateFunction(simple_select_pramary);
2101
+ const agreegateFunction = hasFunction(simple_select_pramary, fun => isAggregateFunction(fun));
2026
2102
  if (agreegateFunction) {
2027
2103
  return true;
2028
2104
  }
@@ -2042,28 +2118,32 @@ function isSingleRowResult(selectstmt, fromColumns) {
2042
2118
  }
2043
2119
  return false;
2044
2120
  }
2045
- function hasAggregateFunction(simple_select_pramary) {
2121
+ function hasFunction(simple_select_pramary, checkFunction) {
2046
2122
  const target_list_ = simple_select_pramary.target_list_();
2047
2123
  if (target_list_) {
2048
- return target_list_.target_list().target_el_list().some(target_el => isAggregateFunction_target_el(target_el));
2124
+ return target_list_.target_list().target_el_list().some(target_el => checkFunction_target_el(target_el, checkFunction));
2049
2125
  }
2050
2126
  const target_list = simple_select_pramary.target_list();
2051
- return target_list.target_el_list().some(target_el => isAggregateFunction_target_el(target_el));
2127
+ if (target_list) {
2128
+ return target_list.target_el_list().some(target_el => checkFunction_target_el(target_el, checkFunction));
2129
+ }
2130
+ return false;
2052
2131
  }
2053
2132
  function getTableName(table_ref) {
2054
2133
  const relation_expr = table_ref.relation_expr();
2055
- const tableName = relation_expr.qualified_name().getText();
2134
+ if (relation_expr) {
2135
+ return traverse_relation_expr(relation_expr);
2136
+ }
2056
2137
  const aliasClause = table_ref.alias_clause();
2057
- const tableAlias = aliasClause ? aliasClause.colid().getText() : '';
2058
2138
  return {
2059
- name: tableName,
2060
- alias: tableAlias
2139
+ name: aliasClause.colid().getText(),
2140
+ alias: ''
2061
2141
  };
2062
2142
  }
2063
- function isAggregateFunction_target_el(target_el) {
2143
+ function checkFunction_target_el(target_el, checkFunction) {
2064
2144
  if (target_el instanceof PostgreSQLParser_1.Target_labelContext) {
2065
2145
  const c_expr_list = collectContextsOfType(target_el, PostgreSQLParser_1.Func_exprContext, false);
2066
- const aggrFunction = c_expr_list.some(func_expr => isAggregateFunction_c_expr(func_expr));
2146
+ const aggrFunction = c_expr_list.some(func_expr => checkFunction(func_expr));
2067
2147
  return aggrFunction;
2068
2148
  }
2069
2149
  return false;
@@ -2116,25 +2196,98 @@ const aggregateFunctions = new Set([
2116
2196
  'variance',
2117
2197
  'xmlagg'
2118
2198
  ]);
2119
- function isAggregateFunction_c_expr(func_expr) {
2199
+ function isAggregateFunction(func_expr) {
2120
2200
  var _a, _b, _c;
2121
2201
  const funcName = (_c = (_b = (_a = func_expr === null || func_expr === void 0 ? void 0 : func_expr.func_application()) === null || _a === void 0 ? void 0 : _a.func_name()) === null || _b === void 0 ? void 0 : _b.getText()) === null || _c === void 0 ? void 0 : _c.toLowerCase();
2122
2202
  // RANK(), DENSE_RANK(), PERCENT_RANK() - they are window functions, not aggregate functions,
2123
2203
  // even though your query is returning them from a join involving pg_aggregate.
2124
2204
  return !func_expr.over_clause() && aggregateFunctions.has(funcName);
2125
2205
  }
2126
- function isSetReturningFunction_target_el(target_el) {
2127
- if (target_el instanceof PostgreSQLParser_1.Target_labelContext) {
2128
- const c_expr_list = collectContextsOfType(target_el, PostgreSQLParser_1.Func_exprContext);
2129
- const setReturningFunction = c_expr_list.some(func_expr => isSetReturningFunction_c_expr(func_expr));
2130
- return setReturningFunction;
2131
- }
2132
- return false;
2133
- }
2134
- function isSetReturningFunction_c_expr(func_expr) {
2206
+ // SELECT distinct '''' || p.proname || ''',' AS function_name
2207
+ // FROM pg_proc p
2208
+ // JOIN pg_namespace n ON p.pronamespace = n.oid
2209
+ // WHERE p.proretset = true
2210
+ // ORDER BY function_name;
2211
+ function isSetReturningFunction(func_expr) {
2135
2212
  var _a, _b, _c;
2136
2213
  const funcName = (_c = (_b = (_a = func_expr === null || func_expr === void 0 ? void 0 : func_expr.func_application()) === null || _a === void 0 ? void 0 : _a.func_name()) === null || _b === void 0 ? void 0 : _b.getText()) === null || _c === void 0 ? void 0 : _c.toLowerCase();
2137
- return funcName === 'generate_series';
2214
+ const setReturning = new Set([
2215
+ '_pg_expandarray',
2216
+ 'aclexplode',
2217
+ 'generate_series',
2218
+ 'generate_subscripts',
2219
+ 'get_clients_with_addresses',
2220
+ 'get_mytable1',
2221
+ 'get_mytable1_by_id',
2222
+ 'get_mytable1_with_nested_function',
2223
+ 'get_mytable_plpgsql',
2224
+ 'get_users_with_posts',
2225
+ 'get_users_with_posts_plpgsql',
2226
+ 'json_array_elements',
2227
+ 'json_array_elements_text',
2228
+ 'json_each',
2229
+ 'json_each_text',
2230
+ 'json_object_keys',
2231
+ 'json_populate_recordset',
2232
+ 'json_to_recordset',
2233
+ 'jsonb_array_elements',
2234
+ 'jsonb_array_elements_text',
2235
+ 'jsonb_each',
2236
+ 'jsonb_each_text',
2237
+ 'jsonb_object_keys',
2238
+ 'jsonb_path_query',
2239
+ 'jsonb_populate_recordset',
2240
+ 'jsonb_to_recordset',
2241
+ 'pg_available_extension_versions',
2242
+ 'pg_available_extensions',
2243
+ 'pg_config',
2244
+ 'pg_cursor',
2245
+ 'pg_event_trigger_ddl_commands',
2246
+ 'pg_event_trigger_dropped_objects',
2247
+ 'pg_extension_update_paths',
2248
+ 'pg_get_keywords',
2249
+ 'pg_get_multixact_members',
2250
+ 'pg_get_publication_tables',
2251
+ 'pg_get_replication_slots',
2252
+ 'pg_hba_file_rules',
2253
+ 'pg_listening_channels',
2254
+ 'pg_lock_status',
2255
+ 'pg_logical_slot_get_binary_changes',
2256
+ 'pg_logical_slot_get_changes',
2257
+ 'pg_logical_slot_peek_binary_changes',
2258
+ 'pg_logical_slot_peek_changes',
2259
+ 'pg_ls_archive_statusdir',
2260
+ 'pg_ls_dir',
2261
+ 'pg_ls_logdir',
2262
+ 'pg_ls_tmpdir',
2263
+ 'pg_ls_waldir',
2264
+ 'pg_mcv_list_items',
2265
+ 'pg_options_to_table',
2266
+ 'pg_partition_ancestors',
2267
+ 'pg_partition_tree',
2268
+ 'pg_prepared_statement',
2269
+ 'pg_prepared_xact',
2270
+ 'pg_show_all_file_settings',
2271
+ 'pg_show_all_settings',
2272
+ 'pg_show_replication_origin_status',
2273
+ 'pg_stat_get_activity',
2274
+ 'pg_stat_get_backend_idset',
2275
+ 'pg_stat_get_progress_info',
2276
+ 'pg_stat_get_wal_senders',
2277
+ 'pg_stop_backup',
2278
+ 'pg_tablespace_databases',
2279
+ 'pg_timezone_abbrevs',
2280
+ 'pg_timezone_names',
2281
+ 'regexp_matches',
2282
+ 'regexp_split_to_table',
2283
+ 'ts_debug',
2284
+ 'ts_parse',
2285
+ 'ts_stat',
2286
+ 'ts_token_type',
2287
+ 'txid_snapshot_xip',
2288
+ 'unnest'
2289
+ ]);
2290
+ return setReturning.has(funcName);
2138
2291
  }
2139
2292
  function isSingleRowResult_where(a_expr, uniqueKeys) {
2140
2293
  var _a, _b;