mirror of
https://github.com/postgres/postgres.git
synced 2025-11-29 23:43:17 +03:00
Support enum data types. Along the way, use macros for the values of
pg_type.typtype whereever practical. Tom Dunstan, with some kibitzing from Tom Lane.
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
* Copyright (c) 2002-2007, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.33 2007/02/01 19:10:28 momjian Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.34 2007/04/02 03:49:39 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@@ -193,8 +193,8 @@ shutdown_MultiFuncCall(Datum arg)
|
||||
* only when we couldn't resolve the actual rowtype for lack of information.
|
||||
*
|
||||
* The other hard case that this handles is resolution of polymorphism.
|
||||
* We will never return ANYELEMENT or ANYARRAY, either as a scalar result
|
||||
* type or as a component of a rowtype.
|
||||
* We will never return ANYELEMENT, ANYARRAY or ANYENUM, either as a scalar
|
||||
* result type or as a component of a rowtype.
|
||||
*
|
||||
* This function is relatively expensive --- in a function returning set,
|
||||
* try to call it only the first time through.
|
||||
@@ -338,7 +338,7 @@ internal_get_result_type(Oid funcid,
|
||||
/*
|
||||
* If scalar polymorphic result, try to resolve it.
|
||||
*/
|
||||
if (rettype == ANYARRAYOID || rettype == ANYELEMENTOID)
|
||||
if (IsPolymorphicType(rettype))
|
||||
{
|
||||
Oid newrettype = exprType(call_expr);
|
||||
|
||||
@@ -389,8 +389,8 @@ internal_get_result_type(Oid funcid,
|
||||
|
||||
/*
|
||||
* Given the result tuple descriptor for a function with OUT parameters,
|
||||
* replace any polymorphic columns (ANYELEMENT/ANYARRAY) with correct data
|
||||
* types deduced from the input arguments. Returns TRUE if able to deduce
|
||||
* replace any polymorphic columns (ANYELEMENT/ANYARRAY/ANYENUM) with correct
|
||||
* data types deduced from the input arguments. Returns TRUE if able to deduce
|
||||
* all types, FALSE if not.
|
||||
*/
|
||||
static bool
|
||||
@@ -401,6 +401,7 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
|
||||
int nargs = declared_args->dim1;
|
||||
bool have_anyelement_result = false;
|
||||
bool have_anyarray_result = false;
|
||||
bool have_anyenum = false;
|
||||
Oid anyelement_type = InvalidOid;
|
||||
Oid anyarray_type = InvalidOid;
|
||||
int i;
|
||||
@@ -416,6 +417,10 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
|
||||
case ANYARRAYOID:
|
||||
have_anyarray_result = true;
|
||||
break;
|
||||
case ANYENUMOID:
|
||||
have_anyelement_result = true;
|
||||
have_anyenum = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -435,6 +440,7 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
|
||||
switch (declared_args->values[i])
|
||||
{
|
||||
case ANYELEMENTOID:
|
||||
case ANYENUMOID:
|
||||
if (!OidIsValid(anyelement_type))
|
||||
anyelement_type = get_call_expr_argtype(call_expr, i);
|
||||
break;
|
||||
@@ -461,12 +467,17 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
|
||||
anyelement_type,
|
||||
ANYELEMENTOID);
|
||||
|
||||
/* Check for enum if needed */
|
||||
if (have_anyenum && !type_is_enum(anyelement_type))
|
||||
return false;
|
||||
|
||||
/* And finally replace the tuple column types as needed */
|
||||
for (i = 0; i < natts; i++)
|
||||
{
|
||||
switch (tupdesc->attrs[i]->atttypid)
|
||||
{
|
||||
case ANYELEMENTOID:
|
||||
case ANYENUMOID:
|
||||
TupleDescInitEntry(tupdesc, i + 1,
|
||||
NameStr(tupdesc->attrs[i]->attname),
|
||||
anyelement_type,
|
||||
@@ -490,8 +501,8 @@ resolve_polymorphic_tupdesc(TupleDesc tupdesc, oidvector *declared_args,
|
||||
|
||||
/*
|
||||
* Given the declared argument types and modes for a function,
|
||||
* replace any polymorphic types (ANYELEMENT/ANYARRAY) with correct data
|
||||
* types deduced from the input arguments. Returns TRUE if able to deduce
|
||||
* replace any polymorphic types (ANYELEMENT/ANYARRAY/ANYENUM) with correct
|
||||
* data types deduced from the input arguments. Returns TRUE if able to deduce
|
||||
* all types, FALSE if not. This is the same logic as
|
||||
* resolve_polymorphic_tupdesc, but with a different argument representation.
|
||||
*
|
||||
@@ -517,6 +528,7 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes,
|
||||
switch (argtypes[i])
|
||||
{
|
||||
case ANYELEMENTOID:
|
||||
case ANYENUMOID:
|
||||
if (argmode == PROARGMODE_OUT)
|
||||
have_anyelement_result = true;
|
||||
else
|
||||
@@ -571,12 +583,15 @@ resolve_polymorphic_argtypes(int numargs, Oid *argtypes, char *argmodes,
|
||||
anyelement_type,
|
||||
ANYELEMENTOID);
|
||||
|
||||
/* XXX do we need to enforce ANYENUM here? I think not */
|
||||
|
||||
/* And finally replace the output column types as needed */
|
||||
for (i = 0; i < numargs; i++)
|
||||
{
|
||||
switch (argtypes[i])
|
||||
{
|
||||
case ANYELEMENTOID:
|
||||
case ANYENUMOID:
|
||||
argtypes[i] = anyelement_type;
|
||||
break;
|
||||
case ANYARRAYOID:
|
||||
@@ -603,12 +618,13 @@ get_type_func_class(Oid typid)
|
||||
{
|
||||
switch (get_typtype(typid))
|
||||
{
|
||||
case 'c':
|
||||
case TYPTYPE_COMPOSITE:
|
||||
return TYPEFUNC_COMPOSITE;
|
||||
case 'b':
|
||||
case 'd':
|
||||
case TYPTYPE_BASE:
|
||||
case TYPTYPE_DOMAIN:
|
||||
case TYPTYPE_ENUM:
|
||||
return TYPEFUNC_SCALAR;
|
||||
case 'p':
|
||||
case TYPTYPE_PSEUDO:
|
||||
if (typid == RECORDOID)
|
||||
return TYPEFUNC_RECORD;
|
||||
|
||||
@@ -840,7 +856,7 @@ get_func_result_name(Oid functionId)
|
||||
* Given a pg_proc row for a function, return a tuple descriptor for the
|
||||
* result rowtype, or NULL if the function does not have OUT parameters.
|
||||
*
|
||||
* Note that this does not handle resolution of ANYELEMENT/ANYARRAY types;
|
||||
* Note that this does not handle resolution of polymorphic types;
|
||||
* that is deliberate.
|
||||
*/
|
||||
TupleDesc
|
||||
|
||||
Reference in New Issue
Block a user