use of com.questdb.griffin.common.ExprNode in project questdb by bluestreak01.
the class QueryFilterAnalyser method analyzeListOfValues.
private boolean analyzeListOfValues(IntrinsicModel model, CharSequence col, RecordMetadata meta, ExprNode node) {
RecordColumnMetadata colMeta = meta.getColumn(col);
if (colMeta.isIndexed()) {
boolean newColumn = true;
if (preferredKeyColumn != null && !col.equals(preferredKeyColumn)) {
return false;
}
// check if we already have indexed column and it is of worse selectivity
if (model.keyColumn != null && (newColumn = !Chars.equals(model.keyColumn, col)) && colMeta.getBucketCount() <= meta.getColumn(model.keyColumn).getBucketCount()) {
return false;
}
int i = node.paramCount - 1;
tempKeys.clear();
tempPos.clear();
// if any of values is not an indexed constant - bail out
if (i == 1) {
if (node.rhs == null || node.rhs.type != ExprNode.CONSTANT) {
return false;
}
if (tempKeys.add(unquote(node.rhs.token))) {
tempPos.add(node.position);
}
} else {
for (i--; i > -1; i--) {
ExprNode c = node.args.getQuick(i);
if (c.type != ExprNode.CONSTANT) {
return false;
}
if (tempKeys.add(unquote(c.token))) {
tempPos.add(c.position);
}
}
}
// and reset intrinsic values on nodes associated with old column
if (newColumn) {
model.keyValues.clear();
model.keyValuePositions.clear();
model.keyValues.addAll(tempKeys);
model.keyValuePositions.addAll(tempPos);
for (int n = 0, k = keyNodes.size(); n < k; n++) {
keyNodes.getQuick(n).intrinsicValue = IntrinsicValue.UNDEFINED;
}
keyNodes.clear();
model.keyColumn = col;
keyNodes.add(node);
node.intrinsicValue = IntrinsicValue.TRUE;
return true;
} else if (!model.keyValuesIsLambda) {
// calculate overlap of values
replaceAllWithOverlap(model);
keyNodes.add(node);
node.intrinsicValue = IntrinsicValue.TRUE;
return true;
}
}
return false;
}
use of com.questdb.griffin.common.ExprNode in project questdb by bluestreak01.
the class QueryFilterAnalyser method analyzeNotIn.
private boolean analyzeNotIn(AliasTranslator translator, IntrinsicModel model, ExprNode notNode, RecordMetadata m) throws ParserException {
ExprNode node = notNode.rhs;
if (node.paramCount < 2) {
throw ParserException.$(node.position, "Too few arguments for 'in'");
}
ExprNode col = node.paramCount < 3 ? node.lhs : node.args.getLast();
if (col.type != ExprNode.LITERAL) {
throw ParserException.$(col.position, "Column name expected");
}
CharSequence column = translator.translateAlias(col.token);
if (m.getColumnIndexQuiet(column) == -1) {
throw ParserException.invalidColumn(col.position, col.token);
}
boolean ok = analyzeNotInInterval(model, col, node);
if (ok) {
notNode.intrinsicValue = IntrinsicValue.TRUE;
} else {
analyzeNotListOfValues(column, m, notNode);
}
return ok;
}
use of com.questdb.griffin.common.ExprNode in project questdb by bluestreak01.
the class QueryFilterAnalyser method extract.
IntrinsicModel extract(AliasTranslator translator, ExprNode node, RecordMetadata m, String preferredKeyColumn, int timestampIndex) throws ParserException {
reset();
this.timestamp = timestampIndex < 0 ? null : m.getColumnName(timestampIndex);
this.preferredKeyColumn = preferredKeyColumn;
IntrinsicModel model = models.next();
if (removeAndIntrinsics(translator, model, node, m)) {
return model;
}
ExprNode root = node;
while (!stack.isEmpty() || node != null) {
if (node != null) {
if (Chars.equals("and", node.token)) {
if (!removeAndIntrinsics(translator, model, node.rhs, m)) {
stack.push(node.rhs);
}
node = removeAndIntrinsics(translator, model, node.lhs, m) ? null : node.lhs;
} else {
node = stack.poll();
}
} else {
node = stack.poll();
}
}
applyKeyExclusions(translator, model);
model.filter = collapseIntrinsicNodes(root);
return model;
}
use of com.questdb.griffin.common.ExprNode in project questdb by bluestreak01.
the class QueryFilterAnalyser method analyzeNotInInterval.
private boolean analyzeNotInInterval(IntrinsicModel model, ExprNode col, ExprNode in) throws ParserException {
if (!isTimestamp(col)) {
return false;
}
if (in.paramCount > 3) {
throw ParserException.$(in.args.getQuick(0).position, "Too many args");
}
if (in.paramCount < 3) {
throw ParserException.$(in.position, "Too few args");
}
ExprNode lo = in.args.getQuick(1);
ExprNode hi = in.args.getQuick(0);
if (lo.type == ExprNode.CONSTANT && hi.type == ExprNode.CONSTANT) {
long loMillis;
long hiMillis;
try {
loMillis = DateFormatUtils.tryParse(lo.token, 1, lo.token.length() - 1);
} catch (NumericException ignore) {
throw ParserException.invalidDate(lo.position);
}
try {
hiMillis = DateFormatUtils.tryParse(hi.token, 1, hi.token.length() - 1);
} catch (NumericException ignore) {
throw ParserException.invalidDate(hi.position);
}
model.subtractIntervals(loMillis, hiMillis);
in.intrinsicValue = IntrinsicValue.TRUE;
return true;
}
return false;
}
use of com.questdb.griffin.common.ExprNode in project questdb by bluestreak01.
the class PostOrderTreeTraversalAlgo method traverse.
void traverse(ExprNode node, Visitor visitor) throws ParserException {
// post-order iterative tree traversal
// see http://en.wikipedia.org/wiki/Tree_traversal
stack.clear();
indexStack.clear();
ExprNode lastVisited = null;
while (!stack.isEmpty() || node != null) {
if (node != null) {
stack.push(node);
indexStack.push(0);
node = node.rhs;
} else {
ExprNode peek = stack.peek();
if (peek.paramCount < 3) {
if (peek.lhs != null && lastVisited != peek.lhs) {
node = peek.lhs;
} else {
visitor.visit(peek);
lastVisited = stack.poll();
indexStack.pop();
}
} else {
int index = indexStack.peek();
if (index < peek.paramCount) {
node = peek.args.getQuick(index);
indexStack.update(index + 1);
} else {
visitor.visit(peek);
lastVisited = stack.poll();
indexStack.pop();
}
}
}
}
}
Aggregations