Thread: MAX関数に関する報告

MAX関数に関する報告

From
"y_takesue"
Date:
PostgreSQL7.4 および PostgreSQL8.1 の間でMAX関数による出力結果の違いがありましたので報告いたします。

--テスト用テーブルの作成
create table b (
  item1 char(10),
  item2 varchar(10)
);

--データの追加
insert into b (
  item1,
  item2
) values (
  '1234',
  '5678'
);
insert into b (
  item1,
  item2
) values (
  'ABCD',
  'EFGH'
);

--データの抽出
select max(item1) as item1
     , max(item2) as item2
  from b
;

□7.4での出力結果
item1    item2
----------------
ABCD    EFGH

□8.1での出力結果
item1    item2
---------------------
ABCD          EFGH

となります。
item1がchar型のとき、パディングされている後方スペースがPostgreSQL8.1では取り除かれていませんでした。

仕様変更点および、過去のバグ報告にも記載がな買った内容のため、報告させていただきます。


よろしくお願いいたします。



Re: MAX関数に関する報告

From
ITAGAKI Takahiro
Date:
"y_takesue" <ytakesue05@hotmail.com> wrote:

> PostgreSQL7.4 および PostgreSQL8.1 の間でMAX関数による出力結果の違いがありましたので報告いたします。
> item1がchar型のとき、パディングされている後方スペースがPostgreSQL8.1では取り除かれていませんでした。

リリースノートを見ても、どこで変更されたか特定できませんでしたが、
max() が text 型のみだけではなく、char 型のサポートが追加されたことが
影響しているようです。max() 後の値を必要な型に明示的にキャストするのが
安全だと思われます。

----

BTW, max() returns bpchar type for char(10) and text for varchar(10) in HEAD.
The type modifiers are lost. Is it a limitation?

postgres=# \d b
              Table "public.b"
 Column |         Type          | Modifiers
--------+-----------------------+-----------
 item1  | character(10)         |
 item2  | character varying(10) |

postgres=# select max(item1) as item1
           , max(item2) as item2
           into result from b;

[in 7.4]
postgres=# \d result
   Table "public.result"
 Column | Type | Modifiers
--------+------+-----------
 item1  | text |             <- not a char(10)
 item2  | text |             <- not a varchar(10)

[in HEAD]
postgres=# \d result
    Table "public.result"
 Column |  Type  | Modifiers
--------+--------+-----------
 item1  | bpchar |            <- type modifier 10 is lost
 item2  | text   |            <- type modifier 10 is lost

postgres=# EXPLAIN VERBOSE select max(item1) as item1
                           , max(item2) as item2
                           into result from b;
                        QUERY PLAN
-----------------------------------------------------------
 Aggregate  (cost=20.81..20.81 rows=1 width=82)
   Output: max(item1), max((item2)::text)
   ->  Seq Scan on b  (cost=0.00..17.20 rows=720 width=82)
         Output: item1, item2
(4 rows)

Regards,
---
ITAGAKI Takahiro
NTT Open Source Software Center