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 47b1c5d  EMPIREDB-318 Bugfix DBQuery column expression resolution
47b1c5d is described below

commit 47b1c5dd7148ca9602d32d62bb7f1864d55c48d3
Author: Rainer Döbele <[email protected]>
AuthorDate: Thu Nov 7 12:27:06 2019 +0100

    EMPIREDB-318
    Bugfix DBQuery column expression resolution
---
 .../main/java/org/apache/empire/db/DBQuery.java    | 155 ++++++++++++++++++++-
 .../main/java/org/apache/empire/db/DBRowSet.java   |  18 ++-
 2 files changed, 167 insertions(+), 6 deletions(-)

diff --git a/empire-db/src/main/java/org/apache/empire/db/DBQuery.java 
b/empire-db/src/main/java/org/apache/empire/db/DBQuery.java
index 0615956..147ecd8 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBQuery.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBQuery.java
@@ -25,13 +25,16 @@ import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.Options;
 import org.apache.empire.commons.StringUtils;
+import org.apache.empire.data.DataType;
 import org.apache.empire.db.exceptions.InvalidKeyException;
 import org.apache.empire.db.exceptions.NoPrimaryKeyException;
 import org.apache.empire.db.exceptions.QueryNoResultException;
 import org.apache.empire.db.exceptions.RecordNotFoundException;
 import org.apache.empire.db.exceptions.RecordUpdateFailedException;
 import org.apache.empire.db.exceptions.RecordUpdateInvalidException;
+import org.apache.empire.db.expr.column.DBAliasExpr;
 import org.apache.empire.db.expr.compare.DBCompareColExpr;
 import org.apache.empire.db.expr.compare.DBCompareExpr;
 import org.apache.empire.db.expr.join.DBColumnJoinExpr;
@@ -40,6 +43,8 @@ import org.apache.empire.exceptions.InvalidArgumentException;
 import org.apache.empire.exceptions.ItemNotFoundException;
 import org.apache.empire.exceptions.NotImplementedException;
 import org.apache.empire.exceptions.NotSupportedException;
+import org.apache.empire.xml.XMLUtil;
+import org.w3c.dom.Element;
 
 
 /**
@@ -59,6 +64,102 @@ public class DBQuery extends DBRowSet
     private final static long serialVersionUID = 1L;
 
     private static AtomicInteger queryCount = new AtomicInteger(0);
+    
+    /**
+     * DBQueryExprColumn
+     * wraps a DBColumnExpr object into a DBColumn interface object
+     * @author doebele
+     */
+    protected static class DBQueryExprColumn extends DBColumn
+    {
+        private static final long serialVersionUID = 1L;
+        
+        private final DBColumnExpr expr;
+
+        public DBQueryExprColumn(DBQuery query, String name, DBColumnExpr expr)
+        {
+            super(query, name);
+            this.expr = expr;
+        }
+        
+        public DBColumnExpr getExpr()
+        {
+            return expr;
+        }
+
+        @Override
+        public DBColumn getUpdateColumn()
+        {
+            return expr.getUpdateColumn();
+        }
+
+        @Override
+        public DataType getDataType()
+        {
+            return expr.getDataType();
+        }
+
+        @Override
+        public double getSize()
+        {
+            return 0;
+        }
+
+        @Override
+        public boolean isRequired()
+        {
+            return false;
+        }
+
+        @Override
+        public boolean isAutoGenerated()
+        {
+            return false;
+        }
+
+        @Override
+        public boolean isReadOnly()
+        {
+            return true;
+        }
+
+        @Override
+        public Object getAttribute(String name)
+        {
+            return expr.getAttribute(name);
+        }
+
+        @Override
+        public Options getOptions()
+        {
+            return expr.getOptions();
+        }
+
+        @Override
+        public String getBeanPropertyName()
+        {
+            return expr.getBeanPropertyName();
+        }
+
+        @Override
+        public Object validate(Object value)
+        {
+            log.warn("validate not supported for {}", expr.getName());
+            return value;
+        }
+
+        @Override
+        public Element addXml(Element parent, long flags)
+        {
+            Element elem = XMLUtil.addElement(parent, "column");
+            elem.setAttribute("name", name);
+            // add All Attributes
+            if (attributes != null)
+                attributes.addXml(elem, flags);
+            // done
+            return elem;
+        }
+    }
 
     protected final DBCommandExpr   cmdExpr;
     protected final DBColumn[]      keyColumns;
@@ -82,7 +183,7 @@ public class DBQuery extends DBRowSet
         this.queryColumns = new DBQueryColumn[exprList.length];
         for (int i = 0; i < exprList.length; i++)
         {   // Init Columns 
-            columns.add(exprList[i].getUpdateColumn());
+            columns.add(getColumnFromExpr(exprList[i], i));
             queryColumns[i] = createQueryColumn(exprList[i]);
         }
         // Set the key Column
@@ -612,4 +713,54 @@ public class DBQuery extends DBRowSet
         return new DBQueryColumn(this, expr);
     }
 
-}
\ No newline at end of file
+    /**
+     * Gets the underlying DBColumn from a column expression
+     * If there is no underlying column, a wrapper will be generated
+     * @param expr
+     * @param index
+     * @return the column
+     */
+    protected DBColumn getColumnFromExpr(DBColumnExpr expr, int index)
+    {
+        DBColumn column;
+        if ((expr instanceof DBAliasExpr) || 
(column=expr.getUpdateColumn())==null) 
+        {   // generate name
+            String name = expr.getName();
+            if (StringUtils.isEmpty(name))
+                name = getName()+"_COL"+String.valueOf(index);
+            // create wrapper
+            column=new DBQueryExprColumn(this, name, expr); 
+        }
+        return column;
+    }
+
+    @Override
+    public int getColumnIndex(DBColumn column)
+    {
+        int index = columns.indexOf(column);
+        if (index>=0)
+            return index;
+        // find by update column
+        index=0;
+        for (DBColumn c : columns)
+        {   // check update column
+            if ((c instanceof DBQueryExprColumn) && 
column.equals(c.getUpdateColumn()))
+                 return index;
+            // next
+            index++;
+        }
+        // not found
+        return -1;
+    }
+
+    @Override
+    protected DBColumnExpr getColumnExprAt(int index)
+    {
+        DBColumn column = columns.get(index);
+        if (column instanceof DBQueryExprColumn)
+            return ((DBQueryExprColumn)column).getExpr();  // unwrap
+        // use column
+        return column;
+    }
+  
+}
diff --git a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java 
b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
index 8e31f47..a5085bc 100644
--- a/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
+++ b/empire-db/src/main/java/org/apache/empire/db/DBRowSet.java
@@ -483,6 +483,17 @@ public abstract class DBRowSet extends DBExpr
     }
 
     /**
+     * Returns the column expression at a given column index
+     * Allow overrides in derived classes
+     * @param index
+     * @return the column expression
+     */
+    protected DBColumnExpr getColumnExprAt(int index)
+    {
+        return columns.get(index);
+    }
+    
+    /**
      * Initialize this DBRowSet object and sets it's initial state.
      * 
      * @param rec the DBRecord object to initialize this DBRowSet object
@@ -546,13 +557,12 @@ public abstract class DBRowSet extends DBExpr
         // Get Record Field Values
         Object[] fields = rec.getFields();
         for (int i = 0; i < fields.length; i++)
-        {
-            // Read a value
-               DBColumn column = columns.get(i);
+        {   // Read a value
+               DBColumnExpr column = getColumnExprAt(i);
                int rdi = recData.getFieldIndex(column);
                if (rdi<0)
                {       // Field not available in Record Data
-                       if (primaryKey!=null && primaryKey.contains(column))
+                       if (primaryKey!=null && (column instanceof DBColumn) && 
primaryKey.contains((DBColumn)column))
                        {       // Error: Primary Key not supplied
                            throw new ItemNotFoundException(column.getName());
                        }

Reply via email to