PostgreSQLのデータ型は、基本型、コンテナ型、ドメイン、疑似型に分類されます。
基本型はinteger
のように、SQL言語レベル以下で実装されたものです
(通常はCのような低レベル言語で作成されます)。
一般的にこれらは抽象データ型とも呼ばれるものに対応します。
PostgreSQLは、ユーザによって提供された関数を通してのみ、こうした型に対する操作が可能で、また、こうした型の動作をユーザが記述する限りにおいてのみ理解します。
組み込みの基本型は、第8章に記載されています。
列挙(enum)型は基本型の一種とみなすことができます。 主な違いは、列挙型は低レベルプログラミング無しに、SQLコマンドだけで作ることができることです。 より詳細については、8.7を参照してください。
PostgreSQLには三種類の「コンテナ」型があります。これは他の型の複数の値を含む型です。 配列、複合型、範囲型があります。
配列は、全て同じ型の複数の値を保持できます。 配列型は各基本型、複合型、範囲型およびドメイン型に対して自動的に作られます。 しかし、配列の配列はありません。 この型システムにおいては多次元配列は一次元配列と同じです。 より詳細については、8.15を参照してください。
ユーザがテーブルを作成すると、複合型、もしくは行型が作成されます。 関連するテーブルを持たない「スタンドアローン」の複合型をCREATE TYPEを使用して定義することもできます。 複合型は関連したフィールド名を持つ基本型の単なるリストです。 複合型の値は行もしくはフィールド値のレコードです。 より詳細については、8.16を参照してください。
範囲型は同じ型の二つの値を保持できます。これらは範囲の下限と上限です。 範囲型はユーザによって作られますが、少数の組み込みの型もあります。 より詳細については、8.17を参照してください。
ドメインは、特定の元となる型に基づいたもので、多くの目的では、その元となる型と交換可能です。 しかし、ドメインは元となる基本型で許可される範囲内で値の有効範囲を制限する制約を持つことができます。 ドメインはSQLコマンドのCREATE DOMAINを使って作られます。 より詳細については、8.18を参照してください。
特殊な目的用に数個の「疑似型」があります。 疑似型はテーブルの列やコンテナ型の構成要素として現れることはありません。 しかし、関数の引数や結果型を宣言する際に使用できます。 これは、型システム内で特殊な関数クラスを識別するための機構を提供します。 表 8.27に既存の疑似型を列挙します。
いくつかの特殊な用途を持つ疑似型は多様型で、多様関数を宣言するのに使われます。 この強力な機能により、特定の呼び出しで実際に渡されたデータ型で決定される具体的なデータ型について、一つの関数定義で多数の異なるデータ型を処理できるようになります。 多様型を表 38.1に示します。 これらの使用例は38.5.11にあります。
表38.1 多様型
名前 | 族 | 説明 |
---|---|---|
anyelement | Simple | 関数があらゆるデータ型を受け付けることを示します |
anyarray | Simple | 関数があらゆる配列データ型を受け付けることを示します |
anynonarray | Simple | 関数があらゆる配列でないデータ型を受け付けることを示します |
anyenum | Simple | 関数があらゆる列挙型(8.7を参照)を受け付けることを示します |
anyrange | Simple | 関数があらゆる範囲データ型(8.17を参照)を受け付けることを示します |
anymultirange | Simple | 関数があらゆる多重範囲データ型(8.17を参照)を受け付けることを示します |
anycompatible | Common | さまざまな引数の共通データ型への自動昇格によって、関数があらゆるデータ型を受け付けることを示します |
anycompatiblearray | Common | さまざまな引数の共通データ型への自動昇格によって、関数があらゆる配列データ型を受け付けることを示します |
anycompatiblenonarray | Common | さまざまな引数の共通データ型への自動昇格によって、関数があらゆる配列でないデータ型を受け付けることを示します |
anycompatiblerange | Common | さまざまな引数の共通データ型への自動昇格によって、配列があらゆる範囲データ型を受け付けることを示します |
anycompatiblemultirange | Common | さまざまな引数の共通データ型への自動昇格によって、配列があらゆる多重範囲データ型を受け付けることを示します |
多様の引数と結果は互いに結びつけられていて、多様関数を呼ぶ問い合わせが解析されるときに特定のデータ型に決定されます。 2つ以上の多様引数がある時には、入力値の実データ型は後述するように合わせなければなりません。 関数の結果型が多様、あるいは、多様型の出力パラメータを持つ場合には、それらの結果の型は後述するように多様入力の実際の型から導出されます。
多様型の「simple」族では、一致と導出の規則は以下のように動作します。
anyelement
として宣言された位置(引数もしくは戻り値)にはそれぞれ、任意の実データ型を指定できますが、1つの呼び出しでは、これらはすべて同一の実データ型でなければなりません。
anyarray
として宣言された位置にはそれぞれ、任意の配列データ型を持つことができますが、同様にこれらはすべて同じデータ型でなければなりません。
anyrange
と宣言された位置にはそれぞれ、同様にすべて同じ範囲型でなければなりません。
anymultirange
についても同様です。
さらに、anyarray
と宣言された位置とanyelement
と宣言された位置の両方がある場合、anyarray
の位置の実際の配列型は、その要素の型がanyelement
位置に現れる型と同じでなければなりません。
anynonarray
は、実際の型が配列型であってはならないという制限が加わっている点を除き、anyelement
とまったく同様に扱われます。
anyenum
は、実際の型が列挙型でなければならないという制約が加わっている点を除き、anyelement
とまったく同様に扱われます。
同様にanyrange
と宣言された位置とanyelement
もしくはanyarray
と宣言された位置の両方がある場合、anyrange
の位置の実際の範囲型は、その範囲の派生元型がanyelement
位置に現れる型と同じであり、anyarray
位置の要素の型と同じでなければなりません。
anymultirange
と宣言された位置がある場合、実際の多重範囲型には、宣言された位置とanyrange
が一致する範囲と、宣言された位置anyelement
およびanyarray
と一致する基本要素が含まれている必要があります。
このように、2つ以上の引数位置が多様型と宣言されると、全体の効果として、実引数型の特定の組み合わせのみが許されるようになります。
例えば、equal(anyelement, anyelement)
と宣言された関数は、2つの引数が同じデータ型である限り、任意の入力値を2つ取ることになります。
関数の戻り値を多様型として宣言する時、少なくとも1つの引数位置も多様でなければなりません。
そして多様の引数として与えられる実データ型がその呼び出しの実結果型を決定します。
例えば、配列添字機構がなかったとすると、subscript(anyarray, integer) returns anyelement
として添字機構を実装する関数を定義できます。
この宣言で最初の実引数は配列型に制約され、パーサはこの最初の実引数の型から正しい結果型を推論できます。
他にも例えば、f(anyarray) returns anyenum
と宣言された関数は列挙型の配列のみを受け付けます。
ほとんどの場合、パーサは同じ族の異なる多様型の引数から多様結果型の実データ型を推論できます。
例えば、anyarray
をanyelement
から、もしくはその逆から推定できます。
例外はanyrange
型の多様結果はanyrange
型の引数を必要とします。
anyarray
もしくはanyelement
の引数からは推定できません。
これは、同じ派生元型の複数の範囲型が存在する可能性があるためです。
anynonarray
型とanyenum
型が、別個の型変数を表していないことに注意してください。
これはanyelement
と同じ型で、追加の制約が付いているだけです。
例えば、f(anyelement, anyenum)
として関数を宣言することは、f(anyenum, anyenum)
と宣言することと同一です。
両方の実引数は同じ列挙型でなければなりません。
多様型の「common」族については、一致と導出の規則は概ね「simple」と同じに動作しますが、一つの大きな違いがあります。
一つの共通型へ暗黙にキャスト可能である限り、引数の実際の型が同一である必要がありません。
共通型はUNION
や関連する構文と同じ規則(10.5を参照)に従って選択されます。
共通型の選択では、anycompatible
やanycompatiblenonarray
の入力の実際の型、anycompatiblearray
入力の配列要素型、anycompatiblerange
入力の範囲型とanycompatiblemultirange
入力の多重範囲型、anycompatiblerange
入力の範囲の派生元型が、考慮されます。
anycompatiblenonarray
が存在する場合、共通型は配列でない型である必要があります。
共通データ型が特定されたなら、anycompatible
およびanycompatiblenonarray
の位置の引数は自動的にその型にキャストされ、anycompatiblearray
位置の引数は自動的にその型に対する配列にキャストされます。
その派生元型だけ分かっている範囲型を選択する方法がないため、anycompatiblerange
および/またはanycompatiblemultirange
の使用には、その型で宣言されているすべての引数が同じ実際の範囲型および/または多重範囲型を持ち、また、その型の派生元型は選択された共通型に即したものである必要があり、そのため、範囲値のキャストは必要ありません。
anyrange
およびanymultirange
と同様に、anycompatiblerange
およびanymultirange
を関数の結果型として使用するには、anycompatiblerange
またはanycompatiblemultirange
の引数がある必要があります。
anycompatibleenum
型は無いことに注意してください。
通常、列挙型への暗黙キャストはありません。これは異なる列挙入力に対する共通型を決める方法が無いことを意味します。そのため、このような型はあまり有益ではないでしょう。
「simple」と「common」の多様族は型変数の二つの独立したセットに相当します。 例えば以下を考えてください。
CREATE FUNCTION myfunc(a anyelement, b anyelement, c anycompatible, d anycompatible) RETURNS anycompatible AS ...
この関数の実際の呼び出しでは、最初の2つの入力は正確に同じ型を持たなければなりません。 最後の2つの入力は共通型に昇格できなければなりませんが、この型が最初の2つの入力型と何らか関係がある必要はありません。 結果は最後の2つの入力の共通型を持ちます。
可変長引数の関数(38.5.6で説明する可変個の引数を取る関数)を多様とすることができます。
最後のパラメータをVARIADIC
anyarray
またはVARIADIC
anycompatiblearray
と宣言することで実現されます。
引数を一致させ、実際の結果型を決めるために、こうした関数はanynonarray
またはanycompatiblenonarray
パラメータをあたかも適切な個数記述した場合と同様に動作します