@devrev/meerkat-core 0.0.77 → 0.0.79
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.
- package/package.json +1 -1
- package/src/{get-projection-clause/get-projection-clause.d.ts → get-wrapped-base-query-with-projections/get-aliased-columns-from-filters.d.ts} +16 -7
- package/src/get-wrapped-base-query-with-projections/get-aliased-columns-from-filters.js +141 -0
- package/src/get-wrapped-base-query-with-projections/get-aliased-columns-from-filters.js.map +1 -0
- package/src/get-wrapped-base-query-with-projections/get-projection-clause.d.ts +2 -0
- package/src/get-wrapped-base-query-with-projections/get-projection-clause.js +84 -0
- package/src/get-wrapped-base-query-with-projections/get-projection-clause.js.map +1 -0
- package/src/get-wrapped-base-query-with-projections/get-wrapped-base-query-with-projections.js +6 -72
- package/src/get-wrapped-base-query-with-projections/get-wrapped-base-query-with-projections.js.map +1 -1
- package/src/get-wrapped-base-query-with-projections/sql-expression-modifiers.d.ts +18 -0
- package/src/get-wrapped-base-query-with-projections/sql-expression-modifiers.js +60 -0
- package/src/get-wrapped-base-query-with-projections/sql-expression-modifiers.js.map +1 -0
- package/src/types/cube-types/query.d.ts +3 -45
- package/src/types/cube-types/query.js.map +1 -1
- package/src/types/cube-types/table.d.ts +3 -0
- package/src/get-projection-clause/get-projection-clause.js +0 -135
- package/src/get-projection-clause/get-projection-clause.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,27 +1,36 @@
|
|
|
1
|
-
import { TableSchema } from
|
|
2
|
-
|
|
1
|
+
import { MeerkatQueryFilter, Query, TableSchema } from "../types/cube-types";
|
|
2
|
+
import { Modifier } from "./sql-expression-modifiers";
|
|
3
|
+
export declare const getDimensionProjection: ({ key, tableSchema, modifiers, query }: {
|
|
3
4
|
key: string;
|
|
4
5
|
tableSchema: TableSchema;
|
|
5
|
-
|
|
6
|
+
modifiers: Modifier[];
|
|
7
|
+
query: Query;
|
|
6
8
|
}) => {
|
|
7
9
|
sql: undefined;
|
|
8
10
|
foundMember: undefined;
|
|
9
11
|
aliasKey: undefined;
|
|
10
12
|
} | {
|
|
11
13
|
sql: string;
|
|
12
|
-
foundMember: import("../types/cube-types").
|
|
14
|
+
foundMember: import("../types/cube-types").Dimension;
|
|
13
15
|
aliasKey: string;
|
|
14
16
|
};
|
|
15
|
-
export declare const
|
|
17
|
+
export declare const getFilterMeasureProjection: ({ key, tableSchema, measures, }: {
|
|
16
18
|
key: string;
|
|
17
19
|
tableSchema: TableSchema;
|
|
20
|
+
measures: string[];
|
|
18
21
|
}) => {
|
|
19
22
|
sql: undefined;
|
|
20
23
|
foundMember: undefined;
|
|
21
24
|
aliasKey: undefined;
|
|
22
25
|
} | {
|
|
23
26
|
sql: string;
|
|
24
|
-
foundMember: import("../types/cube-types").
|
|
27
|
+
foundMember: import("../types/cube-types").Measure;
|
|
25
28
|
aliasKey: string;
|
|
26
29
|
};
|
|
27
|
-
export declare const
|
|
30
|
+
export declare const getAliasedColumnsFromFilters: ({ baseSql, meerkatFilters, tableSchema, aliasedColumnSet, query }: {
|
|
31
|
+
meerkatFilters?: MeerkatQueryFilter[] | undefined;
|
|
32
|
+
tableSchema: TableSchema;
|
|
33
|
+
baseSql: string;
|
|
34
|
+
aliasedColumnSet: Set<string>;
|
|
35
|
+
query: Query;
|
|
36
|
+
}) => string;
|
|
@@ -0,0 +1,141 @@
|
|
|
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
|
+
getDimensionProjection: function() {
|
|
10
|
+
return getDimensionProjection;
|
|
11
|
+
},
|
|
12
|
+
getFilterMeasureProjection: function() {
|
|
13
|
+
return getFilterMeasureProjection;
|
|
14
|
+
},
|
|
15
|
+
getAliasedColumnsFromFilters: function() {
|
|
16
|
+
return getAliasedColumnsFromFilters;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const _findintableschema = require("../utils/find-in-table-schema");
|
|
20
|
+
const _memberkeytosafekey = require("../utils/member-key-to-safe-key");
|
|
21
|
+
const _sqlexpressionmodifiers = require("./sql-expression-modifiers");
|
|
22
|
+
const getDimensionProjection = ({ key, tableSchema, modifiers, query })=>{
|
|
23
|
+
// Find the table access key
|
|
24
|
+
const [tableName, measureWithoutTable] = key.split('.');
|
|
25
|
+
const foundMember = (0, _findintableschema.findInDimensionSchema)(measureWithoutTable, tableSchema);
|
|
26
|
+
if (!foundMember || tableName !== tableSchema.name) {
|
|
27
|
+
// If the selected member is not found in the table schema or if it is already selected, continue.
|
|
28
|
+
// If the selected member is not from the current table, don't create an alias.
|
|
29
|
+
return {
|
|
30
|
+
sql: undefined,
|
|
31
|
+
foundMember: undefined,
|
|
32
|
+
aliasKey: undefined
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const modifiedSql = (0, _sqlexpressionmodifiers.getModifiedSqlExpression)({
|
|
36
|
+
dimension: foundMember,
|
|
37
|
+
key: key,
|
|
38
|
+
modifiers: modifiers,
|
|
39
|
+
sqlExpression: foundMember.sql,
|
|
40
|
+
query
|
|
41
|
+
});
|
|
42
|
+
const aliasKey = (0, _memberkeytosafekey.memberKeyToSafeKey)(key);
|
|
43
|
+
// Add the alias key to the set. So we have a reference to all the previously selected members.
|
|
44
|
+
return {
|
|
45
|
+
sql: `${modifiedSql} AS ${aliasKey}`,
|
|
46
|
+
foundMember,
|
|
47
|
+
aliasKey
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
const getFilterMeasureProjection = ({ key, tableSchema, measures })=>{
|
|
51
|
+
const [tableName, measureWithoutTable] = key.split('.');
|
|
52
|
+
const foundMember = (0, _findintableschema.findInMeasureSchema)(measureWithoutTable, tableSchema);
|
|
53
|
+
const isMeasure = measures.includes(key);
|
|
54
|
+
if (!foundMember || isMeasure || tableName !== tableSchema.name) {
|
|
55
|
+
// If the selected member is not found in the table schema or if it is already selected, continue.
|
|
56
|
+
// If the selected member is a measure, don't create an alias. Since measure computation is done in the outermost level of the query
|
|
57
|
+
// If the selected member is not from the current table, don't create an alias.
|
|
58
|
+
return {
|
|
59
|
+
sql: undefined,
|
|
60
|
+
foundMember: undefined,
|
|
61
|
+
aliasKey: undefined
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const aliasKey = (0, _memberkeytosafekey.memberKeyToSafeKey)(key);
|
|
65
|
+
return {
|
|
66
|
+
sql: `${key} AS ${aliasKey}`,
|
|
67
|
+
foundMember,
|
|
68
|
+
aliasKey
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
const getFilterProjections = ({ member, tableSchema, measures, query })=>{
|
|
72
|
+
const memberWithoutTable = member.split('.')[1];
|
|
73
|
+
const isDimension = (0, _findintableschema.findInDimensionSchema)(memberWithoutTable, tableSchema);
|
|
74
|
+
if (isDimension) {
|
|
75
|
+
return getDimensionProjection({
|
|
76
|
+
key: member,
|
|
77
|
+
tableSchema,
|
|
78
|
+
modifiers: [],
|
|
79
|
+
query
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
const isMeasure = (0, _findintableschema.findInMeasureSchema)(memberWithoutTable, tableSchema);
|
|
83
|
+
if (isMeasure) {
|
|
84
|
+
return getFilterMeasureProjection({
|
|
85
|
+
key: member,
|
|
86
|
+
tableSchema,
|
|
87
|
+
measures
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
sql: undefined,
|
|
92
|
+
foundMember: undefined,
|
|
93
|
+
aliasKey: undefined
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
const getAliasedColumnsFromFilters = ({ baseSql, meerkatFilters, tableSchema, aliasedColumnSet, query })=>{
|
|
97
|
+
let sql = baseSql;
|
|
98
|
+
const { measures } = query;
|
|
99
|
+
meerkatFilters == null ? void 0 : meerkatFilters.forEach((filter)=>{
|
|
100
|
+
if ('and' in filter) {
|
|
101
|
+
// Traverse through the passed 'and' filters
|
|
102
|
+
sql += getAliasedColumnsFromFilters({
|
|
103
|
+
baseSql: '',
|
|
104
|
+
meerkatFilters: filter.and,
|
|
105
|
+
tableSchema,
|
|
106
|
+
aliasedColumnSet,
|
|
107
|
+
query
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if ('or' in filter) {
|
|
111
|
+
// Traverse through the passed 'or' filters
|
|
112
|
+
sql += getAliasedColumnsFromFilters({
|
|
113
|
+
baseSql: '',
|
|
114
|
+
tableSchema,
|
|
115
|
+
meerkatFilters: filter.or,
|
|
116
|
+
aliasedColumnSet,
|
|
117
|
+
query
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
if ('member' in filter) {
|
|
121
|
+
const { aliasKey, foundMember, sql: memberSql } = getFilterProjections({
|
|
122
|
+
member: filter.member,
|
|
123
|
+
tableSchema,
|
|
124
|
+
measures,
|
|
125
|
+
query
|
|
126
|
+
});
|
|
127
|
+
if (!foundMember || aliasedColumnSet.has(aliasKey)) {
|
|
128
|
+
// If the selected member is not found in the table schema or if it is already selected, continue.
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (aliasKey) {
|
|
132
|
+
aliasedColumnSet.add(aliasKey);
|
|
133
|
+
}
|
|
134
|
+
// Add the alias key to the set. So we have a reference to all the previously selected members.
|
|
135
|
+
sql += `, ${memberSql}`;
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
return sql;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
//# sourceMappingURL=get-aliased-columns-from-filters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../meerkat-core/src/get-wrapped-base-query-with-projections/get-aliased-columns-from-filters.ts"],"sourcesContent":["import { MeerkatQueryFilter, Query, TableSchema } from \"../types/cube-types\";\nimport { findInDimensionSchema, findInMeasureSchema } from \"../utils/find-in-table-schema\";\nimport { memberKeyToSafeKey } from \"../utils/member-key-to-safe-key\";\nimport { getModifiedSqlExpression, Modifier } from \"./sql-expression-modifiers\";\n\n\nexport const getDimensionProjection = ({\n key,\n tableSchema,\n modifiers,\n query\n}: {\n key: string;\n tableSchema: TableSchema;\n modifiers: Modifier[],\n query: Query\n}) => {\n // Find the table access key\n const [tableName, measureWithoutTable] = key.split('.');\n\n const foundMember = findInDimensionSchema(measureWithoutTable, tableSchema);\n if (!foundMember || tableName !== tableSchema.name) {\n // If the selected member is not found in the table schema or if it is already selected, continue.\n // If the selected member is not from the current table, don't create an alias.\n return {\n sql: undefined,\n foundMember: undefined,\n aliasKey: undefined,\n };\n }\n\n const modifiedSql = getModifiedSqlExpression({\n dimension: foundMember,\n key: key,\n modifiers: modifiers,\n sqlExpression: foundMember.sql,\n query\n })\n\n const aliasKey = memberKeyToSafeKey(key);\n // Add the alias key to the set. So we have a reference to all the previously selected members.\n return { sql: `${modifiedSql} AS ${aliasKey}`, foundMember, aliasKey };\n};\n\n\nexport const getFilterMeasureProjection = ({\n key,\n tableSchema,\n measures,\n}: {\n key: string;\n tableSchema: TableSchema;\n measures: string[];\n}) => {\n const [tableName, measureWithoutTable] = key.split('.');\n const foundMember = findInMeasureSchema(measureWithoutTable, tableSchema);\n const isMeasure = measures.includes(key);\n if (!foundMember || isMeasure || tableName !== tableSchema.name) {\n // If the selected member is not found in the table schema or if it is already selected, continue.\n // If the selected member is a measure, don't create an alias. Since measure computation is done in the outermost level of the query\n // If the selected member is not from the current table, don't create an alias.\n return {\n sql: undefined,\n foundMember: undefined,\n aliasKey: undefined,\n };\n }\n const aliasKey = memberKeyToSafeKey(key);\n return { sql: `${key} AS ${aliasKey}`, foundMember, aliasKey };\n};\n\n\nconst getFilterProjections = ({\n member,\n tableSchema,\n measures,\n query\n}: {\n member: string;\n tableSchema: TableSchema;\n measures: string[];\n query: Query\n}) => {\n const memberWithoutTable = member.split('.')[1];\n const isDimension = findInDimensionSchema(memberWithoutTable, tableSchema);\n if (isDimension) {\n return getDimensionProjection({ key: member, tableSchema, modifiers: [], query });\n }\n const isMeasure = findInMeasureSchema(memberWithoutTable, tableSchema);\n if (isMeasure) {\n return getFilterMeasureProjection({ key: member, tableSchema, measures });\n }\n return {\n sql: undefined,\n foundMember: undefined,\n aliasKey: undefined,\n };\n};\n\n\nexport const getAliasedColumnsFromFilters = ({\n baseSql,\n meerkatFilters,\n tableSchema,\n aliasedColumnSet,\n query\n}: {\n meerkatFilters?: MeerkatQueryFilter[];\n tableSchema: TableSchema;\n baseSql: string;\n aliasedColumnSet: Set<string>;\n query: Query;\n}) => {\n let sql = baseSql;\n const { measures } = query;\n meerkatFilters?.forEach((filter) => {\n if ('and' in filter) {\n // Traverse through the passed 'and' filters\n sql += getAliasedColumnsFromFilters({\n baseSql: '',\n meerkatFilters: filter.and,\n tableSchema,\n aliasedColumnSet,\n query,\n });\n }\n if ('or' in filter) {\n // Traverse through the passed 'or' filters\n sql += getAliasedColumnsFromFilters({\n baseSql: '',\n tableSchema,\n meerkatFilters: filter.or,\n aliasedColumnSet,\n query,\n });\n }\n if ('member' in filter) {\n const {\n aliasKey,\n foundMember,\n sql: memberSql,\n } = getFilterProjections({\n member: filter.member,\n tableSchema,\n measures,\n query\n });\n if (!foundMember || aliasedColumnSet.has(aliasKey)) {\n // If the selected member is not found in the table schema or if it is already selected, continue.\n return;\n }\n if (aliasKey) {\n aliasedColumnSet.add(aliasKey);\n }\n // Add the alias key to the set. So we have a reference to all the previously selected members.\n sql += `, ${memberSql}`;\n }\n });\n return sql;\n};\n "],"names":["getDimensionProjection","getFilterMeasureProjection","getAliasedColumnsFromFilters","key","tableSchema","modifiers","query","tableName","measureWithoutTable","split","foundMember","findInDimensionSchema","name","sql","undefined","aliasKey","modifiedSql","getModifiedSqlExpression","dimension","sqlExpression","memberKeyToSafeKey","measures","findInMeasureSchema","isMeasure","includes","getFilterProjections","member","memberWithoutTable","isDimension","baseSql","meerkatFilters","aliasedColumnSet","forEach","filter","and","or","memberSql","has","add"],"mappings":"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"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "getProjectionClause", {
|
|
3
|
+
enumerable: true,
|
|
4
|
+
get: function() {
|
|
5
|
+
return getProjectionClause;
|
|
6
|
+
}
|
|
7
|
+
});
|
|
8
|
+
const _cubemeasuretransformer = require("../cube-measure-transformer/cube-measure-transformer");
|
|
9
|
+
const _memberkeytosafekey = require("../utils/member-key-to-safe-key");
|
|
10
|
+
const _getaliasedcolumnsfromfilters = require("./get-aliased-columns-from-filters");
|
|
11
|
+
const _sqlexpressionmodifiers = require("./sql-expression-modifiers");
|
|
12
|
+
const aggregator = ({ member, aliasedColumnSet, acc, sql })=>{
|
|
13
|
+
if (aliasedColumnSet.has(member) || !sql) {
|
|
14
|
+
return acc;
|
|
15
|
+
}
|
|
16
|
+
aliasedColumnSet.add(member);
|
|
17
|
+
acc.push(sql);
|
|
18
|
+
return acc;
|
|
19
|
+
};
|
|
20
|
+
const getProjectionClause = (query, tableSchema, aliasedColumnSet)=>{
|
|
21
|
+
const { measures, dimensions = [] } = query;
|
|
22
|
+
const filteredDimensions = dimensions.filter((dimension)=>{
|
|
23
|
+
return dimension.split('.')[0] === tableSchema.name;
|
|
24
|
+
});
|
|
25
|
+
const filteredMeasures = measures.filter((measure)=>{
|
|
26
|
+
return measure.split('.')[0] === tableSchema.name;
|
|
27
|
+
});
|
|
28
|
+
const dimensionsProjectionsArr = filteredDimensions.reduce((acc, member, currentIndex, members)=>{
|
|
29
|
+
const { sql: memberSql } = (0, _getaliasedcolumnsfromfilters.getDimensionProjection)({
|
|
30
|
+
key: member,
|
|
31
|
+
tableSchema,
|
|
32
|
+
modifiers: _sqlexpressionmodifiers.MODIFIERS,
|
|
33
|
+
query
|
|
34
|
+
});
|
|
35
|
+
return aggregator({
|
|
36
|
+
member,
|
|
37
|
+
aliasedColumnSet,
|
|
38
|
+
acc,
|
|
39
|
+
currentIndex,
|
|
40
|
+
members,
|
|
41
|
+
sql: memberSql
|
|
42
|
+
});
|
|
43
|
+
}, []);
|
|
44
|
+
const dimensionsProjections = dimensionsProjectionsArr.join(', ');
|
|
45
|
+
const measureProjectionsArr = filteredMeasures.reduce((acc, member, currentIndex, members)=>{
|
|
46
|
+
const { sql: memberSql } = (0, _getaliasedcolumnsfromfilters.getFilterMeasureProjection)({
|
|
47
|
+
key: member,
|
|
48
|
+
tableSchema,
|
|
49
|
+
measures
|
|
50
|
+
});
|
|
51
|
+
return aggregator({
|
|
52
|
+
member,
|
|
53
|
+
aliasedColumnSet,
|
|
54
|
+
acc,
|
|
55
|
+
currentIndex,
|
|
56
|
+
members,
|
|
57
|
+
sql: memberSql
|
|
58
|
+
});
|
|
59
|
+
}, []);
|
|
60
|
+
const measureProjections = measureProjectionsArr.join(', ');
|
|
61
|
+
const usedMeasureObjects = tableSchema.measures.filter((measure)=>{
|
|
62
|
+
return measures.findIndex((key)=>{
|
|
63
|
+
const keyWithoutTable = key.split('.')[1];
|
|
64
|
+
return keyWithoutTable === measure.name;
|
|
65
|
+
}) !== -1;
|
|
66
|
+
});
|
|
67
|
+
const columnsUsedInMeasures = (0, _cubemeasuretransformer.getAllColumnUsedInMeasures)(usedMeasureObjects, tableSchema);
|
|
68
|
+
let columnsUsedInMeasuresInProjection = '';
|
|
69
|
+
columnsUsedInMeasures.forEach((column, index)=>{
|
|
70
|
+
const safeKey = (0, _memberkeytosafekey.memberKeyToSafeKey)(column);
|
|
71
|
+
columnsUsedInMeasuresInProjection += `${column} AS ${safeKey}`;
|
|
72
|
+
if (index !== columnsUsedInMeasures.length - 1) {
|
|
73
|
+
columnsUsedInMeasuresInProjection += ', ';
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
const combinedStr = [
|
|
77
|
+
dimensionsProjections,
|
|
78
|
+
measureProjections,
|
|
79
|
+
columnsUsedInMeasuresInProjection
|
|
80
|
+
];
|
|
81
|
+
return combinedStr.filter((str)=>str.length > 0).join(', ');
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=get-projection-clause.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../meerkat-core/src/get-wrapped-base-query-with-projections/get-projection-clause.ts"],"sourcesContent":["import { getAllColumnUsedInMeasures } from '../cube-measure-transformer/cube-measure-transformer';\nimport { Query, TableSchema } from '../types/cube-types';\nimport { memberKeyToSafeKey } from '../utils/member-key-to-safe-key';\nimport { getDimensionProjection, getFilterMeasureProjection } from './get-aliased-columns-from-filters';\nimport { MODIFIERS } from './sql-expression-modifiers';\n\nconst aggregator = ({\n member,\n aliasedColumnSet,\n acc,\n sql,\n}: {\n member: string;\n aliasedColumnSet: Set<string>;\n acc: string[];\n sql?: string;\n currentIndex: number;\n members: string[];\n}) => {\n if (aliasedColumnSet.has(member) || !sql) {\n return acc;\n }\n aliasedColumnSet.add(member);\n acc.push(sql);\n return acc;\n};\n\nexport const getProjectionClause = (\n query: Query,\n tableSchema: TableSchema,\n aliasedColumnSet: Set<string>\n) => {\n const { measures, dimensions = [] } = query;\n const filteredDimensions = dimensions.filter((dimension) => {\n return dimension.split('.')[0] === tableSchema.name;\n });\n const filteredMeasures = measures.filter((measure) => {\n return measure.split('.')[0] === tableSchema.name;\n });\n const dimensionsProjectionsArr = filteredDimensions.reduce(\n (acc, member, currentIndex, members) => {\n const { sql: memberSql } = getDimensionProjection({\n key: member,\n tableSchema,\n modifiers: MODIFIERS,\n query\n });\n return aggregator({\n member,\n aliasedColumnSet,\n acc,\n currentIndex,\n members,\n sql: memberSql,\n });\n },\n [] as string[]\n );\n const dimensionsProjections = dimensionsProjectionsArr.join(', ');\n\n const measureProjectionsArr = filteredMeasures.reduce(\n (acc, member, currentIndex, members) => {\n const { sql: memberSql } = getFilterMeasureProjection({\n key: member,\n tableSchema,\n measures,\n });\n return aggregator({\n member,\n aliasedColumnSet,\n acc,\n currentIndex,\n members,\n sql: memberSql,\n });\n },\n [] as string[]\n );\n\n const measureProjections = measureProjectionsArr.join(', ');\n\n const usedMeasureObjects = tableSchema.measures.filter((measure) => {\n return (\n measures.findIndex((key) => {\n const keyWithoutTable = key.split('.')[1];\n return keyWithoutTable === measure.name;\n }) !== -1\n );\n });\n const columnsUsedInMeasures = getAllColumnUsedInMeasures(\n usedMeasureObjects,\n tableSchema\n );\n\n let columnsUsedInMeasuresInProjection = '';\n columnsUsedInMeasures.forEach((column, index) => {\n const safeKey = memberKeyToSafeKey(column);\n columnsUsedInMeasuresInProjection += `${column} AS ${safeKey}`;\n if (index !== columnsUsedInMeasures.length - 1) {\n columnsUsedInMeasuresInProjection += ', ';\n }\n });\n\n const combinedStr = [\n dimensionsProjections,\n measureProjections,\n columnsUsedInMeasuresInProjection,\n ];\n\n return combinedStr.filter((str) => str.length > 0).join(', ');\n};\n"],"names":["getProjectionClause","aggregator","member","aliasedColumnSet","acc","sql","has","add","push","query","tableSchema","measures","dimensions","filteredDimensions","filter","dimension","split","name","filteredMeasures","measure","dimensionsProjectionsArr","reduce","currentIndex","members","memberSql","getDimensionProjection","key","modifiers","MODIFIERS","dimensionsProjections","join","measureProjectionsArr","getFilterMeasureProjection","measureProjections","usedMeasureObjects","findIndex","keyWithoutTable","columnsUsedInMeasures","getAllColumnUsedInMeasures","columnsUsedInMeasuresInProjection","forEach","column","index","safeKey","memberKeyToSafeKey","length","combinedStr","str"],"mappings":";+BA2BaA;;;eAAAA;;;wCA3B8B;oCAER;8CACgC;wCACzC;AAE1B,MAAMC,aAAa,CAAC,EAClBC,MAAM,EACNC,gBAAgB,EAChBC,GAAG,EACHC,GAAG,EAQJ;IACC,IAAIF,iBAAiBG,GAAG,CAACJ,WAAW,CAACG,KAAK;QACxC,OAAOD;IACT;IACAD,iBAAiBI,GAAG,CAACL;IACrBE,IAAII,IAAI,CAACH;IACT,OAAOD;AACT;AAEO,MAAMJ,sBAAsB,CACjCS,OACAC,aACAP;IAEA,MAAM,EAAEQ,QAAQ,EAAEC,aAAa,EAAE,EAAE,GAAGH;IACtC,MAAMI,qBAAqBD,WAAWE,MAAM,CAAC,CAACC;QAC5C,OAAOA,UAAUC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAKN,YAAYO,IAAI;IACrD;IACA,MAAMC,mBAAmBP,SAASG,MAAM,CAAC,CAACK;QACxC,OAAOA,QAAQH,KAAK,CAAC,IAAI,CAAC,EAAE,KAAKN,YAAYO,IAAI;IACnD;IACA,MAAMG,2BAA2BP,mBAAmBQ,MAAM,CACxD,CAACjB,KAAKF,QAAQoB,cAAcC;QAC1B,MAAM,EAAElB,KAAKmB,SAAS,EAAE,GAAGC,IAAAA,oDAAsB,EAAC;YAChDC,KAAKxB;YACLQ;YACAiB,WAAWC,iCAAS;YACpBnB;QACF;QACA,OAAOR,WAAW;YAChBC;YACAC;YACAC;YACAkB;YACAC;YACAlB,KAAKmB;QACP;IACF,GACA,EAAE;IAEJ,MAAMK,wBAAwBT,yBAAyBU,IAAI,CAAC;IAE5D,MAAMC,wBAAwBb,iBAAiBG,MAAM,CACnD,CAACjB,KAAKF,QAAQoB,cAAcC;QAC1B,MAAM,EAAElB,KAAKmB,SAAS,EAAE,GAAGQ,IAAAA,wDAA0B,EAAC;YACpDN,KAAKxB;YACLQ;YACAC;QACF;QACA,OAAOV,WAAW;YAChBC;YACAC;YACAC;YACAkB;YACAC;YACAlB,KAAKmB;QACP;IACF,GACA,EAAE;IAGJ,MAAMS,qBAAqBF,sBAAsBD,IAAI,CAAC;IAEtD,MAAMI,qBAAqBxB,YAAYC,QAAQ,CAACG,MAAM,CAAC,CAACK;QACtD,OACER,SAASwB,SAAS,CAAC,CAACT;YAClB,MAAMU,kBAAkBV,IAAIV,KAAK,CAAC,IAAI,CAAC,EAAE;YACzC,OAAOoB,oBAAoBjB,QAAQF,IAAI;QACzC,OAAO,CAAC;IAEZ;IACA,MAAMoB,wBAAwBC,IAAAA,kDAA0B,EACtDJ,oBACAxB;IAGF,IAAI6B,oCAAoC;IACxCF,sBAAsBG,OAAO,CAAC,CAACC,QAAQC;QACrC,MAAMC,UAAUC,IAAAA,sCAAkB,EAACH;QACnCF,qCAAqC,CAAC,EAAEE,OAAO,IAAI,EAAEE,QAAQ,CAAC;QAC9D,IAAID,UAAUL,sBAAsBQ,MAAM,GAAG,GAAG;YAC9CN,qCAAqC;QACvC;IACF;IAEA,MAAMO,cAAc;QAClBjB;QACAI;QACAM;KACD;IAED,OAAOO,YAAYhC,MAAM,CAAC,CAACiC,MAAQA,IAAIF,MAAM,GAAG,GAAGf,IAAI,CAAC;AAC1D"}
|
package/src/get-wrapped-base-query-with-projections/get-wrapped-base-query-with-projections.js
CHANGED
|
@@ -6,73 +6,8 @@ Object.defineProperty(exports, "getWrappedBaseQueryWithProjections", {
|
|
|
6
6
|
}
|
|
7
7
|
});
|
|
8
8
|
const _cubemeasuretransformer = require("../cube-measure-transformer/cube-measure-transformer");
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const getFilterProjections = ({ member, tableSchema, measures })=>{
|
|
12
|
-
const memberWithoutTable = member.split('.')[1];
|
|
13
|
-
const isDimension = (0, _findintableschema.findInDimensionSchema)(memberWithoutTable, tableSchema);
|
|
14
|
-
if (isDimension) {
|
|
15
|
-
return (0, _getprojectionclause.getDimensionProjection)({
|
|
16
|
-
key: member,
|
|
17
|
-
tableSchema
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
const isMeasure = (0, _findintableschema.findInMeasureSchema)(memberWithoutTable, tableSchema);
|
|
21
|
-
if (isMeasure) {
|
|
22
|
-
return (0, _getprojectionclause.getFilterMeasureProjection)({
|
|
23
|
-
key: member,
|
|
24
|
-
tableSchema,
|
|
25
|
-
measures
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
return {
|
|
29
|
-
sql: undefined,
|
|
30
|
-
foundMember: undefined,
|
|
31
|
-
aliasKey: undefined
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
const getAliasedColumnsFromFilters = ({ baseSql, meerkatFilters, tableSchema, aliasedColumnSet, measures })=>{
|
|
35
|
-
let sql = baseSql;
|
|
36
|
-
meerkatFilters == null ? void 0 : meerkatFilters.forEach((filter)=>{
|
|
37
|
-
if ('and' in filter) {
|
|
38
|
-
// Traverse through the passed 'and' filters
|
|
39
|
-
sql += getAliasedColumnsFromFilters({
|
|
40
|
-
baseSql: '',
|
|
41
|
-
meerkatFilters: filter.and,
|
|
42
|
-
tableSchema,
|
|
43
|
-
aliasedColumnSet,
|
|
44
|
-
measures
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
if ('or' in filter) {
|
|
48
|
-
// Traverse through the passed 'or' filters
|
|
49
|
-
sql += getAliasedColumnsFromFilters({
|
|
50
|
-
baseSql: '',
|
|
51
|
-
tableSchema,
|
|
52
|
-
meerkatFilters: filter.or,
|
|
53
|
-
aliasedColumnSet,
|
|
54
|
-
measures
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
if ('member' in filter) {
|
|
58
|
-
const { aliasKey, foundMember, sql: memberSql } = getFilterProjections({
|
|
59
|
-
member: filter.member,
|
|
60
|
-
tableSchema,
|
|
61
|
-
measures
|
|
62
|
-
});
|
|
63
|
-
if (!foundMember || aliasedColumnSet.has(aliasKey)) {
|
|
64
|
-
// If the selected member is not found in the table schema or if it is already selected, continue.
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
if (aliasKey) {
|
|
68
|
-
aliasedColumnSet.add(aliasKey);
|
|
69
|
-
}
|
|
70
|
-
// Add the alias key to the set. So we have a reference to all the previously selected members.
|
|
71
|
-
sql += `, ${memberSql}`;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
return sql;
|
|
75
|
-
};
|
|
9
|
+
const _getaliasedcolumnsfromfilters = require("./get-aliased-columns-from-filters");
|
|
10
|
+
const _getprojectionclause = require("./get-projection-clause");
|
|
76
11
|
const getWrappedBaseQueryWithProjections = ({ baseQuery, tableSchema, query })=>{
|
|
77
12
|
/*
|
|
78
13
|
* Im order to be able to filter on computed metric from a query, we need to project the computed metric in the base query.
|
|
@@ -80,16 +15,15 @@ const getWrappedBaseQueryWithProjections = ({ baseQuery, tableSchema, query })=>
|
|
|
80
15
|
*/ // Wrap the query into another 'SELECT * FROM (baseQuery) AS baseTable'' in order to project everything in the base query, and other computed metrics to be able to filter on them
|
|
81
16
|
const newBaseSql = `SELECT * FROM (${baseQuery}) AS ${tableSchema.name}`;
|
|
82
17
|
const aliasedColumnSet = new Set();
|
|
83
|
-
const aliasFromFilters = getAliasedColumnsFromFilters({
|
|
18
|
+
const aliasFromFilters = (0, _getaliasedcolumnsfromfilters.getAliasedColumnsFromFilters)({
|
|
84
19
|
aliasedColumnSet,
|
|
85
20
|
baseSql: 'SELECT *',
|
|
86
21
|
// setting measures to empty array, since we don't want to project measures present in the filters in the base query
|
|
87
22
|
tableSchema: tableSchema,
|
|
88
|
-
|
|
89
|
-
|
|
23
|
+
query,
|
|
24
|
+
meerkatFilters: query.filters
|
|
90
25
|
});
|
|
91
|
-
|
|
92
|
-
const memberProjections = (0, _getprojectionclause.getProjectionClause)(query.measures, (_query_dimensions = query.dimensions) != null ? _query_dimensions : [], tableSchema, aliasedColumnSet);
|
|
26
|
+
const memberProjections = (0, _getprojectionclause.getProjectionClause)(query, tableSchema, aliasedColumnSet);
|
|
93
27
|
const formattedMemberProjection = memberProjections ? `, ${memberProjections}` : '';
|
|
94
28
|
const finalAliasedColumnsClause = aliasFromFilters + formattedMemberProjection;
|
|
95
29
|
const sqlWithFilterProjects = (0, _cubemeasuretransformer.getSelectReplacedSql)(newBaseSql, finalAliasedColumnsClause);
|
package/src/get-wrapped-base-query-with-projections/get-wrapped-base-query-with-projections.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../meerkat-core/src/get-wrapped-base-query-with-projections/get-wrapped-base-query-with-projections.ts"],"sourcesContent":["import { getSelectReplacedSql } from '../cube-measure-transformer/cube-measure-transformer';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../meerkat-core/src/get-wrapped-base-query-with-projections/get-wrapped-base-query-with-projections.ts"],"sourcesContent":["import { getSelectReplacedSql } from '../cube-measure-transformer/cube-measure-transformer';\nimport { Query, TableSchema } from '../types/cube-types';\nimport { getAliasedColumnsFromFilters } from './get-aliased-columns-from-filters';\nimport {\n getProjectionClause\n} from './get-projection-clause';\n\ninterface GetWrappedBaseQueryWithProjectionsParams {\n baseQuery: string;\n tableSchema: TableSchema;\n query: Query;\n}\n\nexport const getWrappedBaseQueryWithProjections = ({\n baseQuery,\n tableSchema,\n query,\n}: GetWrappedBaseQueryWithProjectionsParams) => {\n /*\n * Im order to be able to filter on computed metric from a query, we need to project the computed metric in the base query.\n * If theres filters supplied, we can safely return the original base query. Since nothing need to be projected and filtered in this case\n */\n // Wrap the query into another 'SELECT * FROM (baseQuery) AS baseTable'' in order to project everything in the base query, and other computed metrics to be able to filter on them\n const newBaseSql = `SELECT * FROM (${baseQuery}) AS ${tableSchema.name}`;\n const aliasedColumnSet = new Set<string>();\n\n const aliasFromFilters = getAliasedColumnsFromFilters({\n aliasedColumnSet,\n baseSql: 'SELECT *',\n // setting measures to empty array, since we don't want to project measures present in the filters in the base query\n tableSchema: tableSchema,\n query,\n meerkatFilters: query.filters,\n });\n\n const memberProjections = getProjectionClause(\n query,\n tableSchema,\n aliasedColumnSet\n );\n const formattedMemberProjection = memberProjections\n ? `, ${memberProjections}`\n : '';\n\n const finalAliasedColumnsClause =\n aliasFromFilters + formattedMemberProjection;\n\n const sqlWithFilterProjects = getSelectReplacedSql(\n newBaseSql,\n finalAliasedColumnsClause\n );\n return sqlWithFilterProjects;\n};\n"],"names":["getWrappedBaseQueryWithProjections","baseQuery","tableSchema","query","newBaseSql","name","aliasedColumnSet","Set","aliasFromFilters","getAliasedColumnsFromFilters","baseSql","meerkatFilters","filters","memberProjections","getProjectionClause","formattedMemberProjection","finalAliasedColumnsClause","sqlWithFilterProjects","getSelectReplacedSql"],"mappings":";+BAaaA;;;eAAAA;;;wCAbwB;8CAEQ;qCAGtC;AAQA,MAAMA,qCAAqC,CAAC,EACjDC,SAAS,EACTC,WAAW,EACXC,KAAK,EACoC;IACzC;;;GAGC,GACD,kLAAkL;IAClL,MAAMC,aAAa,CAAC,eAAe,EAAEH,UAAU,KAAK,EAAEC,YAAYG,IAAI,CAAC,CAAC;IACxE,MAAMC,mBAAmB,IAAIC;IAE7B,MAAMC,mBAAmBC,IAAAA,0DAA4B,EAAC;QACpDH;QACAI,SAAS;QACT,oHAAoH;QACpHR,aAAaA;QACbC;QACAQ,gBAAgBR,MAAMS,OAAO;IAC/B;IAEA,MAAMC,oBAAoBC,IAAAA,wCAAmB,EAC3CX,OACAD,aACAI;IAEF,MAAMS,4BAA4BF,oBAC9B,CAAC,EAAE,EAAEA,kBAAkB,CAAC,GACxB;IAEJ,MAAMG,4BACJR,mBAAmBO;IAErB,MAAME,wBAAwBC,IAAAA,4CAAoB,EAChDd,YACAY;IAEF,OAAOC;AACT"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Dimension, Query } from "../types/cube-types";
|
|
2
|
+
export interface DimensionModifier {
|
|
3
|
+
sqlExpression: string;
|
|
4
|
+
dimension: Dimension;
|
|
5
|
+
key: string;
|
|
6
|
+
query: Query;
|
|
7
|
+
}
|
|
8
|
+
export declare const arrayFieldUnNestModifier: ({ sqlExpression }: DimensionModifier) => string;
|
|
9
|
+
export declare const shouldUnnest: ({ dimension, query }: DimensionModifier) => boolean;
|
|
10
|
+
export type Modifier = {
|
|
11
|
+
name: string;
|
|
12
|
+
matcher: (modifier: DimensionModifier) => boolean;
|
|
13
|
+
modifier: (modifier: DimensionModifier) => string;
|
|
14
|
+
};
|
|
15
|
+
export declare const MODIFIERS: Modifier[];
|
|
16
|
+
export declare const getModifiedSqlExpression: ({ sqlExpression, dimension, key, modifiers, query }: DimensionModifier & {
|
|
17
|
+
modifiers: Modifier[];
|
|
18
|
+
}) => string;
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
arrayFieldUnNestModifier: function() {
|
|
10
|
+
return arrayFieldUnNestModifier;
|
|
11
|
+
},
|
|
12
|
+
shouldUnnest: function() {
|
|
13
|
+
return shouldUnnest;
|
|
14
|
+
},
|
|
15
|
+
MODIFIERS: function() {
|
|
16
|
+
return MODIFIERS;
|
|
17
|
+
},
|
|
18
|
+
getModifiedSqlExpression: function() {
|
|
19
|
+
return getModifiedSqlExpression;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
const _isarraymembertype = require("../utils/is-array-member-type");
|
|
23
|
+
const arrayFieldUnNestModifier = ({ sqlExpression })=>{
|
|
24
|
+
return `array[unnest(${sqlExpression})]`;
|
|
25
|
+
};
|
|
26
|
+
const shouldUnnest = ({ dimension, query })=>{
|
|
27
|
+
var _dimension_modifier;
|
|
28
|
+
const isArrayType = (0, _isarraymembertype.isArrayTypeMember)(dimension.type);
|
|
29
|
+
const hasUnNestedGroupBy = (_dimension_modifier = dimension.modifier) == null ? void 0 : _dimension_modifier.shouldUnnestGroupBy;
|
|
30
|
+
return !!(isArrayType && hasUnNestedGroupBy && query.measures.length > 0);
|
|
31
|
+
};
|
|
32
|
+
const MODIFIERS = [
|
|
33
|
+
{
|
|
34
|
+
name: 'shouldUnnestGroupBy',
|
|
35
|
+
matcher: shouldUnnest,
|
|
36
|
+
modifier: arrayFieldUnNestModifier
|
|
37
|
+
}
|
|
38
|
+
];
|
|
39
|
+
const getModifiedSqlExpression = ({ sqlExpression, dimension, key, modifiers, query })=>{
|
|
40
|
+
let finalDimension = sqlExpression;
|
|
41
|
+
modifiers.forEach(({ modifier, matcher })=>{
|
|
42
|
+
const shouldModify = matcher({
|
|
43
|
+
sqlExpression: finalDimension,
|
|
44
|
+
dimension,
|
|
45
|
+
key,
|
|
46
|
+
query
|
|
47
|
+
});
|
|
48
|
+
if (shouldModify) {
|
|
49
|
+
finalDimension = modifier({
|
|
50
|
+
sqlExpression: finalDimension,
|
|
51
|
+
dimension,
|
|
52
|
+
key,
|
|
53
|
+
query
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return finalDimension;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
//# sourceMappingURL=sql-expression-modifiers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../meerkat-core/src/get-wrapped-base-query-with-projections/sql-expression-modifiers.ts"],"sourcesContent":["import { Dimension, Query } from \"../types/cube-types\";\nimport { isArrayTypeMember } from \"../utils/is-array-member-type\";\n\nexport interface DimensionModifier {\n sqlExpression: string,\n dimension: Dimension,\n key: string,\n query: Query\n}\n\nexport const arrayFieldUnNestModifier = ({ sqlExpression }: DimensionModifier): string => {\n return `array[unnest(${sqlExpression})]`;\n}\n\nexport const shouldUnnest = ({ dimension, query }: DimensionModifier): boolean => {\n const isArrayType = isArrayTypeMember(dimension.type);\n const hasUnNestedGroupBy = dimension.modifier?.shouldUnnestGroupBy;\n return !!(isArrayType && hasUnNestedGroupBy && query.measures.length > 0);\n}\n\n\nexport type Modifier = {\n name: string,\n matcher: (modifier: DimensionModifier) => boolean,\n modifier: (modifier: DimensionModifier) => string\n}\n\nexport const MODIFIERS: Modifier[] = [{\n name: 'shouldUnnestGroupBy',\n matcher: shouldUnnest,\n modifier: arrayFieldUnNestModifier\n}]\n\n\nexport const getModifiedSqlExpression = ({ sqlExpression, dimension, key, modifiers, query }: DimensionModifier & {\n modifiers: Modifier[]\n}) => {\n let finalDimension: string = sqlExpression;\n modifiers.forEach(({ modifier, matcher }) => {\n const shouldModify = matcher({ sqlExpression: finalDimension, dimension, key, query });\n if (shouldModify) {\n finalDimension = modifier({ sqlExpression: finalDimension, dimension, key, query });\n }\n })\n return finalDimension;\n} "],"names":["arrayFieldUnNestModifier","shouldUnnest","MODIFIERS","getModifiedSqlExpression","sqlExpression","dimension","query","isArrayType","isArrayTypeMember","type","hasUnNestedGroupBy","modifier","shouldUnnestGroupBy","measures","length","name","matcher","key","modifiers","finalDimension","forEach","shouldModify"],"mappings":";;;;;;;;IAUaA,wBAAwB;eAAxBA;;IAIAC,YAAY;eAAZA;;IAaAC,SAAS;eAATA;;IAOAC,wBAAwB;eAAxBA;;;mCAjCqB;AAS3B,MAAMH,2BAA2B,CAAC,EAAEI,aAAa,EAAqB;IAC5E,OAAO,CAAC,aAAa,EAAEA,cAAc,EAAE,CAAC;AACzC;AAEO,MAAMH,eAAe,CAAC,EAAEI,SAAS,EAAEC,KAAK,EAAqB;QAEvCD;IAD3B,MAAME,cAAeC,IAAAA,oCAAiB,EAACH,UAAUI,IAAI;IACrD,MAAMC,sBAAqBL,sBAAAA,UAAUM,QAAQ,qBAAlBN,oBAAoBO,mBAAmB;IAClE,OAAO,CAAC,CAAEL,CAAAA,eAAeG,sBAAsBJ,MAAMO,QAAQ,CAACC,MAAM,GAAG,CAAA;AACzE;AASO,MAAMZ,YAAwB;IAAC;QACpCa,MAAM;QACNC,SAASf;QACTU,UAAUX;IACZ;CAAE;AAGK,MAAMG,2BAA2B,CAAC,EAAEC,aAAa,EAAEC,SAAS,EAAEY,GAAG,EAAEC,SAAS,EAAEZ,KAAK,EAEzF;IACC,IAAIa,iBAAyBf;IAC7Bc,UAAUE,OAAO,CAAC,CAAC,EAAET,QAAQ,EAAEK,OAAO,EAAE;QACtC,MAAMK,eAAeL,QAAQ;YAAEZ,eAAee;YAAgBd;YAAWY;YAAKX;QAAM;QACpF,IAAIe,cAAc;YAChBF,iBAAiBR,SAAS;gBAAEP,eAAee;gBAAgBd;gBAAWY;gBAAKX;YAAM;QACnF;IACF;IACA,OAAOa;AACT"}
|
|
@@ -22,19 +22,10 @@ type MemberType = 'measures' | 'dimensions' | 'segments';
|
|
|
22
22
|
* Member identifier. Should satisfy to the following regexp: /^[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+$/
|
|
23
23
|
*/
|
|
24
24
|
type Member = string;
|
|
25
|
-
/**
|
|
26
|
-
* Datetime member identifier. Should satisfy to the following
|
|
27
|
-
* regexp: /^[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+(\.(second|minute|hour|day|week|month|year))?$/
|
|
28
|
-
*/
|
|
29
|
-
type TimeMember = string;
|
|
30
25
|
/**
|
|
31
26
|
* Filter operator string.
|
|
32
27
|
*/
|
|
33
28
|
type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'in' | 'notIn' | 'gt' | 'gte' | 'lt' | 'lte' | 'set' | 'notSet' | 'inDateRange' | 'notInDateRange' | 'onTheDate' | 'beforeDate' | 'afterDate' | 'measureFilter';
|
|
34
|
-
/**
|
|
35
|
-
* Time dimension granularity data type.
|
|
36
|
-
*/
|
|
37
|
-
type QueryTimeDimensionGranularity = 'quarter' | 'day' | 'month' | 'year' | 'week' | 'hour' | 'minute' | 'second';
|
|
38
29
|
/**
|
|
39
30
|
* Query order data type.
|
|
40
31
|
*/
|
|
@@ -63,14 +54,6 @@ type LogicalAndFilter = {
|
|
|
63
54
|
type LogicalOrFilter = {
|
|
64
55
|
or: (QueryFilter | LogicalAndFilter)[];
|
|
65
56
|
};
|
|
66
|
-
/**
|
|
67
|
-
* Query datetime dimention interface.
|
|
68
|
-
*/
|
|
69
|
-
interface QueryTimeDimension {
|
|
70
|
-
dimension: Member;
|
|
71
|
-
dateRange?: string[] | string;
|
|
72
|
-
granularity?: QueryTimeDimensionGranularity;
|
|
73
|
-
}
|
|
74
57
|
/**
|
|
75
58
|
* Join Edge data type.
|
|
76
59
|
*/
|
|
@@ -106,36 +89,11 @@ export declare const isJoinNode: (node: JoinNode | SingleNode) => node is JoinNo
|
|
|
106
89
|
type MeerkatQueryFilter = QueryFilter | LogicalAndFilter | LogicalOrFilter;
|
|
107
90
|
interface Query {
|
|
108
91
|
measures: Member[];
|
|
109
|
-
dimensions?:
|
|
92
|
+
dimensions?: Member[];
|
|
110
93
|
filters?: MeerkatQueryFilter[];
|
|
111
|
-
timeDimensions?: QueryTimeDimension[];
|
|
112
94
|
joinPaths?: JoinPath[];
|
|
113
|
-
segments?: Member[];
|
|
114
95
|
limit?: null | number;
|
|
115
96
|
offset?: number;
|
|
116
|
-
|
|
117
|
-
totalQuery?: boolean;
|
|
118
|
-
order?: any;
|
|
119
|
-
timezone?: string;
|
|
120
|
-
renewQuery?: boolean;
|
|
121
|
-
ungrouped?: boolean;
|
|
122
|
-
responseFormat?: ResultType;
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Normalized filter interface.
|
|
126
|
-
*/
|
|
127
|
-
interface NormalizedQueryFilter extends QueryFilter {
|
|
128
|
-
dimension?: Member;
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Normalized query interface.
|
|
132
|
-
*/
|
|
133
|
-
interface NormalizedQuery extends Query {
|
|
134
|
-
filters?: NormalizedQueryFilter[];
|
|
135
|
-
rowLimit?: null | number;
|
|
136
|
-
order?: [{
|
|
137
|
-
id: string;
|
|
138
|
-
desc: boolean;
|
|
139
|
-
}];
|
|
97
|
+
order?: Record<string, QueryOrderType>;
|
|
140
98
|
}
|
|
141
|
-
export { ApiScopes, ApiType, FilterOperator, JoinPath, LogicalAndFilter, LogicalOrFilter, MeerkatQueryFilter, Member, MemberType,
|
|
99
|
+
export { ApiScopes, ApiType, FilterOperator, JoinPath, LogicalAndFilter, LogicalOrFilter, MeerkatQueryFilter, Member, MemberType, Query, QueryFilter, QueryOrderType, QueryType, RequestType, ResultType };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../meerkat-core/src/types/cube-types/query.ts"],"sourcesContent":["/**\n * Request type data type.\n */\ntype RequestType = 'multi';\n\n/**\n * Result type data type.\n */\ntype ResultType = 'default' | 'compact';\n\n/**\n * API type data type.\n */\ntype ApiType = 'sql' | 'graphql' | 'rest' | 'ws' | 'stream';\n\n/**\n * Parsed query type data type.\n */\ntype QueryType = 'regularQuery' | 'compareDateRangeQuery' | 'blendingQuery';\n\n/**\n * String that represent query member type.\n */\ntype MemberType = 'measures' | 'dimensions' | 'segments';\n\n/**\n * Member identifier. Should satisfy to the following regexp: /^[a-zA-Z0-9_]+\\.[a-zA-Z0-9_]+$/\n */\ntype Member = string;\n\n
|
|
1
|
+
{"version":3,"sources":["../../../../../meerkat-core/src/types/cube-types/query.ts"],"sourcesContent":["/**\n * Request type data type.\n */\ntype RequestType = 'multi';\n\n/**\n * Result type data type.\n */\ntype ResultType = 'default' | 'compact';\n\n/**\n * API type data type.\n */\ntype ApiType = 'sql' | 'graphql' | 'rest' | 'ws' | 'stream';\n\n/**\n * Parsed query type data type.\n */\ntype QueryType = 'regularQuery' | 'compareDateRangeQuery' | 'blendingQuery';\n\n/**\n * String that represent query member type.\n */\ntype MemberType = 'measures' | 'dimensions' | 'segments';\n\n/**\n * Member identifier. Should satisfy to the following regexp: /^[a-zA-Z0-9_]+\\.[a-zA-Z0-9_]+$/\n */\ntype Member = string;\n\n\n/**\n * Filter operator string.\n */\ntype FilterOperator =\n | 'equals'\n | 'notEquals'\n | 'contains'\n | 'notContains'\n | 'in'\n | 'notIn'\n | 'gt'\n | 'gte'\n | 'lt'\n | 'lte'\n | 'set'\n | 'notSet'\n | 'inDateRange'\n | 'notInDateRange'\n | 'onTheDate'\n | 'beforeDate'\n | 'afterDate'\n | 'measureFilter';\n\n/**\n * Query order data type.\n */\ntype QueryOrderType = 'asc' | 'desc';\n\n/**\n * ApiScopes data type.\n */\ntype ApiScopes = 'graphql' | 'meta' | 'data' | 'jobs';\n\nexport type FilterType = 'BASE_FILTER' | 'PROJECTION_FILTER';\n\ninterface QueryFilter {\n member: Member;\n operator: FilterOperator;\n values?: string[];\n}\n\n/**\n * Query 'and'-filters type definition.\n */\ntype LogicalAndFilter = {\n and: (QueryFilter | { or: (QueryFilter | LogicalAndFilter)[] })[];\n};\n\n/**\n * Query 'or'-filters type definition.\n */\ntype LogicalOrFilter = {\n or: (QueryFilter | LogicalAndFilter)[];\n};\n\n\n/**\n * Join Edge data type.\n */\n\ninterface JoinNode {\n /**\n * Left node.\n */\n left: Member;\n\n /**\n * Right node.\n */\n right: Member;\n\n /**\n * On condition.\n */\n on: string;\n\n /**\n * Example\n * [\n * [\n * {\n * left: dim_ticket,\n * right: dim_user\n * on: 'created_by_id'\n * },\n * {\n * left : dim_user,\n * right: dim_user_role,\n * on: 'role_id'\n * }\n * ]\n * ]\n *\n *\n */\n}\n\n/**\n * Single node data type.\n * This is the case when there is no join. Just a single node.\n */\ninterface SingleNode {\n /**\n * Left node.\n */\n left: Member;\n}\n\ntype JoinPath = [JoinNode | SingleNode, ...JoinNode[]];\n\nexport const isJoinNode = (node: JoinNode | SingleNode): node is JoinNode => {\n return 'right' in node;\n};\n\n/**\n * Incoming network query data type.\n */\n\ntype MeerkatQueryFilter = QueryFilter | LogicalAndFilter | LogicalOrFilter;\n\ninterface Query {\n measures: Member[];\n dimensions?: Member[];\n filters?: MeerkatQueryFilter[];\n joinPaths?: JoinPath[];\n limit?: null | number;\n offset?: number;\n order?: Record<string, QueryOrderType>;\n}\n\n\nexport {\n ApiScopes,\n ApiType,\n FilterOperator,\n JoinPath,\n LogicalAndFilter,\n LogicalOrFilter,\n MeerkatQueryFilter,\n Member,\n MemberType,\n Query,\n QueryFilter,\n QueryOrderType,\n QueryType,\n RequestType,\n ResultType\n};\n"],"names":["isJoinNode","node"],"mappings":"AAAA;;CAEC;+BA2IYA;;;eAAAA;;;AAAN,MAAMA,aAAa,CAACC;IACzB,OAAO,WAAWA;AACpB"}
|
|
@@ -1,135 +0,0 @@
|
|
|
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
|
-
getFilterMeasureProjection: function() {
|
|
10
|
-
return getFilterMeasureProjection;
|
|
11
|
-
},
|
|
12
|
-
getDimensionProjection: function() {
|
|
13
|
-
return getDimensionProjection;
|
|
14
|
-
},
|
|
15
|
-
getProjectionClause: function() {
|
|
16
|
-
return getProjectionClause;
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
const _cubemeasuretransformer = require("../cube-measure-transformer/cube-measure-transformer");
|
|
20
|
-
const _findintableschema = require("../utils/find-in-table-schema");
|
|
21
|
-
const _memberkeytosafekey = require("../utils/member-key-to-safe-key");
|
|
22
|
-
const getFilterMeasureProjection = ({ key, tableSchema, measures })=>{
|
|
23
|
-
const tableName = key.split('.')[0];
|
|
24
|
-
const measureWithoutTable = key.split('.')[1];
|
|
25
|
-
const foundMember = (0, _findintableschema.findInMeasureSchema)(measureWithoutTable, tableSchema);
|
|
26
|
-
const isMeasure = measures.includes(key);
|
|
27
|
-
if (!foundMember || isMeasure || tableName !== tableSchema.name) {
|
|
28
|
-
// If the selected member is not found in the table schema or if it is already selected, continue.
|
|
29
|
-
// If the selected member is a measure, don't create an alias. Since measure computation is done in the outermost level of the query
|
|
30
|
-
// If the selected member is not from the current table, don't create an alias.
|
|
31
|
-
return {
|
|
32
|
-
sql: undefined,
|
|
33
|
-
foundMember: undefined,
|
|
34
|
-
aliasKey: undefined
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
const aliasKey = (0, _memberkeytosafekey.memberKeyToSafeKey)(key);
|
|
38
|
-
return {
|
|
39
|
-
sql: `${key} AS ${aliasKey}`,
|
|
40
|
-
foundMember,
|
|
41
|
-
aliasKey
|
|
42
|
-
};
|
|
43
|
-
};
|
|
44
|
-
const getDimensionProjection = ({ key, tableSchema })=>{
|
|
45
|
-
// Find the table access key
|
|
46
|
-
const measureWithoutTable = key.split('.')[1];
|
|
47
|
-
const tableName = key.split('.')[0];
|
|
48
|
-
const foundMember = (0, _findintableschema.findInDimensionSchema)(measureWithoutTable, tableSchema);
|
|
49
|
-
if (!foundMember || tableName !== tableSchema.name) {
|
|
50
|
-
// If the selected member is not found in the table schema or if it is already selected, continue.
|
|
51
|
-
// If the selected member is not from the current table, don't create an alias.
|
|
52
|
-
return {
|
|
53
|
-
sql: undefined,
|
|
54
|
-
foundMember: undefined,
|
|
55
|
-
aliasKey: undefined
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
const aliasKey = (0, _memberkeytosafekey.memberKeyToSafeKey)(key);
|
|
59
|
-
// Add the alias key to the set. So we have a reference to all the previously selected members.
|
|
60
|
-
return {
|
|
61
|
-
sql: `${foundMember.sql} AS ${aliasKey}`,
|
|
62
|
-
foundMember,
|
|
63
|
-
aliasKey
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
const aggregator = ({ member, aliasedColumnSet, acc, sql })=>{
|
|
67
|
-
if (aliasedColumnSet.has(member) || !sql) {
|
|
68
|
-
return acc;
|
|
69
|
-
}
|
|
70
|
-
aliasedColumnSet.add(member);
|
|
71
|
-
acc.push(sql);
|
|
72
|
-
return acc;
|
|
73
|
-
};
|
|
74
|
-
const getProjectionClause = (measures, dimensions, tableSchema, aliasedColumnSet)=>{
|
|
75
|
-
const filteredDimensions = dimensions.filter((dimension)=>{
|
|
76
|
-
return dimension.split('.')[0] === tableSchema.name;
|
|
77
|
-
});
|
|
78
|
-
const filteredMeasures = measures.filter((measure)=>{
|
|
79
|
-
return measure.split('.')[0] === tableSchema.name;
|
|
80
|
-
});
|
|
81
|
-
const dimensionsProjectionsArr = filteredDimensions.reduce((acc, member, currentIndex, members)=>{
|
|
82
|
-
const { sql: memberSql } = getDimensionProjection({
|
|
83
|
-
key: member,
|
|
84
|
-
tableSchema
|
|
85
|
-
});
|
|
86
|
-
return aggregator({
|
|
87
|
-
member,
|
|
88
|
-
aliasedColumnSet,
|
|
89
|
-
acc,
|
|
90
|
-
currentIndex,
|
|
91
|
-
members,
|
|
92
|
-
sql: memberSql
|
|
93
|
-
});
|
|
94
|
-
}, []);
|
|
95
|
-
const dimensionsProjections = dimensionsProjectionsArr.join(', ');
|
|
96
|
-
const measureProjectionsArr = filteredMeasures.reduce((acc, member, currentIndex, members)=>{
|
|
97
|
-
const { sql: memberSql } = getFilterMeasureProjection({
|
|
98
|
-
key: member,
|
|
99
|
-
tableSchema,
|
|
100
|
-
measures
|
|
101
|
-
});
|
|
102
|
-
return aggregator({
|
|
103
|
-
member,
|
|
104
|
-
aliasedColumnSet,
|
|
105
|
-
acc,
|
|
106
|
-
currentIndex,
|
|
107
|
-
members,
|
|
108
|
-
sql: memberSql
|
|
109
|
-
});
|
|
110
|
-
}, []);
|
|
111
|
-
const measureProjections = measureProjectionsArr.join(', ');
|
|
112
|
-
const usedMeasureObjects = tableSchema.measures.filter((measure)=>{
|
|
113
|
-
return measures.findIndex((key)=>{
|
|
114
|
-
const keyWithoutTable = key.split('.')[1];
|
|
115
|
-
return keyWithoutTable === measure.name;
|
|
116
|
-
}) !== -1;
|
|
117
|
-
});
|
|
118
|
-
const columnsUsedInMeasures = (0, _cubemeasuretransformer.getAllColumnUsedInMeasures)(usedMeasureObjects, tableSchema);
|
|
119
|
-
let columnsUsedInMeasuresInProjection = '';
|
|
120
|
-
columnsUsedInMeasures.forEach((column, index)=>{
|
|
121
|
-
const safeKey = (0, _memberkeytosafekey.memberKeyToSafeKey)(column);
|
|
122
|
-
columnsUsedInMeasuresInProjection += `${column} AS ${safeKey}`;
|
|
123
|
-
if (index !== columnsUsedInMeasures.length - 1) {
|
|
124
|
-
columnsUsedInMeasuresInProjection += ', ';
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
const combinedStr = [
|
|
128
|
-
dimensionsProjections,
|
|
129
|
-
measureProjections,
|
|
130
|
-
columnsUsedInMeasuresInProjection
|
|
131
|
-
];
|
|
132
|
-
return combinedStr.filter((str)=>str.length > 0).join(', ');
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
//# sourceMappingURL=get-projection-clause.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../meerkat-core/src/get-projection-clause/get-projection-clause.ts"],"sourcesContent":["import { getAllColumnUsedInMeasures } from '../cube-measure-transformer/cube-measure-transformer';\nimport { TableSchema } from '../types/cube-types';\nimport {\n findInDimensionSchema,\n findInMeasureSchema,\n} from '../utils/find-in-table-schema';\nimport { memberKeyToSafeKey } from '../utils/member-key-to-safe-key';\n\nexport const getFilterMeasureProjection = ({\n key,\n tableSchema,\n measures,\n}: {\n key: string;\n tableSchema: TableSchema;\n measures: string[];\n}) => {\n const tableName = key.split('.')[0];\n const measureWithoutTable = key.split('.')[1];\n const foundMember = findInMeasureSchema(measureWithoutTable, tableSchema);\n const isMeasure = measures.includes(key);\n if (!foundMember || isMeasure || tableName !== tableSchema.name) {\n // If the selected member is not found in the table schema or if it is already selected, continue.\n // If the selected member is a measure, don't create an alias. Since measure computation is done in the outermost level of the query\n // If the selected member is not from the current table, don't create an alias.\n return {\n sql: undefined,\n foundMember: undefined,\n aliasKey: undefined,\n };\n }\n const aliasKey = memberKeyToSafeKey(key);\n return { sql: `${key} AS ${aliasKey}`, foundMember, aliasKey };\n};\n\nexport const getDimensionProjection = ({\n key,\n tableSchema,\n}: {\n key: string;\n tableSchema: TableSchema;\n}) => {\n // Find the table access key\n const measureWithoutTable = key.split('.')[1];\n const tableName = key.split('.')[0];\n\n const foundMember = findInDimensionSchema(measureWithoutTable, tableSchema);\n if (!foundMember || tableName !== tableSchema.name) {\n // If the selected member is not found in the table schema or if it is already selected, continue.\n // If the selected member is not from the current table, don't create an alias.\n return {\n sql: undefined,\n foundMember: undefined,\n aliasKey: undefined,\n };\n }\n const aliasKey = memberKeyToSafeKey(key);\n // Add the alias key to the set. So we have a reference to all the previously selected members.\n return { sql: `${foundMember.sql} AS ${aliasKey}`, foundMember, aliasKey };\n};\n\nconst aggregator = ({\n member,\n aliasedColumnSet,\n acc,\n sql,\n}: {\n member: string;\n aliasedColumnSet: Set<string>;\n acc: string[];\n sql?: string;\n currentIndex: number;\n members: string[];\n}) => {\n if (aliasedColumnSet.has(member) || !sql) {\n return acc;\n }\n aliasedColumnSet.add(member);\n acc.push(sql);\n return acc;\n};\n\nexport const getProjectionClause = (\n measures: string[],\n dimensions: string[],\n tableSchema: TableSchema,\n aliasedColumnSet: Set<string>\n) => {\n const filteredDimensions = dimensions.filter((dimension) => {\n return dimension.split('.')[0] === tableSchema.name;\n });\n const filteredMeasures = measures.filter((measure) => {\n return measure.split('.')[0] === tableSchema.name;\n });\n const dimensionsProjectionsArr = filteredDimensions.reduce(\n (acc, member, currentIndex, members) => {\n const { sql: memberSql } = getDimensionProjection({\n key: member,\n tableSchema,\n });\n return aggregator({\n member,\n aliasedColumnSet,\n acc,\n currentIndex,\n members,\n sql: memberSql,\n });\n },\n [] as string[]\n );\n const dimensionsProjections = dimensionsProjectionsArr.join(', ');\n\n const measureProjectionsArr = filteredMeasures.reduce(\n (acc, member, currentIndex, members) => {\n const { sql: memberSql } = getFilterMeasureProjection({\n key: member,\n tableSchema,\n measures,\n });\n return aggregator({\n member,\n aliasedColumnSet,\n acc,\n currentIndex,\n members,\n sql: memberSql,\n });\n },\n [] as string[]\n );\n\n const measureProjections = measureProjectionsArr.join(', ');\n\n const usedMeasureObjects = tableSchema.measures.filter((measure) => {\n return (\n measures.findIndex((key) => {\n const keyWithoutTable = key.split('.')[1];\n return keyWithoutTable === measure.name;\n }) !== -1\n );\n });\n const columnsUsedInMeasures = getAllColumnUsedInMeasures(\n usedMeasureObjects,\n tableSchema\n );\n\n let columnsUsedInMeasuresInProjection = '';\n columnsUsedInMeasures.forEach((column, index) => {\n const safeKey = memberKeyToSafeKey(column);\n columnsUsedInMeasuresInProjection += `${column} AS ${safeKey}`;\n if (index !== columnsUsedInMeasures.length - 1) {\n columnsUsedInMeasuresInProjection += ', ';\n }\n });\n\n const combinedStr = [\n dimensionsProjections,\n measureProjections,\n columnsUsedInMeasuresInProjection,\n ];\n\n return combinedStr.filter((str) => str.length > 0).join(', ');\n};\n"],"names":["getFilterMeasureProjection","getDimensionProjection","getProjectionClause","key","tableSchema","measures","tableName","split","measureWithoutTable","foundMember","findInMeasureSchema","isMeasure","includes","name","sql","undefined","aliasKey","memberKeyToSafeKey","findInDimensionSchema","aggregator","member","aliasedColumnSet","acc","has","add","push","dimensions","filteredDimensions","filter","dimension","filteredMeasures","measure","dimensionsProjectionsArr","reduce","currentIndex","members","memberSql","dimensionsProjections","join","measureProjectionsArr","measureProjections","usedMeasureObjects","findIndex","keyWithoutTable","columnsUsedInMeasures","getAllColumnUsedInMeasures","columnsUsedInMeasuresInProjection","forEach","column","index","safeKey","length","combinedStr","str"],"mappings":"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"}
|