From bac3e83622b588eb449eb4e26c4b1e62e7cca3d5 Mon Sep 17 00:00:00 2001
From: Tom Lane
Date: Wed, 30 Jul 2008 17:05:05 +0000
Subject: Replace the hard-wired type knowledge in TypeCategory() and
IsPreferredType() with system catalog lookups, as was foreseen to be
necessary almost since their creation. Instead put the information into two
new pg_type columns, typcategory and typispreferred. Add support for setting
these when creating a user-defined base type.
The category column is just a "char" (i.e. a poor man's enum), allowing
a crude form of user extensibility of the category list: just use an
otherwise-unused character. This seems sufficient for foreseen uses,
but we could upgrade to having an actual category catalog someday, if
there proves to be a huge demand for custom type categories.
In this patch I have attempted to hew exactly to the behavior of the
previous hardwired logic, except for introducing new type categories for
arrays, composites, and enums. In particular the default preferred state
for user-defined types remains TRUE. That seems worth revisiting, but it
should be done as a separate patch from introducing the infrastructure.
Likewise, any adjustment of the standard set of categories should be done
separately.
---
doc/src/sgml/catalogs.sgml | 127 ++++++++++++++++++++++++++++++++++----
doc/src/sgml/ref/create_type.sgml | 50 ++++++++++++++-
doc/src/sgml/typeconv.sgml | 69 ++++++++++-----------
3 files changed, 195 insertions(+), 51 deletions(-)
(limited to 'doc/src')
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index a7a3cea9068..f756830a95d 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,4 +1,4 @@
-
+
@@ -994,7 +994,7 @@
int4
- The number of direct ancestors this column has. A column with a
+ The number of direct ancestors this column has. A column with a
nonzero number of ancestors cannot be dropped nor renamed
@@ -1005,7 +1005,7 @@
In a dropped column's pg_attribute entry,
- atttypid is reset to zero, but
+ atttypid is reset to zero, but
attlen and the other fields copied from
pg_type> are still valid. This arrangement is needed
to cope with the situation where the dropped column's data type was
@@ -1118,7 +1118,7 @@
rolconnlimitint4
- For roles that can log in, this sets maximum number of concurrent
+ For roles that can log in, this sets maximum number of concurrent
connections this role can make. -1 means no limit
@@ -2169,7 +2169,7 @@
int4
- Sets maximum number of concurrent connections that can be made
+ Sets maximum number of concurrent connections that can be made
to this database. -1 means no limit
@@ -4855,7 +4855,7 @@
The catalog pg_type stores information about data
- types. Base types (scalar types) are created with
+ types. Base types and enum types (scalar types) are created with
, and
domains with
.
@@ -4926,8 +4926,7 @@
where Datum is 8 bytes).
Variable-length types are always passed by reference. Note that
typbyval can be false even if the
- length would allow pass-by-value; this is currently true for
- type float4, for example
+ length would allow pass-by-value
@@ -4947,6 +4946,28 @@
+
+ typcategory
+ char
+
+
+ typcategory is an arbitrary classification
+ of data types that is used by the parser to determine which implicit
+ casts should be preferred>.
+ See
+
+
+
+
+ typispreferred
+ bool
+
+
+ True if the type is a preferred cast target within its
+ typcategory
+
+
+
typisdefinedbool
@@ -5217,6 +5238,86 @@
+
+
+ lists the system-defined values
+ of typcategory>. Any future additions to this list will
+ also be upper-case ASCII letters. All other ASCII characters are reserved
+ for user-defined categories.
+
+
+
+ typcategory> Codes
+
+
+
+
+ Code
+ Category
+
+
+
+
+
+ A
+ Array types
+
+
+ B
+ Boolean types
+
+
+ C
+ Composite types
+
+
+ D
+ Date/time types
+
+
+ E
+ Enum types
+
+
+ G
+ Geometric types
+
+
+ I
+ Network address types
+
+
+ N
+ Numeric types
+
+
+ P
+ Pseudo-types
+
+
+ S
+ String types
+
+
+ T
+ Timespan types
+
+
+ U
+ User-defined types
+
+
+ V
+ Bit-string types
+
+
+ X
+ unknown> type
+
+
+
+
+
@@ -5787,7 +5888,7 @@
for another transaction, it does so by attempting to acquire share lock on
the other transaction ID (either virtual or permanent ID depending on the
situation). That will succeed only when the other transaction
- terminates and releases its locks.
+ terminates and releases its locks.
@@ -6036,7 +6137,7 @@
The view pg_roles provides access to
information about database roles. This is simply a publicly
- readable view of
+ readable view of
pg_authid
that blanks out the password field.
@@ -6121,7 +6222,7 @@
int4
- For roles that can log in, this sets maximum number of concurrent
+ For roles that can log in, this sets maximum number of concurrent
connections this role can make. -1 means no limit
@@ -6316,7 +6417,7 @@
-
+
The pg_settings view cannot be inserted into or
deleted from, but it can be updated. An UPDATE applied
@@ -6774,7 +6875,7 @@
The view pg_user provides access to
information about database users. This is simply a publicly
- readable view of
+ readable view of
pg_shadow
that blanks out the password field.
diff --git a/doc/src/sgml/ref/create_type.sgml b/doc/src/sgml/ref/create_type.sgml
index e643f098252..8002e2c4b9c 100644
--- a/doc/src/sgml/ref/create_type.sgml
+++ b/doc/src/sgml/ref/create_type.sgml
@@ -1,5 +1,5 @@
@@ -38,6 +38,8 @@ CREATE TYPE name (
[ , PASSEDBYVALUE ]
[ , ALIGNMENT = alignment ]
[ , STORAGE = storage ]
+ [ , CATEGORY = category ]
+ [ , PREFERRED = preferred ]
[ , DEFAULT = default ]
[ , ELEMENT = element ]
[ , DELIMITER = delimiter ]
@@ -281,6 +283,27 @@ CREATE TYPE nameexternal items.)
+
+ The category and
+ preferred parameters can be
+ used to help control which implicit cast will be applied in ambiguous
+ situations. Each data type belongs to a category named by a single ASCII
+ character, and each type is either preferred> or not within its
+ category. The parser will prefer casting to preferred types (but only from
+ other types within the same category) when this rule is helpful in
+ resolving overloaded functions or operators. For more details see . For types that have no implicit casts to or from any
+ other types, it is sufficient to leave these settings at the defaults.
+ However, for a group of related types that have implicit casts, it is often
+ helpful to mark them all as belonging to a category and select one or two
+ of the most general> types as being preferred within the category.
+ The category parameter is
+ especially useful when adding a user-defined type to an existing built-in
+ category, such as the numeric or string types. However, it is also
+ possible to create new entirely-user-defined type categories. Select any
+ ASCII character other than an upper-case letter to name such a category.
+
+
A default value can be specified, in case a user wants columns of the
data type to default to something other than the null value.
@@ -494,6 +517,31 @@ CREATE TYPE name
+
+ category
+
+
+ The category code (a single ASCII character) for this type.
+ The default is 'U'> for user-defined type>.
+ Other standard category codes can be found in
+ . You may also choose
+ other ASCII characters in order to create custom categories.
+
+
+
+
+
+ preferred
+
+
+ True if this type is a preferred type within its type category,
+ else false. The default is true (which is appropriate for
+ all entries in category U>, but is usually not
+ appropriate for new types in other categories — beware!).
+
+
+
+
default
diff --git a/doc/src/sgml/typeconv.sgml b/doc/src/sgml/typeconv.sgml
index 4f04801210b..c9f96323f30 100644
--- a/doc/src/sgml/typeconv.sgml
+++ b/doc/src/sgml/typeconv.sgml
@@ -1,4 +1,4 @@
-
+
Type Conversion
@@ -10,7 +10,7 @@
SQL statements can, intentionally or not, require
-mixing of different data types in the same expression.
+mixing of different data types in the same expression.
PostgreSQL has extensive facilities for
evaluating mixed-type expressions.
@@ -153,19 +153,32 @@ altered.)
An additional heuristic is provided in the parser to allow better guesses
-at proper behavior for SQL standard types. There are
-several basic type categories defined: boolean,
-numeric, string, bitstring, datetime, timespan, geometric, network,
-and user-defined. Each category, with the exception of user-defined, has
-one or more preferred types which are preferentially
-selected when there is ambiguity.
-In the user-defined category, each type is its own preferred type.
-Ambiguous expressions (those with multiple candidate parsing solutions)
-can therefore often be resolved when there are multiple possible built-in types, but
-they will raise an error when there are multiple choices for user-defined
-types.
+at proper casting behavior among groups of types that have implicit casts.
+Data types are divided into several basic type
+categories, including boolean, numeric,
+string, bitstring, datetime,
+timespan, geometric, network, and
+user-defined. (For a list see ;
+but note it is also possible to create custom type categories.) Within each
+category there are one or more preferred types, which
+are preferentially selected when there is ambiguity. With careful selection
+of preferred types and available implicit casts, it is possible to ensure that
+ambiguous expressions (those with multiple candidate parsing solutions) can be
+resolved in a useful way.
+
+
+ For what are now historical reasons, types in the user-defined>
+ category are normally always marked as preferred>. Since all types
+ in this category are preferred, the heuristic that favors preferred types
+ accomplishes nothing, and thus this situation is equivalent to treating them
+ all as non-preferred. The preferred> marking is useful within the
+ system-defined type categories, and can be useful within custom type
+ categories.
+
+
+
All type conversion rules are designed with several principles in mind:
@@ -176,23 +189,6 @@ Implicit conversions should never have surprising or unpredictable outcomes.
-
-
-User-defined types, of which the parser has no a priori> knowledge, should be
-higher in the type hierarchy. In mixed-type expressions, native types shall always
-be converted to a user-defined type (of course, only if conversion is necessary).
-
-
-
-
-
-User-defined types are not related. Currently, PostgreSQL
-does not have information available to it on relationships between types, other than
-hardcoded heuristics for built-in types and implicit relationships based on
-available functions and casts.
-
-
-
There should be no extra overhead from the parser or executor
@@ -317,7 +313,7 @@ all the remaining candidates accept the same type category, select that
category; otherwise fail because the correct choice cannot be deduced
without more clues. Now discard
candidates that do not accept the selected type category. Furthermore,
-if any candidate accepts a preferred type at a given argument position,
+if any candidate accepts a preferred type in that category,
discard candidates that accept non-preferred types for that argument.
@@ -341,7 +337,7 @@ Some examples follow.
There is only one factorial operator (postfix !>)
-defined in the standard catalog, and it takes an argument of type
+defined in the standard catalog, and it takes an argument of type
bigint.
The scanner assigns an initial type of integer to the argument
in this query expression:
@@ -407,7 +403,7 @@ In this case there is no initial hint for which type to use, since no types
are specified in the query. So, the parser looks for all candidate operators
and finds that there are candidates accepting both string-category and
bit-string-category inputs. Since string category is preferred when available,
-that category is selected, and then the
+that category is selected, and then the
preferred type for strings, text, is used as the specific
type to resolve the unknown literals to.
@@ -585,7 +581,7 @@ If only one candidate remains, use it; else continue to the next step.
If any input arguments are unknown, check the type categories
-accepted
+accepted
at those argument positions by the remaining candidates. At each position,
select the string category if any candidate accepts that category.
(This bias towards string
@@ -594,9 +590,8 @@ Otherwise, if all the remaining candidates accept the same type category,
select that category; otherwise fail because
the correct choice cannot be deduced without more clues.
Now discard candidates that do not accept the selected type category.
-Furthermore, if any candidate accepts a preferred type at a given argument
-position, discard candidates that accept non-preferred types for that
-argument.
+Furthermore, if any candidate accepts a preferred type in that category,
+discard candidates that accept non-preferred types for that argument.
--
cgit v1.2.3