Search in sources :

Example 1 with EdgeContext

use of datawave.query.tables.edge.contexts.EdgeContext in project datawave by NationalSecurityAgency.

the class EdgeTableRangeBuildingVisitor method visit.

/**
 * Or node should have exactly two children This or node's only function is to combine the lists returned by its children.
 *
 * The Children can return lists of type IdentityContext or QueryContext both children must return the same type of lists else its an improper query ex:
 * Both children return lists of IdentityContexts where the identity is source Both children return lists of QueryContexts
 *
 * There is one exception where a QueryContext list and a IdentityContext list could be returned by the children in which case the returned IdentityContext
 * list is immediately packaged into a new QueryContext and is then combined with the returned other QueryContext list Happens with a query like this:
 * {@code (SOURCE == 'source1' && SINK == 'sink') || (SOURCE == 'source2')}
 *
 * Or node will return either a list of IdentityContexts or QueryContexts
 */
@Override
public Object visit(ASTOrNode node, Object data) {
    if (termCount > maxTerms) {
        log.error("Query has too many terms");
        throw new IllegalArgumentException("Too many search terms " + termCount);
    }
    // run the visitor against all of the children
    List<List<? extends EdgeContext>> childContexts = new ArrayList<>(node.jjtGetNumChildren());
    for (JexlNode child : children(node)) {
        childContexts.add((List<? extends EdgeContext>) child.jjtAccept(this, null));
    }
    if (childContexts.isEmpty()) {
        log.error("Unable to get edge context from OR node");
        throw new IllegalArgumentException("Unable to get edge context from OR node");
    }
    List<? extends EdgeContext> mergedContext = childContexts.remove(childContexts.size() - 1);
    // now merge the child contexts
    while (!childContexts.isEmpty()) {
        List<? extends EdgeContext> childContext = childContexts.remove(childContexts.size() - 1);
        if ((childContext.get(0) instanceof IdentityContext) && (mergedContext.get(0) instanceof IdentityContext)) {
            // Combine two lists of Identity contexts
            IdentityContext iContext1 = (IdentityContext) childContext.get(0);
            IdentityContext iContext2 = (IdentityContext) mergedContext.get(0);
            checkNotExclusion(iContext1, "Can't OR exclusion expressions");
            checkNotExclusion(iContext2, "Can't OR exclusion expressions");
            if (iContext1.getIdentity().equals(iContext2.getIdentity())) {
                ((List<IdentityContext>) childContext).addAll((List<IdentityContext>) mergedContext);
                mergedContext = childContext;
            } else {
                log.error("Query attempted to or like terms: " + iContext1.getIdentity() + " and " + iContext1.getIdentity());
                throw new IllegalArgumentException("Can't OR unlike terms: " + iContext1.getIdentity() + " and " + iContext2.getIdentity());
            }
        } else if ((childContext.get(0) instanceof QueryContext) && (mergedContext.get(0) instanceof QueryContext)) {
            List<QueryContext> context1 = (List<QueryContext>) childContext;
            List<QueryContext> context2 = (List<QueryContext>) mergedContext;
            if (context1.size() == 1 && context1.get(0).hasSourceList() == false) {
                runCombine(context2, context1);
                mergedContext = context2;
            } else if (context2.size() == 1 && context2.get(0).hasSourceList() == false) {
                runCombine(context1, context2);
                mergedContext = context1;
            } else {
                context1.addAll(context2);
                mergedContext = context1;
            }
        } else if ((childContext.get(0) instanceof IdentityContext) && (mergedContext.get(0) instanceof QueryContext)) {
            checkNotExclusion((IdentityContext) childContext.get(0), "Can't OR exclusion expressions");
            QueryContext queryContext = new QueryContext();
            queryContext.packageIdentities((List<IdentityContext>) childContext, false);
            if (isSourceList((List<IdentityContext>) childContext)) {
                ((List<QueryContext>) mergedContext).add(queryContext);
            } else {
                List<QueryContext> otherContexts = new ArrayList<>();
                otherContexts.add(queryContext);
                runCombine((List<QueryContext>) mergedContext, otherContexts);
            }
        } else if ((childContext.get(0) instanceof QueryContext) && (mergedContext.get(0) instanceof IdentityContext)) {
            checkNotExclusion((IdentityContext) mergedContext.get(0), "Can't OR exclusion expressions");
            QueryContext queryContext = new QueryContext();
            queryContext.packageIdentities((List<IdentityContext>) mergedContext, false);
            if (isSourceList((List<IdentityContext>) mergedContext)) {
                ((List<QueryContext>) childContext).add(queryContext);
            } else {
                List<QueryContext> otherContexts = new ArrayList<>();
                otherContexts.add(queryContext);
                runCombine((List<QueryContext>) childContext, otherContexts);
            }
            mergedContext = childContext;
        } else {
            log.error("OR node had unexpected return type");
            throw new IllegalArgumentException("Error: problem with query syntax");
        }
    }
    return mergedContext;
}
Also used : EdgeContext(datawave.query.tables.edge.contexts.EdgeContext) ArrayList(java.util.ArrayList) JexlNode(org.apache.commons.jexl2.parser.JexlNode) ArrayList(java.util.ArrayList) List(java.util.List) IdentityContext(datawave.query.tables.edge.contexts.IdentityContext) QueryContext(datawave.query.tables.edge.contexts.QueryContext)

Example 2 with EdgeContext

use of datawave.query.tables.edge.contexts.EdgeContext in project datawave by NationalSecurityAgency.

the class EdgeTableRangeBuildingVisitor method visit.

/*
     * And node should have exactly two children This node's only function is to pack lists of IdentityContexts into a QueryContext
     * 
     * Returns a QueryContext
     */
@Override
public Object visit(ASTAndNode node, Object data) {
    if (termCount > maxTerms) {
        log.error("Query has too many terms");
        throw new IllegalArgumentException("Too many search terms " + termCount);
    }
    // run the visitor against all of the children
    List<List<? extends EdgeContext>> childContexts = new ArrayList<>(node.jjtGetNumChildren());
    for (JexlNode child : children(node)) {
        childContexts.add((List<? extends EdgeContext>) child.jjtAccept(this, null));
    }
    if (childContexts.isEmpty()) {
        log.error("Unable to get edge context from AND node");
        throw new IllegalArgumentException("Unable to get edge context from AND node");
    }
    List<? extends EdgeContext> mergedContext = childContexts.remove(childContexts.size() - 1);
    // now merge the child contexts
    while (!childContexts.isEmpty()) {
        List<? extends EdgeContext> childContext = childContexts.remove(childContexts.size() - 1);
        if ((childContext.get(0) instanceof IdentityContext) && (mergedContext.get(0) instanceof IdentityContext)) {
            QueryContext qContext = new QueryContext();
            qContext.packageIdentities((List<IdentityContext>) childContext);
            qContext.packageIdentities((List<IdentityContext>) mergedContext);
            ArrayList<QueryContext> aList = new ArrayList<>();
            aList.add(qContext);
            mergedContext = aList;
        } else if ((childContext.get(0) instanceof IdentityContext) && (mergedContext.get(0) instanceof QueryContext)) {
            for (QueryContext qContext : (List<QueryContext>) mergedContext) {
                qContext.packageIdentities((List<IdentityContext>) childContext);
            }
        } else if ((childContext.get(0) instanceof QueryContext) && (mergedContext.get(0) instanceof IdentityContext)) {
            for (QueryContext qContext : (List<QueryContext>) childContext) {
                qContext.packageIdentities((List<IdentityContext>) mergedContext);
            }
            mergedContext = childContext;
        /*
                 * On rare occasion a group of Query contexts without a source can get grouped together, this happens with queries like: SOURCE == 's1' &&
                 * ((TYPE == 't1' && RELATIONSHIP == 'r1') || (TYPE == 't2' && RELATIONSHIP == 'r2'))
                 * 
                 * This probably was not supposed to be allowed, you should only be ANDing groups of sources with groups of other identifiers rather here it is
                 * ANDing source(s) with groups of expressions. Honestly it would be safer to split that type of query up into two separate ones but limited
                 * support has been included. However it can be dangerous if the user tries to use SINK in one of the grouped expressions so that is not
                 * allowed.
                 */
        } else if ((childContext.get(0) instanceof QueryContext) && (mergedContext.get(0) instanceof QueryContext)) {
            // Assumes that if the first query context does not have a row context then they all don't
            if (((List<QueryContext>) childContext).get(0).getRowContext() != null) {
                // The size of the list for contexts1 is usually going to be 1
                for (QueryContext qContext : ((List<QueryContext>) childContext)) {
                    // Combine the query contexts if anything fails blame the user
                    if (!(qContext.combineQueryContexts(((List<QueryContext>) mergedContext), false))) {
                        log.error("And node had unexpected return type");
                        throw new IllegalArgumentException("Error: problem with query syntax");
                    }
                }
                mergedContext = childContext;
            } else if (((List<QueryContext>) mergedContext).get(0).getRowContext() != null) {
                for (QueryContext qContext : ((List<QueryContext>) mergedContext)) {
                    if (!(qContext.combineQueryContexts(((List<QueryContext>) childContext), false))) {
                        log.error("And node had unexpected return type");
                        throw new IllegalArgumentException("Error: problem with query syntax");
                    }
                }
            } else {
                log.error("Problem parsing query");
                throw new IllegalArgumentException("Error: problem with query syntax");
            }
        } else {
            log.error("And node had unexpected return type");
            throw new IllegalArgumentException("Error: problem with query syntax");
        }
    }
    return mergedContext;
}
Also used : EdgeContext(datawave.query.tables.edge.contexts.EdgeContext) ArrayList(java.util.ArrayList) JexlNode(org.apache.commons.jexl2.parser.JexlNode) ArrayList(java.util.ArrayList) List(java.util.List) IdentityContext(datawave.query.tables.edge.contexts.IdentityContext) QueryContext(datawave.query.tables.edge.contexts.QueryContext)

Example 3 with EdgeContext

use of datawave.query.tables.edge.contexts.EdgeContext in project datawave by NationalSecurityAgency.

the class EdgeTableRangeBuildingVisitor method visit.

/*
     * This is treated as the root node of the tree it can only have one child
     * 
     * The job of this node is to take the results of its child and create the visitation context to be returned
     */
public Object visit(ASTJexlScript node, Object data) {
    int numChildren = node.jjtGetNumChildren();
    if (numChildren != 1) {
        log.error("JexlScript node had an unexpected number of children: " + numChildren);
        BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.NODE_PROCESSING_ERROR);
        throw new RuntimeException(qe);
    }
    @SuppressWarnings("unchecked") List<? extends EdgeContext> context = (List<? extends EdgeContext>) node.jjtGetChild(0).jjtAccept(this, null);
    if (context.get(0) instanceof IdentityContext) {
        // this can only happen if there is no AND node in the query
        // Build singleton list of QueryContexts then create VisitationContext
        QueryContext qContext = new QueryContext();
        qContext.packageIdentities((List<IdentityContext>) context);
        return computeVisitaionContext(Collections.singletonList(qContext));
    } else if (context.get(0) instanceof QueryContext) {
        return computeVisitaionContext((List<QueryContext>) context);
    // return context;
    } else {
        log.error("JexlScript node recieved unexpected return type: " + context);
        BadRequestQueryException qe = new BadRequestQueryException(DatawaveErrorCode.NODE_PROCESSING_ERROR);
        throw new RuntimeException(qe);
    }
}
Also used : EdgeContext(datawave.query.tables.edge.contexts.EdgeContext) BadRequestQueryException(datawave.webservice.query.exception.BadRequestQueryException) ArrayList(java.util.ArrayList) List(java.util.List) IdentityContext(datawave.query.tables.edge.contexts.IdentityContext) QueryContext(datawave.query.tables.edge.contexts.QueryContext)

Aggregations

EdgeContext (datawave.query.tables.edge.contexts.EdgeContext)3 IdentityContext (datawave.query.tables.edge.contexts.IdentityContext)3 QueryContext (datawave.query.tables.edge.contexts.QueryContext)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 JexlNode (org.apache.commons.jexl2.parser.JexlNode)2 BadRequestQueryException (datawave.webservice.query.exception.BadRequestQueryException)1