private Node expressionNodeToSqlNode()

in cayenne/src/main/java/org/apache/cayenne/access/translator/select/QualifierTranslator.java [154:285]


    private Node expressionNodeToSqlNode(Expression node, Expression parentNode) {
        switch (node.getType()) {
            case NOT_IN:
                return new InNode(true);
            case IN:
                return new InNode(false);
            case NOT_BETWEEN:
            case BETWEEN:
                return new BetweenNode(node.getType() == NOT_BETWEEN);
            case NOT:
                return new NotNode();
            case BITWISE_NOT:
                return new BitwiseNotNode();
            case EQUAL_TO:
                return new EqualNode();
            case NOT_EQUAL_TO:
                return new NotEqualNode();

            case LIKE:
            case NOT_LIKE:
            case LIKE_IGNORE_CASE:
            case NOT_LIKE_IGNORE_CASE:
                PatternMatchNode patternMatchNode = (PatternMatchNode)node;
                boolean not = node.getType() == NOT_LIKE || node.getType() == NOT_LIKE_IGNORE_CASE;
                return new LikeNode(patternMatchNode.isIgnoringCase(), not, patternMatchNode.getEscapeChar());

            case OBJ_PATH:
                CayennePath path = (CayennePath)node.getOperand(0);
                PathTranslationResult result = pathTranslator.translatePath(context.getMetadata().getObjEntity(), path);
                return processPathTranslationResult(node, parentNode, result);

            case DB_PATH:
                CayennePath dbPath = (CayennePath)node.getOperand(0);
                PathTranslationResult dbResult = pathTranslator.translatePath(context.getMetadata().getDbEntity(), dbPath);
                return processPathTranslationResult(node, parentNode, dbResult);

            case DBID_PATH:
                CayennePath dbIdPath = (CayennePath)node.getOperand(0);
                PathTranslationResult dbIdResult = pathTranslator.translateIdPath(context.getMetadata().getObjEntity(), dbIdPath);
                return processPathTranslationResult(node, parentNode, dbIdResult);

            case FUNCTION_CALL:
                ASTFunctionCall functionCall = (ASTFunctionCall)node;
                return function(functionCall.getFunctionName()).build();

            case ADD:
            case SUBTRACT:
            case MULTIPLY:
            case DIVIDE:
            case BITWISE_AND:
            case BITWISE_LEFT_SHIFT:
            case BITWISE_OR:
            case BITWISE_RIGHT_SHIFT:
            case BITWISE_XOR:
            case OR:
            case AND:
            case LESS_THAN:
            case LESS_THAN_EQUAL_TO:
            case GREATER_THAN:
            case GREATER_THAN_EQUAL_TO:
                return new OpExpressionNode(expToStr(node.getType()));
            case NEGATIVE:
                // we need to add minus sign as a prefix, not a separator
                return new FunctionNode(expToStr(node.getType()), null, false);
            case TRUE:
            case FALSE:
            case ASTERISK:
                return new TextNode(' ' + expToStr(node.getType()));

            case CUSTOM_OP:
                return new OpExpressionNode(((ASTCustomOperator)node).getOperator());

            case EXISTS:
                return new FunctionNode("EXISTS", null, false);
            case NOT_EXISTS:
                return new FunctionNode("NOT EXISTS", null, false);
            case ALL:
                return new FunctionNode("ALL", null, false);
            case ANY:
                return new FunctionNode("ANY", null, false);

            case SUBQUERY:
                ASTSubquery subquery = (ASTSubquery)node;
                DefaultSelectTranslator translator = new DefaultSelectTranslator(subquery.getQuery(), context);
                translator.translate();
                return translator.getContext().getSelectBuilder().build();

            case ENCLOSING_OBJECT:
                // Translate via parent context's translator
                Expression expression = (Expression) node.getOperand(0);
                if(context.getParentContext() == null) {
                    throw new CayenneRuntimeException("Unable to translate qualifier, no parent context to use for expression " + node);
                }
                expressionsToSkip.add(expression);
                return context.getParentContext().getQualifierTranslator().translate(expression);

            case FULL_OBJECT:
                ASTFullObject fullObject = (ASTFullObject)node;
                if(fullObject.getOperandCount() == 0) {
                    Collection<DbAttribute> dbAttributes = context.getMetadata().getDbEntity().getPrimaryKeys();
                    if(dbAttributes.size() > 1) {
                        throw new CayenneRuntimeException("Unable to translate reference on entity with more than one PK.");
                    }
                    DbAttribute attribute = dbAttributes.iterator().next();
                    String alias = context.getTableTree().aliasForPath(CayennePath.EMPTY_PATH);
                    return table(alias).column(attribute).build();
                } else {
                    return null;
                }
            case SCALAR:
                if (parentNode != null){
                    throw new CayenneRuntimeException("Incorrect state, a node %s can't have parent here", node.getClass().getName());
                }
                Object scalarVal = ((ASTScalar) node).getValue();
                if (scalarVal instanceof Collection || scalarVal.getClass().isArray()) {
                    throw new CayenneRuntimeException("%s %s",ERR_MSG_ARRAYS_NOT_SUPPORTED, node.getClass().getName());
                } else {
                    objectNode(scalarVal, null);
                }
                return null;

            case CASE_WHEN:
                return new CaseNode();
            case WHEN:
                return new WhenNode();
            case THEN:
                return new ThenNode();
            case ELSE:
                return new ElseNode();
        }
        return null;
    }