[ 
https://issues.apache.org/jira/browse/DERBY-5823?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13809188#comment-13809188
 ] 

Knut Anders Hatlen commented on DERBY-5823:
-------------------------------------------

There are multiple problems in this area:

1. InsertResultSet collects generated keys even in the case where there are no 
auto-generated keys. This is unnecessary, and causes problems when overflowing 
to a heap conglomerate since heap conglomerates don't support zero-sized rows. 
It should stop doing this.

2. On re-execution of a PreparedStatement that was created with 
RETURN_GENERATED_KEYS, InsertResultSet will collect all columns, not only key 
columns. This is because InsertResultSet only calculates the key columns on the 
first execution, but it doesn't cache the result, so on re-execution it will be 
null, which the code interprets as all columns. This makes the temporary row 
holder take up more space than necessary. One odd effect of this problem is 
that it cancels problem (1) on re-execution. That is, if you call 
executeUpdate() on a PS and get the "Conglomerate could not be created" error 
mentioned in the bug description, calling executeUpdate() again on the same PS 
will succeed. It succeeds the second time because then it adds all inserted 
columns to the temporary row holder, and therefore doesn't hit the problem with 
zero-length rows. Of course, it should add the same set of columns to the 
temporary row holder regardless of how many times the PS is executed, so this 
should be fixed together with problem (1).

3. As Kristian noted, getGeneratedKeys() is supposed to return an empty 
ResultSet if no keys were generated, but it returns a ResultSet with one row. 
This is because the collected set of keys is discarded by getGeneratedKeys() 
and instead the result of VALUES IDENTITY_VAL_LOCAL() is returned. I believe 
this part of the problem will be handled by DERBY-3609, and does not need to be 
tackled in this issue.

> Multi-row insert fails on table without generated keys with 
> RETURN_GENERATED_KEYS
> ---------------------------------------------------------------------------------
>
>                 Key: DERBY-5823
>                 URL: https://issues.apache.org/jira/browse/DERBY-5823
>             Project: Derby
>          Issue Type: Bug
>          Components: JDBC
>    Affects Versions: 10.7.1.1, 10.8.2.2, 10.9.1.0, 10.10.1.1
>            Reporter: Kristian Waagan
>            Assignee: Knut Anders Hatlen
>            Priority: Minor
>              Labels: derby_triage10_10
>         Attachments: derby-5823-1a-regression_test.diff
>
>
> Exeuting an insert that results in multiple rows being inserted into a table 
> without any generated keys defined fails if the JDBC statement is configured 
> to return generated keys. Example stack trace:
> Caused by: ERROR XSCH4: Conglomerate could not be created.
>         at 
> org.apache.derby.iapi.error.StandardException.newException(StandardException.java:268)
>         at org.apache.derby.impl.store.access.heap.Heap.create(Heap.java:296)
>         at 
> org.apache.derby.impl.store.access.heap.HeapConglomerateFactory.createConglomerate(HeapConglomerateFactory.java:206)
>         at 
> org.apache.derby.impl.store.access.RAMTransaction.createConglomerate(RAMTransaction.java:820)
>         at 
> org.apache.derby.impl.sql.execute.TemporaryRowHolderImpl.insert(TemporaryRowHolderImpl.java:302)
>         at 
> org.apache.derby.impl.sql.execute.InsertResultSet.normalInsertCore(InsertResultSet.java:1007)
>         at 
> org.apache.derby.impl.sql.execute.InsertResultSet.open(InsertResultSet.java:508)
>         at 
> org.apache.derby.impl.sql.GenericPreparedStatement.executeStmt(GenericPreparedStatement.java:443)
>         at 
> org.apache.derby.impl.sql.GenericPreparedStatement.execute(GenericPreparedStatement.java:324)
>         at 
> org.apache.derby.impl.jdbc.EmbedStatement.executeStatement(EmbedStatement.java:1242)
>         ... 30 more
> This happens only with multi-row inserts, and only with the embedded driver 
> (the client driver uses IDENTITY_VAL_LOCAL).
> The problem is that Derby tries to create a temporary conglomerate with a 
> zero-length row template. A guard against this scenario is probably missing.
> FYI, the transition threshold (from in-memory to on-disk) is currently five 
> rows.
> I marked versions back to 10.7 as affected, but this bug probably goes back 
> all the way.



--
This message was sent by Atlassian JIRA
(v6.1#6144)

Reply via email to