提交 6a208aa4 编写于 作者: P Peter Eisentraut

Allow casting a table's row type to the table's supertype if it's a typed table

This is analogous to the existing facility that allows casting a row type to a
supertable's row type.
上级 92a73d21
......@@ -15,6 +15,7 @@
#include "postgres.h"
#include "catalog/pg_cast.h"
#include "catalog/pg_class.h"
#include "catalog/pg_inherits_fn.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_type.h"
......@@ -48,6 +49,7 @@ static Node *coerce_record_to_complex(ParseState *pstate, Node *node,
CoercionForm cformat,
int location);
static bool is_complex_array(Oid typid);
static bool typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId);
/*
......@@ -371,7 +373,8 @@ coerce_type(ParseState *pstate, Node *node,
/* NB: we do NOT want a RelabelType here */
return node;
}
if (typeInheritsFrom(inputTypeId, targetTypeId))
if (typeInheritsFrom(inputTypeId, targetTypeId)
|| typeIsOfTypedTable(inputTypeId, targetTypeId))
{
/*
* Input class type is a subclass of target, so generate an
......@@ -482,7 +485,8 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *target_typeids,
/*
* If input is a class type that inherits from target, accept
*/
if (typeInheritsFrom(inputTypeId, targetTypeId))
if (typeInheritsFrom(inputTypeId, targetTypeId)
|| typeIsOfTypedTable(inputTypeId, targetTypeId))
continue;
/*
......@@ -2046,3 +2050,34 @@ is_complex_array(Oid typid)
return (OidIsValid(elemtype) && ISCOMPLEX(elemtype));
}
/*
* Check whether reltypeId is the row type of a typed table of type
* reloftypeId. (This is conceptually similar to the subtype
* relationship checked by typeInheritsFrom().)
*/
static bool
typeIsOfTypedTable(Oid reltypeId, Oid reloftypeId)
{
Oid relid = typeidTypeRelid(reltypeId);
bool result = false;
if (relid)
{
HeapTuple tp;
Form_pg_class reltup;
tp = SearchSysCache1(RELOID, ObjectIdGetDatum(relid));
if (!HeapTupleIsValid(tp))
elog(ERROR, "cache lookup failed for relation %u", relid);
reltup = (Form_pg_class) GETSTRUCT(tp);
if (reltup->reloftype == reloftypeId)
result = true;
ReleaseSysCache(tp);
}
return result;
}
......@@ -92,3 +92,18 @@ drop cascades to function get_all_persons()
drop cascades to table persons2
drop cascades to table persons3
DROP TABLE stuff;
-- implicit casting
CREATE TYPE person_type AS (id int, name text);
CREATE TABLE persons OF person_type;
INSERT INTO persons VALUES (1, 'test');
CREATE FUNCTION namelen(person_type) RETURNS int LANGUAGE SQL AS $$ SELECT length($1.name) $$;
SELECT id, namelen(persons) FROM persons;
id | namelen
----+---------
1 | 4
(1 row)
DROP TYPE person_type CASCADE;
NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to table persons
drop cascades to function namelen(person_type)
......@@ -47,3 +47,15 @@ DROP TYPE person_type RESTRICT;
DROP TYPE person_type CASCADE;
DROP TABLE stuff;
-- implicit casting
CREATE TYPE person_type AS (id int, name text);
CREATE TABLE persons OF person_type;
INSERT INTO persons VALUES (1, 'test');
CREATE FUNCTION namelen(person_type) RETURNS int LANGUAGE SQL AS $$ SELECT length($1.name) $$;
SELECT id, namelen(persons) FROM persons;
DROP TYPE person_type CASCADE;
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册