aboutsummaryrefslogtreecommitdiff
path: root/src/backend/libpq/be-dumpdata.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/libpq/be-dumpdata.c')
-rw-r--r--src/backend/libpq/be-dumpdata.c448
1 files changed, 231 insertions, 217 deletions
diff --git a/src/backend/libpq/be-dumpdata.c b/src/backend/libpq/be-dumpdata.c
index b47e79fa65c..db0a99141d6 100644
--- a/src/backend/libpq/be-dumpdata.c
+++ b/src/backend/libpq/be-dumpdata.c
@@ -1,32 +1,32 @@
/*-------------------------------------------------------------------------
*
* be-dumpdata.c--
- * support for collection of returned tuples from an internal
- * PQ call into a backend buffer.
+ * support for collection of returned tuples from an internal
+ * PQ call into a backend buffer.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-dumpdata.c,v 1.5 1997/08/18 20:52:31 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-dumpdata.c,v 1.6 1997/09/07 04:42:12 momjian Exp $
*
*-------------------------------------------------------------------------
*/
/*
* INTERFACE ROUTINES
- * be_portalinit - initialize backend portal administration
- * be_portalpush - add a portal to the top of the portal stack
- * be_portalpop - remove portal on the top of the stack & return it
- * be_currentportal - return the top portal on the portal stack
- * be_newportal - return a new portal.
- * be_portalinit - initialize backend portal expected to hold results.
- * be_printtup - add a tuple to a backend portal
+ * be_portalinit - initialize backend portal administration
+ * be_portalpush - add a portal to the top of the portal stack
+ * be_portalpop - remove portal on the top of the stack & return it
+ * be_currentportal - return the top portal on the portal stack
+ * be_newportal - return a new portal.
+ * be_portalinit - initialize backend portal expected to hold results.
+ * be_printtup - add a tuple to a backend portal
*
* NOTES
- * Since backend user-defined operators can call queries
- * which in turn call user-defined operators can call queries...
- * we have to keep track of portals on a stack. BeginCommand()
- * puts portals on the stack and the PQ functions remove them.
+ * Since backend user-defined operators can call queries
+ * which in turn call user-defined operators can call queries...
+ * we have to keep track of portals on a stack. BeginCommand()
+ * puts portals on the stack and the PQ functions remove them.
*
*/
#include <string.h>
@@ -48,274 +48,288 @@
#include <access/printtup.h>
/* ----------------
- * backend portal stack for recursive PQexec calls
+ * backend portal stack for recursive PQexec calls
* ----------------
*/
-static Dllist *be_portalstack;
+static Dllist *be_portalstack;
/* ----------------
- * be_portalinit - initialize backend portal administration
+ * be_portalinit - initialize backend portal administration
*
- * This is called once from InitPostgres() to initialize
- * the portal stack.
+ * This is called once from InitPostgres() to initialize
+ * the portal stack.
* ----------------
*/
void
be_portalinit(void)
{
- be_portalstack = DLNewList();
+ be_portalstack = DLNewList();
}
/* ----------------
- * be_portalpush - add a portal to the top of the portal stack
+ * be_portalpush - add a portal to the top of the portal stack
*
- * used by BeginCommand()
+ * used by BeginCommand()
* ----------------
*/
void
-be_portalpush(PortalEntry *entry)
+be_portalpush(PortalEntry * entry)
{
- DLAddTail(be_portalstack, DLNewElem(entry));
+ DLAddTail(be_portalstack, DLNewElem(entry));
}
/* ----------------
- * be_portalpop - remove the portal on the top of the stack & return it
+ * be_portalpop - remove the portal on the top of the stack & return it
*
- * used by PQexec()
+ * used by PQexec()
* ----------------
*/
-PortalEntry *
+PortalEntry *
be_portalpop(void)
{
- PortalEntry *p;
- Dlelem* elt;
- elt = DLRemTail(be_portalstack);
+ PortalEntry *p;
+ Dlelem *elt;
+
+ elt = DLRemTail(be_portalstack);
+
+ p = (elt ? (PortalEntry *) DLE_VAL(elt) : NULL);
+ DLFreeElem(elt);
+ return p;
- p = (elt ? (PortalEntry*)DLE_VAL(elt) : NULL);
- DLFreeElem(elt);
- return p;
-
}
/* ----------------
- * be_currentportal - return the top portal on the portal stack
+ * be_currentportal - return the top portal on the portal stack
*
- * used by be_printtup()
+ * used by be_printtup()
* ----------------
*/
-PortalEntry *
+PortalEntry *
be_currentportal(void)
{
- Dlelem* elt;
- elt = DLGetTail(be_portalstack);
- return (elt ? (PortalEntry*)DLE_VAL(elt) : NULL);
+ Dlelem *elt;
+
+ elt = DLGetTail(be_portalstack);
+ return (elt ? (PortalEntry *) DLE_VAL(elt) : NULL);
}
/* ----------------
- * be_newportal - return a new portal.
+ * be_newportal - return a new portal.
*
- * If the user-defined function does not specify a portal name,
- * we generate a unique one. Names are generated from a combination
- * of a postgres oid and an integer counter which is incremented
- * every time we ask for a local portal.
+ * If the user-defined function does not specify a portal name,
+ * we generate a unique one. Names are generated from a combination
+ * of a postgres oid and an integer counter which is incremented
+ * every time we ask for a local portal.
*
- * used by BeginCommand()
+ * used by BeginCommand()
* ----------------
*/
-static Oid be_portaloid;
+static Oid be_portaloid;
static u_int be_portalcnt = 0;
-PortalEntry *
-be_newportal(void)
+PortalEntry *
+be_newportal(void)
{
- PortalEntry *entry;
- char buf[PortalNameLength];
-
- /* ----------------
- * generate a new name
- * ----------------
- */
- if (be_portalcnt == 0)
- be_portaloid = newoid();
- be_portalcnt++;
- sprintf(buf, "be_%d_%d", be_portaloid, be_portalcnt);
-
- /* ----------------
- * initialize the new portal entry and keep track
- * of the current memory context for be_printtup().
- * This is important - otherwise whatever we allocate
- * will go away and the contents of the portal after
- * PQexec() returns will be meaningless.
- * ----------------
- */
- entry = pbuf_setup(buf);
- entry->portalcxt = (Pointer) CurrentMemoryContext;
-
- return entry;
+ PortalEntry *entry;
+ char buf[PortalNameLength];
+
+ /* ----------------
+ * generate a new name
+ * ----------------
+ */
+ if (be_portalcnt == 0)
+ be_portaloid = newoid();
+ be_portalcnt++;
+ sprintf(buf, "be_%d_%d", be_portaloid, be_portalcnt);
+
+ /* ----------------
+ * initialize the new portal entry and keep track
+ * of the current memory context for be_printtup().
+ * This is important - otherwise whatever we allocate
+ * will go away and the contents of the portal after
+ * PQexec() returns will be meaningless.
+ * ----------------
+ */
+ entry = pbuf_setup(buf);
+ entry->portalcxt = (Pointer) CurrentMemoryContext;
+
+ return entry;
}
/* ----------------
- * be_typeinit - initialize backend portal expected to hold
- * query results.
+ * be_typeinit - initialize backend portal expected to hold
+ * query results.
*
- * used by BeginCommand()
+ * used by BeginCommand()
* ----------------
*/
void
-be_typeinit(PortalEntry *entry,
- TupleDesc tupDesc,
- int natts)
+be_typeinit(PortalEntry * entry,
+ TupleDesc tupDesc,
+ int natts)
{
- PortalBuffer *portal;
- GroupBuffer *group;
- int i;
- AttributeTupleForm *attrs = tupDesc->attrs;
-
- /* ----------------
- * add a new portal group to the portal
- * ----------------
- */
- portal = entry->portal;
- portal->no_groups++;
- portal->groups = group = pbuf_addGroup(portal);
- group->no_fields = natts;
-
- /* ----------------
- * initialize portal group type info
- * ----------------
- */
- if (natts > 0) {
- group->types = pbuf_addTypes(natts);
- for (i = 0; i < natts; ++i) {
- strncpy(group->types[i].name, attrs[i]->attname.data, NAMEDATALEN);
- group->types[i].adtid = attrs[i]->atttypid;
- group->types[i].adtsize = attrs[i]->attlen;
+ PortalBuffer *portal;
+ GroupBuffer *group;
+ int i;
+ AttributeTupleForm *attrs = tupDesc->attrs;
+
+ /* ----------------
+ * add a new portal group to the portal
+ * ----------------
+ */
+ portal = entry->portal;
+ portal->no_groups++;
+ portal->groups = group = pbuf_addGroup(portal);
+ group->no_fields = natts;
+
+ /* ----------------
+ * initialize portal group type info
+ * ----------------
+ */
+ if (natts > 0)
+ {
+ group->types = pbuf_addTypes(natts);
+ for (i = 0; i < natts; ++i)
+ {
+ strncpy(group->types[i].name, attrs[i]->attname.data, NAMEDATALEN);
+ group->types[i].adtid = attrs[i]->atttypid;
+ group->types[i].adtsize = attrs[i]->attlen;
+ }
}
- }
}
/* ----------------
- * be_printtup - add a tuple to a backend portal
+ * be_printtup - add a tuple to a backend portal
*
- * used indirectly by ExecRetrieve()
+ * used indirectly by ExecRetrieve()
*
- * This code is pretty much copied from printtup(), dump_type()
- * and dump_data(). -cim 2/12/91
+ * This code is pretty much copied from printtup(), dump_type()
+ * and dump_data(). -cim 2/12/91
* ----------------
*/
void
be_printtup(HeapTuple tuple, TupleDesc typeinfo)
{
- int i;
- char *attr;
- bool isnull;
- Oid typoutput;
-
- PortalEntry *entry = NULL;
- PortalBuffer *portal = NULL;
- GroupBuffer *group = NULL ;
- TupleBlock *tuples = NULL;
- char **values;
- int *lengths;
-
- MemoryContext savecxt;
-
- /* ----------------
- * get the current portal and group
- * ----------------
- */
- entry = be_currentportal();
- portal = entry->portal;
- group = portal->groups;
-
- /* ----------------
- * switch to the portal's memory context so that
- * the tuples we allocate are returned to the user.
- * ----------------
- */
- savecxt = MemoryContextSwitchTo((MemoryContext)entry->portalcxt);
-
- /* ----------------
- * If no tuple block yet, allocate one.
- * If the current block is full, allocate another one.
- * ----------------
- */
- if (group->tuples == NULL) {
- tuples = group->tuples = pbuf_addTuples();
- tuples->tuple_index = 0;
- } else {
- tuples = group->tuples;
- /* walk to the end of the linked list of TupleBlocks */
- while (tuples->next)
- tuples = tuples->next;
- /* now, tuples is the last TupleBlock, check to see if it is full.
- If so, allocate a new TupleBlock and add it to the end of
- the chain */
-
- if (tuples->tuple_index == TupleBlockSize) {
- tuples->next = pbuf_addTuples();
- tuples = tuples->next;
- tuples->tuple_index = 0;
+ int i;
+ char *attr;
+ bool isnull;
+ Oid typoutput;
+
+ PortalEntry *entry = NULL;
+ PortalBuffer *portal = NULL;
+ GroupBuffer *group = NULL;
+ TupleBlock *tuples = NULL;
+ char **values;
+ int *lengths;
+
+ MemoryContext savecxt;
+
+ /* ----------------
+ * get the current portal and group
+ * ----------------
+ */
+ entry = be_currentportal();
+ portal = entry->portal;
+ group = portal->groups;
+
+ /* ----------------
+ * switch to the portal's memory context so that
+ * the tuples we allocate are returned to the user.
+ * ----------------
+ */
+ savecxt = MemoryContextSwitchTo((MemoryContext) entry->portalcxt);
+
+ /* ----------------
+ * If no tuple block yet, allocate one.
+ * If the current block is full, allocate another one.
+ * ----------------
+ */
+ if (group->tuples == NULL)
+ {
+ tuples = group->tuples = pbuf_addTuples();
+ tuples->tuple_index = 0;
}
- }
-
- /* ----------------
- * Allocate space for a tuple.
- * ----------------
- */
- tuples->values[tuples->tuple_index] = pbuf_addTuple(tuple->t_natts);
- tuples->lengths[tuples->tuple_index] = pbuf_addTupleValueLengths(tuple->t_natts);
- /* ----------------
- * copy printable representations of the tuple's attributes
- * to the portal.
- *
- * This seems silly, because the user's function which is calling
- * PQexec() or PQfn() will probably just convert this back into the
- * internal form anyways, but the point here is to provide a uniform
- * libpq interface and this is how the fe libpq interface currently
- * works. Pretty soon we'll have to add code to let the fe or be
- * select the desired data representation and then deal with that.
- * This should not be too hard, as there already exist typrecieve()
- * and typsend() procedures for user-defined types (see pg_type.h)
- * -cim 2/11/91
- * ----------------
- */
-
- values = tuples->values[tuples->tuple_index];
- lengths = tuples->lengths[tuples->tuple_index];
-
- for (i = 0; i < tuple->t_natts; i++) {
- attr = heap_getattr(tuple, InvalidBuffer, i+1, typeinfo, &isnull);
- typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
-
- lengths[i] = typeinfo->attrs[i]->attlen;
-
- if (lengths[i] == -1) /* variable length attribute */
- if (!isnull)
- lengths[i] = VARSIZE(attr)-VARHDRSZ;
- else
- lengths[i] = 0;
-
- if (!isnull && OidIsValid(typoutput)) {
- values[i] = fmgr(typoutput, attr, gettypelem(typeinfo->attrs[i]->atttypid));
- } else
- values[i] = NULL;
-
- }
-
- /* ----------------
- * increment tuple group counters
- * ----------------
- */
- portal->no_tuples++;
- group->no_tuples++;
- tuples->tuple_index++;
-
- /* ----------------
- * return to the original memory context
- * ----------------
- */
- MemoryContextSwitchTo(savecxt);
+ else
+ {
+ tuples = group->tuples;
+ /* walk to the end of the linked list of TupleBlocks */
+ while (tuples->next)
+ tuples = tuples->next;
+
+ /*
+ * now, tuples is the last TupleBlock, check to see if it is full.
+ * If so, allocate a new TupleBlock and add it to the end of the
+ * chain
+ */
+
+ if (tuples->tuple_index == TupleBlockSize)
+ {
+ tuples->next = pbuf_addTuples();
+ tuples = tuples->next;
+ tuples->tuple_index = 0;
+ }
+ }
+
+ /* ----------------
+ * Allocate space for a tuple.
+ * ----------------
+ */
+ tuples->values[tuples->tuple_index] = pbuf_addTuple(tuple->t_natts);
+ tuples->lengths[tuples->tuple_index] = pbuf_addTupleValueLengths(tuple->t_natts);
+ /* ----------------
+ * copy printable representations of the tuple's attributes
+ * to the portal.
+ *
+ * This seems silly, because the user's function which is calling
+ * PQexec() or PQfn() will probably just convert this back into the
+ * internal form anyways, but the point here is to provide a uniform
+ * libpq interface and this is how the fe libpq interface currently
+ * works. Pretty soon we'll have to add code to let the fe or be
+ * select the desired data representation and then deal with that.
+ * This should not be too hard, as there already exist typrecieve()
+ * and typsend() procedures for user-defined types (see pg_type.h)
+ * -cim 2/11/91
+ * ----------------
+ */
+
+ values = tuples->values[tuples->tuple_index];
+ lengths = tuples->lengths[tuples->tuple_index];
+
+ for (i = 0; i < tuple->t_natts; i++)
+ {
+ attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
+ typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
+
+ lengths[i] = typeinfo->attrs[i]->attlen;
+
+ if (lengths[i] == -1) /* variable length attribute */
+ if (!isnull)
+ lengths[i] = VARSIZE(attr) - VARHDRSZ;
+ else
+ lengths[i] = 0;
+
+ if (!isnull && OidIsValid(typoutput))
+ {
+ values[i] = fmgr(typoutput, attr, gettypelem(typeinfo->attrs[i]->atttypid));
+ }
+ else
+ values[i] = NULL;
+
+ }
+
+ /* ----------------
+ * increment tuple group counters
+ * ----------------
+ */
+ portal->no_tuples++;
+ group->no_tuples++;
+ tuples->tuple_index++;
+
+ /* ----------------
+ * return to the original memory context
+ * ----------------
+ */
+ MemoryContextSwitchTo(savecxt);
}