diff options
author | Peter Eisentraut <peter_e@gmx.net> | 2002-07-18 23:11:32 +0000 |
---|---|---|
committer | Peter Eisentraut <peter_e@gmx.net> | 2002-07-18 23:11:32 +0000 |
commit | 97377048b460823a300b1d414203c5f09c8efc1b (patch) | |
tree | 7c567e9728b214a10604afa1aa923d02a683156e /src/backend/utils/adt/ruleutils.c | |
parent | a345ac8842089cbca1678d5b28773a827937693f (diff) | |
download | postgresql-97377048b460823a300b1d414203c5f09c8efc1b.tar.gz postgresql-97377048b460823a300b1d414203c5f09c8efc1b.zip |
pg_cast table, and standards-compliant CREATE/DROP CAST commands, plus
extension to create binary compatible casts. Includes dependency tracking
as well.
pg_proc.proimplicit is now defunct, but will be removed in a separate
commit.
pg_dump provides a migration path from the previous scheme to declare
casts. Dumping binary compatible casts is currently impossible, though.
Diffstat (limited to 'src/backend/utils/adt/ruleutils.c')
-rw-r--r-- | src/backend/utils/adt/ruleutils.c | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c index 2772b668738..5999ad96285 100644 --- a/src/backend/utils/adt/ruleutils.c +++ b/src/backend/utils/adt/ruleutils.c @@ -3,7 +3,7 @@ * back to source text * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.111 2002/07/18 17:14:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.112 2002/07/18 23:11:28 petere Exp $ * * This software is copyrighted by Jan Wieck - Hamburg. * @@ -43,6 +43,7 @@ #include "catalog/heap.h" #include "catalog/index.h" #include "catalog/namespace.h" +#include "catalog/pg_cast.h" #include "catalog/pg_index.h" #include "catalog/pg_opclass.h" #include "catalog/pg_operator.h" @@ -2048,9 +2049,9 @@ get_agg_expr(Aggref *aggref, deparse_context *context) * Strip any type coercions at the top of the given expression tree, * as long as they are coercions to the given datatype. * - * A RelabelType node is always a type coercion. A function call is also - * considered a type coercion if it has one argument and the function name - * is the same as the (internal) name of its result type. + * A RelabelType node is always a type coercion. A function call is + * also considered a type coercion if it has one argument and there is + * a cast declared that uses it. * * XXX It'd be better if the parsetree retained some explicit indication * of the coercion, so we didn't need these heuristics. @@ -2069,9 +2070,9 @@ strip_type_coercion(Node *expr, Oid resultType) { Func *func; HeapTuple procTuple; - HeapTuple typeTuple; + HeapTuple castTuple; Form_pg_proc procStruct; - Form_pg_type typeStruct; + Form_pg_cast castStruct; func = (Func *) (((Expr *) expr)->oper); Assert(IsA(func, Func)); @@ -2085,33 +2086,33 @@ strip_type_coercion(Node *expr, Oid resultType) elog(ERROR, "cache lookup for proc %u failed", func->funcid); procStruct = (Form_pg_proc) GETSTRUCT(procTuple); /* Double-check func has one arg and correct result type */ - /* Also, it must be an implicit coercion function */ if (procStruct->pronargs != 1 || - procStruct->prorettype != resultType || - !procStruct->proimplicit) + procStruct->prorettype != resultType) { ReleaseSysCache(procTuple); return expr; } - /* See if function has same name/namespace as its result type */ - typeTuple = SearchSysCache(TYPEOID, - ObjectIdGetDatum(procStruct->prorettype), - 0, 0, 0); - if (!HeapTupleIsValid(typeTuple)) - elog(ERROR, "cache lookup for type %u failed", - procStruct->prorettype); - typeStruct = (Form_pg_type) GETSTRUCT(typeTuple); - if (strcmp(NameStr(procStruct->proname), - NameStr(typeStruct->typname)) != 0 || - procStruct->pronamespace != typeStruct->typnamespace) + /* See if function has is actually declared as a cast */ + castTuple = SearchSysCache(CASTSOURCETARGET, + ObjectIdGetDatum(procStruct->proargtypes[0]), + ObjectIdGetDatum(procStruct->prorettype), + 0, 0); + if (!HeapTupleIsValid(castTuple)) + { + ReleaseSysCache(procTuple); + return expr; + } + /* It must also be an implicit cast. */ + castStruct = (Form_pg_cast) GETSTRUCT(castTuple); + if (!castStruct->castimplicit) { ReleaseSysCache(procTuple); - ReleaseSysCache(typeTuple); + ReleaseSysCache(castTuple); return expr; } /* Okay, it is indeed a type-coercion function */ ReleaseSysCache(procTuple); - ReleaseSysCache(typeTuple); + ReleaseSysCache(castTuple); return strip_type_coercion(lfirst(((Expr *) expr)->args), resultType); } |