-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathQueryUtils.js
142 lines (96 loc) · 3.78 KB
/
QueryUtils.js
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
var NodeFactory = require('../rdf/NodeFactory');
var Query = require('../sparql/Query');
var ExprVar = require('../sparql/expr/ExprVar');
var SortCondition = require('../sparql/SortCondition');
var ExprModRegistry = []; // TODO Get rid of this
var E_LogicalNot = require('../sparql/expr/E_LogicalNot');
var E_Bound = require('../sparql/expr/E_Bound');
var QueryUtils = {
/**
* Creates a query by applying the modifications specified by the tableMod to an element
*/
createQueryFacet: function(element, tableMod) {
if(!element) {
return null;
}
var isDistinct = tableMod.isDistinct();
var result = new Query();
result.setQueryPattern(element);
var columns = tableMod.getColumns();
// Map from column id to SPARQL expression representing this column
var idToColExpr = {};
var aggColumnIds = [];
var nonAggColumnIds = [];
columns.forEach(function(c) {
var columnId = c.getId();
var v = NodeFactory.createVar(columnId);
var ev = new ExprVar(v);
// TODO Get aggregators working again
var agg = c.getAggregator();
if(agg) {
aggColumnIds.push(columnId);
var aggName = agg.getName();
var aggExprFactory = ExprModRegistry[aggName];
if(!aggExprFactory) {
throw new Error('No aggExprFactory for ' + aggName);
}
var aggExpr = aggExprFactory.createExpr(ev);
ev = aggExpr;
result.getProject().add(v, ev);
} else {
nonAggColumnIds.push(columnId);
result.getProject().add(v);
}
idToColExpr[columnId] = ev;
});
if(aggColumnIds.length > 0) {
nonAggColumnIds.forEach(function(nonAggColumnId) {
var expr = idToColExpr[nonAggColumnId];
result.getGroupBy().push(expr);
});
// Aggregation implies distinct
isDistinct = false;
}
// Apply limit / offset
var lo = tableMod.getLimitAndOffset();
result.setLimit(lo.getLimit());
result.setOffset(lo.getOffset());
// Apply sort conditions
var sortConditions = tableMod.getSortConditions();
sortConditions.forEach(function(sortCondition) {
var columnId = sortCondition.getColumnId();
var colExpr = idToColExpr[columnId];
if(!colExpr) {
console.log('[ERROR] Should not happen');
throw new Error('Should not happen');
}
// Ordering of null values
//var sortCondition = cs.getSortCondition();
var sortDir = sortCondition.getSortDir();
var sortType = sortCondition.getSortType();
var sortCond = null;
switch(sortType) {
case 'null':
// Null ordering only works with non-aggregate columns
if(aggColumnIds.indexOf(columnId) < 0) {
if(sortDir > 0) {
sortCond = new SortCondition(new E_LogicalNot(new E_Bound(colExpr)), 1);
} else if(sortDir < 0) {
sortCond = new SortCondition(new E_Bound(colExpr), 1);
}
}
break;
case 'data':
sortCond = !sortDir ? null : new SortCondition(colExpr, sortDir);
break;
default:
throw new Error('Should not happen');
}
if(sortCond) {
result.getOrderBy().push(sortCond);
}
});
result.setDistinct(isDistinct);
return result;
}
};