summaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_coerce.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_coerce.c')
-rw-r--r--src/backend/parser/parse_coerce.c224
1 files changed, 34 insertions, 190 deletions
diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c
index 24676404340..df5ad09bae1 100644
--- a/src/backend/parser/parse_coerce.c
+++ b/src/backend/parser/parse_coerce.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.161 2008/01/11 18:39:40 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.162 2008/07/30 17:05:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -967,7 +967,8 @@ Oid
select_common_type(List *typeids, const char *context)
{
Oid ptype;
- CATEGORY pcategory;
+ TYPCATEGORY pcategory;
+ bool pispreferred;
ListCell *type_item;
Assert(typeids != NIL);
@@ -993,7 +994,7 @@ select_common_type(List *typeids, const char *context)
/* Nope, so set up for the full algorithm */
ptype = getBaseType(ptype);
- pcategory = TypeCategory(ptype);
+ get_type_category_preferred(ptype, &pcategory, &pispreferred);
for_each_cell(type_item, lnext(list_head(typeids)))
{
@@ -1002,13 +1003,18 @@ select_common_type(List *typeids, const char *context)
/* move on to next one if no new information... */
if (ntype != UNKNOWNOID && ntype != ptype)
{
+ TYPCATEGORY ncategory;
+ bool nispreferred;
+
+ get_type_category_preferred(ntype, &ncategory, &nispreferred);
if (ptype == UNKNOWNOID)
{
/* so far, only unknowns so take anything... */
ptype = ntype;
- pcategory = TypeCategory(ptype);
+ pcategory = ncategory;
+ pispreferred = nispreferred;
}
- else if (TypeCategory(ntype) != pcategory)
+ else if (ncategory != pcategory)
{
/*
* both types in different categories? then not much hope...
@@ -1023,7 +1029,7 @@ select_common_type(List *typeids, const char *context)
format_type_be(ptype),
format_type_be(ntype))));
}
- else if (!IsPreferredType(pcategory, ptype) &&
+ else if (!pispreferred &&
can_coerce_type(1, &ptype, &ntype, COERCION_IMPLICIT) &&
!can_coerce_type(1, &ntype, &ptype, COERCION_IMPLICIT))
{
@@ -1032,7 +1038,8 @@ select_common_type(List *typeids, const char *context)
* other way; but if we have a preferred type, stay on it.
*/
ptype = ntype;
- pcategory = TypeCategory(ptype);
+ pcategory = ncategory;
+ pispreferred = nispreferred;
}
}
}
@@ -1549,202 +1556,39 @@ resolve_generic_type(Oid declared_type,
/* TypeCategory()
* Assign a category to the specified type OID.
*
- * NB: this must not return INVALID_TYPE.
- *
- * XXX This should be moved to system catalog lookups
- * to allow for better type extensibility.
- * - thomas 2001-09-30
+ * NB: this must not return TYPCATEGORY_INVALID.
*/
-CATEGORY
-TypeCategory(Oid inType)
+TYPCATEGORY
+TypeCategory(Oid type)
{
- CATEGORY result;
+ char typcategory;
+ bool typispreferred;
- switch (inType)
- {
- case (BOOLOID):
- result = BOOLEAN_TYPE;
- break;
-
- case (CHAROID):
- case (NAMEOID):
- case (BPCHAROID):
- case (VARCHAROID):
- case (TEXTOID):
- result = STRING_TYPE;
- break;
-
- case (BITOID):
- case (VARBITOID):
- result = BITSTRING_TYPE;
- break;
-
- case (OIDOID):
- case (REGPROCOID):
- case (REGPROCEDUREOID):
- case (REGOPEROID):
- case (REGOPERATOROID):
- case (REGCLASSOID):
- case (REGTYPEOID):
- case (REGCONFIGOID):
- case (REGDICTIONARYOID):
- case (INT2OID):
- case (INT4OID):
- case (INT8OID):
- case (FLOAT4OID):
- case (FLOAT8OID):
- case (NUMERICOID):
- case (CASHOID):
- result = NUMERIC_TYPE;
- break;
-
- case (DATEOID):
- case (TIMEOID):
- case (TIMETZOID):
- case (ABSTIMEOID):
- case (TIMESTAMPOID):
- case (TIMESTAMPTZOID):
- result = DATETIME_TYPE;
- break;
-
- case (RELTIMEOID):
- case (TINTERVALOID):
- case (INTERVALOID):
- result = TIMESPAN_TYPE;
- break;
-
- case (POINTOID):
- case (LSEGOID):
- case (PATHOID):
- case (BOXOID):
- case (POLYGONOID):
- case (LINEOID):
- case (CIRCLEOID):
- result = GEOMETRIC_TYPE;
- break;
-
- case (INETOID):
- case (CIDROID):
- result = NETWORK_TYPE;
- break;
-
- case (UNKNOWNOID):
- case (InvalidOid):
- result = UNKNOWN_TYPE;
- break;
-
- case (RECORDOID):
- case (CSTRINGOID):
- case (ANYOID):
- case (ANYARRAYOID):
- case (VOIDOID):
- case (TRIGGEROID):
- case (LANGUAGE_HANDLEROID):
- case (INTERNALOID):
- case (OPAQUEOID):
- case (ANYELEMENTOID):
- case (ANYNONARRAYOID):
- case (ANYENUMOID):
- result = GENERIC_TYPE;
- break;
-
- default:
- result = USER_TYPE;
- break;
- }
- return result;
-} /* TypeCategory() */
+ get_type_category_preferred(type, &typcategory, &typispreferred);
+ Assert(typcategory != TYPCATEGORY_INVALID);
+ return (TYPCATEGORY) typcategory;
+}
/* IsPreferredType()
* Check if this type is a preferred type for the given category.
*
- * If category is INVALID_TYPE, then we'll return TRUE for preferred types
- * of any category; otherwise, only for preferred types of that category.
- *
- * XXX This should be moved to system catalog lookups
- * to allow for better type extensibility.
- * - thomas 2001-09-30
+ * If category is TYPCATEGORY_INVALID, then we'll return TRUE for preferred
+ * types of any category; otherwise, only for preferred types of that
+ * category.
*/
bool
-IsPreferredType(CATEGORY category, Oid type)
+IsPreferredType(TYPCATEGORY category, Oid type)
{
- Oid preftype;
+ char typcategory;
+ bool typispreferred;
- if (category == INVALID_TYPE)
- category = TypeCategory(type);
- else if (category != TypeCategory(type))
+ get_type_category_preferred(type, &typcategory, &typispreferred);
+ if (category == typcategory || category == TYPCATEGORY_INVALID)
+ return typispreferred;
+ else
return false;
-
- /*
- * This switch should agree with TypeCategory(), above. Note that at this
- * point, category certainly matches the type.
- */
- switch (category)
- {
- case (UNKNOWN_TYPE):
- case (GENERIC_TYPE):
- preftype = UNKNOWNOID;
- break;
-
- case (BOOLEAN_TYPE):
- preftype = BOOLOID;
- break;
-
- case (STRING_TYPE):
- preftype = TEXTOID;
- break;
-
- case (BITSTRING_TYPE):
- preftype = VARBITOID;
- break;
-
- case (NUMERIC_TYPE):
- if (type == OIDOID ||
- type == REGPROCOID ||
- type == REGPROCEDUREOID ||
- type == REGOPEROID ||
- type == REGOPERATOROID ||
- type == REGCLASSOID ||
- type == REGTYPEOID ||
- type == REGCONFIGOID ||
- type == REGDICTIONARYOID)
- preftype = OIDOID;
- else
- preftype = FLOAT8OID;
- break;
-
- case (DATETIME_TYPE):
- if (type == DATEOID)
- preftype = TIMESTAMPOID;
- else
- preftype = TIMESTAMPTZOID;
- break;
-
- case (TIMESPAN_TYPE):
- preftype = INTERVALOID;
- break;
-
- case (GEOMETRIC_TYPE):
- preftype = type;
- break;
-
- case (NETWORK_TYPE):
- preftype = INETOID;
- break;
-
- case (USER_TYPE):
- preftype = type;
- break;
-
- default:
- elog(ERROR, "unrecognized type category: %d", (int) category);
- preftype = UNKNOWNOID;
- break;
- }
-
- return (type == preftype);
-} /* IsPreferredType() */
+}
/* IsBinaryCoercible()