use of datawave.query.jexl.LiteralRange in project datawave by NationalSecurityAgency.
the class CompositeRange method addComponent.
@Override
public void addComponent(JexlNode node) {
List<JexlNode> nodes = new ArrayList<>();
LiteralRange range = JexlASTHelper.findRange().getRange(node);
if (range != null) {
nodes.add(range.getLowerNode());
nodes.add(range.getUpperNode());
} else if (node instanceof ASTEQNode) {
String fieldName = JexlASTHelper.getIdentifier(node);
String expression = JexlASTHelper.getLiteralValue(node).toString();
nodes.add(JexlNodeFactory.buildNode((ASTGENode) null, fieldName, expression));
nodes.add(JexlNodeFactory.buildNode((ASTLENode) null, fieldName, expression));
} else {
nodes.add(node);
}
jexlNodeList.add(node);
fieldNameList.add(JexlASTHelper.getIdentifier(nodes.get(0)));
for (JexlNode boundNode : nodes) {
String expression = JexlASTHelper.getLiteralValue(boundNode).toString();
if (boundNode instanceof ASTGENode || boundNode instanceof ASTGTNode) {
jexlNodeListLowerBound.add(boundNode);
expressionListLowerBound.add(expression);
if (nodes.size() < 2) {
jexlNodeListUpperBound.add(null);
expressionListUpperBound.add(null);
}
} else if (boundNode instanceof ASTLENode || boundNode instanceof ASTLTNode) {
jexlNodeListUpperBound.add(boundNode);
expressionListUpperBound.add(expression);
if (nodes.size() < 2) {
jexlNodeListLowerBound.add(null);
expressionListLowerBound.add(null);
}
}
}
}
use of datawave.query.jexl.LiteralRange in project datawave by NationalSecurityAgency.
the class LiteralRangeSerializer method deserialize.
@Override
public LiteralRange<String> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
JsonObject obj = json.getAsJsonObject();
String fieldName = (obj.get("FN") == null ? null : obj.get("FN").getAsString());
String lower = (obj.get("L") == null ? null : obj.get("L").getAsString());
String upper = (obj.get("U") == null ? null : obj.get("U").getAsString());
LiteralRange.NodeOperand operand = (obj.get("O") == null ? null : LiteralRange.NodeOperand.valueOf(obj.get("O").getAsString()));
Boolean lowerInclusive = (obj.get("LI") == null ? null : obj.get("LI").getAsBoolean());
Boolean upperInclusive = (obj.get("UI") == null ? null : obj.get("UI").getAsBoolean());
return new LiteralRange<>(lower, lowerInclusive, upper, upperInclusive, fieldName, operand);
}
use of datawave.query.jexl.LiteralRange in project datawave by NationalSecurityAgency.
the class IteratorBuildingVisitor method visit.
@Override
public Object visit(ASTAndNode and, Object data) {
QueryPropertyMarker.Instance instance = QueryPropertyMarker.findInstance(and);
if (instance.isType(ExceededOrThresholdMarkerJexlNode.class)) {
JexlNode source = instance.getSource();
// Ivarator to get the job done
if (source instanceof ASTAndNode) {
try {
ivarateList(and, source, data);
} catch (IOException ioe) {
throw new DatawaveFatalQueryException(ioe);
}
} else {
QueryException qe = new QueryException(DatawaveErrorCode.UNEXPECTED_SOURCE_NODE, MessageFormat.format("{0}", "Limited ExceededOrThresholdMarkerJexlNode"));
throw new DatawaveFatalQueryException(qe);
}
} else if (data instanceof IndexRangeIteratorBuilder) {
// index checking has already been done, otherwise we would not have
// an "ExceededValueThresholdMarker"
// hence the "IndexAgnostic" method can be used here
LiteralRange range = JexlASTHelper.findRange().recursively().getRange(and);
if (range == null) {
QueryException qe = new QueryException(DatawaveErrorCode.MULTIPLE_RANGES_IN_EXPRESSION);
throw new DatawaveFatalQueryException(qe);
}
((IndexRangeIteratorBuilder) data).setRange(range);
} else if (instance.isType(ExceededValueThresholdMarkerJexlNode.class)) {
// if the parent is our ExceededValueThreshold marker, then use an
// Ivarator to get the job done unless we don't have to
JexlNode source = instance.getSource();
String identifier = null;
LiteralRange<?> range = null;
boolean negatedLocal = false;
if (source instanceof ASTAndNode) {
range = buildLiteralRange(source, null);
identifier = range.getFieldName();
} else {
if (source instanceof ASTNRNode || source instanceof ASTNotNode)
negatedLocal = true;
range = buildLiteralRange(source);
identifier = JexlASTHelper.getIdentifier(source);
}
boolean negatedOverall = negatedLocal;
if (data instanceof AbstractIteratorBuilder) {
AbstractIteratorBuilder oib = (AbstractIteratorBuilder) data;
if (oib.isInANot()) {
negatedOverall = !negatedOverall;
}
}
// or the field is index only but not in the term frequencies, then we must ivarate
if (!limitLookup || !allowTermFrequencyLookup || (indexOnlyFields.contains(identifier) && !termFrequencyFields.contains(identifier))) {
if (source instanceof ASTAndNode) {
try {
List<ASTFunctionNode> functionNodes = JexlASTHelper.getFunctionNodes(source).stream().filter(node -> JexlFunctionArgumentDescriptorFactory.F.getArgumentDescriptor(node).allowIvaratorFiltering()).collect(Collectors.toList());
if (functionNodes.isEmpty()) {
ivarateRange(and, source, data);
} else {
ivarateFilter(and, source, data, functionNodes);
}
} catch (IOException ioe) {
throw new DatawaveFatalQueryException("Unable to ivarate", ioe);
}
} else if (source instanceof ASTERNode || source instanceof ASTNRNode) {
try {
ivarateRegex(and, source, data);
} catch (IOException ioe) {
throw new DatawaveFatalQueryException("Unable to ivarate", ioe);
}
} else {
QueryException qe = new QueryException(DatawaveErrorCode.UNEXPECTED_SOURCE_NODE, MessageFormat.format("{0}", "ExceededValueThresholdMarkerJexlNode"));
throw new DatawaveFatalQueryException(qe);
}
} else {
NestedIterator<Key> nested = null;
if (termFrequencyFields.contains(identifier)) {
nested = buildExceededFromTermFrequency(identifier, and, source, range, data);
} else {
/**
* This is okay since 1) We are doc specific 2) We are not index only or tf 3) Therefore, we must evaluate against the document for this
* expression 4) Return a stubbed range in case we have a disjunction that breaks the current doc.
*/
if (!limitOverride && !negatedOverall)
nested = createExceededCheck(identifier, range, and);
}
if (null != nested && null != data && data instanceof AbstractIteratorBuilder) {
AbstractIteratorBuilder iterators = (AbstractIteratorBuilder) data;
if (negatedLocal) {
iterators.addExclude(nested);
} else {
iterators.addInclude(nested);
}
} else {
if (isQueryFullySatisfied == true) {
log.warn("Determined that isQueryFullySatisfied should be false, but it was not preset to false in the SatisfactionVisitor");
}
return nested;
}
}
} else if (null != data && data instanceof AndIteratorBuilder) {
and.childrenAccept(this, data);
} else {
// Create an AndIterator and recursively add the children
AbstractIteratorBuilder andItr = new AndIteratorBuilder();
andItr.negateAsNeeded(data);
and.childrenAccept(this, andItr);
// If there is no parent
if (data == null) {
// Make this AndIterator the root node
if (!andItr.includes().isEmpty()) {
root = andItr.build();
}
} else {
// Otherwise, add this AndIterator to its parent
AbstractIteratorBuilder parent = (AbstractIteratorBuilder) data;
if (!andItr.includes().isEmpty()) {
parent.addInclude(andItr.build());
}
}
if (log.isTraceEnabled()) {
log.trace("ASTAndNode visit: pretty formatting of:\nparent.includes:" + formatIncludesOrExcludes(andItr.includes()) + "\nparent.excludes:" + formatIncludesOrExcludes(andItr.excludes()));
}
}
return null;
}
use of datawave.query.jexl.LiteralRange in project datawave by NationalSecurityAgency.
the class DiscoveryLogic method configureIndexMatchingIterator.
public static final void configureIndexMatchingIterator(DiscoveryQueryConfiguration config, ScannerBase bs, Multimap<String, String> literals, Multimap<String, String> patterns, Multimap<String, LiteralRange<String>> ranges, boolean reverseIndex) {
if ((literals == null || literals.isEmpty()) && (patterns == null || patterns.isEmpty()) && (ranges == null || ranges.isEmpty())) {
return;
}
log.debug("Configuring IndexMatchingIterator with " + literals + " and " + patterns);
IteratorSetting cfg = new IteratorSetting(config.getBaseIteratorPriority() + 23, "termMatcher", IndexMatchingIterator.class);
IndexMatchingIterator.Configuration conf = new IndexMatchingIterator.Configuration();
if (literals != null) {
for (Entry<String, String> literal : literals.entries()) {
if (Constants.ANY_FIELD.equals(literal.getValue())) {
conf.addLiteral(literal.getKey());
} else {
conf.addLiteral(literal.getKey(), literal.getValue());
}
}
}
if (patterns != null) {
for (Entry<String, String> pattern : patterns.entries()) {
if (Constants.ANY_FIELD.equals(pattern.getValue())) {
conf.addPattern(pattern.getKey());
} else {
conf.addPattern(pattern.getKey(), pattern.getValue());
}
}
}
if (ranges != null) {
for (Entry<String, LiteralRange<String>> range : ranges.entries()) {
if (Constants.ANY_FIELD.equals(range.getKey())) {
conf.addRange(range.getValue());
} else {
conf.addRange(range.getValue(), range.getKey());
}
}
}
cfg.addOption(IndexMatchingIterator.CONF, IndexMatchingIterator.gson().toJson(conf));
cfg.addOption(IndexMatchingIterator.REVERSE_INDEX, Boolean.toString(reverseIndex));
bs.addScanIterator(cfg);
}
use of datawave.query.jexl.LiteralRange in project datawave by NationalSecurityAgency.
the class IteratorBuildingVisitor method getFiRangeForTF.
/**
* Range should be built from the start key of the rangeLimiter only, as the end key likely doesn't parse properly so don't rely on it. rangeLimiter must be
* non-null (limitLookup == true)
*
* @param range
* non-null literal range to generate an FI range from
* @return non-null FI based range for the literal range provided
*/
protected Range getFiRangeForTF(LiteralRange<?> range) {
Key startKey = rangeLimiter.getStartKey();
StringBuilder strBuilder = new StringBuilder("fi");
strBuilder.append(NULL_DELIMETER).append(range.getFieldName());
Text cf = new Text(strBuilder.toString());
strBuilder = new StringBuilder(range.getLower().toString());
strBuilder.append(NULL_DELIMETER).append(startKey.getColumnFamily());
Text cq = new Text(strBuilder.toString());
Key seekBeginKey = new Key(startKey.getRow(), cf, cq, startKey.getTimestamp());
strBuilder = new StringBuilder(range.getUpper().toString());
strBuilder.append(NULL_DELIMETER).append(startKey.getColumnFamily());
cq = new Text(strBuilder.toString());
Key seekEndKey = new Key(startKey.getRow(), cf, cq, startKey.getTimestamp());
return new Range(seekBeginKey, true, seekEndKey, true);
}
Aggregations