Skip to content

Commit ba790a5

Browse files
committed
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
1 parent bffc4b6 commit ba790a5

File tree

5 files changed

+242
-14
lines changed

5 files changed

+242
-14
lines changed

src/backend/access/common/tupdesc.c

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.78 2002/03/29 19:05:59 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.79 2002/06/20 17:19:08 momjian Exp $
1212
*
1313
* NOTES
1414
* some of the executor utility code such as "ExecTypeFromTL" should be
@@ -19,6 +19,9 @@
1919

2020
#include "postgres.h"
2121

22+
#include "funcapi.h"
23+
#include "access/heapam.h"
24+
#include "catalog/namespace.h"
2225
#include "catalog/pg_type.h"
2326
#include "nodes/parsenodes.h"
2427
#include "parser/parse_type.h"
@@ -549,3 +552,109 @@ BuildDescForRelation(List *schema)
549552
}
550553
return desc;
551554
}
555+
556+
557+
/*
558+
* RelationNameGetTupleDesc
559+
*
560+
* Given a (possibly qualified) relation name, build a TupleDesc.
561+
*/
562+
TupleDesc
563+
RelationNameGetTupleDesc(char *relname)
564+
{
565+
RangeVar *relvar;
566+
Relation rel;
567+
TupleDesc tupdesc;
568+
List *relname_list;
569+
570+
/* Open relation and get the tuple description */
571+
relname_list = stringToQualifiedNameList(relname, "RelationNameGetTupleDesc");
572+
relvar = makeRangeVarFromNameList(relname_list);
573+
rel = heap_openrv(relvar, AccessShareLock);
574+
tupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
575+
relation_close(rel, AccessShareLock);
576+
577+
return tupdesc;
578+
}
579+
580+
/*
581+
* TypeGetTupleDesc
582+
*
583+
* Given a type Oid, build a TupleDesc.
584+
*
585+
* If the type is composite, *and* a colaliases List is provided, *and*
586+
* the List is of natts length, use the aliases instead of the relation
587+
* attnames.
588+
*
589+
* If the type is a base type, a single item alias List is required.
590+
*/
591+
TupleDesc
592+
TypeGetTupleDesc(Oid typeoid, List *colaliases)
593+
{
594+
Oid relid = typeidTypeRelid(typeoid);
595+
TupleDesc tupdesc;
596+
597+
/*
598+
* Build a suitable tupledesc representing the output rows
599+
*/
600+
if (OidIsValid(relid))
601+
{
602+
/* Composite data type, i.e. a table's row type */
603+
Relation rel;
604+
int natts;
605+
606+
rel = relation_open(relid, AccessShareLock);
607+
tupdesc = CreateTupleDescCopy(RelationGetDescr(rel));
608+
natts = tupdesc->natts;
609+
relation_close(rel, AccessShareLock);
610+
611+
/* check to see if we've given column aliases */
612+
if(colaliases != NIL)
613+
{
614+
char *label;
615+
int varattno;
616+
617+
/* does the List length match the number of attributes */
618+
if (length(colaliases) != natts)
619+
elog(ERROR, "TypeGetTupleDesc: number of aliases does not match number of attributes");
620+
621+
/* OK, use the aliases instead */
622+
for (varattno = 0; varattno < natts; varattno++)
623+
{
624+
label = strVal(nth(varattno, colaliases));
625+
626+
if (label != NULL)
627+
namestrcpy(&(tupdesc->attrs[varattno]->attname), label);
628+
else
629+
MemSet(NameStr(tupdesc->attrs[varattno]->attname), 0, NAMEDATALEN);
630+
}
631+
}
632+
}
633+
else
634+
{
635+
/* Must be a base data type, i.e. scalar */
636+
char *attname;
637+
638+
/* the alias List is required for base types */
639+
if (colaliases == NIL)
640+
elog(ERROR, "TypeGetTupleDesc: no column alias was provided");
641+
642+
/* the alias List length must be 1 */
643+
if (length(colaliases) != 1)
644+
elog(ERROR, "TypeGetTupleDesc: number of aliases does not match number of attributes");
645+
646+
/* OK, get the column alias */
647+
attname = strVal(lfirst(colaliases));
648+
649+
tupdesc = CreateTemplateTupleDesc(1);
650+
TupleDescInitEntry(tupdesc,
651+
(AttrNumber) 1,
652+
attname,
653+
typeoid,
654+
-1,
655+
0,
656+
false);
657+
}
658+
659+
return tupdesc;
660+
}

src/backend/executor/execTuples.c

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.51 2002/03/21 06:21:04 tgl Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.52 2002/06/20 17:19:08 momjian Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -107,11 +107,11 @@
107107
*/
108108
#include "postgres.h"
109109

110+
#include "funcapi.h"
110111
#include "access/heapam.h"
111112
#include "catalog/pg_type.h"
112113
#include "executor/executor.h"
113114

114-
115115
/* ----------------------------------------------------------------
116116
* tuple table create/delete functions
117117
* ----------------------------------------------------------------
@@ -673,3 +673,123 @@ ExecTypeFromTL(List *targetList)
673673

674674
return typeInfo;
675675
}
676+
677+
/*
678+
* TupleDescGetSlot - Initialize a slot based on the supplied
679+
* tupledesc
680+
*/
681+
TupleTableSlot *
682+
TupleDescGetSlot(TupleDesc tupdesc)
683+
{
684+
TupleTableSlot *slot;
685+
686+
/* Make a standalone slot */
687+
slot = MakeTupleTableSlot();
688+
689+
/* Bind the tuple description to the slot */
690+
ExecSetSlotDescriptor(slot, tupdesc, true);
691+
692+
/* Return the slot */
693+
return slot;
694+
}
695+
696+
/*
697+
* TupleDescGetAttInMetadata - Get a pointer to AttInMetadata based on the
698+
* supplied TupleDesc. AttInMetadata can be used in conjunction with C strings
699+
* to produce a properly formed tuple.
700+
*/
701+
AttInMetadata *
702+
TupleDescGetAttInMetadata(TupleDesc tupdesc)
703+
{
704+
int natts;
705+
int i;
706+
Oid atttypeid;
707+
Oid attinfuncid;
708+
Oid attelem;
709+
FmgrInfo *attinfuncinfo;
710+
Oid *attelems;
711+
int4 *atttypmods;
712+
AttInMetadata *attinmeta;
713+
714+
attinmeta = (AttInMetadata *) palloc(sizeof(AttInMetadata));
715+
natts = tupdesc->natts;
716+
717+
/*
718+
* Gather info needed later to call the "in" function for each attribute
719+
*/
720+
attinfuncinfo = (FmgrInfo *) palloc(natts * sizeof(FmgrInfo));
721+
attelems = (Oid *) palloc(natts * sizeof(Oid));
722+
atttypmods = (int4 *) palloc(natts * sizeof(int4));
723+
724+
for (i = 0; i < natts; i++)
725+
{
726+
atttypeid = tupdesc->attrs[i]->atttypid;
727+
get_type_metadata(atttypeid, &attinfuncid, &attelem);
728+
729+
fmgr_info(attinfuncid, &attinfuncinfo[i]);
730+
attelems[i] = attelem;
731+
atttypmods[i] = tupdesc->attrs[i]->atttypmod;
732+
}
733+
attinmeta->tupdesc = tupdesc;
734+
attinmeta->attinfuncs = attinfuncinfo;
735+
attinmeta->attelems = attelems;
736+
attinmeta->atttypmods = atttypmods;
737+
738+
return attinmeta;
739+
}
740+
741+
/*
742+
* BuildTupleFromCStrings - build a HeapTuple given user data in C string form.
743+
* values is an array of C strings, one for each attribute of the return tuple.
744+
*/
745+
HeapTuple
746+
BuildTupleFromCStrings(AttInMetadata *attinmeta, char **values)
747+
{
748+
TupleDesc tupdesc;
749+
int natts;
750+
HeapTuple tuple;
751+
char *nulls;
752+
int i;
753+
Datum *dvalues;
754+
FmgrInfo attinfuncinfo;
755+
Oid attelem;
756+
int4 atttypmod;
757+
758+
tupdesc = attinmeta->tupdesc;
759+
natts = tupdesc->natts;
760+
761+
dvalues = (Datum *) palloc(natts * sizeof(Datum));
762+
763+
/* Call the "in" function for each attribute */
764+
for (i = 0; i < natts; i++)
765+
{
766+
if (values[i] != NULL)
767+
{
768+
attinfuncinfo = attinmeta->attinfuncs[i];
769+
attelem = attinmeta->attelems[i];
770+
atttypmod = attinmeta->atttypmods[i];
771+
772+
dvalues[i] = FunctionCall3(&attinfuncinfo, CStringGetDatum(values[i]),
773+
ObjectIdGetDatum(attelem),
774+
Int32GetDatum(atttypmod));
775+
}
776+
else
777+
dvalues[i] = PointerGetDatum(NULL);
778+
}
779+
780+
/*
781+
* Form a tuple
782+
*/
783+
nulls = (char *) palloc(natts * sizeof(char));
784+
for (i = 0; i < natts; i++)
785+
{
786+
if (DatumGetPointer(dvalues[i]) != NULL)
787+
nulls[i] = ' ';
788+
else
789+
nulls[i] = 'n';
790+
}
791+
tuple = heap_formtuple(tupdesc, dvalues, nulls);
792+
793+
return tuple;
794+
}
795+

src/backend/utils/adt/regproc.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
*
1515
* IDENTIFICATION
16-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.68 2002/05/11 00:24:16 tgl Exp $
16+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.69 2002/06/20 17:19:08 momjian Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -37,8 +37,6 @@
3737
#include "utils/lsyscache.h"
3838
#include "utils/syscache.h"
3939

40-
41-
static List *stringToQualifiedNameList(const char *string, const char *caller);
4240
static void parseNameAndArgTypes(const char *string, const char *caller,
4341
const char *type0_spelling,
4442
List **names, int *nargs, Oid *argtypes);
@@ -960,14 +958,10 @@ regtypeout(PG_FUNCTION_ARGS)
960958
}
961959

962960

963-
/*****************************************************************************
964-
* SUPPORT ROUTINES *
965-
*****************************************************************************/
966-
967961
/*
968962
* Given a C string, parse it into a qualified-name list.
969963
*/
970-
static List *
964+
List *
971965
stringToQualifiedNameList(const char *string, const char *caller)
972966
{
973967
char *rawname;
@@ -997,6 +991,10 @@ stringToQualifiedNameList(const char *string, const char *caller)
997991
return result;
998992
}
999993

994+
/*****************************************************************************
995+
* SUPPORT ROUTINES *
996+
*****************************************************************************/
997+
1000998
/*
1001999
* Given a C string, parse it into a qualified function or operator name
10021000
* followed by a parenthesized list of type names. Reduce the

src/backend/utils/fmgr/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44
# Makefile for utils/fmgr
55
#
66
# IDENTIFICATION
7-
# $Header: /cvsroot/pgsql/src/backend/utils/fmgr/Makefile,v 1.12 2001/09/16 16:11:11 petere Exp $
7+
# $Header: /cvsroot/pgsql/src/backend/utils/fmgr/Makefile,v 1.13 2002/06/20 17:19:08 momjian Exp $
88
#
99
#-------------------------------------------------------------------------
1010

1111
subdir = src/backend/utils/fmgr
1212
top_builddir = ../../../..
1313
include $(top_builddir)/src/Makefile.global
1414

15-
OBJS = dfmgr.o fmgr.o
15+
OBJS = dfmgr.o fmgr.o funcapi.o
1616

1717
override CPPFLAGS += -DPKGLIBDIR=\"$(pkglibdir)\" -DDLSUFFIX=\"$(DLSUFFIX)\"
1818

src/include/utils/builtins.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: builtins.h,v 1.184 2002/06/13 03:40:49 tgl Exp $
10+
* $Id: builtins.h,v 1.185 2002/06/20 17:19:08 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -342,6 +342,7 @@ extern Datum regclassin(PG_FUNCTION_ARGS);
342342
extern Datum regclassout(PG_FUNCTION_ARGS);
343343
extern Datum regtypein(PG_FUNCTION_ARGS);
344344
extern Datum regtypeout(PG_FUNCTION_ARGS);
345+
extern List *stringToQualifiedNameList(const char *string, const char *caller);
345346

346347
/* ruleutils.c */
347348
extern Datum pg_get_ruledef(PG_FUNCTION_ARGS);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy