This is an automated email from the ASF dual-hosted git repository.

doebele pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/empire-db.git


The following commit(s) were added to refs/heads/master by this push:
     new 66601c47 EMPIREDB-416 DBCaseExpr improvement
66601c47 is described below

commit 66601c470a9e0706997ca46418f8e22c3598b45d
Author: Rainer Döbele <[email protected]>
AuthorDate: Mon Mar 25 13:20:47 2024 +0100

    EMPIREDB-416
    DBCaseExpr improvement
---
 .../main/java/org/apache/empire/db/DBDatabase.java | 29 ++++---
 .../apache/empire/db/expr/column/DBCaseExpr.java   | 93 ++++++++++++----------
 .../empire/db/expr/column/DBCaseMapExpr.java       | 59 +++++++-------
 .../empire/db/expr/column/DBCaseWhenExpr.java      | 10 +--
 4 files changed, 106 insertions(+), 85 deletions(-)

diff --git a/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java 
b/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
index 99fdbc87..03fe8b77 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBDatabase.java
@@ -47,6 +47,7 @@ import org.apache.empire.db.exceptions.FieldNotNullException;
 import org.apache.empire.db.exceptions.FieldValueException;
 import org.apache.empire.db.exceptions.FieldValueOutOfRangeException;
 import org.apache.empire.db.exceptions.FieldValueTooLongException;
+import org.apache.empire.db.expr.column.DBCaseExpr;
 import org.apache.empire.db.expr.column.DBCaseMapExpr;
 import org.apache.empire.db.expr.column.DBCaseWhenExpr;
 import org.apache.empire.db.expr.column.DBValueExpr;
@@ -1170,7 +1171,7 @@ public abstract class DBDatabase extends DBObject
     }
     
     /**
-     * Creates a case column expression
+     * Creates a SQL case expression
      * in the form "case when [condition] then [trueValue] else [falseValue] 
end"
      * This is a helper function to simplify client usage
      * @param condition the compare expression
@@ -1178,7 +1179,7 @@ public abstract class DBDatabase extends DBObject
      * @param falseValue the value to select if the condition is false
      * @return the case expression
      */
-    public DBColumnExpr caseWhen(DBCompareExpr condition, Object trueValue, 
Object falseValue)
+    public DBCaseExpr caseWhen(DBCompareExpr condition, Object trueValue, 
Object falseValue)
     {
         DataType dataType = detectDataType((trueValue!=null ? trueValue : 
falseValue)); 
         DBColumnExpr trueExpr = ((trueValue instanceof DBColumnExpr) ? 
(DBColumnExpr)trueValue : this.getValueExpr(trueValue, dataType));
@@ -1186,18 +1187,19 @@ public abstract class DBDatabase extends DBObject
     }
     
     /**
-     * Creates a case column expression
+     * Creates a SQL case expression
+     * in the form "case when [mapKey] then [mapValue] else [elseValue] end"
      * @param whenMap the map with constraints
      * @param elseValue the else expression
      * @return the expression
      */
-    public DBColumnExpr caseWhen(Map<DBCompareExpr, ? extends Object> whenMap, 
Object elseValue)
+    public DBCaseExpr caseWhen(Map<DBCompareExpr, ? extends Object> whenMap, 
Object elseValue)
     {
         return new DBCaseWhenExpr(whenMap, elseValue);
     }
 
     /**
-     * Creates a case column expression that check whether a column or column 
expression is null
+     * Creates a SQL case expression that check whether a column or column 
expression is null
      * "case when [condition] is null then [trueValue] else [falseValue] end"
      * This is a helper function to simplify client usage
      * @param expr a column or column expression
@@ -1205,41 +1207,44 @@ public abstract class DBDatabase extends DBObject
      * @param falseValue the value to select if the condition is false
      * @return an sql case expression
      */
-    public DBColumnExpr caseWhenNull(DBColumnExpr column, Object trueValue, 
Object falseValue)
+    public DBCaseExpr caseWhenNull(DBColumnExpr column, Object trueValue, 
Object falseValue)
     {
         // return caseMap(column, null, trueValue, falseValue);
         return caseWhen(column.is(null), trueValue, falseValue);
     }
     
     /**
-     * Creates a case column expression
+     * Creates a SQL case expression
+     * in the form "case [Expr] when [mapKey] then [mapValue] else [elseValue] 
end"
      * @param valueMap map of key value pairs
      * @param elseValue the else expression
      * @return the expression
      */
-    public DBColumnExpr caseMap(DBColumnExpr column, Map< ? extends Object,  ? 
extends Object> valueMap, Object elseValue)
+    public DBCaseExpr caseMap(DBColumnExpr column, Map< ? extends Object,  ? 
extends Object> valueMap, Object elseValue)
     {
         return new DBCaseMapExpr(column, valueMap, elseValue);
     }
     
     /**
-     * Creates a case column expression
+     * Creates a SQL case expression
+     * in the form "case [Expr] when [optionValue] then [optionText] else 
[elseValue] end"
      * @param Options the options to map
      * @param elseValue the else expression
      * @return the expression
      */
-    public DBColumnExpr caseMap(DBColumnExpr column, Options options, Object 
elseValue)
+    public DBCaseExpr caseMap(DBColumnExpr column, Options options, Object 
elseValue)
     {
         return new DBCaseMapExpr(column, options.map(), elseValue);
     }
     
     /**
-     * Creates a case column expression
+     * Creates a SQL case expression
+     * in the form "case [Expr] when [compareValue] then [trueValue] else 
[elseValue] end"
      * @param whenMap the map with constraints
      * @param elseValue the else expression
      * @return the expression
      */
-    public DBColumnExpr caseMap(DBColumnExpr column, Object cmpValue, Object 
trueValue, Object falseValue)
+    public DBCaseExpr caseMap(DBColumnExpr column, Object cmpValue, Object 
trueValue, Object falseValue)
     {
         return new DBCaseMapExpr(column, cmpValue, trueValue, falseValue);
     }
diff --git 
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java 
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java
index 2d2b3f23..6da77e29 100644
--- a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java
+++ b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseExpr.java
@@ -18,6 +18,7 @@
  */
 package org.apache.empire.db.expr.column;
 
+import java.util.Collection;
 import java.util.Map;
 
 import org.apache.empire.data.DataType;
@@ -128,62 +129,74 @@ public abstract class DBCaseExpr extends DBColumnExpr
     /**
      * Init case expression. 
      * Must be called from all constructors!
-     * @param caseColumn the case expression column (if any)
+     * @param caseExpr the case expr (if any)
      * @param valueMap the value or conditions map
      * @param elseValue the else value
      */
-    protected void init(DBColumn caseColumn, Map<?,?> valueMap, Object 
elseValue)
+    protected void init(DBColumnExpr caseExpr, Map<?,?> valueMap, Object 
elseValue)
     {
         /*
-         * Important: caseColumn is not the sourceColumn
+         * Important: caseExpr is not the sourceColumn
          * sourceColumn must be set from target values!
          */
-        this.database = (caseColumn!=null ? caseColumn.getDatabase() : null);
+        if (caseExpr!=null)
+        {   // init from caseExpr
+            this.database = caseExpr.getDatabase();
+            this.aggregateFunc = caseExpr.isAggregate();
+        }
+        // find source column
+        DBColumnExpr sourceExpr = getSourceColumnExpr(valueMap.values(), 
elseValue);
+        if (sourceExpr!=null)
+        {   // set type
+            this.database = sourceExpr.getDatabase();
+            this.sourceColumn = sourceExpr.getSourceColumn();
+            this.dataType = sourceExpr.getDataType();
+            this.enumType = sourceExpr.getEnumType();
+        }
+        // Check rest
         for (Map.Entry<?, ?> entry : valueMap.entrySet())
-        {   // check compare expr
-            registerCompareValue(entry.getKey());
-            registerTargetValue (entry.getValue());
+        {   // key
+            Object key = entry.getValue();
+            if (key instanceof DBCompareColExpr)
+                key = ((DBCompareColExpr)key).getColumnExpr();
+            if (key instanceof DBColumnExpr && 
((DBColumnExpr)key).isAggregate())
+                this.aggregateFunc = true;
+            // value
+            Object value = entry.getValue(); 
+            if ((value instanceof DBColumnExpr) && 
((DBColumnExpr)entry.getValue()).isAggregate())
+                this.aggregateFunc = true;
+            if (dataType==DataType.UNKNOWN)
+                initDataTypeFromValue(value);
         }
-        registerTargetValue(elseValue);
+        if (dataType==DataType.UNKNOWN)
+            initDataTypeFromValue(elseValue);
     }
     
-    private void registerCompareValue(Object value)
+    protected DBColumnExpr getSourceColumnExpr(Collection<?> values, Object 
elseValue)
     {
-        // set properties from value
-        if (this.database==null && (value instanceof DBExpr) && 
((DBExpr)value).getDatabase()!=null)
-            this.database=((DBExpr)value).getDatabase();
-        if (value instanceof DBCompareColExpr)
-            value = ((DBCompareColExpr)value).getColumnExpr();
-        if (value instanceof DBColumnExpr && 
((DBColumnExpr)value).isAggregate())
-            this.aggregateFunc = true;
+        for (Object val : values)
+        {
+            if (val instanceof DBColumnExpr)
+                return (DBColumnExpr)val;
+        }
+        if (elseValue instanceof DBColumnExpr)
+            return (DBColumnExpr)elseValue;
+        // No DBColumnExpr found
+        return null;
     }
-
+    
     @SuppressWarnings("unchecked")
-    private void registerTargetValue(Object value)
+    protected void initDataTypeFromValue(Object value)
     {
-        if (isNull(value))
-            return;
-        // check
-        if (value instanceof DBColumnExpr)
-        {   // Column Expression
-            DBColumnExpr colExpr = ((DBColumnExpr)value);
-            if (this.database==null)
-                this.database=colExpr.getDatabase();
-            if (this.sourceColumn==null && colExpr.getSourceColumn()!=null)
-                this.sourceColumn = colExpr.getSourceColumn();
-            if (this.dataType==DataType.UNKNOWN)
-                this.dataType = colExpr.getDataType();
-            if (this.enumType== null && colExpr.getEnumType()!=null)
-                this.enumType = colExpr.getEnumType();
-            if (colExpr.isAggregate())
-                this.aggregateFunc = true;
+        // check enum
+        if (value instanceof Enum)
+        {   // Enum
+            this.enumType = (Class<Enum<?>>)value.getClass();
+            this.dataType = DataType.VARCHAR;
         }
-        else if (!(value instanceof DBExpr))
-        {   // Simple Value
-            if (this.dataType==DataType.UNKNOWN)
-                this.dataType = DataType.fromJavaType(value.getClass());
-            if (this.enumType== null && (value instanceof Enum<?>))
-                this.enumType = (Class<Enum<?>>)value.getClass();
+        else if (!isNull(value) && !(value instanceof DBExpr))
+        {   // normal type
+            this.dataType = DataType.fromJavaType(value.getClass());
         }
     }
     
diff --git 
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseMapExpr.java 
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseMapExpr.java
index 420bc816..3e49c319 100644
--- 
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseMapExpr.java
+++ 
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseMapExpr.java
@@ -25,6 +25,7 @@ import org.apache.empire.commons.ArrayMap;
 import org.apache.empire.db.DBColumn;
 import org.apache.empire.db.DBColumnExpr;
 import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.exceptions.InvalidArgumentException;
 
@@ -45,7 +46,7 @@ public class DBCaseMapExpr extends DBCaseExpr
 {
     // *Deprecated* private static final long serialVersionUID = 1L;
   
-    private final DBColumnExpr columnExpr;
+    private final DBColumnExpr caseExpr;
     private final Map<Object, Object> valueMap;
     private final Object elseValue;
     
@@ -56,53 +57,53 @@ public class DBCaseMapExpr extends DBCaseExpr
      * @param elseValue the else Expression
      */
     @SuppressWarnings("unchecked")
-    public DBCaseMapExpr(DBColumnExpr columnExpr, Map<? extends Object, ? 
extends Object> valueMap, Object elseValue)
+    public DBCaseMapExpr(DBColumnExpr caseExpr, Map<? extends Object, ? 
extends Object> valueMap, Object elseValue)
     {
-        if (columnExpr==null)
-            throw new InvalidArgumentException("colExpr", columnExpr);
+        if (caseExpr==null)
+            throw new InvalidArgumentException("colExpr", caseExpr);
         if (valueMap==null || (valueMap.isEmpty() && isNull(elseValue)))
             throw new InvalidArgumentException("valueMap", valueMap);
         // set
-        this.columnExpr = columnExpr;
+        this.caseExpr = caseExpr;
         this.valueMap = (Map<Object, Object>)valueMap;
         this.elseValue = elseValue;
         // init
-        init(columnExpr.getSourceColumn(), valueMap, elseValue);
+        init(caseExpr, valueMap, elseValue);
     }
 
-    public DBCaseMapExpr(DBColumnExpr columnExpr, Object cmpVal, Object 
trueValue, Object elseValue)
+    public DBCaseMapExpr(DBColumnExpr caseExpr, Object cmpVal, Object 
trueValue, Object elseValue)
     {
-        if (columnExpr==null)
-            throw new InvalidArgumentException("colExpr", columnExpr);
+        if (caseExpr==null)
+            throw new InvalidArgumentException("colExpr", caseExpr);
         if (isNull(trueValue) && isNull(elseValue))
-            throw new InvalidArgumentException("colExpr", columnExpr);
-        this.columnExpr = columnExpr;
+            throw new InvalidArgumentException("colExpr", caseExpr);
+        this.caseExpr = caseExpr;
         this.valueMap = new ArrayMap<Object, Object>(1);
         this.valueMap.put(cmpVal, trueValue);
         this.elseValue = elseValue; 
         // init
-        init(columnExpr.getSourceColumn(), valueMap, elseValue);
+        init(caseExpr, valueMap, elseValue);
     }
 
-    public DBCaseMapExpr(DBColumnExpr columnExpr, Object cmpVal1, Object 
trueValue1, Object cmpVal2, Object trueValue2, Object elseValue)
+    public DBCaseMapExpr(DBColumnExpr caseExpr, Object cmpVal1, Object 
trueValue1, Object cmpVal2, Object trueValue2, Object elseValue)
     {
-        if (columnExpr==null)
-            throw new InvalidArgumentException("colExpr", columnExpr);
+        if (caseExpr==null)
+            throw new InvalidArgumentException("colExpr", caseExpr);
         if (isNull(trueValue1) && isNull(trueValue2) && isNull(elseValue))
-            throw new InvalidArgumentException("colExpr", columnExpr);
-        this.columnExpr = columnExpr;
+            throw new InvalidArgumentException("colExpr", caseExpr);
+        this.caseExpr = caseExpr;
         this.valueMap = new ArrayMap<Object, Object>(2);
         this.valueMap.put(cmpVal1, trueValue1);
         this.valueMap.put(cmpVal2, trueValue2);
         this.elseValue = elseValue; 
         // init
-        init(columnExpr.getSourceColumn(), valueMap, elseValue);
+        init(caseExpr, valueMap, elseValue);
     }
 
     @Override
     public String getName()
     {
-        return "CASE_"+columnExpr.getName();
+        return "CASE_"+caseExpr.getName();
     }
     
     /**
@@ -118,7 +119,7 @@ public class DBCaseMapExpr extends DBCaseExpr
         {   // Compare
             DBCaseMapExpr otherCase = (DBCaseMapExpr)other;
             // Expression must match
-            if (!columnExpr.equals(otherCase.columnExpr))
+            if (!caseExpr.equals(otherCase.caseExpr))
                 return false;
         }
         return false;
@@ -127,13 +128,15 @@ public class DBCaseMapExpr extends DBCaseExpr
     @Override
     public void addReferencedColumns(Set<DBColumn> list)
     {
-        columnExpr.addReferencedColumns(list);
-        for (Object expr : valueMap.values())
-        {
-            if (expr instanceof DBColumnExpr)
-               ((DBColumnExpr)expr).addReferencedColumns(list);
+        caseExpr.addReferencedColumns(list);
+        for (Map.Entry<?,?> e : valueMap.entrySet())
+        {   // Check Key of Value for Expressions
+            if (e.getKey() instanceof DBExpr)
+                ((DBExpr)e.getKey()).addReferencedColumns(list);
+            if (e.getValue() instanceof DBExpr)
+                ((DBExpr)e.getValue()).addReferencedColumns(list);
         }
-        if (elseValue instanceof DBColumnExpr)
+        if (elseValue instanceof DBExpr)
            ((DBColumnExpr)elseValue).addReferencedColumns(list);
     }
 
@@ -145,13 +148,13 @@ public class DBCaseMapExpr extends DBCaseExpr
         if (!valueMap.isEmpty())
         {   // append case 
             sql.append("CASE ");
-            columnExpr.addSQL(sql, context);
+            caseExpr.addSQL(sql, context);
             // add values
             for (Map.Entry<Object, Object> entry : valueMap.entrySet())
             {
                 // append value
                 sql.append(" WHEN ");
-                sql.appendValue(columnExpr.getDataType(), entry.getKey(), 
context);
+                sql.appendValue(caseExpr.getDataType(), entry.getKey(), 
context);
                 sql.append(" THEN ");
                 sql.appendValue(getDataType(), entry.getValue(), context);
             }
diff --git 
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java 
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java
index c90f8d91..98f21a8c 100644
--- 
a/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java
+++ 
b/empire-db/src/main/java/org/apache/empire/db/expr/column/DBCaseWhenExpr.java
@@ -26,7 +26,7 @@ import org.apache.empire.commons.ArrayMap;
 import org.apache.empire.commons.ArraySet;
 import org.apache.empire.commons.ObjectUtils;
 import org.apache.empire.db.DBColumn;
-import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.db.DBExpr;
 import org.apache.empire.db.DBSQLBuilder;
 import org.apache.empire.db.expr.compare.DBCompareExpr;
 import org.apache.empire.exceptions.InvalidArgumentException;
@@ -142,11 +142,11 @@ public class DBCaseWhenExpr extends DBCaseExpr
         {
             if (entry.getKey()!=null)
                 entry.getKey().addReferencedColumns(list);
-            if (entry.getValue() instanceof DBColumnExpr)
-                ((DBColumnExpr)entry.getValue()).addReferencedColumns(list);
+            if (entry.getValue() instanceof DBExpr)
+                ((DBExpr)entry.getValue()).addReferencedColumns(list);
         }
-        if (elseValue instanceof DBColumnExpr)
-            ((DBColumnExpr)elseValue).addReferencedColumns(list);
+        if (elseValue instanceof DBExpr)
+            ((DBExpr)elseValue).addReferencedColumns(list);
     }
 
     @Override

Reply via email to