Search in sources :

Example 1 with Symbol

use of org.datanucleus.query.compiler.Symbol in project tests by datanucleus.

the class JDOQLCompilerTest method testFilterCollectionContainsVariable.

/**
 * Tests for collection.contains(element).
 */
public void testFilterCollectionContainsVariable() {
    JavaQueryCompiler compiler = null;
    QueryCompilation compilation = null;
    try {
        compiler = new JDOQLCompiler(nucCtx, nucCtx.getClassLoaderResolver(null), null, Inventory.class, null, "products.contains(element) && element.price < 200", null, null, null, null, null, null, Product.class.getName() + " element", null);
        compilation = compiler.compile(new HashMap(), null);
    } catch (NucleusException ne) {
        NucleusLogger.QUERY.error("Exception thrown during compilation", ne);
        fail("compilation of filter with valid field threw exception : " + ne.getMessage());
    }
    Expression expr = compilation.getExprFilter();
    assertTrue("Compiled expression should have been DyadicExpression but wasnt", expr instanceof DyadicExpression);
    DyadicExpression dyExpr = (DyadicExpression) expr;
    // product.contains(element)
    assertTrue("Left expression should have been InvokeExpression but wasnt", dyExpr.getLeft() instanceof InvokeExpression);
    InvokeExpression leftExpr = (InvokeExpression) dyExpr.getLeft();
    assertTrue("InvokeExpression should have been invoked on PrimaryExpression but wasnt", leftExpr.getLeft() instanceof PrimaryExpression);
    assertEquals("Left expression : Name of field upon which we invoke the method was wrong", "products", ((PrimaryExpression) leftExpr.getLeft()).getId());
    assertEquals("Left expression : Name of invoked method was wrong", "contains", leftExpr.getOperation());
    assertEquals("Left expression : Number of parameters to contains() is wrong", 1, leftExpr.getArguments().size());
    Object param1 = leftExpr.getArguments().get(0);
    assertTrue("Left expression : Parameter1 to contains() is of wrong type", param1 instanceof VariableExpression);
    VariableExpression vrExpr = (VariableExpression) param1;
    assertEquals("Left expression : Name of variable to contains() is incorrect", "element", vrExpr.getId());
    // element.price < 200
    assertTrue("Right expression should have been DyadicExpression but wasnt", dyExpr.getRight() instanceof DyadicExpression);
    DyadicExpression rightExpr = (DyadicExpression) dyExpr.getRight();
    assertTrue("Right expression (left) should have been PrimaryExpression but wasnt", rightExpr.getLeft() instanceof PrimaryExpression);
    PrimaryExpression rightExprLeft = (PrimaryExpression) rightExpr.getLeft();
    assertTrue("Right expression (left).left is of incorrect type", rightExprLeft.getLeft() instanceof VariableExpression);
    VariableExpression rightExprLeftLeft = (VariableExpression) rightExprLeft.getLeft();
    assertTrue("Right expression (left).left is of incorrect type", rightExprLeft.getLeft() instanceof VariableExpression);
    assertEquals("Right expression (left) part1 is incorrect", "element", rightExprLeftLeft.getId());
    assertEquals("Right expression (left) has incorrect number of tuples", 1, rightExprLeft.getTuples().size());
    assertEquals("Right expression (left) part2 is incorrect", "price", rightExprLeft.getTuples().get(0));
    assertEquals("Right expression : Operator between left and right is incorrect", Expression.OP_LT, rightExpr.getOperator());
    assertTrue("Right expression (right) should have been Literal but wasnt", rightExpr.getRight() instanceof Literal);
    Literal rightExprRight = (Literal) rightExpr.getRight();
    assertEquals("Right expression (right) literal has incorrect value", 200, ((Long) rightExprRight.getLiteral()).longValue());
    // Check symbols
    SymbolTable symbols = compilation.getSymbolTable();
    assertTrue("Symbol table doesnt have entry for 'element'", symbols.hasSymbol("element"));
    assertTrue("Symbol table doesnt have entry for 'this'", symbols.hasSymbol("this"));
    Symbol sy1 = symbols.getSymbol("element");
    assertEquals("Type of symbol for 'element' is wrong", Product.class, sy1.getValueType());
    Symbol sy2 = symbols.getSymbol("this");
    assertEquals("Type of symbol for 'this' is wrong", Inventory.class, sy2.getValueType());
}
Also used : JDOQLCompiler(org.datanucleus.query.compiler.JDOQLCompiler) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) HashMap(java.util.HashMap) Symbol(org.datanucleus.query.compiler.Symbol) Product(org.datanucleus.samples.store.Product) SymbolTable(org.datanucleus.query.compiler.SymbolTable) VariableExpression(org.datanucleus.query.expression.VariableExpression) DyadicExpression(org.datanucleus.query.expression.DyadicExpression) JavaQueryCompiler(org.datanucleus.query.compiler.JavaQueryCompiler) DyadicExpression(org.datanucleus.query.expression.DyadicExpression) ParameterExpression(org.datanucleus.query.expression.ParameterExpression) Expression(org.datanucleus.query.expression.Expression) InvokeExpression(org.datanucleus.query.expression.InvokeExpression) VariableExpression(org.datanucleus.query.expression.VariableExpression) OrderExpression(org.datanucleus.query.expression.OrderExpression) PrimaryExpression(org.datanucleus.query.expression.PrimaryExpression) Literal(org.datanucleus.query.expression.Literal) QueryCompilation(org.datanucleus.query.compiler.QueryCompilation) NucleusException(org.datanucleus.exceptions.NucleusException) Inventory(org.datanucleus.samples.store.Inventory)

Example 2 with Symbol

use of org.datanucleus.query.compiler.Symbol in project datanucleus-core by datanucleus.

the class Query method checkForMissingParameters.

/**
 * Method to check for any missing parameters that the query compilation is expecting but which aren't
 * supplied to execute().
 * @param parameterValues The input parameter values keyed by their name (or position)
 */
protected void checkForMissingParameters(Map parameterValues) {
    if (compilation == null) {
        return;
    } else if (parameterValues == null) {
        parameterValues = new HashMap();
    }
    boolean namedParametersSupplied = true;
    if (!parameterValues.isEmpty()) {
        Object key = parameterValues.keySet().iterator().next();
        if (!(key instanceof String)) {
            namedParametersSupplied = false;
        }
    }
    if (namedParametersSupplied) {
        // Check for missing named parameters
        SymbolTable symtbl = compilation.getSymbolTable();
        Collection<String> symNames = symtbl.getSymbolNames();
        if (symNames != null && !symNames.isEmpty()) {
            for (String symName : symNames) {
                Symbol sym = symtbl.getSymbol(symName);
                if (sym.getType() == Symbol.PARAMETER) {
                    if (!parameterValues.containsKey(symName)) {
                        throw new QueryInvalidParametersException(Localiser.msg("021119", symName));
                    }
                }
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Symbol(org.datanucleus.query.compiler.Symbol) SymbolTable(org.datanucleus.query.compiler.SymbolTable)

Example 3 with Symbol

use of org.datanucleus.query.compiler.Symbol in project datanucleus-core by datanucleus.

the class Query method checkParameterTypesAgainstCompilation.

/**
 * Method to do checks of the input parameters with respect to their types being consistent
 * with the types of the parameters in the compilation.
 * Checks for unused input parameters. Doesn't check for missing parameters.
 * @param parameterValues The input parameter values keyed by their name (or position)
 */
protected void checkParameterTypesAgainstCompilation(Map parameterValues) {
    if (compilation == null) {
        return;
    } else if (parameterValues == null || parameterValues.isEmpty()) {
        return;
    }
    // Check for unused parameters
    boolean checkUnusedParams = checkUnusedParameters();
    Iterator it = parameterValues.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry entry = (Map.Entry) it.next();
        Object paramKey = entry.getKey();
        Symbol sym = null;
        // Find the symbol for the parameter in the compilation (or subquery compilations)
        sym = deepFindSymbolForParameterInCompilation(compilation, paramKey);
        if (sym != null) {
            Class expectedValueType = sym.getValueType();
            if (entry.getValue() != null && expectedValueType != null && !QueryUtils.queryParameterTypesAreCompatible(expectedValueType, entry.getValue().getClass())) {
                // Supplied parameter value is of inconsistent type
                throw new NucleusUserException("Parameter \"" + paramKey + "\" was specified as " + entry.getValue().getClass().getName() + " but should have been " + expectedValueType.getName());
            }
        } else // TODO Also do this for positional params if not found ?
        if (paramKey instanceof String) {
            if ((fromInclParam == null && toExclParam == null) || (!paramKey.equals(fromInclParam) && !paramKey.equals(toExclParam))) {
                if (checkUnusedParams) {
                    throw new QueryInvalidParametersException(Localiser.msg("021116", paramKey));
                }
            }
        }
    }
}
Also used : Symbol(org.datanucleus.query.compiler.Symbol) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Iterator(java.util.Iterator) HashMap(java.util.HashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 4 with Symbol

use of org.datanucleus.query.compiler.Symbol in project datanucleus-core by datanucleus.

the class DyadicExpression method bind.

/**
 * Method to bind the expression to the symbol table as appropriate.
 * @param symtbl Symbol table
 * @return The symbol for this expression
 */
public Symbol bind(SymbolTable symtbl) {
    if (left != null) {
        try {
            left.bind(symtbl);
        } catch (PrimaryExpressionIsClassLiteralException peil) {
            // PrimaryExpression should be swapped for a class Literal
            left = peil.getLiteral();
            left.bind(symtbl);
        } catch (PrimaryExpressionIsClassStaticFieldException peil) {
            // PrimaryExpression should be swapped for a static field Literal
            Field fld = peil.getLiteralField();
            try {
                // Get the value of the static field
                Object value = fld.get(null);
                left = new Literal(value);
                left.bind(symtbl);
            } catch (Exception e) {
                throw new NucleusUserException("Error processing static field " + fld.getName(), e);
            }
        } catch (PrimaryExpressionIsVariableException pive) {
            // PrimaryExpression should be swapped for a VariableExpression
            left = pive.getVariableExpression();
            left.bind(symtbl);
        } catch (PrimaryExpressionIsInvokeException piie) {
            // PrimaryExpression should be swapped for a InvokeExpression
            left = piie.getInvokeExpression();
            left.bind(symtbl);
        }
    }
    if (right != null) {
        try {
            right.bind(symtbl);
        } catch (PrimaryExpressionIsClassLiteralException peil) {
            // PrimaryExpression should be swapped for a class Literal
            right = peil.getLiteral();
            right.bind(symtbl);
        } catch (PrimaryExpressionIsClassStaticFieldException peil) {
            // PrimaryExpression should be swapped for a static field Literal
            Field fld = peil.getLiteralField();
            try {
                // Get the value of the static field
                Object value = fld.get(null);
                right = new Literal(value);
                right.bind(symtbl);
            } catch (Exception e) {
                throw new NucleusUserException("Error processing static field " + fld.getName(), e);
            }
        } catch (PrimaryExpressionIsVariableException pive) {
            // PrimaryExpression should be swapped for a VariableExpression
            right = pive.getVariableExpression();
            right.bind(symtbl);
        } catch (PrimaryExpressionIsInvokeException piie) {
            // PrimaryExpression should be swapped for a InvokeExpression
            right = piie.getInvokeExpression();
            right.bind(symtbl);
        }
    }
    if (left != null && left instanceof VariableExpression) {
        Symbol leftSym = left.getSymbol();
        if (leftSym != null && leftSym.getValueType() == null) {
            // Set type of implicit variable
            if (right instanceof Literal && ((Literal) right).getLiteral() != null) {
                leftSym.setValueType(((Literal) right).getLiteral().getClass());
            }
        }
    }
    if (right != null) {
        Symbol rightSym = right.getSymbol();
        if (rightSym != null && rightSym.getValueType() == null) {
            // Set type of implicit variable
            if (left instanceof Literal && ((Literal) left).getLiteral() != null) {
                rightSym.setValueType(((Literal) left).getLiteral().getClass());
            }
        }
    }
    // Interpret types of parameters etc when used in comparison operator
    if (op == Expression.OP_EQ || op == Expression.OP_NOTEQ || op == Expression.OP_GT || op == Expression.OP_GTEQ || op == Expression.OP_LT || op == Expression.OP_LTEQ) {
        Class leftType = (left != null && left.getSymbol() != null) ? left.getSymbol().getValueType() : null;
        Class rightType = (right != null && right.getSymbol() != null) ? right.getSymbol().getValueType() : null;
        if (left instanceof ParameterExpression && leftType == null && rightType != null) {
            // parameter {op} primary
            left.getSymbol().setValueType(rightType);
        } else if (right instanceof ParameterExpression && rightType == null && leftType != null) {
            // primary {op} parameter
            right.getSymbol().setValueType(leftType);
        }
        leftType = (left != null && left.getSymbol() != null) ? left.getSymbol().getValueType() : null;
        rightType = (right != null && right.getSymbol() != null) ? right.getSymbol().getValueType() : null;
    }
    return null;
}
Also used : NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Symbol(org.datanucleus.query.compiler.Symbol) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) Field(java.lang.reflect.Field)

Example 5 with Symbol

use of org.datanucleus.query.compiler.Symbol in project datanucleus-core by datanucleus.

the class ExpressionCompiler method compilePrimaryExpression.

private Expression compilePrimaryExpression(Node node) {
    if (node.getNodeType() == NodeType.PRIMARY) {
        Node currentNode = node.getFirstChild();
        Node invokeNode = node.getNextChild();
        if (invokeNode.getNodeType() != NodeType.INVOKE) {
            // TODO Support more combinations
            throw new QueryCompilerSyntaxException("Dont support compilation of " + node);
        }
        Expression currentExpr = compileExpression(currentNode);
        String methodName = (String) invokeNode.getNodeValue();
        List<Expression> parameterExprs = getExpressionsForPropertiesOfNode(invokeNode);
        Expression invokeExpr = new InvokeExpression(currentExpr, methodName, parameterExprs);
        return invokeExpr;
    } else if (node.getNodeType() == NodeType.IDENTIFIER) {
        Node currentNode = node;
        List tupple = new ArrayList();
        Expression currentExpr = null;
        while (currentNode != null) {
            tupple.add(currentNode.getNodeValue());
            if (currentNode.getNodeType() == NodeType.INVOKE) {
                if (currentExpr == null && tupple.size() > 1) {
                    // Check for starting with parameter/variable
                    String first = (String) tupple.get(0);
                    Symbol firstSym = symtbl.getSymbol(first);
                    if (firstSym != null) {
                        if (firstSym.getType() == Symbol.PARAMETER) {
                            currentExpr = new ParameterExpression(first, -1);
                            if (tupple.size() > 2) {
                                currentExpr = new PrimaryExpression(currentExpr, tupple.subList(1, tupple.size() - 1));
                            }
                        } else if (firstSym.getType() == Symbol.VARIABLE) {
                            currentExpr = new VariableExpression(first);
                            if (tupple.size() > 2) {
                                currentExpr = new PrimaryExpression(currentExpr, tupple.subList(1, tupple.size() - 1));
                            }
                        }
                    }
                    if (currentExpr == null) {
                        currentExpr = new PrimaryExpression(tupple.subList(0, tupple.size() - 1));
                    }
                } else if (currentExpr != null && tupple.size() > 1) {
                    currentExpr = new PrimaryExpression(currentExpr, tupple.subList(0, tupple.size() - 1));
                }
                String methodName = (String) tupple.get(tupple.size() - 1);
                if (currentExpr instanceof PrimaryExpression) {
                    // Check if this is a defined method prefix, and if so use the alias
                    String id = ((PrimaryExpression) currentExpr).getId();
                    if (aliasByPrefix != null && aliasByPrefix.containsKey(id)) {
                        String alias = aliasByPrefix.get(id);
                        methodName = alias + "." + methodName;
                        currentExpr = null;
                    }
                }
                List<Expression> parameterExprs = getExpressionsForPropertiesOfNode(currentNode);
                currentExpr = new InvokeExpression(currentExpr, methodName, parameterExprs);
                currentNode = currentNode.getFirstChild();
                tupple = new ArrayList();
            } else if (currentNode.getNodeType() == NodeType.CAST) {
                if (currentExpr == null && tupple.size() > 1) {
                    // Start from PrimaryExpression and invoke on that
                    currentExpr = new PrimaryExpression(tupple.subList(0, tupple.size() - 1));
                    PrimaryExpression primExpr = (PrimaryExpression) currentExpr;
                    if (primExpr.tuples.size() == 1) {
                        Symbol sym = symtbl.getSymbol(primExpr.getId());
                        if (sym != null) {
                            if (sym.getType() == Symbol.PARAMETER) {
                                // Parameter symbol registered for this identifier so use ParameterExpression
                                currentExpr = new ParameterExpression(primExpr.getId(), -1);
                            } else if (sym.getType() == Symbol.VARIABLE) {
                                // Variable symbol registered for this identifier so use VariableExpression
                                currentExpr = new VariableExpression(primExpr.getId());
                            }
                        }
                    }
                }
                String className = (String) tupple.get(tupple.size() - 1);
                currentExpr = new DyadicExpression(currentExpr, Expression.OP_CAST, new Literal(className));
                currentNode = currentNode.getFirstChild();
                tupple = new ArrayList();
            } else {
                // Part of identifier chain
                currentNode = currentNode.getFirstChild();
            }
        }
        if (currentExpr != null && !tupple.isEmpty()) {
            // We have a trailing identifier expression e.g "((B)a).c" where we have a CastExpression and trailing "c"
            currentExpr = new PrimaryExpression(currentExpr, tupple);
        }
        if (currentExpr == null) {
            // Find type of first of tupples
            String first = (String) tupple.get(0);
            Symbol firstSym = symtbl.getSymbol(first);
            if (firstSym != null) {
                // TODO If the user has a field in the candidate the same name as a parameter and they just put the name (rather than "this.{name}") then it interprets as parameter
                if (firstSym.getType() == Symbol.PARAMETER) {
                    ParameterExpression paramExpr = new ParameterExpression(first, -1);
                    if (tupple.size() > 1) {
                        currentExpr = new PrimaryExpression(paramExpr, tupple.subList(1, tupple.size()));
                    } else {
                        currentExpr = paramExpr;
                    }
                } else if (firstSym.getType() == Symbol.VARIABLE) {
                    VariableExpression varExpr = new VariableExpression(first);
                    if (tupple.size() > 1) {
                        currentExpr = new PrimaryExpression(varExpr, tupple.subList(1, tupple.size()));
                    } else {
                        currentExpr = varExpr;
                    }
                } else {
                    currentExpr = new PrimaryExpression(tupple);
                }
            } else {
                currentExpr = new PrimaryExpression(tupple);
            }
        }
        return currentExpr;
    } else if (node.getNodeType() == NodeType.PARAMETER) {
        // "{paramExpr}", "{paramExpr}.invoke(...)", "{paramExpr}.invoke(...).invoke(...)"
        Object val = node.getNodeValue();
        Expression currentExpr = null;
        if (val instanceof Integer) {
            // Positional parameter TODO Store as Integer to avoid confusion
            currentExpr = new ParameterExpression("" + node.getNodeValue(), ((ParameterNode) node).getPosition());
        } else {
            // Named parameter
            currentExpr = new ParameterExpression((String) node.getNodeValue(), ((ParameterNode) node).getPosition());
        }
        Node childNode = node.getFirstChild();
        while (childNode != null) {
            if (childNode.getNodeType() == NodeType.INVOKE) {
                String methodName = (String) childNode.getNodeValue();
                List<Expression> parameterExprs = getExpressionsForPropertiesOfNode(childNode);
                currentExpr = new InvokeExpression(currentExpr, methodName, parameterExprs);
            } else if (childNode.getNodeType() == NodeType.IDENTIFIER) {
                String identifier = childNode.getNodeId();
                List tuples = new ArrayList();
                tuples.add(identifier);
                boolean moreIdentifierNodes = true;
                while (moreIdentifierNodes) {
                    Node currentNode = childNode;
                    childNode = childNode.getFirstChild();
                    if (childNode == null || childNode.getNodeType() != NodeType.IDENTIFIER) {
                        moreIdentifierNodes = false;
                        childNode = currentNode;
                    } else {
                        // Add as a component of the primary
                        tuples.add(childNode.getNodeId());
                    }
                }
                currentExpr = new PrimaryExpression(currentExpr, tuples);
            } else {
                throw new QueryCompilerSyntaxException("Dont support compilation of " + node);
            }
            childNode = childNode.getFirstChild();
        }
        return currentExpr;
    } else if (node.getNodeType() == NodeType.INVOKE) {
        Node currentNode = node;
        List tupple = new ArrayList();
        Expression currentExpr = null;
        while (currentNode != null) {
            tupple.add(currentNode.getNodeValue());
            if (currentNode.getNodeType() == NodeType.INVOKE) {
                String methodName = (String) tupple.get(tupple.size() - 1);
                List<Expression> parameterExprs = getExpressionsForPropertiesOfNode(currentNode);
                currentExpr = new InvokeExpression(currentExpr, methodName, parameterExprs);
                currentNode = currentNode.getFirstChild();
                if (currentNode != null) {
                    // Continue on along the chain
                    tupple = new ArrayList();
                    // Start from this expression
                    tupple.add(currentExpr);
                }
            } else {
                // TODO What node type is this that comes after an INVOKE?
                currentNode = currentNode.getFirstChild();
            }
        }
        return currentExpr;
    } else if (node.getNodeType() == NodeType.CREATOR) {
        Node currentNode = node.getFirstChild();
        List tupple = new ArrayList();
        boolean method = false;
        while (currentNode != null) {
            tupple.add(currentNode.getNodeValue());
            if (currentNode.getNodeType() == NodeType.INVOKE) {
                method = true;
                break;
            }
            currentNode = currentNode.getFirstChild();
        }
        List<Expression> parameterExprs = null;
        if (method) {
            parameterExprs = getExpressionsForPropertiesOfNode(currentNode);
        } else {
            parameterExprs = new ArrayList();
        }
        return new CreatorExpression(tupple, parameterExprs);
    } else if (node.getNodeType() == NodeType.LITERAL) {
        Node currentNode = node;
        List tupple = new ArrayList();
        Expression currentExpr = null;
        while (currentNode != null) {
            tupple.add(currentNode.getNodeValue());
            if (currentNode.getNodeType() == NodeType.INVOKE) {
                if (currentExpr == null && tupple.size() > 1) {
                    // Start from Literal and invoke on that
                    currentExpr = new Literal(node.getNodeValue());
                }
                String methodName = (String) tupple.get(tupple.size() - 1);
                List<Expression> parameterExprs = getExpressionsForPropertiesOfNode(currentNode);
                currentExpr = new InvokeExpression(currentExpr, methodName, parameterExprs);
                currentNode = currentNode.getFirstChild();
                tupple = new ArrayList();
            } else {
                currentNode = currentNode.getFirstChild();
            }
        }
        if (currentExpr == null) {
            currentExpr = new Literal(node.getNodeValue());
        }
        return currentExpr;
    } else if (node.getNodeType() == NodeType.ARRAY) {
        Node currentNode = node;
        List<Node> arrayElements = (List<Node>) node.getNodeValue();
        // Check if this is an array literal
        boolean literal = true;
        Class type = null;
        Iterator<Node> iter = arrayElements.iterator();
        while (iter.hasNext()) {
            Node element = iter.next();
            if (type == null) {
                type = element.getNodeValue().getClass();
            }
            if (element.getNodeType() == NodeType.IDENTIFIER) {
                literal = false;
                break;
            }
        }
        Expression currentExpr = null;
        if (literal) {
            Object array = Array.newInstance(type, arrayElements.size());
            iter = arrayElements.iterator();
            int index = 0;
            while (iter.hasNext()) {
                Node element = iter.next();
                Array.set(array, index++, element.getNodeValue());
            }
            currentExpr = new Literal(array);
        } else {
            Expression[] arrayElementExprs = new Expression[arrayElements.size()];
            for (int i = 0; i < arrayElementExprs.length; i++) {
                arrayElementExprs[i] = compilePrimaryExpression(arrayElements.get(i));
            }
            currentExpr = new ArrayExpression(arrayElementExprs);
        }
        currentNode = currentNode.getFirstChild();
        List tupple = new ArrayList();
        while (currentNode != null) {
            tupple.add(currentNode.getNodeValue());
            if (currentNode.getNodeType() == NodeType.INVOKE) {
                if (tupple.size() > 1) {
                    // Start from Literal and invoke on that
                    currentExpr = new Literal(node.getNodeValue());
                }
                String methodName = (String) tupple.get(tupple.size() - 1);
                List<Expression> parameterExprs = getExpressionsForPropertiesOfNode(currentNode);
                currentExpr = new InvokeExpression(currentExpr, methodName, parameterExprs);
                currentNode = currentNode.getFirstChild();
                tupple = new ArrayList();
            } else {
                currentNode = currentNode.getFirstChild();
            }
        }
        return currentExpr;
    } else if (node.getNodeType() == NodeType.SUBQUERY) {
        List children = node.getChildNodes();
        if (children.size() != 1) {
            throw new QueryCompilerSyntaxException("Invalid number of children for SUBQUERY node : " + node);
        }
        Node varNode = (Node) children.get(0);
        VariableExpression subqueryExpr = new VariableExpression(varNode.getNodeId());
        Expression currentExpr = new SubqueryExpression((String) node.getNodeValue(), subqueryExpr);
        return currentExpr;
    } else if (node.getNodeType() == NodeType.CASE) {
        // Node with children in the order "when", "action"[, "when", "action"], "else"
        List<Node> children = node.getChildNodes();
        if ((children.size() % 2) == 0) {
            throw new QueryCompilerSyntaxException("Invalid number of children for CASE node (should be odd). Have you omitted the ELSE clause? : " + node);
        }
        Node elseNode = children.get(children.size() - 1);
        Expression elseExpr = compileExpression(elseNode);
        CaseExpression caseExpr = new CaseExpression();
        Iterator<Node> childIter = children.iterator();
        while (childIter.hasNext()) {
            Node whenNode = childIter.next();
            if (childIter.hasNext()) {
                Node actionNode = childIter.next();
                Expression whenExpr = compileExpression(whenNode);
                Expression actionExpr = compileExpression(actionNode);
                caseExpr.addCondition(whenExpr, actionExpr);
            }
        }
        caseExpr.setElseExpression(elseExpr);
        return caseExpr;
    } else if (node.getNodeType() == NodeType.TYPE) {
        List<Node> children = node.getChildNodes();
        Expression containedExpr = compileExpression(children.get(0));
        TypeExpression typeExpr = new TypeExpression(containedExpr);
        return typeExpr;
    } else {
        NucleusLogger.QUERY.warn("ExpressionCompiler.compilePrimaryExpression node=" + node + " ignored by ExpressionCompiler since not of a supported type");
    }
    return null;
}
Also used : Symbol(org.datanucleus.query.compiler.Symbol) Node(org.datanucleus.query.compiler.Node) ParameterNode(org.datanucleus.query.compiler.ParameterNode) ArrayList(java.util.ArrayList) ParameterNode(org.datanucleus.query.compiler.ParameterNode) QueryCompilerSyntaxException(org.datanucleus.store.query.QueryCompilerSyntaxException) ArrayList(java.util.ArrayList) List(java.util.List)

Aggregations

Symbol (org.datanucleus.query.compiler.Symbol)12 HashMap (java.util.HashMap)5 QueryCompilation (org.datanucleus.query.compiler.QueryCompilation)4 SymbolTable (org.datanucleus.query.compiler.SymbolTable)4 ParameterExpression (org.datanucleus.query.expression.ParameterExpression)4 NucleusException (org.datanucleus.exceptions.NucleusException)3 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)3 JavaQueryCompiler (org.datanucleus.query.compiler.JavaQueryCompiler)3 DyadicExpression (org.datanucleus.query.expression.DyadicExpression)3 Expression (org.datanucleus.query.expression.Expression)3 InvokeExpression (org.datanucleus.query.expression.InvokeExpression)3 PrimaryExpression (org.datanucleus.query.expression.PrimaryExpression)3 VariableExpression (org.datanucleus.query.expression.VariableExpression)3 Field (java.lang.reflect.Field)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 JDOQLCompiler (org.datanucleus.query.compiler.JDOQLCompiler)2 Literal (org.datanucleus.query.expression.Literal)2 OrderExpression (org.datanucleus.query.expression.OrderExpression)2 Inventory (org.datanucleus.samples.store.Inventory)2 Product (org.datanucleus.samples.store.Product)2