db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Knut Anders Hatlen (JIRA)" <derby-...@db.apache.org>
Subject [jira] Commented: (DERBY-970) Add new metadata methods to network client driver
Date Fri, 10 Mar 2006 14:44:41 GMT
    [ http://issues.apache.org/jira/browse/DERBY-970?page=comments#action_12369863 ] 

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

> Kathey Marsden commented on DERBY-970:
> --------------------------------------
>
> Sorry I didn't look at this earlier I have a few questions as I try
  to come up to speed on the issues.

Thanks for your comments and suggestions! See my answers below.

>
> 1) Could you clarify the issue with JDK 1.6?
> From what I understand, the issue is:
> We just don't have access to the JDK 1.6 interfaces because in our
> build we don't build with JDK 1.6.  Is that correct?

That's correct. For instance, most of the client driver is compiled
with 1.4. Code that doesn't run in 1.3 is wrapped in an if, like this:

  if (JVMInfo.JDK_ID >= JVMInfo.J2SE_14) {
    // call a method that's not in java 1.3
  }

We could do this with 1.6 code too, but since the 1.6 compiler only
can be used to compile optional (that is, JDBC 4) modules, the body of
the if statement needs to be written using reflection.

> If that is the
> case, can our SystemProcedure just call our internal implementation?

Yes, that is basically what alternative a would do. Since the JDBC 4.0
database metadata methods are implemented in EmbedDatabaseMetaData40,
we need to use reflection to check whether there is an internal
implementation of the metadata call.

Alternatively, we could move the metadata methods from the 4.0 class
to the base class (or add a dummy method throwing not implemented in
the base class). In that case we could avoid the reflection.

Currently, the system procedures do this to get result sets

  rs[0] = getDMD().getXXX(x,y,z);

We would need to cast the return value from getDMD() to
EmbedDatabaseMetaData and change the code like this

  rs[0] = ((EmbedDatabaseMetaData) getDMD()).getXXX(x,y,z);

I was considering this approach earlier, but rejected it because
  a) I didn't like casting from the java.sql interface to some
     internal implementation, and
  b) It wouldn't work if the method signatures contained new language
     constructs

Looking at it again, at least b) doesn't seem to be an issue since
none of the metadata methods added by JDBC 4 use new language
constructs in their signatures.

If SystemProcedure.getDMD() is guaranteed to return an
EmbedDatabaseMetaData object, a) isn't an issue either. I'll check if
that's the case. If it is, I think I like that solution better than
the factory.

> 2) With your plan will metadata.properties remain as is and we keep
>    the stored prepared statements?

Yes.

> 3)Could you epxplain how thie factory solution would work a little
>   more?

Methods that need 1.6 to compile are moved out into another class, say
SysProcHelper40. We would also need a base class, say SysProcHelper,
which is possible to compile under 1.4. For the new getSchemas()
method, we would have something like this:

class SysProcHelper {
    ResultSet getSchemas(DatabaseMetaData dmd, String arg1, String arg2)
        throws SQLException {
        // throw not implemented
    }
}

class SysProcHelper40 extends SysProcHelper {
    ResultSet getSchemas(DatabaseMetaData dmd, String arg1, String arg2)
        throws SQLException {
        return dmd.getSchemas(arg1, arg2);
    }
}

In SystemProcedures, we would need to add a variable of type
SysProcHelper, which is initialized (using reflection) to a
SysProcHelper or SysProcHelper40 instance depending on JVM.

Then we would implement the system procedure like this:

  rs[0] = sysProcHelper.getSchemas(getDMD(), arg1, arg2);

This way, we would get code that compiles without 1.6, returns the
correct result set when running under 1.6 (with JDBC 4 compiled in),
and throws not implemented when JDBC 4 isn't enabled.

> And a couple of tangental questions:
> 4)
> Do you understand how metadata.properties changes are handled with
> regard to soft upgrade, downgrade, upgrade, etc currentlyy?

Not at all! :)

I guess adding a new query wouldn't cause problems, since that will
just add a new SPS the first time it is used and not affect other
queries.

Modifying existing queries, which has to be done for
DatabaseMetaData.getProcedures() and getProcedureColumns(), is
probably worse. Dropping the SPS or using a new name for the modified
query are the two options I can think of.

> I have
> had on my list for a long time to research what is happenning in
> Derby with this as it was the source of intractable upgrade issues
> in the past and the mechanism that I knew of to handle it (dropping
> the SPS's whenever the version changed) is no longer in Derby.  I
> just haven't been able to get to researching it yet.

Why was the dropping of SPSs removed?

Frankly, I don't see the value in storing SPSs for metadata calls. Is
it for performance? If yes, how many applications exist that would
suffer noticeably from more expensive metadata calls? And if such
applications exist, wouldn't it be better to have prepared statements
whose lifetime didn't exceed the lifetime of the JVM process? Then the
queries would be prepared at most once per process, and we wouldn't
have the upgrade problem. I'm probably missing something.

> 5) Is there a general problem with incompatiblity of compiled Stored
>    Prepared Statements in databases that may have been created with
>    different JVM versions?

I don't think so. Incompatibilities only occur if the SQL text of the
stored prepared statements change when changing JVM, and that is not
the case.

If the SQL text has to change depending on JVM, I think you could
avoid the problem by giving the queries/SPSs different names.

> On   the earlier suggestions:
> Either c or d would be a fatal blow to client/server compatibility,
> so they have all the appeal of euthanasia for client/server compat.

Oh, then we *certainly* should try to avoid that!

By the way, how strict is that rule? It seems like the client driver
already has the queries for these metadata methods hard coded:

  - getSuperTypes()
  - getSuperTables()
  - getAttributes()

All of these have a corresponding entry in metadata.properties, and
SPSs which are only used by the embedded driver. However, all of these
methods return empty result sets.

I was hoping that I could follow the same pattern for
getClientInfoProperties() (which also returns an empty result set).

> Add new metadata methods to network client driver
> -------------------------------------------------
>
>          Key: DERBY-970
>          URL: http://issues.apache.org/jira/browse/DERBY-970
>      Project: Derby
>         Type: Sub-task
>     Reporter: David Van Couvering
>     Assignee: Knut Anders Hatlen

>
> Implement new JDBC 4.0 DatabaseMetaData methods in the client driver:
>   - supportsStoredFunctionsUsingCallSyntax()
>   - autoCommitFailureClosesAllResultSets()
>   - getClientInfoProperties()
>   - providesQueryObjectGenerator()
>   - getSchemas()

-- 
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


Mime
View raw message