aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/ruleutils.c
diff options
context:
space:
mode:
authorPeter Eisentraut <peter_e@gmx.net>2002-07-18 23:11:32 +0000
committerPeter Eisentraut <peter_e@gmx.net>2002-07-18 23:11:32 +0000
commit97377048b460823a300b1d414203c5f09c8efc1b (patch)
tree7c567e9728b214a10604afa1aa923d02a683156e /src/backend/utils/adt/ruleutils.c
parenta345ac8842089cbca1678d5b28773a827937693f (diff)
downloadpostgresql-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.c45
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);
}