1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-16 06:01:02 +03:00

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.
This commit is contained in:
Peter Eisentraut
2002-07-18 23:11:32 +00:00
parent a345ac8842
commit 97377048b4
36 changed files with 1299 additions and 343 deletions

View File

@ -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);
ReleaseSysCache(typeTuple);
return expr;
}
/* It must also be an implicit cast. */
castStruct = (Form_pg_cast) GETSTRUCT(castTuple);
if (!castStruct->castimplicit)
{
ReleaseSysCache(procTuple);
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);
}