JDBC仕様解釈

JDBCの仕様で定められているインタフェースの1つDatabaseMetaDataにgetProceduresというメソッドがある.
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/sql/DatabaseMetaData.html#getProcedures(java.lang.String,%20java.lang.String,%20java.lang.String)
これは現在接続中のデータベース(カタログ)からパラメータ条件にあう定義済みストアドプロシージャの情報を取得するためのメソッドなのだが,以下の仕様説明文の意味が分からない.

パラメータ:

  • catalog - カタログ名。データベースに格納されたカタログ名と一致しなければならない。"" はカタログなしでカタログ名を検索する。null は、カタログ名を検索の限定に使用してはならないことを意味する
  • schemaPattern - スキーマ名パターン。データベースに格納されたスキーマ名と一致しなければならない。"" はスキーマなしでスキーマ名を検索する。null は、スキーマ名を検索の限定に使用してはならないことを意味する
  • procedureNamePattern - プロシージャ名パターン。データベースに格納されたプロシージャ名と一致しなければならない

""とnullの違いはSQLで表現すると何であるのかが分からない.""はWHERE句に使用するなという意味であろうと思うのだけど,nullの場合の「検索の限定に使用してはならない」ってあんた何が違うのさ.

Connector/Jの実装コードをみてたらこんな感じだったのだけど

String db = null;

if (catalog == null) {
        db = this.database;
} else if (catalog.length() > 0) {
        db = catalog;
} else {
        if (!this.conn.getNullCatalogMeansCurrent()) {
                throw new SQLException("'catalog' parameter can not be null",
                                SQLError.SQL_STATE_ILLEGAL_ARGUMENT);
        }

        catalog = null;
        db = null;
}

これだとnullの場合は現在接続中のデータベース(カタログ)が使用されるのに対して""だと変数にはnullが突っ込まれている.ちなみにこのString型変数dbはPreparedStatementの引数としてそのまま修正されずに使われる.
ということはWHERE句の条件の値に"null"ってでちゃうわけだ.これだとデータベース名(カタログ名)がnullのデータベースでもない限り検索はヒットしない.

で,これをバグじゃないのとMark Matthews氏に言おうかと思って,その前に仕様をよく理解しようと読んだのがさっきの上のURLのやつ.まいったまいった.