Hi Boris,

I think that you are asking two questions here:

1) Why doesn't the syntax in metadata.properties work for you

2) How can you get the same information out of the columndatatype column

Here are some answers:

(1) The syntax in metadata.properties can only be used internally by Derby itself. Derby evolved out of a product called Cloudscape. Older versions of Cloudscape let you declare columns to be Serializable Java types and to execute those types' public methods in your queries. Some of the columns in system tables, including columndatatype, were Cloudscape-specific Serializable objects. And some JDBC metadata calls were implemented using the method-calling syntax.

Unfortunately, the syntax used to declare those object types was not the SQL Standard syntax for declaring abstract data types. Before Derby was open-sourced, that non-standard syntax was removed so that Derby could conform closely to the SQL Standard--that is an important part of Derby's charter. The system tables and metadata queries were not changed, however. Internally, Derby can still store objects in columns and execute methods off those columns in queries.

As you can see, object-savvy syntax is just under the surface in Derby. There is a JIRA for exposing this capability via SQL Standard syntax: http://issues.apache.org/jira/browse/DERBY-651 However, no-one is working on this right now.

(2) You can write your own functions to unpack the information in the TypeDescriptor that is stored in the columndatatype column. In a moment, I will show you how to do this. Please bear in mind that TypeDescriptor is not part of Derby's public API and that the following code is not guaranteed to work in future releases of Derby. On the positive side, TypeDescriptor has tended to evolve in upward compatible ways.

Here is a function which extracts the type name out of a TypeDescriptor:

import java.sql.*;
import org.apache.derby.catalog.TypeDescriptor;

public class z
{
public static String getTypeName( String referenceID, String columnName )
       throws Exception
   {
Connection conn = DriverManager.getConnection("jdbc:default:connection");
       PreparedStatement   ps = conn.prepareStatement
( "select columndatatype from sys.syscolumns where referenceID = ? and columnName = ?" );

       ps.setString( 1, referenceID );
       ps.setString( 2, columnName );
ResultSet rs = ps.executeQuery();
       rs.next();
       TypeDescriptor  td = (TypeDescriptor) rs.getObject( 1 );

       rs.close();
       ps.close();

       return td.getTypeName();
   }
}

And here is a little sql script which registers that function and then uses it in a query:

create function getTypeName
(
   referenceID char( 36 ),
   columnName varchar( 128 )
)
returns varchar( 50 )
language java
parameter style java
reads sql data
external name 'z.getTypeName'
;

select getTypeName( c.referenceID, c.columnName )
from sys.syscolumns c
where c.columnName = 'TABLEID'
;

Hope this helps,
-Rick


Boris Stumm wrote:
Hi,

I have an application that uses several INFORMATION_SCHEMA views.
This app I now want to use with derby, and found out that derby
has no INFORMATION_SCHEMA. I decided that writing the needed views
myself will be the easiest way, but stumbled over a problem that
I could not solve by googling etc.:


I need to get info from the type descriptor in SYS.SYSCOLUMNS,
and wanted it to do like in the following code snippet:

Connection c = DriverManager.getConnection("jdbc:derby:testdb");
c.createStatement()
 .executeQuery("select c.columndatatype.getTypeName()
                from sys.syscolumns c");

That does not work, so I was looking in the derby source code,
and found
java/engine/org/apache/derby/impl/jdbc/metadata.properties
There, for example in the getColumns query string, it uses
basically the same method that I tried. How can I make this
work in my code?

I use derby 10.4.1.3 and Java 6.

Thanks for your help!

The exception thrown with above query is:

Exception in thread "main" java.sql.SQLSyntaxErrorException: Syntaxfehler: org.apache.derby.catalog.TypeDescriptor.getTypeName. at org.apache.derby.impl.jdbc.SQLExceptionFactory40.getSQLException(Unknown Source) at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source) at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown Source) at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source) at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source) at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
    at org.apache.derby.impl.jdbc.EmbedStatement.execute(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedStatement.executeQuery(Unknown Source)
    at TestDerby.main(TestDerby.java:59)
Caused by: java.sql.SQLException: Syntaxfehler: org.apache.derby.catalog.TypeDescriptor.getTypeName. at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source) at org.apache.derby.impl.jdbc.SQLExceptionFactory40.wrapArgsForTransportAcrossDRDA(Unknown Source)
    ... 9 more
Caused by: ERROR 42X01: Syntaxfehler: org.apache.derby.catalog.TypeDescriptor.getTypeName. at org.apache.derby.iapi.error.StandardException.newException(Unknown Source) at org.apache.derby.impl.sql.compile.MethodCallNode.resolveMethodCall(Unknown Source) at org.apache.derby.impl.sql.compile.NonStaticMethodCallNode.bindExpression(Unknown Source) at org.apache.derby.impl.sql.compile.JavaToSQLValueNode.bindExpression(Unknown Source) at org.apache.derby.impl.sql.compile.ResultColumn.bindExpression(Unknown Source) at org.apache.derby.impl.sql.compile.ResultColumnList.bindExpressions(Unknown Source) at org.apache.derby.impl.sql.compile.SelectNode.bindExpressions(Unknown Source) at org.apache.derby.impl.sql.compile.DMLStatementNode.bindExpressions(Unknown Source) at org.apache.derby.impl.sql.compile.DMLStatementNode.bind(Unknown Source) at org.apache.derby.impl.sql.compile.CursorNode.bindStatement(Unknown Source) at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
    at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
at org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown Source)
    ... 3 more




Reply via email to