[pgsql-jp: 33344] Postgresql7.4.2 char列に対するmax関数の動作が7.3.3と異なる

aya shigeto_aya_za @ mail.toyota.co.jp
2004年 6月 23日 (水) 02:37:40 JST


綾 重人と申します。

PostgreSQL7.3.3で正常に動いていたecpgプログラムを
PostgreSQL7.4.2にしてコンパイルしたところ動きが異なりました。

not null制約のあるchar(1)型の列に対し、max関数で問合せを実行したところ、
見つかるはずのデータがブランクの場合、ホスト変数にブランクが入りません。
sqlcodeを見ると0が戻っているのでデータは1件とれていると思います。

Postgresql7.3.3の場合、ホスト変数に正常にブランクが入ります。

仕様が変わったのかと思いバージョンがあがったときの
変更点を一通りみたのですが、見つけることが出来ませんでした、、
char型の列に集計関数を使うのがおかしいと言われると
確かにそうかと思うのですが、スペース以外の場合は
値が戻ってくるので、動くようにも思えます。
バグのように感じているのですが、どうでしょうか、、、


以下にサンプルソースをのせます。
row1 char(1) not nullという列を持つテーブルに用意し、
その列にブランクデータをinsertし、それをmax関数で呼び出すという
サンプルプログラムです。

     1  #include <stdio.h>
     2  /* #include
</usr/local/src/postgresql-7.4.2/src/interfaces/ecpg/include/sqlca.h> */
     3
     4  #include <sqlca.h>
     5
     6  void dbclose(void);
     7  void dbopen(void);
     8  void error_exit(void);
     9
    10  int main(int argc, char* argv[]){
    11
    12      /* ホスト変数 */
    13      exec sql begin declare section;
    14          char host_row1[2];
    15          short ind_row1;
    16      exec sql end declare section;
    17
    18      /* データベースopen */
    19      dbopen();
    20
    21      /* トランザクションレベル */
    22      exec sql set transaction isolation level read committed;
    23
    24      exec sql whenever sqlerror continue;
    25
    26      /* テーブル削除 */
    27         EXEC SQL drop table tmptable;
    28          printf("drop sqlcode %d\n",sqlca.sqlcode);
    29
    30      /* テーブル作成 */
    31      EXEC SQL create table tmptable ( row1 char(1) not null );
    32          printf("create sqlcode %d\n",sqlca.sqlcode);
    33
    34      /* 静的に通常のデータinsert */
    35      EXEC SQL insert into tmptable values (' ');
    36          printf("insert sqlcode %d\n",sqlca.sqlcode);
    37
    38      EXEC SQL declare aya_cur cursor for select max(row1) from
tmptable;
    39          printf("declare select * from tmptable sqlcode
%d\n",sqlca.sqlcode);
    40
    41      EXEC SQL open aya_cur ;
    42          printf("open sqlcode %d\n",sqlca.sqlcode);
    43
    44      while(1){
    45          memset(host_row1,'\0',sizeof(host_row1));
    46          ind_row1=0;
    47
    48          EXEC SQL fetch aya_cur into :host_row1:ind_row1;
    49
    50              printf("fetch sqlcode=%d error_msg=%s\n",sqlca.sqlcode,
    51
sqlca.sqlerrm.sqlerrmc);
    52
    53          if (sqlca.sqlcode == 100 ) {
    54              break;
    55          }
    56
    57          if (ind_row1 == -1 ){
    58              printf("row1 is null\n");
    59          } else {
    60              printf("row1 [%s]\n",host_row1);
    61          }
    62      }
    63
    64      exec sql commit work;
    65
    66      dbclose();
    67
    68      exit(0);
    69
    70  }
    71
    72  /* エラー処理 */
    73  void error_exit(void){
    74      fprintf(stderr, "PostgreSQL error : %d[%.*s]\n",
    75              sqlca.sqlcode, sqlca.sqlerrm.sqlerrml,
sqlca.sqlerrm.sqlerrmc);
    76
    77      exec sql whenever sqlerror continue;
    78      exec sql rollback;
    79      exec sql disconnect;
    80
    81      exit(1);
    82  }
    83
    84  void dbopen(void){
    85      /* データベースに接続 */
    86      /* 何らかのエラーが発生した場合は関数 error_exit() をコール
する */
    87      exec sql whenever sqlerror do error_exit();
    88      /* データベース bookmark へユーザ dbuser として接続する */
    89      exec sql connect to aya user aya;
    90  }
    91
    92  void dbclose(void){
    93      /* データベース切り離し postgres_sqlca*/
    94      exec sql disconnect;
    95  }





pgsql-jp メーリングリストの案内