-
-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathtransforms2sql.ts
More file actions
66 lines (64 loc) · 1.96 KB
/
transforms2sql.ts
File metadata and controls
66 lines (64 loc) · 1.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import {
Transform,
isFilter,
isAggregate
} from "vega-lite/build/src/transform";
export class Transforms2SQL {
// we can only support a small subset of aggregate operations with our current approach
public static agg_op_mappings = {
mean: "avg",
average: "avg"
};
public static convert(
table: string,
selections: string[],
transforms: Transform[]
): string {
let components = {
select: new Set(Object.assign([], selections)),
where: [],
group: new Set()
};
for (const transform of transforms) {
if (isFilter(transform)) {
if (typeof transform.filter === "string") {
// naive conversion to SQL
components.where.push(
transform.filter.replace(/==/g, "=").replace(/datum\./g, "")
);
} else {
// field predicates not supported
}
} else if (isAggregate(transform)) {
for (const aggregate of transform.aggregate) {
const translated_op = this.translate_op(aggregate.op);
if (aggregate.field !== undefined) {
components.select.add(
`${translated_op}(${aggregate.field}) AS ${aggregate.as}`
);
} else {
// must be a counting operation
components.select.add(`${translated_op}(*) AS ${aggregate.as}`);
}
}
if (transform.groupby !== undefined) {
for (const group of transform.groupby) {
components.group.add(group);
}
}
}
}
for (const group of selections) {
components.group.add(group);
}
return `SELECT ${Array.from(components.select).join(", ")}
FROM ${table}${
components.where.length > 0 ? "\nWHERE " : ""
}${components.where.join(", ")}${
components.group.size > 0 ? "\nGROUP BY " : ""
}${Array.from(components.group).join(", ")}`;
}
private static translate_op(op: string): string {
return this.agg_op_mappings[op] || op;
}
}