mirror of
https://github.com/postgres/postgres.git
synced 2025-04-22 23:02:54 +03:00
Here is a patch for Composite and Set returning function support. I made
two small changes to the API since last patch, which hopefully completes the decoupling of composite function support from SRF specific support. Joe Conway
This commit is contained in:
parent
bffc4b6da1
commit
ba790a5608
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.78 2002/03/29 19:05:59 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.79 2002/06/20 17:19:08 momjian Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* some of the executor utility code such as "ExecTypeFromTL" should be
|
* some of the executor utility code such as "ExecTypeFromTL" should be
|
||||||
@ -19,6 +19,9 @@
|
|||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "funcapi.h"
|
||||||
|
#include "access/heapam.h"
|
||||||
|
#include "catalog/namespace.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "nodes/parsenodes.h"
|
#include "nodes/parsenodes.h"
|
||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
@ -549,3 +552,109 @@ BuildDescForRelation(List *schema)
|
|||||||
}
|
}
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RelationNameGetTupleDesc
|
||||||
|
*
|
||||||
|
* Given a (possibly qualified) relation name, build a TupleDesc.
|
||||||
|
*/
|
||||||
|
TupleDesc
|
||||||
|
RelationNameGetTupleDesc(char *relname)
|
||||||
|
{
|
||||||
|
RangeVar *relvar;
|
||||||
|
Relation rel;
|
||||||
|
TupleDesc tupdesc;
|
||||||
|
List *relname_list;
|
||||||
|
|
||||||
|
/* Open relation and get the tuple description */
|
||||||
|
relname_list = stringToQualifiedNameList(relname, "RelationNameGetTupleDesc");
|
||||||
|
relvar = makeRangeVarFromNameList(relname_list);
|
||||||
|
rel = heap_openrv(relvar, AccessShareLock);
|
||||||
|
tupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
|
||||||
|
relation_close(rel, AccessShareLock);
|
||||||
|
|
||||||
|
return tupdesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TypeGetTupleDesc
|
||||||
|
*
|
||||||
|
* Given a type Oid, build a TupleDesc.
|
||||||
|
*
|
||||||
|
* If the type is composite, *and* a colaliases List is provided, *and*
|
||||||
|
* the List is of natts length, use the aliases instead of the relation
|
||||||
|
* attnames.
|
||||||
|
*
|
||||||
|
* If the type is a base type, a single item alias List is required.
|
||||||
|
*/
|
||||||
|
TupleDesc
|
||||||
|
TypeGetTupleDesc(Oid typeoid, List *colaliases)
|
||||||
|
{
|
||||||
|
Oid relid = typeidTypeRelid(typeoid);
|
||||||
|
TupleDesc tupdesc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build a suitable tupledesc representing the output rows
|
||||||
|
*/
|
||||||
|
if (OidIsValid(relid))
|
||||||
|
{
|
||||||
|
/* Composite data type, i.e. a table's row type */
|
||||||
|
Relation rel;
|
||||||
|
int natts;
|
||||||
|
|
||||||
|
rel = relation_open(relid, AccessShareLock);
|
||||||
|
tupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
|
||||||
|
natts = tupdesc->natts;
|
||||||
|
relation_close(rel, AccessShareLock);
|
||||||
|
|
||||||
|
/* check to see if we've given column aliases */
|
||||||
|
if(colaliases != NIL)
|
||||||
|
{
|
||||||
|
char *label;
|
||||||
|
int varattno;
|
||||||
|
|
||||||
|
/* does the List length match the number of attributes */
|
||||||
|
if (length(colaliases) != natts)
|
||||||
|
elog(ERROR, "TypeGetTupleDesc: number of aliases does not match number of attributes");
|
||||||
|
|
||||||
|
/* OK, use the aliases instead */
|
||||||
|
for (varattno = 0; varattno < natts; varattno++)
|
||||||
|
{
|
||||||
|
label = strVal(nth(varattno, colaliases));
|
||||||
|
|
||||||
|
if (label != NULL)
|
||||||
|
namestrcpy(&(tupdesc->attrs[varattno]->attname), label);
|
||||||
|
else
|
||||||
|
MemSet(NameStr(tupdesc->attrs[varattno]->attname), 0, NAMEDATALEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Must be a base data type, i.e. scalar */
|
||||||
|
char *attname;
|
||||||
|
|
||||||
|
/* the alias List is required for base types */
|
||||||
|
if (colaliases == NIL)
|
||||||
|
elog(ERROR, "TypeGetTupleDesc: no column alias was provided");
|
||||||
|
|
||||||
|
/* the alias List length must be 1 */
|
||||||
|
if (length(colaliases) != 1)
|
||||||
|
elog(ERROR, "TypeGetTupleDesc: number of aliases does not match number of attributes");
|
||||||
|
|
||||||
|
/* OK, get the column alias */
|
||||||
|
attname = strVal(lfirst(colaliases));
|
||||||
|
|
||||||
|
tupdesc = CreateTemplateTupleDesc(1);
|
||||||
|
TupleDescInitEntry(tupdesc,
|
||||||
|
(AttrNumber) 1,
|
||||||
|
attname,
|
||||||
|
typeoid,
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tupdesc;
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.51 2002/03/21 06:21:04 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.52 2002/06/20 17:19:08 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -107,11 +107,11 @@
|
|||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
|
#include "funcapi.h"
|
||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/pg_type.h"
|
#include "catalog/pg_type.h"
|
||||||
#include "executor/executor.h"
|
#include "executor/executor.h"
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
* tuple table create/delete functions
|
* tuple table create/delete functions
|
||||||
* ----------------------------------------------------------------
|
* ----------------------------------------------------------------
|
||||||
@ -673,3 +673,123 @@ ExecTypeFromTL(List *targetList)
|
|||||||
|
|
||||||
return typeInfo;
|
return typeInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TupleDescGetSlot - Initialize a slot based on the supplied
|
||||||
|
* tupledesc
|
||||||
|
*/
|
||||||
|
TupleTableSlot *
|
||||||
|
TupleDescGetSlot(TupleDesc tupdesc)
|
||||||
|
{
|
||||||
|
TupleTableSlot *slot;
|
||||||
|
|
||||||
|
/* Make a standalone slot */
|
||||||
|
slot = MakeTupleTableSlot();
|
||||||
|
|
||||||
|
/* Bind the tuple description to the slot */
|
||||||
|
ExecSetSlotDescriptor(slot, tupdesc, true);
|
||||||
|
|
||||||
|
/* Return the slot */
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TupleDescGetAttInMetadata - Get a pointer to AttInMetadata based on the
|
||||||
|
* supplied TupleDesc. AttInMetadata can be used in conjunction with C strings
|
||||||
|
* to produce a properly formed tuple.
|
||||||
|
*/
|
||||||
|
AttInMetadata *
|
||||||
|
TupleDescGetAttInMetadata(TupleDesc tupdesc)
|
||||||
|
{
|
||||||
|
int natts;
|
||||||
|
int i;
|
||||||
|
Oid atttypeid;
|
||||||
|
Oid attinfuncid;
|
||||||
|
Oid attelem;
|
||||||
|
FmgrInfo *attinfuncinfo;
|
||||||
|
Oid *attelems;
|
||||||
|
int4 *atttypmods;
|
||||||
|
AttInMetadata *attinmeta;
|
||||||
|
|
||||||
|
attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata));
|
||||||
|
natts = tupdesc->natts;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gather info needed later to call the "in" function for each attribute
|
||||||
|
*/
|
||||||
|
attinfuncinfo = (FmgrInfo *) palloc(natts * sizeof(FmgrInfo));
|
||||||
|
attelems = (Oid *) palloc(natts * sizeof(Oid));
|
||||||
|
atttypmods = (int4 *) palloc(natts * sizeof(int4));
|
||||||
|
|
||||||
|
for (i = 0; i < natts; i++)
|
||||||
|
{
|
||||||
|
atttypeid = tupdesc->attrs[i]->atttypid;
|
||||||
|
get_type_metadata(atttypeid, &attinfuncid, &attelem);
|
||||||
|
|
||||||
|
fmgr_info(attinfuncid, &attinfuncinfo[i]);
|
||||||
|
attelems[i] = attelem;
|
||||||
|
atttypmods[i] = tupdesc->attrs[i]->atttypmod;
|
||||||
|
}
|
||||||
|
attinmeta->tupdesc = tupdesc;
|
||||||
|
attinmeta->attinfuncs = attinfuncinfo;
|
||||||
|
attinmeta->attelems = attelems;
|
||||||
|
attinmeta->atttypmods = atttypmods;
|
||||||
|
|
||||||
|
return attinmeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BuildTupleFromCStrings - build a HeapTuple given user data in C string form.
|
||||||
|
* values is an array of C strings, one for each attribute of the return tuple.
|
||||||
|
*/
|
||||||
|
HeapTuple
|
||||||
|
BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
|
||||||
|
{
|
||||||
|
TupleDesc tupdesc;
|
||||||
|
int natts;
|
||||||
|
HeapTuple tuple;
|
||||||
|
char *nulls;
|
||||||
|
int i;
|
||||||
|
Datum *dvalues;
|
||||||
|
FmgrInfo attinfuncinfo;
|
||||||
|
Oid attelem;
|
||||||
|
int4 atttypmod;
|
||||||
|
|
||||||
|
tupdesc = attinmeta->tupdesc;
|
||||||
|
natts = tupdesc->natts;
|
||||||
|
|
||||||
|
dvalues = (Datum *) palloc(natts * sizeof(Datum));
|
||||||
|
|
||||||
|
/* Call the "in" function for each attribute */
|
||||||
|
for (i = 0; i < natts; i++)
|
||||||
|
{
|
||||||
|
if (values[i] != NULL)
|
||||||
|
{
|
||||||
|
attinfuncinfo = attinmeta->attinfuncs[i];
|
||||||
|
attelem = attinmeta->attelems[i];
|
||||||
|
atttypmod = attinmeta->atttypmods[i];
|
||||||
|
|
||||||
|
dvalues[i] = FunctionCall3(&attinfuncinfo, CStringGetDatum(values[i]),
|
||||||
|
ObjectIdGetDatum(attelem),
|
||||||
|
Int32GetDatum(atttypmod));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dvalues[i] = PointerGetDatum(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Form a tuple
|
||||||
|
*/
|
||||||
|
nulls = (char *) palloc(natts * sizeof(char));
|
||||||
|
for (i = 0; i < natts; i++)
|
||||||
|
{
|
||||||
|
if (DatumGetPointer(dvalues[i]) != NULL)
|
||||||
|
nulls[i] = ' ';
|
||||||
|
else
|
||||||
|
nulls[i] = 'n';
|
||||||
|
}
|
||||||
|
tuple = heap_formtuple(tupdesc, dvalues, nulls);
|
||||||
|
|
||||||
|
return tuple;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.68 2002/05/11 00:24:16 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.69 2002/06/20 17:19:08 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -37,8 +37,6 @@
|
|||||||
#include "utils/lsyscache.h"
|
#include "utils/lsyscache.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
|
||||||
|
|
||||||
static List *stringToQualifiedNameList(const char *string, const char *caller);
|
|
||||||
static void parseNameAndArgTypes(const char *string, const char *caller,
|
static void parseNameAndArgTypes(const char *string, const char *caller,
|
||||||
const char *type0_spelling,
|
const char *type0_spelling,
|
||||||
List **names, int *nargs, Oid *argtypes);
|
List **names, int *nargs, Oid *argtypes);
|
||||||
@ -960,14 +958,10 @@ regtypeout(PG_FUNCTION_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
|
||||||
* SUPPORT ROUTINES *
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a C string, parse it into a qualified-name list.
|
* Given a C string, parse it into a qualified-name list.
|
||||||
*/
|
*/
|
||||||
static List *
|
List *
|
||||||
stringToQualifiedNameList(const char *string, const char *caller)
|
stringToQualifiedNameList(const char *string, const char *caller)
|
||||||
{
|
{
|
||||||
char *rawname;
|
char *rawname;
|
||||||
@ -997,6 +991,10 @@ stringToQualifiedNameList(const char *string, const char *caller)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* SUPPORT ROUTINES *
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Given a C string, parse it into a qualified function or operator name
|
* Given a C string, parse it into a qualified function or operator name
|
||||||
* followed by a parenthesized list of type names. Reduce the
|
* followed by a parenthesized list of type names. Reduce the
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
# Makefile for utils/fmgr
|
# Makefile for utils/fmgr
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# IDENTIFICATION
|
||||||
# $Header: /cvsroot/pgsql/src/backend/utils/fmgr/Makefile,v 1.12 2001/09/16 16:11:11 petere Exp $
|
# $Header: /cvsroot/pgsql/src/backend/utils/fmgr/Makefile,v 1.13 2002/06/20 17:19:08 momjian Exp $
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ subdir = src/backend/utils/fmgr
|
|||||||
top_builddir = ../../../..
|
top_builddir = ../../../..
|
||||||
include $(top_builddir)/src/Makefile.global
|
include $(top_builddir)/src/Makefile.global
|
||||||
|
|
||||||
OBJS = dfmgr.o fmgr.o
|
OBJS = dfmgr.o fmgr.o funcapi.o
|
||||||
|
|
||||||
override CPPFLAGS += -DPKGLIBDIR=\"$(pkglibdir)\" -DDLSUFFIX=\"$(DLSUFFIX)\"
|
override CPPFLAGS += -DPKGLIBDIR=\"$(pkglibdir)\" -DDLSUFFIX=\"$(DLSUFFIX)\"
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: builtins.h,v 1.184 2002/06/13 03:40:49 tgl Exp $
|
* $Id: builtins.h,v 1.185 2002/06/20 17:19:08 momjian Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -342,6 +342,7 @@ extern Datum regclassin(PG_FUNCTION_ARGS);
|
|||||||
extern Datum regclassout(PG_FUNCTION_ARGS);
|
extern Datum regclassout(PG_FUNCTION_ARGS);
|
||||||
extern Datum regtypein(PG_FUNCTION_ARGS);
|
extern Datum regtypein(PG_FUNCTION_ARGS);
|
||||||
extern Datum regtypeout(PG_FUNCTION_ARGS);
|
extern Datum regtypeout(PG_FUNCTION_ARGS);
|
||||||
|
extern List *stringToQualifiedNameList(const char *string, const char *caller);
|
||||||
|
|
||||||
/* ruleutils.c */
|
/* ruleutils.c */
|
||||||
extern Datum pg_get_ruledef(PG_FUNCTION_ARGS);
|
extern Datum pg_get_ruledef(PG_FUNCTION_ARGS);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user