[
http://issues.apache.org/jira/browse/DERBY-1624?page=comments#action_12428453 ]
Manish Khettry commented on DERBY-1624:
---------------------------------------
This has to do with the way Derby rewrites querys with a groupby. What I find
odd is that the query works without the having clause because the same rewrite
is done for only group by's. I tracked it down to this bit of code in
FromSubquery#findMatching column. So, when we are trying to bind "model0_.name"
in the select list why look in different places (case 2 vs case 4) depending on
whether there is a having clause or not?!
/* We have 5 cases here:
* 1. ColumnReference was generated to replace an aggregate.
* (We are the wrapper for a HAVING clause and the
ColumnReference
* was generated to reference the aggregate which
was pushed down into
* the SELECT list in the user's query.)
* Just do what you would expect. Try to resolve
the
* ColumnReference against our RCL if the
ColumnReference is unqualified
* or if it is qualified with our exposed name.
* 2. We are the wrapper for a GROUP BY and a HAVING
clause and
* either the ColumnReference is qualified or it
is in
* the HAVING clause. For example:
* select a from t1 group by a having t1.a
= 1
* select a as asdf from t1 group by a
having a = 1
* We need to match against the underlying
FromList and then find
* the grandparent ResultColumn in our RCL so that
we return a
* ResultColumn from the correct ResultSetNode.
It is okay not to
* find a matching grandparent node. In fact,
this is how we ensure
* the correct semantics for ColumnReferences in
the HAVING clause
* (which must be bound against the GROUP BY list.)
* 3. We are the wrapper for a HAVING clause without a GROUP
BY and
* the ColumnReference is from the HAVING clause.
ColumnReferences
* are invalid in this case, so we return null.
* 4. We are the wrapper for a GROUP BY with no HAVING. This
has
* to be a separate case because of #5 and the
following query:
* select * from (select c1 from t1) t,
(select c1 from t1) tt
* group by t1.c1, tt.c1
* (The correlation names are lost in the
generated FromSuquery.)
* 5. Everything else - do what you would expect. Try to
resolve the
* ColumnReference against our RCL if the
ColumnReference is unqualified
* or if it is qualified with our exposed name.
*/
if (columnReference.getGeneratedToReplaceAggregate()) // 1
{
resultColumn =
resultColumns.getResultColumn(columnReference.getColumnName());
}
else if (generatedForGroupByClause && generatedForHavingClause
&&
columnReference.getClause() !=
ValueNode.IN_SELECT_LIST) // 2
{
if (SanityManager.DEBUG)
{
SanityManager.ASSERT(correlationName == null,
"correlationName expected to be null");
SanityManager.ASSERT(subquery instanceof
SelectNode,
"subquery expected to be instanceof
SelectNode, not " +
subquery.getClass().getName());
}
SelectNode select = (SelectNode) subquery;
resultColumn =
select.getFromList().bindColumnReference(columnReference);
/* Find and return the matching RC from our RCL.
* (Not an error if no match found. Let
ColumnReference deal with it.
*/
if (resultColumn != null)
{
/* Is there a matching resultColumn in the
subquery's RCL? */
resultColumn =
subquery.getResultColumns().findParentResultColumn(
resultColumn);
if (resultColumn != null)
{
/* Is there a matching resultColumn in
our RCL? */
resultColumn =
resultColumns.findParentResultColumn(
resultColumn);
}
}
}
else if ((generatedForHavingClause && !
generatedForGroupByClause) // 3
&& (columnReference.getClause() !=
ValueNode.IN_SELECT_LIST) )
{
resultColumn = null;
}
else if (generatedForGroupByClause) // 4
{
resultColumn = resultColumns.getResultColumn(
columnsTableName,
columnReference.getColumnName());
}
else if (columnsTableName == null ||
columnsTableName.equals(correlationName)) // 5?
{
resultColumn =
resultColumns.getAtMostOneResultColumn(columnReference, correlationName);
}
if (resultColumn != null)
{
columnReference.setTableNumber(tableNumber);
}
return resultColumn;
}
Emmanuel, Is this a big problem for Hibernate with Derby? Others on the derby
list who may know this-- how hard is it to ditch the rewrite of groupby/having
queries or can we still keep the rewrite and fix this?
> use of direct column name rather than alias make aggregation fail (Hibernate
> depends on that)
> ---------------------------------------------------------------------------------------------
>
> Key: DERBY-1624
> URL: http://issues.apache.org/jira/browse/DERBY-1624
> Project: Derby
> Issue Type: Improvement
> Components: SQL
> Affects Versions: 10.1.1.0, 10.1.3.1
> Reporter: Emmanuel Bernard
>
> Error: org.apache.derby.client.am.SqlException: Column 'MODEL0_.COL_0_0_' is
> either not in any table in the FROM list or appears within a join
> specification and is outside the scope of the join specification or appears
> in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or
> ALTER TABLE statement then 'MODEL0_.COL_0_0_' is not a column in the target
> table., SQL State: 42X04, Error Code: -1
> for
> select
> model0_.balance as col_0_0_,
> count(*) as col_1_0_
> from
> account model0_
> group by
> model0_.balance
> having
> count(*) > 1
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira