You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-dev@db.apache.org by "Knut Anders Hatlen (JIRA)" <ji...@apache.org> on 2012/11/26 16:37:01 UTC

[jira] [Commented] (DERBY-6003) Create row templates outside of the generated code

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

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

I first said the generated method created and initialized the row templates. That's not quite right. The row template is created in the generated constructor, and the generated method (re-)initializes it and returns a reference to it.

I have a mostly working patch in my sandbox. However, the original plan of storing the ExecRow in GenericPreparedStatement.savedObjects didn't work as smoothly as I'd hoped. Anything stored in savedObjects has to be serializable, which ExecRow isn't, and making it serializable is not straightforward. It must be serializable so that it can be used in stored prepared statements. We might make ExecRow serializable, but the template ExecRow contains SQL null values, and the writeExternal() and readExternal() methods of the SQL type classes do not work with null, as saving/restoring null values is usually handled at a higher level in the code. The approach used at the higher level actually depends on having a template row to handle nulls, so we run into a chicken-and-egg problem if we try to use the same approach to store the template row.

I don't think it's an option to change the writeExternal() and readExternal() methods of all the SQL type classes so they handle null. Although it is possible to change the stored format of the data types, that will require too much upgrade logic (and testing) to be worthwhile.

The alternative that I'm exploring now, is to store an array of DataTypeDescriptors from which the result sets can create the ExecRow. DataTypeDescriptor is already serializable, and it has a getNull() method which can be used to create empty SQL values of the right type that we can put in the ExecRow template. There are some problems with that approach too:

- RowLocation values don't have a corresponding DataTypeDescriptor, so they'll need some special handling. The code that generates the byte code already has a special case for row locations, so the new code shouldn't be much worse than the current code.

- DataTypeDescriptor.readExternal() is not able to read the type descriptor for a UDT written by DataTypeDescriptor.writeExternal(). It doesn't fail, but some of the state of the original type descriptor isn't restored, which leads to subsequent NullPointerExceptions. But it looks like writeExternal() does write all necessary information to restore the fields for UDTs too, so I think the bug should be fixable, even without changing the stored format of DataTypeDescriptor.
                
> Create row templates outside of the generated code
> --------------------------------------------------
>
>                 Key: DERBY-6003
>                 URL: https://issues.apache.org/jira/browse/DERBY-6003
>             Project: Derby
>          Issue Type: Improvement
>          Components: SQL
>    Affects Versions: 10.10.0.0
>            Reporter: Knut Anders Hatlen
>            Assignee: Knut Anders Hatlen
>            Priority: Minor
>         Attachments: d6003-1a-cleanup.diff
>
>
> The constructors for many of the result set classes take GeneratedMethod parameters that create row templates (an ExecRow of a certain size and column types, each column initialized to an SQL null value).
> As an alternative, the compiler could produce an ExecRow instance and put it into the savedObjects field of GenericPreparedStatement, and the constructors could take parameter that points to the object in savedObjects. Where the result sets currently invoke the generated method to produce a fresh template, they could instead clone the saved object.
> Advantages with the suggested approach would be:
> - Reduce the size of the code generator, which should reduce total code complexity.
> - Reduce the amount of generated code, which makes it easier for tools (profilers, static code analyzers, IDEs) to map executable code to source code.
> - Reduce the actual number of generated methods, which makes it less likely that queries need to use reflection to invoke the remaining generated methods (there's a switchover from DirectCall to ReflectCall when the number of generated methods exceeds 10).

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira