TYPE happiness AS ENUM ('happy', 'very happy', 'ecstatic');
CREATE TABLE holidays (
num_weeks integer,
happiness happiness
);
INSERT INTO holidays(num_weeks,happiness) VALUES (4, 'happy');
INSERT INTO holidays(num_weeks,happiness) VALUES (6, 'very happy');
INSERT INTO holidays(num_weeks,happiness) VALUES (8, 'ecstatic');
INSERT INTO holidays(num_weeks,happiness) VALUES (2, 'sad');
ERROR: invalid input value for enum happiness: "sad"
SELECT person.name, holidays.num_weeks FROM person, holidays
WHERE person.current_mood = holidays.happiness;
ERROR: operator does not exist: mood = happiness
</programlisting>
</para>
<para>
If you really need to do something like that, you can either
write a custom operator or add explicit casts to your query:
<programlisting>
SELECT person.name, holidays.num_weeks FROM person, holidays
WHERE person.current_mood::text = holidays.happiness::text;
name | num_weeks
------+-----------
Moe | 4
(1 row)
</programlisting>
</para>
</sect2>
<sect2 id="datatype-enum-implementation-details">
<title>Implementation Details</title>
<para>
Enum labels are case sensitive, so
<type>'happy'</type> is not the same as <type>'HAPPY'</type>.
White space in the labels is significant too.
</para>
<para>
Although enum types are primarily intended for static sets of values,
there is support for adding new values to an existing enum type, and for
renaming values (see <xref linkend="sql-altertype"/>). Existing values
cannot be removed from an enum type, nor can the sort ordering of such
values be changed, short of dropping and re-creating the enum type.
</para>
<para>
An enum value occupies four bytes on disk. The length of an enum
value's textual label is limited by the <symbol>NAMEDATALEN</symbol>
setting compiled into <productname>PostgreSQL</productname>; in standard
builds this means at most 63 bytes.
</para>
<para>
The translations from internal enum values to textual labels are
kept in the system catalog
<link linkend="catalog-pg-enum"><structname>pg_enum</structname></link>.
Querying this catalog directly can be useful.
</para>
</sect2>
</sect1>
<sect1 id="datatype-geometric">
<title>Geometric Types</title>
<para>
Geometric data types represent two-dimensional spatial
objects. <xref linkend="datatype-geo-table"/> shows the geometric
types available in <productname>PostgreSQL</productname>.
</para>
<table id="datatype-geo-table">
<title>Geometric Types</title>
<tgroup cols="4">
<colspec colname="col1" colwidth="1*"/>
<colspec colname="col2" colwidth="1*"/>
<colspec colname="col3" colwidth="2*"/>
<colspec colname="col4" colwidth="1*"/>
<thead>
<row>
<entry>Name</entry>
<entry>Storage Size</entry>
<entry>Description</entry>
<entry>Representation</entry>
</row>
</thead>
<tbody>
<row>
<entry><type>point</type></entry>
<entry>16 bytes</entry>
<entry>Point on a plane</entry>
<entry>(x,y)</entry>
</row>
<row>
<entry><type>line</type></entry>
<entry>24 bytes</entry>
<entry>Infinite line</entry>
<entry>{A,B,C}</entry>
</row>
<row>
<entry><type>lseg</type></entry>
<entry>32 bytes</entry>
<entry>Finite line segment</entry>
<entry>[(x1,y1),(x2,y2)]</entry>
</row>
<row>
<entry><type>box</type></entry>
<entry>32 bytes</entry>
<entry>Rectangular box</entry>
<entry>(x1,y1),(x2,y2)</entry>
</row>
<row>
<entry><type>path</type></entry>
<entry>16+16n bytes</entry>
<entry>Closed path (similar to polygon)</entry>
<entry>((x1,y1),...)</entry>
</row>
<row>
<entry><type>path</type></entry>