[
https://issues.apache.org/jira/browse/DERBY-1773?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12833417#action_12833417
]
Bryan Pendleton commented on DERBY-1773:
----------------------------------------
I've been investigating this issue a bit, and want to note
what I've found, as well as several ideas.
Firstly, the core of the issue occurs in EmbedResultSet.updateRow, which is
attempting to construct and execute, on the fly, a statement like:
update t set x = 2 where current of my-cursor-name
The problem arises due to the fact that the select statement:
select * from t as a(a1)
has introduced aliases for both the table (T => A) and the column (X => A1)
Now, when EmbedResultSet.updateRow processes the table, it is careful
to use the true underlying base table name (T):
updateWhereCurrentOfSQL.append(getFullBaseTableName(targetTable));//got the
underlying (schema.)table name
The problem arises a bit later, when it tries to access the columns which
are being updated:
for (int i=1; i<=resultDescription.getColumnCount(); i++) { //in
this for loop we are constructing columnname=?,... part of the update sql
if (columnGotUpdated[i-1]) { //if the column got updated, do
following
if (foundOneColumnAlready)
updateWhereCurrentOfSQL.append(",");
//using quotes around the column name to preserve case
sensitivity
updateWhereCurrentOfSQL.append(IdUtil.normalToDelimited(
resultDescription.getColumnDescriptor(i).getName())
+ "=?");
foundOneColumnAlready = true;
}
}
The issue here is that resultDescription.getColumnDescriptor(i) is a
GenericColumnDescriptor, which was constructed from a ResultColumnDescriptor
by the method ResultColumnList.makeResultDescriptors(), and this code doesn't
have enough "smarts" to understand the difference between the column's
"exposedName" (A1)
and its true base column name (X).
So, I can see two possibilities:
1) Enhance GenericColumnDescriptor, ResultColumnDescriptor, and (probably)
ResultColumn,
so that we have a new method GenericColumnDescriptor.getBaseColumnName(), and
call
that new method from EmbedResultSet.updateRow.
2) Refuse the statement. Change (probably) SelectNode.isUpdatableCursor() so
that it
looks through its ResultColumnList to see if any of the result columns have
been aliased,
and state that a SELECT with aliased column names is NOT a legal updatable
SELECT statement.
I'll investigate both possibilities further, just wanted to note my results so
far.
> insertRow() and updateRow() fail with syntax error when column has an alias
> ---------------------------------------------------------------------------
>
> Key: DERBY-1773
> URL: https://issues.apache.org/jira/browse/DERBY-1773
> Project: Derby
> Issue Type: Bug
> Components: JDBC
> Affects Versions: 10.2.1.6
> Reporter: Knut Anders Hatlen
> Assignee: Bryan Pendleton
> Priority: Minor
> Attachments: Alias.java
>
>
> When the select query used in an updatable result set has column aliases, a
> syntax error is thrown when executing ResultSet.insertRow() and
> ResultSet.updateRow(). The problem is seen on embedded and client. Repro is
> attached.
> Exception in thread "main" ERROR 42X14: 'A1' is not a column in table or VTI
> 'APP.T'.
> at
> org.apache.derby.iapi.error.StandardException.newException(StandardException.java:316)
> at
> org.apache.derby.impl.sql.compile.ResultColumn.bindResultColumnByName(ResultColumn.java:677)
> at
> org.apache.derby.impl.sql.compile.ResultColumnList.bindResultColumnsByName(ResultColumnList.java:682)
> at
> org.apache.derby.impl.sql.compile.ResultSetNode.bindResultColumns(ResultSetNode.java:683)
> at
> org.apache.derby.impl.sql.compile.SelectNode.bindResultColumns(SelectNode.java:742)
> at
> org.apache.derby.impl.sql.compile.UpdateNode.bind(UpdateNode.java:349)
> at
> org.apache.derby.impl.sql.GenericStatement.prepMinion(GenericStatement.java:345)
> at
> org.apache.derby.impl.sql.GenericStatement.prepare(GenericStatement.java:111)
> at
> org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(GenericLanguageConnectionContext.java:723)
> at
> org.apache.derby.impl.jdbc.EmbedResultSet.updateRow(EmbedResultSet.java:3734)
> at Alias.main(Alias.java:15)
--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.