METAMODEL-1165: Fixed - added default_table alias table
[metamodel.git] / core / src / main / java / org / apache / metamodel / query / SelectItem.java
index df4b995..fec900d 100644 (file)
@@ -25,6 +25,7 @@ import org.apache.metamodel.schema.Column;
 import org.apache.metamodel.schema.ColumnType;
 import org.apache.metamodel.schema.Schema;
 import org.apache.metamodel.schema.Table;
+import org.apache.metamodel.schema.TableType;
 import org.apache.metamodel.util.BaseObject;
 import org.apache.metamodel.util.EqualsBuilder;
 import org.slf4j.Logger;
@@ -35,12 +36,11 @@ import org.slf4j.LoggerFactory;
  * <ul>
  * <li>column SELECTs (selects a column from a table)</li>
  * <li>column function SELECTs (aggregates the values of a column)</li>
- * <li>expression SELECTs (retrieves data based on an expression (only supported
- * for JDBC datastores)</li>
- * <li>expression function SELECTs (retrieves databased on a function and an
- * expression, only COUNT(*) is supported for non-JDBC datastores))</li>
- * <li>SELECTs from subqueries (works just like column selects, but in stead of
- * pointing to a column, it retrieves data from the select item of a subquery)</li>
+ * <li>expression SELECTs (retrieves data based on an expression (only supported for JDBC datastores)</li>
+ * <li>expression function SELECTs (retrieves databased on a function and an expression, only COUNT(*) is supported for
+ * non-JDBC datastores))</li>
+ * <li>SELECTs from subqueries (works just like column selects, but in stead of pointing to a column, it retrieves data
+ * from the select item of a subquery)</li>
  * </ul>
  * 
  * @see SelectClause
@@ -98,8 +98,8 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     public static boolean isCountAllItem(SelectItem item) {
-        if (item != null && item.getAggregateFunction() != null && item.getAggregateFunction().toString().equals("COUNT")
-                && item.getExpression() == "*") {
+        if (item != null && item.getAggregateFunction() != null
+                && item.getAggregateFunction().toString().equals("COUNT") && item.getExpression() == "*") {
             return true;
         }
         return false;
@@ -115,8 +115,7 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Creates a SelectItem that uses a function on a column, for example
-     * SUM(price) or MAX(age)
+     * Creates a SelectItem that uses a function on a column, for example SUM(price) or MAX(age)
      * 
      * @param function
      * @param column
@@ -137,8 +136,7 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Creates a SelectItem that references a column from a particular
-     * {@link FromItem}, for example a.price or p.age
+     * Creates a SelectItem that references a column from a particular {@link FromItem}, for example a.price or p.age
      * 
      * @param column
      * @param fromItem
@@ -147,7 +145,7 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
         this(null, column, fromItem);
         if (fromItem != null) {
             Table fromItemTable = fromItem.getTable();
-            if (fromItemTable != null) {
+            if (fromItemTable != null && fromItemTable.getType() != TableType.ALIAS) {
                 Table columnTable = column.getTable();
                 if (columnTable != null && !columnTable.equals(fromItemTable)) {
                     throw new IllegalArgumentException("Column's table '" + columnTable.getName()
@@ -158,8 +156,8 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Creates a SelectItem that uses a function on a column from a particular
-     * {@link FromItem}, for example SUM(a.price) or MAX(p.age)
+     * Creates a SelectItem that uses a function on a column from a particular {@link FromItem}, for example
+     * SUM(a.price) or MAX(p.age)
      * 
      * @param function
      * @param column
@@ -173,9 +171,8 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Creates a SelectItem that uses a function with parameters on a column
-     * from a particular {@link FromItem}, for example
-     * MAP_VALUE('path.to.value', doc)
+     * Creates a SelectItem that uses a function with parameters on a column from a particular {@link FromItem}, for
+     * example MAP_VALUE('path.to.value', doc)
      * 
      * @param function
      * @param functionParameters
@@ -190,8 +187,7 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Creates a SelectItem based on an expression. All expression-based
-     * SelectItems must have aliases.
+     * Creates a SelectItem based on an expression. All expression-based SelectItems must have aliases.
      * 
      * @param expression
      * @param alias
@@ -201,8 +197,7 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Creates a SelectItem based on a function and an expression. All
-     * expression-based SelectItems must have aliases.
+     * Creates a SelectItem based on a function and an expression. All expression-based SelectItems must have aliases.
      * 
      * @param function
      * @param expression
@@ -219,8 +214,7 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
      * Creates a SelectItem that references another select item in a subquery
      * 
      * @param subQuerySelectItem
-     * @param subQueryFromItem
-     *            the FromItem that holds the sub-query
+     * @param subQueryFromItem the FromItem that holds the sub-query
      */
     public SelectItem(SelectItem subQuerySelectItem, FromItem subQueryFromItem) {
         this(null, subQueryFromItem, null, null, null, subQuerySelectItem, null, false);
@@ -242,7 +236,7 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
         return this;
     }
 
-    public boolean hasFunction(){
+    public boolean hasFunction() {
         return _function != null;
     }
 
@@ -270,11 +264,9 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * @return if this is a function based SelectItem where function calculation
-     *         is allowed to be approximated (if the datastore type has an
-     *         approximate calculation method). Approximated function results
-     *         are as the name implies not exact, but might be valuable as an
-     *         optimization in some cases.
+     * @return if this is a function based SelectItem where function calculation is allowed to be approximated (if the
+     *         datastore type has an approximate calculation method). Approximated function results are as the name
+     *         implies not exact, but might be valuable as an optimization in some cases.
      */
     public boolean isFunctionApproximationAllowed() {
         return _functionApproximationAllowed;
@@ -289,9 +281,8 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Tries to infer the {@link ColumnType} of this {@link SelectItem}. For
-     * expression based select items, this is not possible, and the method will
-     * return null.
+     * Tries to infer the {@link ColumnType} of this {@link SelectItem}. For expression based select items, this is not
+     * possible, and the method will return null.
      * 
      * @return
      */
@@ -313,9 +304,9 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Returns an "expression" that this select item represents. Expressions are
-     * not necesarily portable across {@link DataContext} implementations, but
-     * may be useful for utilizing database-specific behaviour in certain cases.
+     * Returns an "expression" that this select item represents. Expressions are not necesarily portable across
+     * {@link DataContext} implementations, but may be useful for utilizing database-specific behaviour in certain
+     * cases.
      * 
      * @return
      */
@@ -341,23 +332,19 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * @return the name that this SelectItem can be referenced with, if
-     *         referenced from a super-query. This will usually be the alias,
-     *         but if there is no alias, then the column name will be used.
+     * @return the name that this SelectItem can be referenced with, if referenced from a super-query. This will usually
+     *         be the alias, but if there is no alias, then the column name will be used.
      */
     public String getSuperQueryAlias() {
         return getSuperQueryAlias(true);
     }
 
     /**
-     * @return the name that this SelectItem can be referenced with, if
-     *         referenced from a super-query. This will usually be the alias,
-     *         but if there is no alias, then the column name will be used.
+     * @return the name that this SelectItem can be referenced with, if referenced from a super-query. This will usually
+     *         be the alias, but if there is no alias, then the column name will be used.
      * 
-     * @param includeQuotes
-     *            indicates whether or not the output should include quotes, if
-     *            the select item's column has quotes associated (typically
-     *            true, but false if used for presentation)
+     * @param includeQuotes indicates whether or not the output should include quotes, if the select item's column has
+     *            quotes associated (typically true, but false if used for presentation)
      */
     public String getSuperQueryAlias(boolean includeQuotes) {
         if (_alias != null) {
@@ -391,8 +378,7 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * @return an alias that can be used in WHERE, GROUP BY and ORDER BY clauses
-     *         in the same query
+     * @return an alias that can be used in WHERE, GROUP BY and ORDER BY clauses in the same query
      */
     public String getSameQueryAlias(boolean includeSchemaInColumnPath) {
         if (_column != null) {
@@ -476,32 +462,38 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     private String getToStringColumnPrefix(boolean includeSchemaInColumnPath) {
-        final StringBuilder sb = new StringBuilder();
         if (_fromItem != null && _fromItem.getAlias() != null) {
-            sb.append(_fromItem.getAlias());
-            sb.append('.');
+            return _fromItem.getAlias() + '.';
+        }
+
+        final Table table;
+        if (_fromItem != null && _fromItem.getTable() != null) {
+            table = _fromItem.getTable();
         } else {
-            final Table table = _column.getTable();
-            String tableLabel;
-            if (_query == null) {
-                tableLabel = null;
-            } else {
-                tableLabel = _query.getFromClause().getAlias(table);
-            }
-            if (table != null) {
-                if (tableLabel == null) {
-                    tableLabel = table.getQuotedName();
-                    if (includeSchemaInColumnPath) {
-                        Schema schema = table.getSchema();
-                        if (schema != null) {
-                            tableLabel = schema.getQuotedName() + "." + tableLabel;
-                        }
-                    }
+            table = _column.getTable();
+        }
+        if (table == null) {
+            return "";
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        String tableLabel;
+        if (_query == null) {
+            tableLabel = null;
+        } else {
+            tableLabel = _query.getFromClause().getAlias(table);
+        }
+        if (tableLabel == null) {
+            tableLabel = table.getQuotedName();
+            if (includeSchemaInColumnPath) {
+                Schema schema = table.getSchema();
+                if (schema != null) {
+                    sb.append(schema.getQuotedName() + ".");
                 }
-                sb.append(tableLabel);
-                sb.append('.');
             }
         }
+        sb.append(tableLabel);
+        sb.append('.');
         return sb.toString();
     }
 
@@ -561,13 +553,10 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Creates a clone of the {@link SelectItem} for use within a cloned
-     * {@link Query}.
+     * Creates a clone of the {@link SelectItem} for use within a cloned {@link Query}.
      * 
-     * @param clonedQuery
-     *            a new {@link Query} object that represents the clone-to-be of
-     *            a query. It is expected that {@link FromItem}s have already
-     *            been cloned in this {@link Query}.
+     * @param clonedQuery a new {@link Query} object that represents the clone-to-be of a query. It is expected that
+     *            {@link FromItem}s have already been cloned in this {@link Query}.
      * @return
      */
     protected SelectItem clone(Query clonedQuery) {
@@ -592,8 +581,7 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Creates a copy of the {@link SelectItem}, with a different
-     * {@link FunctionType}.
+     * Creates a copy of the {@link SelectItem}, with a different {@link FunctionType}.
      * 
      * @param function
      * @return
@@ -604,8 +592,7 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Creates a copy of the {@link SelectItem}, with a different
-     * {@link #isFunctionApproximationAllowed()} flag set.
+     * Creates a copy of the {@link SelectItem}, with a different {@link #isFunctionApproximationAllowed()} flag set.
      * 
      * @param functionApproximationAllowed
      * @return
@@ -616,13 +603,11 @@ public class SelectItem extends BaseObject implements QueryItem, Cloneable {
     }
 
     /**
-     * Investigates whether or not this SelectItem references a particular
-     * column. This will search for direct references and indirect references
-     * via subqueries.
+     * Investigates whether or not this SelectItem references a particular column. This will search for direct
+     * references and indirect references via subqueries.
      * 
      * @param column
-     * @return a boolean that is true if the specified column is referenced by
-     *         this SelectItem and false otherwise.
+     * @return a boolean that is true if the specified column is referenced by this SelectItem and false otherwise.
      */
     public boolean isReferenced(Column column) {
         if (column != null) {