[ 
https://issues.apache.org/jira/browse/DERBY-5823?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Knut Anders Hatlen updated DERBY-5823:
--------------------------------------

    Attachment: derby-5823-2a.diff

Attaching derby-5823-2a.diff which tackles problem 1 and 2 mentioned above.

It skips adding rows to the temporary row holder if there are no columns to 
add. This means the row holder will never overflow to disk if there are no 
generated keys, so there will be no attempt to create a heap conglomerate with 
zero-length rows, and the "Conglomerate could not be created" error is avoided.

It also keeps the set of key columns between executions so that we avoid the 
overhead of collecting all columns for all inserted rows on re-execution. In 
addition to avoiding overhead, this also ensures that the internal result set 
that holds the generated keys (InsertResultSet.autoGeneratedKeysResultSet) has 
the correct shape. Although the shape of this ResultSet doesn't matter right 
now (getGeneratedKeys() only cares whether it's non-null), this might change in 
DERBY-3609, so this should also get fixed.

And while I was at it, I just couldn't resist the temptation to replace a for 
loop with a call to Arrays.fill() in 
InsertResultSet.generatedColumnPositionsArray()...

The regression test case contributed by Kristian passed with the fix. So did 
all the existing regression tests in derbyall and suites.All.

> 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, derby-5823-2a.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