TYPEは、現在のデータベースで使用できる新しいデータ型を登録します。型を定義したユーザがその所有者となります。スキーマ名が与えられている場合、型は指定されたスキーマに作成されます。スキーマ名がなければ、その型は現在のスキーマに作成されます。(さらに、テーブルはデータ型と関連しているため、データ型名は同じスキーマのテーブル名とも競合しないようにしてください)。TYPEには5つの構文があります。シェル型を作成します。これらの内最初の4個についてはここで順番に説明します。TYPEを実行することで作成されます。シェル型は、範囲型と基本型を作成するときの前方参照として必要となるもので、それぞれの節で説明します。TYPEの最初の構文を使用すると、複合型を作成できます。複合型は、属性名およびデータ型のリストにより指定されます。データ型の照合順序が設定可能である場合、属性の照合順序も指定することができます。複合型は本質的にはテーブルの行型と同じです。TYPEを使用することで、実際のテーブルを作成する必要がなくなります。スタンドアロンの複合型は、例えば関数の引数や戻り値の型として有用です。複合型を作成するためには、すべての属性型に対してUSAGE権限を持たなければなりません。列挙型で説明する列挙型(enum)を作成します。列挙型は、1つ以上の引用符付きのラベルのリストを取ります。ラベルはNAMEDATALEN(PostgreSQLの標準のビルドでは64バイト)バイトよりも少ない長さでなければなりません。範囲型で説明する範囲型を新規に作成します。範囲型のsubtypeは、関連する(範囲型の値を順序を決定するための)b-tree演算子クラスを持つ任意の型を取ることができます。通常、派生元型のデフォルトのb-tree演算子クラスが順序を決定するために使用されます。デフォルト以外の演算子クラスを使用するためには、subtype_opclassでその名前を指定してください。派生元型が照合順序変更可能であり、範囲の順序付けでデフォルト以外の照合順序を使用したい場合は、collationオプションで使用したい照合順序を指定してください。canonical関数(省略可能)は、定義する範囲型の引数を1つ取り、同じ型の値を返さなければなりません。これは適切な時に範囲値を正規形式に変換するために使用されます。新しい範囲型の定義を参照してください。canonical関数を作成することは多少厄介です、というのは、範囲型を定義できるようになる前に定義されている必要があるからです。このためには、まず、名前と所有者以外の属性を持たないプレースホルダであるシェル型を作成しなければなりません。nameを実行することで行われます。その後、このシェル型を引数と結果として使用する関数を宣言することができます。最後に同じ名前を用いて範囲型を宣言することができます。これは自動的にシェル型の項目を有効な範囲型に置き換えます。precision型を返さなければなりません。これは省略することができますが、提供することでその範囲型の列に対するGiSTインデックスの効率を大きく向上させることができます。新しい範囲型の定義を参照してください。TYPEの4つ目の構文を使用すると、基本型(スカラ型)を新しく作成できます。新しい基本型を作成するにはスーパーユーザでなければなりません。(エラーがある型定義が混乱を招き、サーバがクラッシュすることすらあるため、この制限がなされました。)パラメータは、上述の順番である必要はなく、任意の順番で指定することができ、多くは省略可能です。FUNCTIONを用いて)2つ以上の関数を登録しておく必要があります。サポート関数であるinput_functionとoutput_functionは必須です。receive_function関数、send_function関数、type_modifier_input_function関数、type_modifier_output_function関数、およびanalyze_function関数は省略可能です。通常、これらの関数は、C言語やその他の低レベル言語で作成されなければなりません。input_functionは、型のテキストによる外部表現を内部表現形式に変換するものであり、その型用に定義される演算子や関数で使用されます。output_functionはこの逆の変換を行うものです。入力関数は、1つのcstring型の引数、あるいは、cstring型、oid型、integer型という3つの引数を取るように宣言されます。(不明な場合は-1を渡します)。この入力関数では、データ型自身の値を返さなければなりません。通常入力関数はSTRICTとして宣言しなければなりません。しないと、NULLという入力値を読み取った時、NULLという最初のパラメータを持って呼び出されます。この場合でもエラーを発生させるのでなければ、関数はNULLを返さなければなりません。(こうした状況はほとんどの場合、ドメイン入力関数をサポートすることを意図しています。ドメイン入力関数ではNULL入力を拒絶しなければならない可能性があります。出力関数は、新しいデータ型の引数を1つ取るように宣言しなければなりません。出力関数は、cstring型を返さなければなりません。出力関数はNULL値に対して呼び出されることはありません。receive_functionでは、型のバイナリによる外部表現を内部表現に変換します。この関数は省略可能です。この関数が与えられない場合、この型ではバイナリ入力を行うことができません。(例えば標準の整数データ型は、外部バイナリ表現としてはネットワークバイトオーダを使用し、内部表現ではマシン固有のバイトオーダを使用します)。この受信関数では、値が有効かどうかを判定するための適切な検査を行わなければなりません。受信関数は、internal型の引数1つ、または、internal型とoid、integer型の3つの引数を取るように宣言されます。最初の引数は受信したバイト文字列を保持するStringInfoバッファへのポインタ、省略可能な引数は、テキスト入力関数の説明と同じです。受信関数は、データ型自体の値を返す必要があります。通常受信関数はSTRICTとして宣言しなければなりません。しないと、NULLという入力値を読み取った時、NULLという最初のパラメータを持って呼び出されます。この場合でも関数はエラーを発生させるのでなければNULLを返さなければなりません。(こうした状況はほとんどの場合、ドメイン受信関数をサポートすることを意図しています。ドメイン受信関数ではNULL入力を拒絶しなければならない可能性があります。同様に、send_functionは、内部表現からバイナリによる外部表現に変換します。この関数も省略可能です。この関数が与えられない場合、この型ではバイナリ出力を行うことができません。この送信関数は、新しいデータ型の引数1つを取るように宣言しなければなりません。送信関数はbytea型を返さなければなりません。送信関数はNULL値に対して呼び出されません。ここで、新しいデータ型を作成する前に入力関数と出力関数を作成する必要があるのに、どのようにしてそれらの関数で新しいデータ型を戻り値や入力として宣言できるのか、疑問に思うかもしれません。その答えは、まず型が最初にシェル型として定義されます。これは名称と所有者以外の属性を持たないプレースホルダ型です。nameを他にパラメータをつけずに発行することで行われます。この後、Cの入出力関数をこのシェル型を参照するように定義することができます。TYPEによって、シェル型の項目が完全かつ有効な型定義に置き換わり、新しい型を普通に使用することができるようになります。type_modifier_input_functionとtype_modifier_output_functionは必須ではありませんが、型が修飾子をサポートする場合は必要です。修飾子とは、char(5)やnumeric(30,2)などの型宣言に付与されるオプションの制約です。PostgreSQLでは、ユーザ定義型が1つ以上の整数定数または識別子を修飾子として取ることができます。この情報はシステムカタログに格納される時に0以上の整数1つにまとめられるものでなければなりません。type_modifier_input_functionには、cstring型配列の形で宣言された修飾子が渡されます。その値について妥当性を検査しなければなりません(不当な場合はエラーとします)。正しい場合は、「typmod」列として格納される、0以上のinteger値を1つ返さなければなりません。型がtype_modifier_input_functionを持たない場合、型修飾子は拒否されます。type_modifier_output_functionは内部的な整数typmod値をユーザ側の表示に合わせて変換します。この関数は型名に付与する正確な文字列となるcstring値を返さなければなりません。numeric用の関数では(30,2)を返すかもしれません。デフォルトの表示用書式が保管されたtypmod整数値を括弧で括ったものと一致している場合は、type_modifier_output_functionを省略することができます。オプションのanalyze_functionは、このデータ型の列に対する、型固有の統計情報の収集を行います。その型用のデフォルトのB-tree演算子クラスがあれば、ANALYZEはデフォルトでは型の「等価」演算子と「小なり」演算子を使用して統計情報を集めようと試みます。非スカラ型には、この振舞いはあまり適していません。そのため、独自の解析関数を指定することで、この振舞いを上書きすることができます。この解析関数は、internal型の引数を1つ取り、戻り値としてbooleanを返すように宣言する必要があります。解析関数用のAPIの詳細は、src/include/commands/vacuum.hにあります。新しい型の内部表現の詳細を理解しなければならないのは、これらのI/O関数とその型に関連して動作するユーザ定義の関数のみですが、内部表現には、PostgreSQLに対し宣言しなければならない複数の属性値があります。属性の中で最も重要なものはinternallengthです。(内部的には、これはtyplenを-1に設定することで表現されます)。全ての可変長型の内部表現は、型の値の全長を示す4バイトの整数値から始まらなければなりません。TOASTに記述されているようにエンコードされており、それに直接アクセスすることは賢明ではないことに注意してください。)オプションのPASSEDBYVALUEフラグは、このデータ型の値が参照ではなく値によって渡されることを示します。値によって渡される型は固定長でなければならず、その内部表現はDatum型のサイズ(4バイトのマシンもあれば8バイトのマシンもあります)を超えてはいけません。alignmentパラメータは、そのデータ型の格納の際に必要な整列を指定します。設定可能な値は、1、2、4、8バイト境界での整列です。可変長の型は最低でも4の整列を持たなければならないことに注意してください。最初の要素としてint4を持たなければならないからです。(固定長の型にはplainのみが使用できます)。plainを指定すると、その型のデータは常にインラインで格納され、圧縮されません。extendedを指定すると、システムはまず長いデータ値を圧縮しようとし、それでもまだ長過ぎる場合は値をメインテーブルの行から削除して移動します。externalはメインテーブルから値を削除して移動することを許しますが、システムはデータを圧縮しようとしません。(行を収めるために他に方法がない場合にはメインテーブルから削除されてしまう可能性がありますが、extendedやexternalが指定されたアイテムよりも優先してメインテーブルに残されます)。TOASTの考慮に記述されているようにtoastされた値を処理できることを暗示します。その他の特定の値を指定するのは、TOAST可能なデータ型の列について、単にデフォルトのTOAST戦略を決めるだけです。STORAGEを使って他の戦略を選択できます。like_typeパラメータは、何らかの既存のデータ型から複製するという、データ型の基本表現プロパティを指定する、別の方法を提供します。internallength、passedbyvalue、alignment、storageの値が指定された型から複製されます。(通常は望ましくありませんが、LIKE句と一緒にこれらの値を指定することで、値を上書きすることも可能です。新しい型の低レベル実装にある流儀に従った既存の型を「移す」時に、この方法で表現を指定することが特に有用です。categoryとpreferredパラメータは、あいまいな状況でどの暗黙的なキャストが適用されるかについての制御を補助するために使用することができます。各データ型は単一のASCII文字で命名されるカテゴリに属しており、各型はそのカテゴリ内で「優先される(preferred)」か否かです。オーバーロードされた関数または演算子の解決に、この規則が有用な場合には、パーサは優先される型へのキャストを優先します(ただし、同一のカテゴリ内の他の型からだけです)。詳細は10章型変換を参照してください。他の型への、または、ほかの型からの暗黙的なキャストを持たない型では、これらの設定をデフォルトのままにしておくことで十分です。暗黙的なキャストを持つ関連する型のグループでは、それらすべてを1つのカテゴリに属すものとし、「最も汎用的な」型の1つまたは2つをカテゴリ内で優先されるものとして選択することが有用となる場合が多くあります。ユーザ定義型を、数値型や文字列型などの既存の組み込みカテゴリに追加する場合に、categoryパラメータは特に有用です。完全にユーザ定義の新しい型カテゴリを作成することもできます。そのようなカテゴリの命名には大文字以外の任意のASCII文字を選択してください。ユーザがそのデータ型の列のデフォルトをNULL以外にしたい場合は、デフォルト値を指定することができます。(この方法で指定されたデフォルト値を、特定の列に付与された、明示的なDEFAULT句によって上書きすることができます)。データ型が配列であることを示すには、ELEMENTキーワードを使用して配列要素の型を指定してください。int4と指定してください。配列型の詳細は後述します。この型による配列の外部形式における値間の区切り文字を示すために、delimiterで特定の文字を設定することができます。デフォルトの区切り文字はカンマ(',')です。この区切り文字は、配列要素の型に関係するものであり、配列型自体に関係するものでないことに注意してください。論理型のcollatableパラメータ(省略可能)が真の場合、COLLATE句を使用することによって、型の列定義と式は照合順序情報を持つことができます。照合順序情報を実際に使用するかどうかは、型に対する操作を行う関数実装に任されています。照合順序を設定可能な型を作成することにより、これが自動的に行われることはありません。配列型ユーザ定義型が作成されると、PostgreSQLは、自動的に関連する配列型を作成します。その要素型の名前の前にアンダースコアを付け、必要に応じてNAMEDATALEN長より短くなるように切り詰められた名前になります。(こうして付けられた名前が既存の型名と競合する場合、競合する名称がなくなるまでこの処理が繰り返されます。この暗黙的に作成される配列型は可変長で、組み込み入出力関数array_inとarray_outを使用します。配列型はその要素となる型の所有者とスキーマのなんらかの変更に追従し、また、要素となる型が削除された場合に削除されます。「システムが自動的に配列型を正しく作成するのであれば、ELEMENTオプションはどうして存在するのだろう」と疑問に思うのも道理です。ELEMENTが意味を持つ、唯一の場合は次のような条件を満たす固定長の型を作成する時です。その条件とは、内部的に複数の同一の要素からなる配列となっていること、その配列に対して添字を指定して直接アクセスできること、加えて、今後作成する型全体に対する操作がどのようなものであっても、それらから直接アクセスできることです。point型は、2つの浮動小数点だけから構成され、それらはpoint[0]およびpoint[1]を用いてアクセスすることができます。この機能は、その内部形式が同一の固定長フィールドの正確な並びである、固定長の型でのみ動作することに注意してください。添字による指定が可能な可変長型は、array_inとarray_outを使用して、一般化された内部表現を持つ必要があります。歴史的な理由(明らかに間違いなのですが、変更するには遅すぎたため)により、固定長配列型への要素番号指定は0から始まり、可変長配列の場合は1から始まります。パラメータname作成するデータ型の名前です(スキーマ修飾名も可)。attribute_name複合型用の属性(列)名です。data_type複合型の列となる、既存のデータ型の名前です。collation複合型の列または範囲型に関連付けされる、既存の照合順序の名前です。label列挙型の1つの値に関連付けられるテキスト形式のラベルを表す、文字列リテラルです。subtype範囲型がその範囲の対象として表現する、要素型の名前です。subtype_operator_class派生元型のb-tree演算子クラスの名前です。canonical_function範囲型の正規化関数の名前です。subtype_diff_function派生元型の差異をとる関数の名前です。input_function指定された型のテキストによる外部形式のデータを内部形式に変換する関数の名前です。output_function指定された型の内部形式のデータをテキストによる外部形式に変換する関数の名前です。receive_function指定された型のバイナリによる外部形式のデータを内部形式に変換する関数の名前です。send_function指定された型の内部形式のデータをバイナリによる外部形式に変換する関数の名前です。type_modifier_input_function型に関する修飾子の配列を内部形式に変換する関数の名前です。type_modifier_output_function内部形式の型修飾子をテキストの外部形式に変換する関数の名前です。analyze_function指定したデータ型の統計情報解析を行う関数の名前です。internallength新しいデータ型の内部表現のバイト長を表す数値定数です。デフォルトでは、可変長であるとみなされます。alignmentデータ型の格納整列条件です。このオプションを指定する場合は、char、int2、int4、doubleのいずれかでなければなりません。デフォルトはint4です。storageデータ型の格納戦略です。このオプションを指定する場合は、plain、external、extended、mainのいずれかでなければなりません。デフォルトはplainです。like_type新しい型に同じ表現を持たせる既存のデータ型の名前です。TYPEコマンドのどこかで明示的な指定により上書きされない限り、型から複製されます。categoryこの型用のカテゴリコード(単一のASCII文字)です。デフォルトは「ユーザ定義型」を表す'U'です。他の標準カテゴリコードを表49.55「typcategoryのコード」に示します。独自のカテゴリを作成するために他のASCII文字を選択することもできます。preferredこの型がカテゴリ内で優先される型である場合に真、さもなくば偽です。動作に予想外の変化を引き起こしますので既存の型カテゴリに新しく優先される型を作成することには十分注意してください。defaultそのデータ型のデフォルト値です。省略された場合、デフォルトはNULLです。element配列型を作成する場合、その配列の要素の型を指定します。delimiterこのデータ型による配列で、値間の区切り文字として使われる文字です。collatableこの型を操作する時に照合順序情報を使用することができる場合に真を取ります。一度作成したデータ型の使用には制限はありませんので、基本型または範囲型の作成は型定義で言及した関数の実行権をPUBLICに対して付与することと同じです。この種の型定義において有用な関数では、これは通常問題になりません。外部形式から、または、外部形式への変換を行う時に、その関数が「秘密の」情報を必要とする場合、型を設計する前に熟考してください。PostgreSQLバージョン8.3より前のバージョンでは、生成される配列型の名前は常に要素型の名前の前に1つのアンダースコア文字(_)を付けたものになりました。(このため型の名前は他の名前よりも1文字短く制限されていました。通常はこのように名付けられることは変わりありませんが、最大長の名前の場合やアンダースコアから始まるユーザ定義の型と競合する場合、配列型の名前はこの変換とは変わることがあります。このため、この規則に依存したコードを書くことは避けてください。代わりに、pg_type.typarrayを使用して、指定した型に関連した配列型を特定してください。アンダースコアから始まる型やテーブル名の使用を避けることが賢明です。サーバは生成された配列型名称をユーザ指定の名前と競合しないように変更しますが、混乱する危険があります。古いクライアントソフトウェアを使用する場合、名前がアンダースコアから始まる型を常に配列を表すものと想定しているかもしれません。name構文は存在しません。新規に基本型を作成する方法は、最初に入力関数を作成することでした。この方法では、PostgreSQLは新しいデータ型の名称を、入力関数の戻り値型で初めて見ます。このときに、シェル型が暗黙的に作成され、残りの入出力関数の定義で参照することができます。この方法もまだ使用できますが、廃止予定であり、将来のリリースで禁止される可能性があります。関数定義における単純なタイプミスの結果作成されるシェル型によって起こるカタログの混乱を防止するため、入力関数がCで作成された場合にのみこの方法によってシェル型が作成されます。7.3より前のバージョンでは、関数の下位参照を、プレースホルダとなる疑似データ型であるopaque型のデータ型名と置き換えることによって、shell型を作成することを完全に、慣習的に避けていました。7.3より前のバージョンでは、cstring型の引数および結果もopaque型として宣言する必要がありました。TYPEではopaque型を使用するよう宣言された入出力関数を受け入れます。注意を促すメッセージを表示し、正しいデータ型を使用するように関数の宣言を変更します。次の例では、複合型を作成し、それを関数定義で使用します。SQL;次の例では、列挙型を作成し、それをテーブル定義に使用します。bug_status);次の例では、範囲型を作成します。float8mi);次の例では、基本データ型boxを作成し、その型をテーブル定義の中で使用しています。box);box型の内部構造がfloat4型が4つの配列の場合、このように書き換えることもできます。float4);このようにすると、box値の要素に要素番号でアクセスできます。その他は、上の例と同様の動作をします。次の例では、ラージオブジェクト型を作成し、テーブル定義にてそれを使用します。ユーザ定義の型を参照してください。TYPEコマンドの構文は標準SQLに従います。他の構文はPostgreSQLの拡張です。TYPE構文を定義していますが、PostgreSQLでは実装されていません。TABLEの場合と同様)です。