@devrev/meerkat-core 0.0.84 → 0.0.86

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 (59) hide show
  1. package/package.json +1 -1
  2. package/src/ast-serializer/ast-serializer.d.ts +1 -0
  3. package/src/ast-serializer/ast-serializer.js +12 -0
  4. package/src/ast-serializer/ast-serializer.js.map +1 -0
  5. package/src/ast-validator/dimension-validator.d.ts +10 -0
  6. package/src/ast-validator/dimension-validator.js +54 -0
  7. package/src/ast-validator/dimension-validator.js.map +1 -0
  8. package/src/ast-validator/index.d.ts +4 -0
  9. package/src/ast-validator/index.js +25 -0
  10. package/src/ast-validator/index.js.map +1 -0
  11. package/src/ast-validator/measure-validator.d.ts +11 -0
  12. package/src/ast-validator/measure-validator.js +162 -0
  13. package/src/ast-validator/measure-validator.js.map +1 -0
  14. package/src/ast-validator/tests/test-data.d.ts +2133 -0
  15. package/src/ast-validator/tests/test-data.js +2121 -0
  16. package/src/ast-validator/tests/test-data.js.map +1 -0
  17. package/src/ast-validator/types.d.ts +8 -0
  18. package/src/ast-validator/types.js +3 -0
  19. package/src/ast-validator/types.js.map +1 -0
  20. package/src/ast-validator/utils.d.ts +4 -0
  21. package/src/ast-validator/utils.js +35 -0
  22. package/src/ast-validator/utils.js.map +1 -0
  23. package/src/cube-filter-transformer/base-condition-builder/base-condition-builder.js +3 -2
  24. package/src/cube-filter-transformer/base-condition-builder/base-condition-builder.js.map +1 -1
  25. package/src/cube-filter-transformer/constant.d.ts +1 -0
  26. package/src/cube-filter-transformer/constant.js +10 -0
  27. package/src/cube-filter-transformer/constant.js.map +1 -0
  28. package/src/cube-filter-transformer/contains/contains.js +2 -1
  29. package/src/cube-filter-transformer/contains/contains.js.map +1 -1
  30. package/src/cube-filter-transformer/in/in.d.ts +1 -1
  31. package/src/cube-filter-transformer/in/in.js +22 -21
  32. package/src/cube-filter-transformer/in/in.js.map +1 -1
  33. package/src/cube-filter-transformer/not/not.d.ts +2 -2
  34. package/src/cube-filter-transformer/not/not.js.map +1 -1
  35. package/src/cube-filter-transformer/not-contains/not-contains.d.ts +1 -1
  36. package/src/cube-filter-transformer/not-contains/not-contains.js +2 -1
  37. package/src/cube-filter-transformer/not-contains/not-contains.js.map +1 -1
  38. package/src/cube-filter-transformer/not-in/not-in.d.ts +1 -1
  39. package/src/cube-filter-transformer/not-in/not-in.js +23 -22
  40. package/src/cube-filter-transformer/not-in/not-in.js.map +1 -1
  41. package/src/cube-filter-transformer/not-set/not-set.d.ts +1 -1
  42. package/src/cube-filter-transformer/not-set/not-set.js +6 -5
  43. package/src/cube-filter-transformer/not-set/not-set.js.map +1 -1
  44. package/src/cube-filter-transformer/set/set.d.ts +1 -1
  45. package/src/cube-filter-transformer/set/set.js +6 -5
  46. package/src/cube-filter-transformer/set/set.js.map +1 -1
  47. package/src/index.d.ts +4 -1
  48. package/src/index.js +3 -0
  49. package/src/index.js.map +1 -1
  50. package/src/types/duckdb-serialization-types/serialization/ParsedExpression.d.ts +17 -0
  51. package/src/types/duckdb-serialization-types/serialization/ParsedExpression.js.map +1 -1
  52. package/src/types/utils.d.ts +19 -0
  53. package/src/types/utils.js +108 -0
  54. package/src/types/utils.js.map +1 -0
  55. package/src/utils/base-ast.js +2 -3
  56. package/src/utils/base-ast.js.map +1 -1
  57. package/src/utils/get-column-names-from-ast.d.ts +2 -0
  58. package/src/utils/get-column-names-from-ast.js +45 -0
  59. package/src/utils/get-column-names-from-ast.js.map +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devrev/meerkat-core",
3
- "version": "0.0.84",
3
+ "version": "0.0.86",
4
4
  "dependencies": {
5
5
  "@swc/helpers": "~0.5.0"
6
6
  },
@@ -0,0 +1 @@
1
+ export declare const astSerializerQuery: (query: string) => string;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "astSerializerQuery", {
3
+ enumerable: true,
4
+ get: function() {
5
+ return astSerializerQuery;
6
+ }
7
+ });
8
+ const astSerializerQuery = (query)=>{
9
+ return `SELECT json_serialize_sql('${query}')`;
10
+ };
11
+
12
+ //# sourceMappingURL=ast-serializer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../meerkat-core/src/ast-serializer/ast-serializer.ts"],"sourcesContent":["export const astSerializerQuery = (query: string) => {\n return `SELECT json_serialize_sql('${query}')`;\n};\n"],"names":["astSerializerQuery","query"],"mappings":";+BAAaA;;;eAAAA;;;AAAN,MAAMA,qBAAqB,CAACC;IACjC,OAAO,CAAC,2BAA2B,EAAEA,MAAM,EAAE,CAAC;AAChD"}
@@ -0,0 +1,10 @@
1
+ import { ParsedExpression } from '../types/duckdb-serialization-types';
2
+ import { ParsedSerialization } from './types';
3
+ /**
4
+ * Validates an individual expression node
5
+ */
6
+ export declare const validateExpressionNode: (node: ParsedExpression, validFunctions: Set<string>) => boolean;
7
+ /**
8
+ * Validates if the parsed serialization represents a valid dimension
9
+ */
10
+ export declare const validateDimension: (parsedSerialization: ParsedSerialization, validFunctions: string[]) => boolean;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ function _export(target, all) {
3
+ for(var name in all)Object.defineProperty(target, name, {
4
+ enumerable: true,
5
+ get: all[name]
6
+ });
7
+ }
8
+ _export(exports, {
9
+ validateExpressionNode: function() {
10
+ return validateExpressionNode;
11
+ },
12
+ validateDimension: function() {
13
+ return validateDimension;
14
+ }
15
+ });
16
+ const _utils = require("../types/utils");
17
+ const _utils1 = require("./utils");
18
+ const validateExpressionNode = (node, validFunctions)=>{
19
+ // Column references and value constants
20
+ if ((0, _utils.isColumnRefExpression)(node) || (0, _utils.isConstantExpression)(node)) {
21
+ return true;
22
+ }
23
+ // Cast expression
24
+ if ((0, _utils.isCastExpression)(node)) {
25
+ return validateExpressionNode(node.child, validFunctions);
26
+ }
27
+ // Operator expression
28
+ if ((0, _utils.isOperatorExpression)(node)) {
29
+ return node.children.every((child)=>validateExpressionNode(child, validFunctions));
30
+ }
31
+ // Function expression
32
+ if ((0, _utils.isFunctionExpression)(node)) {
33
+ if (!validFunctions.has(node.function_name)) {
34
+ throw new Error(`Invalid function: ${node.function_name}`);
35
+ }
36
+ return node.children.every((child)=>validateExpressionNode(child, validFunctions));
37
+ }
38
+ // Case expression
39
+ if ((0, _utils.isCaseExpression)(node)) {
40
+ return node.case_checks.every((check)=>validateExpressionNode(check.then_expr, validFunctions)) && validateExpressionNode(node.else_expr, validFunctions);
41
+ }
42
+ throw new Error(`Invalid expression type: ${node.type}`);
43
+ };
44
+ const validateDimension = (parsedSerialization, validFunctions)=>{
45
+ const node = (0, _utils1.getSelectNode)(parsedSerialization);
46
+ const validFunctionSet = new Set(validFunctions);
47
+ // Validate the expression
48
+ if (validateExpressionNode(node, validFunctionSet)) {
49
+ return true;
50
+ }
51
+ throw new Error('Expression contains invalid functions or operators');
52
+ };
53
+
54
+ //# sourceMappingURL=dimension-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../meerkat-core/src/ast-validator/dimension-validator.ts"],"sourcesContent":["import { ParsedExpression } from '../types/duckdb-serialization-types';\nimport {\n isCaseExpression,\n isCastExpression,\n isColumnRefExpression,\n isConstantExpression,\n isFunctionExpression,\n isOperatorExpression,\n} from '../types/utils';\nimport { ParsedSerialization } from './types';\nimport { getSelectNode } from './utils';\n\n/**\n * Validates an individual expression node\n */\nexport const validateExpressionNode = (\n node: ParsedExpression,\n validFunctions: Set<string>\n): boolean => {\n // Column references and value constants\n if (isColumnRefExpression(node) || isConstantExpression(node)) {\n return true;\n }\n\n // Cast expression\n if (isCastExpression(node)) {\n return validateExpressionNode(node.child, validFunctions);\n }\n\n // Operator expression\n if (isOperatorExpression(node)) {\n return node.children.every((child) =>\n validateExpressionNode(child, validFunctions)\n );\n }\n\n // Function expression\n if (isFunctionExpression(node)) {\n if (!validFunctions.has(node.function_name)) {\n throw new Error(`Invalid function: ${node.function_name}`);\n }\n return node.children.every((child) =>\n validateExpressionNode(child, validFunctions)\n );\n }\n\n // Case expression\n if (isCaseExpression(node)) {\n return (\n node.case_checks.every((check) =>\n validateExpressionNode(check.then_expr, validFunctions)\n ) && validateExpressionNode(node.else_expr, validFunctions)\n );\n }\n\n throw new Error(`Invalid expression type: ${node.type}`);\n};\n\n/**\n * Validates if the parsed serialization represents a valid dimension\n */\nexport const validateDimension = (\n parsedSerialization: ParsedSerialization,\n validFunctions: string[]\n): boolean => {\n const node = getSelectNode(parsedSerialization);\n\n const validFunctionSet = new Set(validFunctions);\n\n // Validate the expression\n if (validateExpressionNode(node, validFunctionSet)) {\n return true;\n }\n\n throw new Error('Expression contains invalid functions or operators');\n};\n"],"names":["validateExpressionNode","validateDimension","node","validFunctions","isColumnRefExpression","isConstantExpression","isCastExpression","child","isOperatorExpression","children","every","isFunctionExpression","has","function_name","Error","isCaseExpression","case_checks","check","then_expr","else_expr","type","parsedSerialization","getSelectNode","validFunctionSet","Set"],"mappings":";;;;;;;;IAeaA,sBAAsB;eAAtBA;;IA8CAC,iBAAiB;eAAjBA;;;uBArDN;wBAEuB;AAKvB,MAAMD,yBAAyB,CACpCE,MACAC;IAEA,wCAAwC;IACxC,IAAIC,IAAAA,4BAAqB,EAACF,SAASG,IAAAA,2BAAoB,EAACH,OAAO;QAC7D,OAAO;IACT;IAEA,kBAAkB;IAClB,IAAII,IAAAA,uBAAgB,EAACJ,OAAO;QAC1B,OAAOF,uBAAuBE,KAAKK,KAAK,EAAEJ;IAC5C;IAEA,sBAAsB;IACtB,IAAIK,IAAAA,2BAAoB,EAACN,OAAO;QAC9B,OAAOA,KAAKO,QAAQ,CAACC,KAAK,CAAC,CAACH,QAC1BP,uBAAuBO,OAAOJ;IAElC;IAEA,sBAAsB;IACtB,IAAIQ,IAAAA,2BAAoB,EAACT,OAAO;QAC9B,IAAI,CAACC,eAAeS,GAAG,CAACV,KAAKW,aAAa,GAAG;YAC3C,MAAM,IAAIC,MAAM,CAAC,kBAAkB,EAAEZ,KAAKW,aAAa,CAAC,CAAC;QAC3D;QACA,OAAOX,KAAKO,QAAQ,CAACC,KAAK,CAAC,CAACH,QAC1BP,uBAAuBO,OAAOJ;IAElC;IAEA,kBAAkB;IAClB,IAAIY,IAAAA,uBAAgB,EAACb,OAAO;QAC1B,OACEA,KAAKc,WAAW,CAACN,KAAK,CAAC,CAACO,QACtBjB,uBAAuBiB,MAAMC,SAAS,EAAEf,oBACrCH,uBAAuBE,KAAKiB,SAAS,EAAEhB;IAEhD;IAEA,MAAM,IAAIW,MAAM,CAAC,yBAAyB,EAAEZ,KAAKkB,IAAI,CAAC,CAAC;AACzD;AAKO,MAAMnB,oBAAoB,CAC/BoB,qBACAlB;IAEA,MAAMD,OAAOoB,IAAAA,qBAAa,EAACD;IAE3B,MAAME,mBAAmB,IAAIC,IAAIrB;IAEjC,0BAA0B;IAC1B,IAAIH,uBAAuBE,MAAMqB,mBAAmB;QAClD,OAAO;IACT;IAEA,MAAM,IAAIT,MAAM;AAClB"}
@@ -0,0 +1,4 @@
1
+ export { validateDimension } from './dimension-validator';
2
+ export { validateMeasure } from './measure-validator';
3
+ export * from './types';
4
+ export { getSelectNode } from './utils';
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ function _export(target, all) {
3
+ for(var name in all)Object.defineProperty(target, name, {
4
+ enumerable: true,
5
+ get: all[name]
6
+ });
7
+ }
8
+ _export(exports, {
9
+ validateDimension: function() {
10
+ return _dimensionvalidator.validateDimension;
11
+ },
12
+ validateMeasure: function() {
13
+ return _measurevalidator.validateMeasure;
14
+ },
15
+ getSelectNode: function() {
16
+ return _utils.getSelectNode;
17
+ }
18
+ });
19
+ const _export_star = require("@swc/helpers/_/_export_star");
20
+ const _dimensionvalidator = require("./dimension-validator");
21
+ const _measurevalidator = require("./measure-validator");
22
+ _export_star._(require("./types"), exports);
23
+ const _utils = require("./utils");
24
+
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../meerkat-core/src/ast-validator/index.ts"],"sourcesContent":["export { validateDimension } from './dimension-validator';\nexport { validateMeasure } from './measure-validator';\nexport * from './types';\nexport { getSelectNode } from './utils';\n"],"names":["validateDimension","validateMeasure","getSelectNode"],"mappings":";;;;;;;;IAASA,iBAAiB;eAAjBA,qCAAiB;;IACjBC,eAAe;eAAfA,iCAAe;;IAEfC,aAAa;eAAbA,oBAAa;;;;oCAHY;kCACF;uBAClB;uBACgB"}
@@ -0,0 +1,11 @@
1
+ import { ParsedExpression } from '../types/duckdb-serialization-types';
2
+ import { ParsedSerialization } from './types';
3
+ export declare const validateExpressionNode: ({ node, validFunctions, parentNode, validScalarFunctions, hasAggregation, }: {
4
+ node: ParsedExpression;
5
+ validFunctions: Set<string>;
6
+ parentNode: ParsedExpression | null;
7
+ hasAggregation?: boolean | undefined;
8
+ validScalarFunctions: Set<string>;
9
+ }) => boolean;
10
+ export declare const containsAggregation: (node: ParsedExpression, validFunctions: Set<string>) => boolean;
11
+ export declare const validateMeasure: (parsedSerialization: ParsedSerialization, validFunctions: string[], validScalarFunctions: string[]) => boolean;
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ function _export(target, all) {
3
+ for(var name in all)Object.defineProperty(target, name, {
4
+ enumerable: true,
5
+ get: all[name]
6
+ });
7
+ }
8
+ _export(exports, {
9
+ validateExpressionNode: function() {
10
+ return validateExpressionNode;
11
+ },
12
+ containsAggregation: function() {
13
+ return containsAggregation;
14
+ },
15
+ validateMeasure: function() {
16
+ return validateMeasure;
17
+ }
18
+ });
19
+ const _utils = require("../types/utils");
20
+ const _utils1 = require("./utils");
21
+ const validateExpressionNode = ({ node, validFunctions, parentNode, validScalarFunctions, hasAggregation = false })=>{
22
+ // Base cases for column references and constants
23
+ if ((0, _utils.isColumnRefExpression)(node) || (0, _utils.isConstantExpression)(node)) {
24
+ // Allow column references inside aggregation functions
25
+ return !!parentNode;
26
+ }
27
+ // Check for valid aggregation functions
28
+ if ((0, _utils.isFunctionExpression)(node) || (0, _utils.isWindowExpression)(node)) {
29
+ // count_star don't have children
30
+ if (node.function_name === 'count_star') return true;
31
+ // This is a valid aggregation function - verify its children don't contain nested aggregations
32
+ if (validFunctions.has(node.function_name)) {
33
+ return node.children.some((child)=>validateExpressionNode({
34
+ node: child,
35
+ validFunctions,
36
+ parentNode: node,
37
+ validScalarFunctions
38
+ }));
39
+ }
40
+ // For non-aggregation functions
41
+ if (validScalarFunctions.has(node.function_name)) {
42
+ return node.children.some((child)=>{
43
+ return validateExpressionNode({
44
+ node: child,
45
+ validFunctions,
46
+ parentNode: node,
47
+ validScalarFunctions
48
+ }) && (containsAggregation(child, validFunctions) || hasAggregation);
49
+ });
50
+ }
51
+ throw new Error(`Invalid function type: ${node.function_name}`);
52
+ }
53
+ // Operator expression
54
+ if ((0, _utils.isOperatorExpression)(node)) {
55
+ return node.children.some((child)=>validateExpressionNode({
56
+ node: child,
57
+ validFunctions,
58
+ parentNode,
59
+ validScalarFunctions
60
+ }));
61
+ }
62
+ // Cast expression
63
+ if ((0, _utils.isCastExpression)(node)) {
64
+ return validateExpressionNode({
65
+ node: node.child,
66
+ validFunctions,
67
+ parentNode,
68
+ validScalarFunctions
69
+ });
70
+ }
71
+ // Case expression
72
+ if ((0, _utils.isCaseExpression)(node)) {
73
+ const checksValid = node.case_checks.every((caseCheck)=>{
74
+ // WHEN conditions cannot contain aggregations
75
+ const whenValid = !containsAggregation(caseCheck.when_expr, validFunctions);
76
+ // THEN expressions must be valid aggregations or contain no aggregations
77
+ const thenValid = validateExpressionNode({
78
+ node: caseCheck.then_expr,
79
+ validFunctions,
80
+ parentNode: node,
81
+ validScalarFunctions
82
+ }) || !containsAggregation(caseCheck.then_expr, validFunctions);
83
+ return whenValid && thenValid;
84
+ });
85
+ const elseValid = validateExpressionNode({
86
+ node: node.else_expr,
87
+ validFunctions,
88
+ parentNode: node,
89
+ validScalarFunctions
90
+ }) || !containsAggregation(node.else_expr, validFunctions);
91
+ return checksValid && elseValid;
92
+ }
93
+ // Subquery expression
94
+ if ((0, _utils.isSubqueryExpression)(node) && (0, _utils.isSelectNode)(node.subquery.node)) {
95
+ return node.subquery.node.select_list.every((node)=>{
96
+ return validateExpressionNode({
97
+ node,
98
+ validFunctions,
99
+ parentNode,
100
+ validScalarFunctions
101
+ });
102
+ });
103
+ }
104
+ // Window expression
105
+ if ((0, _utils.isWindowExpression)(node)) {
106
+ return node.children.every((node)=>{
107
+ return validateExpressionNode({
108
+ node,
109
+ validFunctions,
110
+ parentNode,
111
+ validScalarFunctions
112
+ });
113
+ });
114
+ }
115
+ throw new Error(`Invalid expression type: ${node.type}`);
116
+ };
117
+ const containsAggregation = (node, validFunctions)=>{
118
+ if (!node) return false;
119
+ // Function expression
120
+ if ((0, _utils.isFunctionExpression)(node) || (0, _utils.isWindowExpression)(node)) {
121
+ return validFunctions.has(node.function_name) || node.children.some((child)=>containsAggregation(child, validFunctions));
122
+ }
123
+ // Case expression
124
+ if ((0, _utils.isCaseExpression)(node)) {
125
+ return node.case_checks.some((check)=>containsAggregation(check.when_expr, validFunctions) || containsAggregation(check.then_expr, validFunctions)) || containsAggregation(node.else_expr, validFunctions);
126
+ }
127
+ // Operator expression
128
+ if ((0, _utils.isOperatorExpression)(node)) {
129
+ return node.children.some((child)=>containsAggregation(child, validFunctions));
130
+ }
131
+ if ((0, _utils.isCastExpression)(node)) {
132
+ return containsAggregation(node.child, validFunctions);
133
+ }
134
+ // Window expression
135
+ if ((0, _utils.isWindowExpression)(node)) {
136
+ return node.children.some((child)=>containsAggregation(child, validFunctions));
137
+ }
138
+ // Subquery expression
139
+ if ((0, _utils.isSubqueryExpression)(node) && (0, _utils.isSelectNode)(node.subquery.node)) {
140
+ return node.subquery.node.select_list.every((node)=>{
141
+ return containsAggregation(node, validFunctions);
142
+ });
143
+ }
144
+ return false;
145
+ };
146
+ const validateMeasure = (parsedSerialization, validFunctions, validScalarFunctions)=>{
147
+ const node = (0, _utils1.getSelectNode)(parsedSerialization);
148
+ const validFunctionSet = new Set(validFunctions);
149
+ const validScalarFunctionSet = new Set(validScalarFunctions);
150
+ // Validate the expression
151
+ if (validateExpressionNode({
152
+ node: node,
153
+ validFunctions: validFunctionSet,
154
+ parentNode: null,
155
+ validScalarFunctions: validScalarFunctionSet
156
+ })) {
157
+ return true;
158
+ }
159
+ throw new Error('Expression contains invalid functions or operators');
160
+ };
161
+
162
+ //# sourceMappingURL=measure-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../meerkat-core/src/ast-validator/measure-validator.ts"],"sourcesContent":["import { ParsedExpression } from '../types/duckdb-serialization-types';\nimport {\n isCaseExpression,\n isCastExpression,\n isColumnRefExpression,\n isConstantExpression,\n isFunctionExpression,\n isOperatorExpression,\n isSelectNode,\n isSubqueryExpression,\n isWindowExpression,\n} from '../types/utils';\nimport { ParsedSerialization } from './types';\nimport { getSelectNode } from './utils';\n\nexport const validateExpressionNode = ({\n node,\n validFunctions,\n parentNode,\n validScalarFunctions,\n hasAggregation = false,\n}: {\n node: ParsedExpression;\n validFunctions: Set<string>;\n parentNode: ParsedExpression | null;\n hasAggregation?: boolean;\n validScalarFunctions: Set<string>;\n}): boolean => {\n // Base cases for column references and constants\n if (isColumnRefExpression(node) || isConstantExpression(node)) {\n // Allow column references inside aggregation functions\n return !!parentNode;\n }\n\n // Check for valid aggregation functions\n if (isFunctionExpression(node) || isWindowExpression(node)) {\n // count_star don't have children\n if (node.function_name === 'count_star') return true;\n\n // This is a valid aggregation function - verify its children don't contain nested aggregations\n if (validFunctions.has(node.function_name)) {\n return node.children.some((child) =>\n validateExpressionNode({\n node: child,\n validFunctions,\n parentNode: node,\n validScalarFunctions,\n })\n );\n }\n // For non-aggregation functions\n if (validScalarFunctions.has(node.function_name)) {\n return node.children.some((child) => {\n return (\n validateExpressionNode({\n node: child,\n validFunctions,\n parentNode: node,\n validScalarFunctions,\n }) &&\n (containsAggregation(child, validFunctions) || hasAggregation)\n );\n });\n }\n\n throw new Error(`Invalid function type: ${node.function_name}`);\n }\n\n // Operator expression\n if (isOperatorExpression(node)) {\n return node.children.some((child) =>\n validateExpressionNode({\n node: child,\n validFunctions,\n parentNode,\n validScalarFunctions,\n })\n );\n }\n\n // Cast expression\n if (isCastExpression(node)) {\n return validateExpressionNode({\n node: node.child,\n validFunctions,\n parentNode,\n validScalarFunctions,\n });\n }\n\n // Case expression\n if (isCaseExpression(node)) {\n const checksValid = node.case_checks.every((caseCheck) => {\n // WHEN conditions cannot contain aggregations\n const whenValid = !containsAggregation(\n caseCheck.when_expr,\n validFunctions\n );\n\n // THEN expressions must be valid aggregations or contain no aggregations\n const thenValid =\n validateExpressionNode({\n node: caseCheck.then_expr,\n validFunctions,\n parentNode: node,\n validScalarFunctions,\n }) || !containsAggregation(caseCheck.then_expr, validFunctions);\n return whenValid && thenValid;\n });\n\n const elseValid =\n validateExpressionNode({\n node: node.else_expr,\n validFunctions,\n parentNode: node,\n validScalarFunctions,\n }) || !containsAggregation(node.else_expr, validFunctions);\n\n return checksValid && elseValid;\n }\n\n // Subquery expression\n if (isSubqueryExpression(node) && isSelectNode(node.subquery.node)) {\n return node.subquery.node.select_list.every((node) => {\n return validateExpressionNode({\n node,\n validFunctions,\n parentNode,\n validScalarFunctions,\n });\n });\n }\n\n // Window expression\n if (isWindowExpression(node)) {\n return node.children.every((node) => {\n return validateExpressionNode({\n node,\n validFunctions,\n parentNode,\n validScalarFunctions,\n });\n });\n }\n\n throw new Error(`Invalid expression type: ${node.type}`);\n};\n\nexport const containsAggregation = (\n node: ParsedExpression,\n validFunctions: Set<string>\n): boolean => {\n if (!node) return false;\n\n // Function expression\n if (isFunctionExpression(node) || isWindowExpression(node)) {\n return (\n validFunctions.has(node.function_name) ||\n node.children.some((child) => containsAggregation(child, validFunctions))\n );\n }\n\n // Case expression\n if (isCaseExpression(node)) {\n return (\n node.case_checks.some(\n (check) =>\n containsAggregation(check.when_expr, validFunctions) ||\n containsAggregation(check.then_expr, validFunctions)\n ) || containsAggregation(node.else_expr, validFunctions)\n );\n }\n\n // Operator expression\n if (isOperatorExpression(node)) {\n return node.children.some((child) =>\n containsAggregation(child, validFunctions)\n );\n }\n\n if (isCastExpression(node)) {\n return containsAggregation(node.child, validFunctions);\n }\n\n // Window expression\n if (isWindowExpression(node)) {\n return node.children.some((child) =>\n containsAggregation(child, validFunctions)\n );\n }\n\n // Subquery expression\n if (isSubqueryExpression(node) && isSelectNode(node.subquery.node)) {\n return node.subquery.node.select_list.every((node) => {\n return containsAggregation(node, validFunctions);\n });\n }\n\n return false;\n};\n\nexport const validateMeasure = (\n parsedSerialization: ParsedSerialization,\n validFunctions: string[],\n validScalarFunctions: string[]\n): boolean => {\n const node = getSelectNode(parsedSerialization);\n\n const validFunctionSet = new Set(validFunctions);\n const validScalarFunctionSet = new Set(validScalarFunctions);\n\n // Validate the expression\n if (\n validateExpressionNode({\n node: node,\n validFunctions: validFunctionSet,\n parentNode: null,\n validScalarFunctions: validScalarFunctionSet,\n })\n ) {\n return true;\n }\n\n throw new Error('Expression contains invalid functions or operators');\n};\n"],"names":["validateExpressionNode","containsAggregation","validateMeasure","node","validFunctions","parentNode","validScalarFunctions","hasAggregation","isColumnRefExpression","isConstantExpression","isFunctionExpression","isWindowExpression","function_name","has","children","some","child","Error","isOperatorExpression","isCastExpression","isCaseExpression","checksValid","case_checks","every","caseCheck","whenValid","when_expr","thenValid","then_expr","elseValid","else_expr","isSubqueryExpression","isSelectNode","subquery","select_list","type","check","parsedSerialization","getSelectNode","validFunctionSet","Set","validScalarFunctionSet"],"mappings":"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"}