H2Databaseを追っかけていたりしたブログ

H2 database のリリースノートを読んだりとか。

Version 1.3.152 Beta (2011-03-01)

リリースされた直後ウェブサイトの内容がリリース前の内容に戻ってしまうということも有りましたが。

ところで、まだBetaは取れないのか。

  • H2コンソール: Mac OS XでOpenJDK1.7の環境で、ブラウザ検知が動作していなかった
  • dobuleとfloatの-0.0と0.0はJavaの中では別扱いされるようになった
    • よくわからない…。doubleとfloatの-0.0が、SQL文上-CAST(0.0 as DOUBLE),-CAST(0.0 as REAL)と扱われる?
  • TCP/PGサーバ: デフォルトポートが使用されていた場合、別の空きポートで起動するようになった(ポート番号が明示的にセットされていた場合を除く)。これにより、TCPサーバもしくはPGサーバが既に起動していた場合でも、H2コンソールが起動できる。
    • 明示的にtcp/pgのポートが設定されていなかった場合、それらのサーバが起動するときにDbExceptionを投げる事がなくなる(開いているポートを探すので)のだけれど、DbExceptionが投げられても、H2コンソールは起動していたので、あんまり関係ないような。
  • LIKEで右辺値にリテラルもしくはパラメータが使われているとき以外インデックスが使用されなかった。LIKE CONCAT(?, '%')でもインデックスが使われるようになった。
    • 地味だけど効く改善。1.3.148だとテーブルスキャンになっている。
Welcome to H2 Shell 1.3.148 (2010-12-12)
Exit with Ctrl+C
Commands are case insensitive; SQL statements end with ';'
help or ?      Display this help
list           Toggle result list / stack trace mode
maxwidth       Set maximum column width (default is 100)
show           List all tables
describe       Describe a table
autocommit     Enable or disable autocommit
history        Show the last 20 statements
quit or exit   Close the connection and exit

sql> create table hoge (id int, val varchar);
(Update count: 0, 6 ms)
sql> create index on hoge(val);
(Update count: 0, 1 ms)
sql> explain select * from hoge where val like ? || '%' {1: 'test'};
PLAN
SELECT HOGE.ID, HOGE.VAL
FROM PUBLIC.HOGE /* PUBLIC.HOGE.tableScan */
WHERE VAL LIKE (?1 || '%')
(1 row, 98 ms)
sql> 
    • 1.3.152だと、前方一致でインデックスが使われている。こういうケースだと、アプリケーション側で既に%を付加してくる場合の方が多いとは思うけれども、これがありなら、こっちがいいという作りのアプリもあるだろうと思う。
Welcome to H2 Shell 1.3.152 (2011-03-01)
Exit with Ctrl+C
Commands are case insensitive; SQL statements end with ';'
help or ?      Display this help
list           Toggle result list / stack trace mode
maxwidth       Set maximum column width (default is 100)
show           List all tables
describe       Describe a table
autocommit     Enable or disable autocommit
history        Show the last 20 statements
quit or exit   Close the connection and exit

sql> create table hoge (id int, val varchar);
(Update count: 0, 3 ms)
sql> create index on hoge(val);
(Update count: 0, 1 ms)
sql> explain select * from hoge where val like ? || '%' {1: 'test'};
PLAN
SELECT
    HOGE.ID,
    HOGE.VAL
FROM PUBLIC.HOGE
    /* PUBLIC.INDEX_2: VAL >= 'test'
        AND VAL < 'tesu'
     */
WHERE VAL LIKE (?1 || '%')
(1 row, 52 ms)
sql> 
    • ところで{1: 'test'}ってのは、H2独自の書き方なのかな。今回初めて知った。
  • Arrayのリテラルで、要素が0もしくは1の場合に正確にパースされなかった。現在、最後についているカンマは無視される。'(1)'は、今現在も1として解釈される。空のArrayは、'()'。1つの要素だけを含むArrayは、'(1,)'のようにカンマを含む事でarrayとしてパースされる。
  • Issue 290: サブクエリを使用している条件がシンプルな条件になる前に複数回評価される事があった。これはパフォーマンスに多大な悪影響を及ぼしていた。これは、値を返すサブクエリ、EXISTSサブクエリ、そして、IN (SELECT ..)のサブクエリが含まれる。
    • Issue 290によれば、400秒かかってたのが、0.01秒になったケースがあったとか。
  • Issue 288: 右外部結合かネストした結合を含むいくつかのクエリで、NullPointerExceptionを投げるケースがあった。
  • Java7でコンパイルできるようになった。JDBC4.1の新しいメソッドに対するスタブは実装済み。ただし、機能自体は実装されていない。
  • Issue 289: 「カラム定義」のレイルロードダイアグラム(BNF)が不正確だった
  • Issue 287: 特定のウェブブラウザの設定(背景が暗色)で、レイルロードダイアグラム(BNF)が読めなかった
  • CSVREADを複数回実行する間にデータがディスク上で変更されると例外が発生する事があった
  • SQLレイルロードダイアグラム: 背景色が黒の設定の人に対する、画像の改善。
    • 二つ上と同じ?
  • 組み込みのドキュメンテーションサーチ: 複数語によるサーチ結果の改善
  • DatabaseMetaData.getColumns: JDBCの仕様に誤字があり、そのため、19番目のカラムはSCOPE_CATALOGではなくSCOPE_CATLOGとなっている。仕様との適合性のため、新しい24番目のカラムとしてSCOPE_CATLOGを追加。この誤字はJDBC4.1仕様で修正される。MySQLはSCOPE_CATALOGのみサポートしており、それ以外のデータベースはSCOPE_CATLOGのみサポートしている点に注意が必要。
    • 原文自体まちがっているような…。ソースコードを見てみると、19番目は元々SCOPE_CATALOGだったのが、SCOPE_CATLOGに変更されており、24番目に追加されているのはSCOPE_CATALOG。
  • ビルド: jar fileが可能であればMavenを使ってダウンロードされる(また、ローカルのMaven repositoryにキャッシュされる) あいにく多くのケースではこの変更で、より多くのデータをMaven repositoryからダウンロードする事になる
    • まぁ、一回ダウンロードしてきたら、あとはキャッシュされるので。ところで前からビルドの際にmvnって必要だったんだっけ。
  • JaQuの多数の改善。新しいコミッタ James Mogerに感謝。
  • 新しいサンプルアプリケーション。instead ofトリガーを使用して、どのように更新可能なビューをサポートするか。
  • H2コンソール: MS SQL Serverを開くのが速くなった。また、データベースメタデータを列挙する際に、時々例外が発生していた点を修正。
  • Linked tables / MS SQL Server: MS SQL Serverでテーブルが大文字小文字混在で作成された場合、テーブル名がH2内でケースセンシティブになっていた。
  • MVCC: 複数のスレッドが同じ行を更新した場合のロックタイムアウトになる可能性が少し低下した
  • ドキュメンテーションのみ(クラスのビルドなし)のビルドが動作していなかった。特に、./build.sh clean javadocImpl.
  • 内部的にどのようにデータがストアされ、インデックスはどのように動作するのかについてドキュメントに記載(パフォーマンスセクション)
  • 何人かの人から、FileObjectDiskMappedでNullPointerExceptionが発生するとの報告。最もありそうな原因は複数のスレッドによる同じオブジェクトへの同時アクセス。そこで、このクラスのパブリックメソッドを同期化した
  • サーバー開始時に不正な引数のエラー検知の改善。例えば、"-tcpPort", "9091"の代わりに、"-tcpPort=9091"や"-tcpPort 9091"(一つの引数として)を渡した場合。
  • 関数STRINGDECODEがエスケープされていないダブルクオート以降を無視していた。修正済み。
    • 1.3.148。"で切れてしまっている。
sql> call stringdecode('test"hoge');
'test'
test
(1 row, 1 ms)
    • 1.3.152
sql> call stringdecode('test"hoge');
'test"hoge'
test"hoge
(1 row, 0 ms)
  • 1.3.150で導入された新しいCSVオプションで複数のスペースをサポートしていなかった。現在エスケープの仕組みを変更し、サポートするように。
  • 疑似列 "_ROWID_"がinsert,updateとmergeをサポート(現在version 1.3.xでのみ有効)
  • そのトリガーの対象のテーブルの行をトリガーの中で削除するとNullPointerExceptionになっていた。