prostgles-server 4.2.483 → 4.2.484

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 (40) hide show
  1. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +1 -0
  2. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
  3. package/dist/DboBuilder/ViewHandler/parseComplexFilter.d.ts.map +1 -1
  4. package/dist/DboBuilder/ViewHandler/parseComplexFilter.js +3 -2
  5. package/dist/DboBuilder/ViewHandler/parseComplexFilter.js.map +1 -1
  6. package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts +1 -0
  7. package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts.map +1 -1
  8. package/dist/DboBuilder/ViewHandler/prepareWhere.js +26 -13
  9. package/dist/DboBuilder/ViewHandler/prepareWhere.js.map +1 -1
  10. package/dist/DboBuilder/getCondition.d.ts +1 -0
  11. package/dist/DboBuilder/getCondition.d.ts.map +1 -1
  12. package/dist/DboBuilder/getCondition.js +10 -8
  13. package/dist/DboBuilder/getCondition.js.map +1 -1
  14. package/dist/DboBuilder/getSubscribeRelatedTables.d.ts.map +1 -1
  15. package/dist/DboBuilder/getSubscribeRelatedTables.js +1 -1
  16. package/dist/DboBuilder/getSubscribeRelatedTables.js.map +1 -1
  17. package/dist/{Filtering.d.ts → Filtering/Filtering.d.ts} +5 -7
  18. package/dist/Filtering/Filtering.d.ts.map +1 -0
  19. package/dist/Filtering/Filtering.js +244 -0
  20. package/dist/Filtering/Filtering.js.map +1 -0
  21. package/dist/Filtering/getFilterItemCondition.d.ts +7 -0
  22. package/dist/Filtering/getFilterItemCondition.d.ts.map +1 -0
  23. package/dist/Filtering/getFilterItemCondition.js +186 -0
  24. package/dist/Filtering/getFilterItemCondition.js.map +1 -0
  25. package/dist/Filtering/parseFilterRightValue.d.ts +8 -0
  26. package/dist/Filtering/parseFilterRightValue.d.ts.map +1 -0
  27. package/dist/Filtering/parseFilterRightValue.js +23 -0
  28. package/dist/Filtering/parseFilterRightValue.js.map +1 -0
  29. package/lib/DboBuilder/ViewHandler/parseComplexFilter.ts +2 -5
  30. package/lib/DboBuilder/ViewHandler/prepareWhere.ts +30 -15
  31. package/lib/DboBuilder/getCondition.ts +15 -13
  32. package/lib/DboBuilder/getSubscribeRelatedTables.ts +3 -1
  33. package/lib/Filtering/Filtering.ts +286 -0
  34. package/lib/Filtering/getFilterItemCondition.ts +205 -0
  35. package/lib/Filtering/parseFilterRightValue.ts +24 -0
  36. package/package.json +1 -1
  37. package/dist/Filtering.d.ts.map +0 -1
  38. package/dist/Filtering.js +0 -418
  39. package/dist/Filtering.js.map +0 -1
  40. package/lib/Filtering.ts +0 -468
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getFilterItemCondition.d.ts","sourceRoot":"","sources":["../../lib/Filtering/getFilterItemCondition.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAGnF,eAAO,MAAM,sBAAsB,GAAI,6BAIpC;IACD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,mBAAmB,CAAC;IAC7B,MAAM,EAAE,OAAO,CAAC;CACjB,KAAG,MAsLH,CAAC"}
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getFilterItemCondition = void 0;
4
+ const prostgles_types_1 = require("prostgles-types");
5
+ const parseFilterRightValue_1 = require("./parseFilterRightValue");
6
+ const Filtering_1 = require("./Filtering");
7
+ const DboBuilderTypes_1 = require("../DboBuilder/DboBuilderTypes");
8
+ const getFilterItemCondition = ({ selItem, leftQ, rightF, }) => {
9
+ const asValue = (v) => DboBuilderTypes_1.pgp.as.format("$1", [v]);
10
+ const parseRightVal = (val, expect) => {
11
+ try {
12
+ return (0, parseFilterRightValue_1.parseFilterRightValue)(val, { selectItem: selItem, expect });
13
+ }
14
+ catch (e) {
15
+ throw new Error(e);
16
+ }
17
+ };
18
+ /* Matching sel item */
19
+ if ((0, prostgles_types_1.isObject)(rightF)) {
20
+ const filterKeys = Object.keys(rightF);
21
+ let filterOperand = filterKeys[0];
22
+ /** JSON cannot be compared so we'll cast it to TEXT */
23
+ if (selItem.column_udt_type === "json" || (0, prostgles_types_1.includes)(prostgles_types_1.TextFilterKeys, filterOperand)) {
24
+ leftQ += "::TEXT ";
25
+ }
26
+ /** It's an object key which means it's an equality comparison against a json object */
27
+ if (selItem.column_udt_type?.startsWith("json") && !(0, prostgles_types_1.includes)(Filtering_1.FILTER_OPERANDS, filterOperand)) {
28
+ return leftQ + " = " + parseRightVal(rightF);
29
+ }
30
+ let filterValue = rightF[filterOperand];
31
+ const ALLOWED_FUNCS = [...prostgles_types_1.GeomFilter_Funcs, ...prostgles_types_1.TextFilter_FullTextSearchFilterKeys];
32
+ let funcName;
33
+ let funcArgs;
34
+ if (selItem.column_udt_type === "interval" &&
35
+ (0, prostgles_types_1.isObject)(rightF) &&
36
+ Object.values(rightF).every((v) => Number.isFinite(v))) {
37
+ filterOperand = "=";
38
+ filterValue = Object.entries(rightF)
39
+ .map(([k, v]) => `${v}${k}`)
40
+ .join(" ");
41
+ }
42
+ else if ((filterKeys.length !== 1 || !(0, prostgles_types_1.isDefined)(filterOperand)) &&
43
+ selItem.column_udt_type !== "jsonb") {
44
+ throw new Error("Bad filter. Expecting one key only");
45
+ }
46
+ else if ((0, prostgles_types_1.isObject)(filterValue) && !(filterValue instanceof Date)) {
47
+ /**
48
+ * Filter notation
49
+ * geom && st_makeenvelope(funcArgs)
50
+ */
51
+ const filterValueKeys = Object.keys(filterValue);
52
+ funcName = filterValueKeys[0];
53
+ if ((0, prostgles_types_1.includes)(ALLOWED_FUNCS, funcName)) {
54
+ funcArgs = filterValue[funcName];
55
+ }
56
+ else {
57
+ funcName = undefined;
58
+ }
59
+ }
60
+ /** st_makeenvelope */
61
+ if ((0, prostgles_types_1.includes)(prostgles_types_1.GeomFilterKeys, filterOperand) &&
62
+ funcName &&
63
+ (0, prostgles_types_1.includes)(prostgles_types_1.GeomFilter_Funcs, funcName)) {
64
+ /**
65
+ * If leftQ is geography then:
66
+ * - err can happen: 'Antipodal (180 degrees long) edge detected!'
67
+ * - inacurrate results at large envelopes due to the curvature of the earth
68
+ * https://gis.stackexchange.com/questions/78816/maximum-size-on-the-bounding-box-with-st-makeenvelope-and-and-geography-colum
69
+ */
70
+ if (funcName.toLowerCase() === "st_makeenvelope") {
71
+ leftQ += "::geometry";
72
+ }
73
+ return `${leftQ} ${filterOperand} ${funcName}${parseRightVal(funcArgs, "csv")}`;
74
+ }
75
+ else if (["=", "$eq"].includes(filterOperand) && !funcName) {
76
+ if (filterValue === null)
77
+ return leftQ + " IS NULL ";
78
+ return leftQ + " = " + parseRightVal(filterValue);
79
+ }
80
+ else if (["<>", "$ne"].includes(filterOperand)) {
81
+ if (filterValue === null)
82
+ return leftQ + " IS NOT NULL ";
83
+ return leftQ + " <> " + parseRightVal(filterValue);
84
+ }
85
+ else if ([">", "$gt"].includes(filterOperand)) {
86
+ return leftQ + " > " + parseRightVal(filterValue);
87
+ }
88
+ else if (["<", "$lt"].includes(filterOperand)) {
89
+ return leftQ + " < " + parseRightVal(filterValue);
90
+ }
91
+ else if ([">=", "$gte"].includes(filterOperand)) {
92
+ return leftQ + " >= " + parseRightVal(filterValue);
93
+ }
94
+ else if (["<=", "$lte"].includes(filterOperand)) {
95
+ return leftQ + " <= " + parseRightVal(filterValue);
96
+ }
97
+ else if (["$in", "$nin"].includes(filterOperand)) {
98
+ const isIn = filterOperand === "$in";
99
+ if (filterValue !== null && !Array.isArray(filterValue)) {
100
+ throw new Error("In filter expects an array");
101
+ }
102
+ if (!filterValue?.length) {
103
+ return isIn ? " FALSE " : " TRUE ";
104
+ }
105
+ const nonNullFilterValues = filterValue.filter((v) => v !== null);
106
+ const conditions = [];
107
+ if (nonNullFilterValues.length) {
108
+ conditions.push(leftQ + (isIn ? " IN " : " NOT IN ") + parseRightVal(nonNullFilterValues, "csv"));
109
+ }
110
+ if (filterValue.includes(null)) {
111
+ const comparator = isIn ? " IS NULL " : " IS NOT NULL ";
112
+ conditions.push(` ${leftQ} ${comparator} `);
113
+ }
114
+ const joinedConditions = conditions.join(isIn ? " OR " : " AND ");
115
+ return conditions.length > 1 ? `(${joinedConditions})` : joinedConditions;
116
+ }
117
+ else if (["$between"].includes(filterOperand)) {
118
+ if (!Array.isArray(filterValue) || filterValue.length !== 2) {
119
+ throw new Error("Between filter expects an array of two values");
120
+ }
121
+ return leftQ + " BETWEEN " + asValue(filterValue[0]) + " AND " + asValue(filterValue[1]);
122
+ }
123
+ else if (["$ilike"].includes(filterOperand)) {
124
+ return leftQ + " ILIKE " + asValue(filterValue);
125
+ }
126
+ else if (["$like"].includes(filterOperand)) {
127
+ return leftQ + " LIKE " + asValue(filterValue);
128
+ }
129
+ else if (["$nilike"].includes(filterOperand)) {
130
+ return leftQ + " NOT ILIKE " + asValue(filterValue);
131
+ }
132
+ else if (["$nlike"].includes(filterOperand)) {
133
+ return leftQ + " NOT LIKE " + asValue(filterValue);
134
+ }
135
+ else if (filterOperand === "$isDistinctFrom" || filterOperand === "$isNotDistinctFrom") {
136
+ const operator = Filtering_1.FILTER_OPERAND_TO_SQL_OPERAND[filterOperand];
137
+ return leftQ + ` ${operator} ` + asValue(filterValue);
138
+ /* MAYBE TEXT OR MAYBE ARRAY */
139
+ }
140
+ else if (["@>", "<@", "$contains", "$containedBy", "$overlaps", "&&", "@@"].includes(filterOperand)) {
141
+ const operand = filterOperand === "@@" ? "@@"
142
+ : ["@>", "$contains"].includes(filterOperand) ? "@>"
143
+ : ["&&", "$overlaps"].includes(filterOperand) ? "&&"
144
+ : "<@";
145
+ if (operand === "<@" || operand === "@>") {
146
+ if (selItem.column_udt_type === "jsonb") {
147
+ const filterValueAsString = typeof filterValue === "string" ? filterValue : JSON.stringify(filterValue);
148
+ return leftQ + operand + parseRightVal(filterValueAsString);
149
+ }
150
+ }
151
+ /* Array for sure */
152
+ if (Array.isArray(filterValue)) {
153
+ return leftQ + operand + parseRightVal(filterValue, "array");
154
+ /* FTSQuery */
155
+ }
156
+ else if (["@@"].includes(filterOperand) &&
157
+ (0, prostgles_types_1.includes)(prostgles_types_1.TextFilter_FullTextSearchFilterKeys, funcName)) {
158
+ let lq = `to_tsvector(${leftQ}::text)`;
159
+ if (selItem.columnPGDataType === "tsvector")
160
+ lq = leftQ;
161
+ const res = `${lq} ${operand} ` + `${funcName}${parseRightVal(funcArgs, "csv")}`;
162
+ return res;
163
+ }
164
+ else {
165
+ throw new Error("Unrecognised filter operand: " + filterOperand + " ");
166
+ }
167
+ }
168
+ else {
169
+ throw new Error("Unrecognised filter operand: " + filterOperand + " ");
170
+ }
171
+ }
172
+ /* Is an equal filter */
173
+ if (rightF === null) {
174
+ return leftQ + " IS NULL ";
175
+ }
176
+ /**
177
+ * Ensure that when comparing an array to a json column, the array is cast to json
178
+ */
179
+ let valueStr = asValue(rightF);
180
+ if (selItem.column_udt_type?.startsWith("json") && Array.isArray(rightF)) {
181
+ valueStr = DboBuilderTypes_1.pgp.as.format(`$1::jsonb`, [JSON.stringify(rightF)]);
182
+ }
183
+ return `${leftQ} = ${valueStr}`;
184
+ };
185
+ exports.getFilterItemCondition = getFilterItemCondition;
186
+ //# sourceMappingURL=getFilterItemCondition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getFilterItemCondition.js","sourceRoot":"","sources":["../../lib/Filtering/getFilterItemCondition.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { type SelectItemValidated } from "../DboBuilder/QueryBuilder/QueryBuilder";
2
+ type ParseRightValOpts = {
3
+ expect?: "csv" | "array" | "json" | "jsonb";
4
+ selectItem: SelectItemValidated | undefined;
5
+ };
6
+ export declare const parseFilterRightValue: (val: any, { expect, selectItem }: ParseRightValOpts) => string;
7
+ export {};
8
+ //# sourceMappingURL=parseFilterRightValue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseFilterRightValue.d.ts","sourceRoot":"","sources":["../../lib/Filtering/parseFilterRightValue.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAEnF,KAAK,iBAAiB,GAAG;IACvB,MAAM,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IAC5C,UAAU,EAAE,mBAAmB,GAAG,SAAS,CAAC;CAC7C,CAAC;AACF,eAAO,MAAM,qBAAqB,GAAI,KAAK,GAAG,EAAE,wBAAwB,iBAAiB,WAgBxF,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseFilterRightValue = void 0;
4
+ const DboBuilderTypes_1 = require("../DboBuilder/DboBuilderTypes");
5
+ const parseFilterRightValue = (val, { expect, selectItem }) => {
6
+ const asValue = (v) => DboBuilderTypes_1.pgp.as.format("$1", [v]);
7
+ const checkIfArr = () => {
8
+ if (!Array.isArray(val)) {
9
+ throw "This type of filter/column expects an Array of items";
10
+ }
11
+ };
12
+ if (expect === "csv" || expect?.startsWith("json")) {
13
+ checkIfArr();
14
+ return DboBuilderTypes_1.pgp.as.format(`($1:${expect})`, [val]);
15
+ }
16
+ else if (expect === "array" || selectItem?.columnPGDataType === "ARRAY") {
17
+ checkIfArr();
18
+ return DboBuilderTypes_1.pgp.as.format(" ARRAY[$1:csv]", [val]);
19
+ }
20
+ return asValue(val);
21
+ };
22
+ exports.parseFilterRightValue = parseFilterRightValue;
23
+ //# sourceMappingURL=parseFilterRightValue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseFilterRightValue.js","sourceRoot":"","sources":["../../lib/Filtering/parseFilterRightValue.ts"],"names":[],"mappings":";;;AAAA,mEAAoD;AAO7C,MAAM,qBAAqB,GAAG,CAAC,GAAQ,EAAE,EAAE,MAAM,EAAE,UAAU,EAAqB,EAAE,EAAE;IAC3F,MAAM,OAAO,GAAG,CAAC,CAAM,EAAE,EAAE,CAAC,qBAAG,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,GAAG,EAAE;QACtB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,sDAAsD,CAAC;QAC/D,CAAC;IACH,CAAC,CAAC;IACF,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,UAAU,EAAE,CAAC;QACb,OAAO,qBAAG,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,MAAM,KAAK,OAAO,IAAI,UAAU,EAAE,gBAAgB,KAAK,OAAO,EAAE,CAAC;QAC1E,UAAU,EAAE,CAAC;QACb,OAAO,qBAAG,CAAC,EAAE,CAAC,MAAM,CAAC,gBAAgB,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC,CAAC;AAhBW,QAAA,qBAAqB,yBAgBhC"}
@@ -1,16 +1,13 @@
1
1
  import type { AnyObject } from "prostgles-types";
2
2
  import { isObject } from "prostgles-types";
3
- import {
4
- FILTER_OPERANDS,
5
- FILTER_OPERAND_TO_SQL_OPERAND,
6
- parseFilterRightValue,
7
- } from "../../Filtering";
3
+ import { FILTER_OPERANDS, FILTER_OPERAND_TO_SQL_OPERAND } from "../../Filtering/Filtering";
8
4
  import { FUNCTIONS } from "../QueryBuilder/Functions/Functions";
9
5
  import { parseFunctionObject } from "../QueryBuilder/QueryBuilder";
10
6
  import type { TableSchemaColumn } from "../DboBuilderTypes";
11
7
  import { asValue } from "../../PubSubManager/PubSubManagerUtils";
12
8
  import { parseFunction } from "../QueryBuilder/Functions/parseFunction";
13
9
  import { asNameAlias } from "../../utils/asNameAlias";
10
+ import { parseFilterRightValue } from "../../Filtering/parseFilterRightValue";
14
11
 
15
12
  const allowedComparators = FILTER_OPERANDS; //[">", "<", "=", "<=", ">=", "<>", "!="]
16
13
  type Args = {
@@ -22,6 +22,7 @@ export async function prepareWhere(
22
22
  this: ViewHandler,
23
23
  params: PrepareWhereParams,
24
24
  ): Promise<{
25
+ columnsUsed: string[];
25
26
  condition: string;
26
27
  where: string;
27
28
  filter: AnyObject;
@@ -45,14 +46,15 @@ export async function prepareWhere(
45
46
 
46
47
  const exists: ExistsFilterConfig[] = [];
47
48
 
49
+ type FilterItemResult = { condition: string; columnsUsed: string[] };
48
50
  const parseFullFilter = async (
49
51
  f: any,
50
52
  parentFilter: AnyObject | null = null,
51
53
  isForcedFilterBypass: boolean,
52
- ): Promise<string> => {
54
+ ): Promise<FilterItemResult> => {
53
55
  if (!f) throw "Invalid/missing group filter provided";
54
56
  if (!isObject(f)) throw "\nInvalid filter\nExpecting an object but got -> " + JSON.stringify(f);
55
- let result = "";
57
+ const result = { condition: "", columnsUsed: [] as string[] };
56
58
  const keys = getKeys(f);
57
59
  if (!keys.length) {
58
60
  return result;
@@ -69,19 +71,21 @@ export async function prepareWhere(
69
71
 
70
72
  if (group && group.length) {
71
73
  const operand = $and ? " AND " : " OR ";
72
- const conditions = (
74
+ const conditionItems = (
73
75
  await Promise.all(
74
76
  group.map(async (gf) => await parseFullFilter(gf, group, isForcedFilterBypass)),
75
77
  )
76
- ).filter((c) => c);
78
+ ).filter((c) => c.condition);
77
79
 
78
- if (conditions.length) {
79
- if (conditions.length === 1) return conditions.join(operand);
80
- else return ` ( ${conditions.sort().join(operand)} ) `;
80
+ if (conditionItems.length) {
81
+ const conditions = conditionItems.map((c) => c.condition);
82
+ const columnsUsed = conditionItems.map((c) => c.columnsUsed).flat();
83
+ if (conditions.length === 1) return { columnsUsed, condition: conditions.join(operand) };
84
+ else return { columnsUsed, condition: ` ( ${conditions.sort().join(operand)} ) ` };
81
85
  }
82
86
  } else if (!group) {
83
87
  /** forcedFilters do not get checked against publish and are treated as server-side requests */
84
- const cond = await getCondition.bind(this)({
88
+ const { condition, exists, columnsUsed } = await getCondition.bind(this)({
85
89
  filter: { ...f },
86
90
  select,
87
91
  allowed_colnames:
@@ -91,8 +95,9 @@ export async function prepareWhere(
91
95
  tableRules: isForcedFilterBypass ? undefined : tableRule,
92
96
  isHaving: params.isHaving,
93
97
  });
94
- result = cond.condition;
95
- exists.push(...cond.exists);
98
+ result.condition = condition;
99
+ result.columnsUsed = columnsUsed;
100
+ exists.push(...exists);
96
101
  }
97
102
  return result;
98
103
  };
@@ -101,8 +106,12 @@ export async function prepareWhere(
101
106
  const forcedFilterCond =
102
107
  forcedFilter ? await parseFullFilter(forcedFilter, null, true) : undefined;
103
108
  const filterCond = await parseFullFilter(filter, null, false);
104
- let cond = [forcedFilterCond, filterCond].filter((c) => c).join(" AND ");
109
+ let combinedConditions = [forcedFilterCond, filterCond]
110
+ .map((c) => (c?.condition ? c.condition : undefined))
111
+ .filter(isDefined)
112
+ .join(" AND ");
105
113
 
114
+ const combinedColumnsUsed = [...(forcedFilterCond?.columnsUsed ?? []), ...filterCond.columnsUsed];
106
115
  const finalFilter =
107
116
  forcedFilter ?
108
117
  {
@@ -110,9 +119,15 @@ export async function prepareWhere(
110
119
  }
111
120
  : { ...filter };
112
121
 
113
- const condition = cond;
114
- if (cond && addKeywords) {
115
- cond = `WHERE ${cond}`;
122
+ const condition = combinedConditions;
123
+ if (combinedConditions && addKeywords) {
124
+ combinedConditions = `WHERE ${combinedConditions}`;
116
125
  }
117
- return { condition, where: cond || "", filter: finalFilter, exists };
126
+ return {
127
+ columnsUsed: combinedColumnsUsed,
128
+ condition,
129
+ where: combinedConditions || "",
130
+ filter: finalFilter,
131
+ exists,
132
+ };
118
133
  }
@@ -1,5 +1,5 @@
1
- import { asName, pickKeys } from "prostgles-types";
2
- import { parseFilterItem } from "../Filtering";
1
+ import { pickKeys } from "prostgles-types";
2
+ import { parseFilterItem } from "../Filtering/Filtering";
3
3
  import type { ParsedTableRule } from "../PublishParser/PublishParser";
4
4
  import type { ExistsFilterConfig, LocalParams, PGIdentifier } from "./DboBuilder";
5
5
  import { pgp } from "./DboBuilder";
@@ -29,7 +29,7 @@ export async function getCondition(
29
29
  tableRules?: ParsedTableRule;
30
30
  isHaving?: boolean;
31
31
  },
32
- ): Promise<{ exists: ExistsFilterConfig[]; condition: string }> {
32
+ ): Promise<{ exists: ExistsFilterConfig[]; condition: string; columnsUsed: string[] }> {
33
33
  const {
34
34
  filter: rawFilter,
35
35
  select,
@@ -179,21 +179,22 @@ export async function getCondition(
179
179
  !existsConfigs.find((ek) => ek.existType === k),
180
180
  );
181
181
 
182
- const validFieldNames = allowedSelect.map((s) => s.alias);
182
+ const selectAliases = allowedSelect.map((s) => s.alias);
183
183
  const invalidColumn = filterKeys.find(
184
- (fName) =>
185
- !validFieldNames.find(
186
- (c) =>
187
- c === fName ||
188
- (fName.startsWith(c) &&
189
- (fName.slice(c.length).includes("->") || fName.slice(c.length).includes("."))),
184
+ (filterKey) =>
185
+ !selectAliases.find(
186
+ (alias) =>
187
+ alias === filterKey ||
188
+ (filterKey.startsWith(alias) &&
189
+ (filterKey.slice(alias.length).includes("->") ||
190
+ filterKey.slice(alias.length).includes("."))),
190
191
  ),
191
192
  );
192
193
 
193
194
  if (invalidColumn) {
194
- const selItem = select?.find((s) => s.alias === invalidColumn);
195
+ const selectItem = select?.find((s) => s.alias === invalidColumn);
195
196
  let isComplexFilter = false;
196
- if (selItem?.type === "aggregation") {
197
+ if (selectItem?.type === "aggregation") {
197
198
  if (!params.isHaving) {
198
199
  throw new Error(
199
200
  `Filtering by ${this.name}.${invalidColumn} is not allowed. Aggregations cannot be filtered. Use HAVING clause instead.`,
@@ -227,7 +228,7 @@ export async function getCondition(
227
228
  : this.parseFieldFilter(tableRules.select?.filterFields ?? tableRules.select?.fields),
228
229
  });
229
230
 
230
- let templates: string[] = [q].filter((q) => q);
231
+ let templates: string[] = q?.condition ? [q.condition] : [];
231
232
 
232
233
  if (existsCond) templates.push(existsCond);
233
234
  templates = templates.concat(funcConds);
@@ -236,6 +237,7 @@ export async function getCondition(
236
237
 
237
238
  /* sorted to ensure duplicate subscription channels are not created due to different condition order */
238
239
  return {
240
+ columnsUsed: q?.columnsUsed ?? [],
239
241
  exists: existsConfigs,
240
242
  condition: templates.sort().join(" AND \n"),
241
243
  };
@@ -80,7 +80,9 @@ export async function getSubscribeRelatedTables(
80
80
  const joinColumns =
81
81
  relatedTableJoinPathItem?.on.map((columnPair) => Object.values(columnPair)).flat() ?? [];
82
82
 
83
- const trackedColumns = Array.from(new Set([...(selectedColumnNames ?? []), ...joinColumns]));
83
+ const trackedColumns = Array.from(
84
+ new Set([...(selectedColumnNames ?? []), ...joinColumns, ...joinConditionInfo.columnsUsed]),
85
+ );
84
86
 
85
87
  viewOptions.relatedTables.push({
86
88
  tableName: relatedTableName,