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());
}