openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fa...@apache.org
Subject svn commit: r725881 - in /openjpa/trunk: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/ openjpa-persistence-jdbc/...
Date Fri, 12 Dec 2008 01:29:20 GMT
Author: fancy
Date: Thu Dec 11 17:29:19 2008
New Revision: 725881

URL: http://svn.apache.org/viewvc?rev=725881&view=rev
Log:
OPENJPA-805 JPQL iteration 1 - add support for COALESCE and NULLIF expressions

Added:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/CoalesceExpression.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NullIfExpression.java
Modified:
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
    openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
    openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
    openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java

Added: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/CoalesceExpression.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/CoalesceExpression.java?rev=725881&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/CoalesceExpression.java
(added)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/CoalesceExpression.java
Thu Dec 11 17:29:19 2008
@@ -0,0 +1,175 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.sql.Joins;
+import org.apache.openjpa.jdbc.sql.Raw;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.kernel.exps.ExpressionVisitor;
+import org.apache.openjpa.meta.ClassMetaData;
+
+/**
+ * Coalesce expression.
+ *
+ * @author Catalina Wei
+ */
+public class CoalesceExpression
+    extends AbstractVal {
+
+    private final Val[] _vals;
+    private ClassMetaData _meta = null;
+    private Class _cast = null;
+
+    /**
+     * Constructor.
+     */
+    public CoalesceExpression(Val[] vals) {
+        _vals = vals;
+    }
+
+    public Val[] getVal() {
+        return _vals;
+    }
+
+    public Class getType() {
+        if (_cast != null)
+            return _cast;
+        Class type = _vals[0].getType();
+        for (int i = 1; i < _vals.length; i++)
+            type = Filters.promote(type, _vals[i].getType());
+        if (type == Raw.class)
+            return String.class;
+        return type;
+    }
+
+    public ExpState initialize(Select sel, ExpContext ctx, int flags) {
+        ExpState[] states = new ExpState[_vals.length];
+        Joins joins = null;
+        for (int i = 0; i < _vals.length; i++) {
+            states[i] = _vals[i].initialize(sel, ctx, flags);
+            if (joins == null)
+                joins = states[i].joins;
+            else
+                joins = sel.and(joins, states[i].joins);
+        }
+        return new CoalesceExpState(joins, states);
+    }
+
+    private static class CoalesceExpState
+        extends ExpState {
+        
+        public ExpState[] states;
+        
+        public CoalesceExpState(Joins joins, ExpState[] states) {
+            super(joins);
+            this.states = states;
+        }
+    }
+
+    public void appendTo(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer buf, int index) {
+        CoalesceExpState cstate = (CoalesceExpState) state;
+        
+        buf.append(" COALESCE ");
+        buf.append("(");
+
+        for (int i = 0; i < _vals.length; i++) {
+            if (i > 0)
+                buf.append(",");
+            _vals[i].appendTo(sel, ctx, cstate.states[i], buf, 0);
+        }
+
+        buf.append(")");
+    }
+
+    public void selectColumns(Select sel, ExpContext ctx, ExpState state, 
+        boolean pks) {
+        CoalesceExpState cstate = (CoalesceExpState) state;
+
+        for (int i = 0; i < _vals.length; i++)
+            _vals[i].selectColumns(sel, ctx, cstate.states[i], pks);
+    }
+
+    public void acceptVisit(ExpressionVisitor visitor) {
+        visitor.enter(this);
+        for (int i = 0; i < _vals.length; i++)
+            _vals[i].acceptVisit(visitor);
+        visitor.exit(this);
+    }
+
+    public int getId() {
+        return Val.COALESCE_VAL;
+    }
+
+    public void calculateValue(Select sel, ExpContext ctx, ExpState state,
+        Val other, ExpState otherState) {
+        CoalesceExpState cstate = (CoalesceExpState) state;
+        for (int i = 0; i < _vals.length; i++)   
+            _vals[i].calculateValue(sel, ctx, cstate.states[i], null, null);
+    }
+
+    public void groupBy(Select sel, ExpContext ctx, ExpState state) {
+        sel.groupBy(newSQLBuffer(sel, ctx, state));
+    }
+
+    public int length(Select sel, ExpContext ctx, ExpState state) {
+        return 1;
+    }
+
+    private SQLBuffer newSQLBuffer(Select sel, ExpContext ctx, ExpState state) {
+        calculateValue(sel, ctx, state, null, null);
+        SQLBuffer buf = new SQLBuffer(ctx.store.getDBDictionary());
+        appendTo(sel, ctx, state, buf, 0);
+        return buf;
+    }
+
+    public Object load(ExpContext ctx, ExpState state, Result res)
+        throws SQLException {
+        return Filters.convert(res.getObject(this,
+            JavaSQLTypes.JDBC_DEFAULT, null), getType());
+    }
+
+    public void orderBy(Select sel, ExpContext ctx, ExpState state,
+        boolean asc) {
+        sel.orderBy(newSQLBuffer(sel, ctx, state), asc, false, getSelectAs());
+    }
+
+    public void select(Select sel, ExpContext ctx, ExpState state, boolean pks){
+        sel.select(newSQLBuffer(sel, ctx, state), this);
+    }
+
+    public ClassMetaData getMetaData() {
+        return _meta;
+    }
+
+    public void setImplicitType(Class type) {
+        _cast = type;        
+    }
+
+    public void setMetaData(ClassMetaData meta) {
+        _meta = meta;
+    }
+}
+

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java?rev=725881&r1=725880&r2=725881&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
(original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java
Thu Dec 11 17:29:19 2008
@@ -447,4 +447,37 @@
         }
         return new WhenScalar((Val) val1, (Val) val2);
     }
+
+    public Value coalesceExpression(Value[] vals) {;
+        Object[] values = new Val[vals.length];
+        for (int i = 0; i < vals.length; i++) {
+            if (vals[i] instanceof Lit) {
+                Lit val = (Lit) vals[i];
+                StringBuffer value = new StringBuffer(val.getValue().toString());
+                if (val.getParseType() == Literal.TYPE_SQ_STRING)
+                    value.insert(0, "'").append("'");
+                val.setValue(new Raw(value.toString()));
+            }
+            values[i] = vals[i];
+        }
+        return new CoalesceExpression((Val[]) values);
+    }
+
+    public Value nullIfExpression(Value val1, Value val2) {
+        if (val1 instanceof Lit) {
+            Lit val = (Lit) val1;
+            StringBuffer value = new StringBuffer(val.getValue().toString());
+            if (val.getParseType() == Literal.TYPE_SQ_STRING)
+                value.insert(0, "'").append("'");
+            val.setValue(new Raw(value.toString()));
+        }
+        if (val2 instanceof Lit) {
+            Lit val = (Lit) val2;
+            StringBuffer value = new StringBuffer(val.getValue().toString());
+            if (val.getParseType() == Literal.TYPE_SQ_STRING)
+                value.insert(0, "'").append("'");
+            val.setValue(new Raw(value.toString()));
+        }
+        return new NullIfExpression((Val) val1, (Val) val2);
+    }
 }

Added: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NullIfExpression.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NullIfExpression.java?rev=725881&view=auto
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NullIfExpression.java
(added)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NullIfExpression.java
Thu Dec 11 17:29:19 2008
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+package org.apache.openjpa.jdbc.kernel.exps;
+
+import java.sql.SQLException;
+
+import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
+import org.apache.openjpa.jdbc.sql.Raw;
+import org.apache.openjpa.jdbc.sql.Result;
+import org.apache.openjpa.jdbc.sql.SQLBuffer;
+import org.apache.openjpa.jdbc.sql.Select;
+import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.kernel.exps.ExpressionVisitor;
+import org.apache.openjpa.meta.ClassMetaData;
+
+/**
+ * NullIf expression.
+ *
+ * @author Catalina Wei
+ */
+public class NullIfExpression
+    extends AbstractVal {
+
+    private final Val _val1;
+    private final Val _val2;
+    private ClassMetaData _meta = null;
+    private Class _cast = null;
+
+    /**
+     * Constructor.
+     */
+    public NullIfExpression(Val val1, Val val2) {
+        _val1 = val1;
+        _val2 = val2;
+    }
+
+    public Val getVal1() {
+        return _val1;
+    }
+
+    public Val getVal2() {
+        return _val2;
+    }
+
+    public Class getType() {
+        if (_cast != null)
+            return _cast;
+        Class c1 = _val1.getType();
+        Class c2 = _val2.getType();
+        Class type = Filters.promote(c1, c2);
+        if (type == Raw.class)
+            return String.class;
+        return type;
+    }
+
+    public ExpState initialize(Select sel, ExpContext ctx, int flags) {
+        ExpState s1 = _val1.initialize(sel, ctx, 0);
+        ExpState s2 = _val2.initialize(sel, ctx, 0);
+        return new BinaryOpExpState(sel.and(s1.joins, s2.joins), s1, s2);
+    }
+
+    public void appendTo(Select sel, ExpContext ctx, ExpState state, 
+        SQLBuffer buf, int index) {
+        BinaryOpExpState bstate = (BinaryOpExpState) state;
+        
+        buf.append(" NULLIF ");
+        buf.append("(");
+
+        _val1.appendTo(sel, ctx, bstate.state1, buf, 0);
+        buf.append(",");
+        _val2.appendTo(sel, ctx, bstate.state2, buf, 0);
+
+        buf.append(")");
+    }
+
+    public void selectColumns(Select sel, ExpContext ctx, ExpState state, 
+        boolean pks) {
+        BinaryOpExpState bstate = (BinaryOpExpState) state;
+        _val1.selectColumns(sel, ctx, bstate.state1, true);
+        _val2.selectColumns(sel, ctx, bstate.state2, true);
+    }
+
+    public void acceptVisit(ExpressionVisitor visitor) {
+        visitor.enter(this);
+        _val1.acceptVisit(visitor);
+        _val2.acceptVisit(visitor);
+        visitor.exit(this);
+    }
+
+    public int getId() {
+        return Val.NULLIF_VAL;
+    }
+
+    public void calculateValue(Select sel, ExpContext ctx, ExpState state,
+        Val other, ExpState otherState) {
+        BinaryOpExpState bstate = (BinaryOpExpState) state;
+        _val1.calculateValue(sel, ctx, bstate.state1, _val2, bstate.state2);
+        _val2.calculateValue(sel, ctx, bstate.state2, _val1, bstate.state1);
+    }
+
+    public void groupBy(Select sel, ExpContext ctx, ExpState state) {
+        sel.groupBy(newSQLBuffer(sel, ctx, state));
+    }
+
+    public int length(Select sel, ExpContext ctx, ExpState state) {
+        return 1;
+    }
+
+    private SQLBuffer newSQLBuffer(Select sel, ExpContext ctx, ExpState state) {
+        calculateValue(sel, ctx, state, null, null);
+        SQLBuffer buf = new SQLBuffer(ctx.store.getDBDictionary());
+        appendTo(sel, ctx, state, buf, 0);
+        return buf;
+    }
+
+    public Object load(ExpContext ctx, ExpState state, Result res)
+        throws SQLException {
+        return Filters.convert(res.getObject(this,
+            JavaSQLTypes.JDBC_DEFAULT, null), getType());
+    }
+
+    public void orderBy(Select sel, ExpContext ctx, ExpState state,
+        boolean asc) {
+        sel.orderBy(newSQLBuffer(sel, ctx, state), asc, false, getSelectAs());
+    }
+
+    public void select(Select sel, ExpContext ctx, ExpState state, boolean pks){
+        sel.select(newSQLBuffer(sel, ctx, state), this);
+    }
+
+    public ClassMetaData getMetaData() {
+        return _meta;
+    }
+
+    public void setImplicitType(Class type) {
+        _cast = type;        
+    }
+
+    public void setMetaData(ClassMetaData meta) {
+        _meta = meta;
+    }
+}
+

Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java?rev=725881&r1=725880&r2=725881&view=diff
==============================================================================
--- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
(original)
+++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Val.java
Thu Dec 11 17:29:19 2008
@@ -68,6 +68,8 @@
     public final int GENERALCASE_VAL = 14;
     public final int WHENCONDITION_VAL = 15;
     public final int WHENSCALAR_VAL = 16;
+    public final int COALESCE_VAL = 17;
+    public final int NULLIF_VAL = 18;
 
     /**
      * Initialize the value. This method should recursively initialize any

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java?rev=725881&r1=725880&r2=725881&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/ExpressionFactory.java
Thu Dec 11 17:29:19 2008
@@ -428,4 +428,14 @@
      * Return a when scalar_expression clause
      */
     public Expression whenScalar(Value val1, Value val2);
+
+    /**
+     * Return a coalesce expression
+     */
+    public Value coalesceExpression(Value[] val);
+
+    /**
+     * Return a nullif expression
+     */
+    public Value nullIfExpression(Value val1, Value val2);
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java?rev=725881&r1=725880&r2=725881&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/InMemoryExpressionFactory.java
Thu Dec 11 17:29:19 2008
@@ -745,4 +745,14 @@
         // TODO Auto-generated method stub
         return null;
     }
+
+    public Value coalesceExpression(Value[] val) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    public Value nullIfExpression(Value val1, Value val2) {
+        // TODO Auto-generated method stub
+        return null;
+    }
 }

Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java?rev=725881&r1=725880&r2=725881&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
(original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
Thu Dec 11 17:29:19 2008
@@ -766,6 +766,12 @@
             case JJTWHENSCALAR:
                 return getWhenScalar(node);
 
+            case JJTCOALESCE:
+                return getCoalesceExpression(node);
+
+            case JJTNULLIF:
+                return getNullIfExpression(node);
+
             case JJTWHERE: // top-level WHERE clause
                 return getExpression(onlyChild(node));
 
@@ -1502,6 +1508,23 @@
         return factory.whenScalar((Value) val1, (Value) val2);
     }
 
+    private Value getCoalesceExpression(JPQLNode node) {
+        int nChild = node.getChildCount();
+        
+        Object vals[] = new Value[nChild];
+        for (int i = 0; i < nChild; i++)
+            vals[i] = eval(node.children[i]);
+        
+        return factory.coalesceExpression((Value[]) vals);
+    }
+
+    private Value getNullIfExpression(JPQLNode node) {
+        Object val1 = eval(firstChild(node));
+        Object val2 = eval(secondChild(node));
+        
+        return factory.nullIfExpression((Value) val1, (Value) val2);
+    }
+
     private Value getValue(JPQLNode node) {
         return getValue(node, VAR_PATH);
     }

Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java?rev=725881&r1=725880&r2=725881&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java
(original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java
Thu Dec 11 17:29:19 2008
@@ -69,6 +69,40 @@
         endEm(em);
     }
 
+    public void testCoalesceExpressions() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+
+        String query = "SELECT e.name, " +
+            "COALESCE (e.address.country, 'Unknown')" +
+            " FROM CompUser e";
+        List rs = em.createQuery(query).getResultList();
+        Object[] result = (Object[]) rs.get(rs.size()-1);
+        assertEquals("the name is not shade", "Shade", result[0]);        
+        assertEquals("Unknown", result[1]);
+
+        endTx(em);
+        endEm(em);
+    }
+
+    public void testNullIfExpressions() {
+        EntityManager em = currentEntityManager();
+        startTx(em);
+
+        String query = "SELECT e.name, " +
+            "NULLIF (e.address.country, 'USA')" +
+            " FROM CompUser e";
+
+        List rs = em.createQuery(query).getResultList();
+        Object[] result = (Object[]) rs.get(1);
+        assertEquals("the name is not shannon ", "Shannon ", result[0]);        
+        assertNull("is not null", result[1]);
+        
+        endTx(em);
+        endEm(em);
+    }
+
     public void testSimpleCaseExpressions() {
         EntityManager em = currentEntityManager();
 



Mime
View raw message