[pgsql-jp: 38578] Re: select テーブル名とは?

Tomoaki Sato sato @ sraoss.co.jp
2007年 7月 16日 (月) 04:10:51 JST


佐藤です。

反応が遅くなってしまいましたが、気になったので調べてみました。

"kawa" <kawa @ g-planets.com> wrote:
>  こんちには、kawaと申します。
> マニュアルを見てみましたが、該当箇所が分からなかったので質問します。
> 
> SELECTコマンドのカラム名を入れるところを間違えてテーブル名を入れて
> しまったところエラーとはならずに、それなりに出力されてしまいました。
> 
> ○ 例
> test=> select master_ken from master_ken;
>    master_ken
> -----------------
>  (1,北海道,1)
>  (2,青森県,2)
>  (3,岩手県,2)
> .....
> 
> ○ 環境
>  OS: Centos 5
>  postgresql-8.2.4
> 
> ○ テーブル構成
> test=> \d master_ken
>    Table "public.master_ken"
>   Column  |  Type   | Modifiers
> ----------+---------+-----------
>  ken_id   | integer | not null
>  ken_name | text    | not null
>  area_id  | integer | not null
> 
>  カラム名に「master_ken」と言うのは存在しません。また、ユーザ定義関数等も
> ありません。他のテーブルでも試してみましたが、上記と同じように出力されます。
> 
> ここで、質問なのですが、このような動作は、仕様なのでしょうか?

これは PostgreSQL の仕様だと思います。

マニュアルには書かれていないようですが、8.0 以降ではソースコードに列と
して参照できない場合はテーブルとして参照すると書いてあります。

src/backend/parser/parse_expr.c:
| static Node *
| transformColumnRef(ParseState *pstate, ColumnRef *cref)
| {
|     int         numnames = list_length(cref->fields);
|     Node       *node;
|     int         levels_up;
| 
|     /*----------
|      * The allowed syntaxes are:
|      *
|      * A        First try to resolve as unqualified column name;
|      *          if no luck, try to resolve as unqualified table name (A.*).
|      * A.B      A is an unqualified table name; B is either a
|      *          column or function name (trying column name first).

ちなみに 7.4 ではエラーになります。

=> SELECT accounts FROM accounts;
ERROR:  relation reference "accounts" cannot be used as a select-list entry
HINT:  Write "accounts".* to denote all the columns of the relation.

> また、仕様だとしたら、どのようなケースの時に役に立つのでしょうか。

どのような場合に役に立つかと聞かれると、複合型として値を取り出したい場
合になります。例えば、それを複合型の列を持ったテーブルに入れる場合や、
複合型の引き数を受け付ける関数に渡す場合といったところでしょうか。

ただし、テーブル名と同じ列名が存在すると列名が優先されてしまうので、あ
まり進んで使うべきものではないと思います。

複合型として値を取り出したいのであれば、以下のように行コンストラクタを
使ったほうがいいと思います。

  SELECT ROW(ken_id, ken_name, area_id) FROM master_ken;
  SELECT ROW(master_ken.*) FROM master_ken; -- 8.2 以降

> 特に今、困っているわけでも、このような使い方をしたいわけでもないのですが、
> かなりびっくりしたので、質問させてもらいました。
> 
> ご存知の方がいらっしゃれば、よろしくお願いします。


----
Tomoaki Sato <sato @ sraoss.co.jp>
SRA OSS, Inc. Japan



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