* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.65 2000/06/08 22:37:01 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.66 2000/07/08 03:04:12 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "libpq/libpq.h"
#include "libpq/pqformat.h"
#include "miscadmin.h"
+#include "tcop/dest.h"
#include "utils/fmgroids.h"
#include "utils/ps_status.h"
#include "utils/syscache.h"
# Makefile for libpq subsystem (backend half of libpq interface)
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.20 2000/06/17 00:09:40 petere Exp $
+# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.21 2000/07/08 03:04:39 tgl Exp $
#
#-------------------------------------------------------------------------
SRCDIR = ../..
include ../../Makefile.global
-OBJS = be-dumpdata.o be-fsstubs.o be-pqexec.o portal.o portalbuf.o \
- auth.o hba.o crypt.o password.o \
+# be-fsstubs is here for historical reasons, probably belongs elsewhere
+
+OBJS = be-fsstubs.o \
+ auth.o crypt.o hba.o password.o \
pqcomm.o pqformat.o pqpacket.o pqsignal.o util.o
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * be-dumpdata.c
- * support for collection of returned tuples from an internal
- * PQ call into a backend buffer.
- *
- * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * $Id: be-dumpdata.c,v 1.34 2000/05/30 04:24:46 tgl 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
- *
- * 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.
- *
- */
-
-#include "postgres.h"
-
-#include "access/heapam.h"
-#include "access/printtup.h"
-#include "catalog/catalog.h"
-#include "lib/dllist.h"
-#include "libpq/libpq.h"
-
-/* ----------------
- * backend portal stack for recursive PQexec calls
- * ----------------
- */
-static Dllist *be_portalstack;
-
-/* ----------------
- * be_portalinit - initialize backend portal administration
- *
- * This is called once from InitPostgres() to initialize
- * the portal stack.
- * ----------------
- */
-void
-be_portalinit(void)
-{
- be_portalstack = DLNewList();
-}
-
-/* ----------------
- * be_portalpush - add a portal to the top of the portal stack
- *
- * used by BeginCommand()
- * ----------------
- */
-void
-be_portalpush(PortalEntry *entry)
-{
- DLAddTail(be_portalstack, DLNewElem(entry));
-}
-
-/* ----------------
- * be_portalpop - remove the portal on the top of the stack & return it
- *
- * used by PQexec()
- * ----------------
- */
-PortalEntry *
-be_portalpop(void)
-{
- PortalEntry *p;
- Dlelem *elt;
-
- elt = DLRemTail(be_portalstack);
-
- p = (elt ? (PortalEntry *) DLE_VAL(elt) : NULL);
- DLFreeElem(elt);
- return p;
-
-
-}
-
-/* ----------------
- * be_currentportal - return the top portal on the portal stack
- *
- * used by be_printtup()
- * ----------------
- */
-PortalEntry *
-be_currentportal(void)
-{
- Dlelem *elt;
-
- elt = DLGetTail(be_portalstack);
- return elt ? (PortalEntry *) DLE_VAL(elt) : NULL;
-}
-
-/* ----------------
- * 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.
- *
- * used by BeginCommand()
- * ----------------
- */
-
-static Oid be_portaloid;
-static u_int be_portalcnt = 0;
-
-PortalEntry *
-be_newportal(void)
-{
- PortalEntry *entry;
- char buf[PortalNameLength];
-
- /* ----------------
- * generate a new name
- * ----------------
- */
- if (be_portalcnt == 0)
- be_portaloid = newoid();
- be_portalcnt++;
- snprintf(buf, PortalNameLength, "be_%u_%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.
- *
- * used by BeginCommand()
- * ----------------
- */
-void
-be_typeinit(PortalEntry *entry,
- TupleDesc tupDesc,
- int natts)
-{
- PortalBuffer *portal;
- GroupBuffer *group;
- int i;
- Form_pg_attribute *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,
- NameStr(attrs[i]->attname), NAMEDATALEN);
- group->types[i].typid = attrs[i]->atttypid;
- group->types[i].typlen = attrs[i]->attlen;
- }
- }
-}
-
-/* ----------------
- * be_printtup - add a tuple to a backend portal
- *
- * used indirectly by ExecRetrieve()
- *
- * This code is pretty much copied from printtup(), dump_type()
- * and dump_data(). -cim 2/12/91
- * ----------------
- */
-void
-be_printtup(HeapTuple tuple, TupleDesc typeinfo, DestReceiver *self)
-{
- int i;
- Datum attr;
- bool isnull;
- Oid typoutput,
- typelem;
-
- 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;
- }
- }
-
- /* ----------------
- * Allocate space for a tuple.
- * ----------------
- */
- tuples->values[tuples->tuple_index] = pbuf_addTuple(tuple->t_data->t_natts);
- tuples->lengths[tuples->tuple_index] = pbuf_addTupleValueLengths(tuple->t_data->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_data->t_natts; i++)
- {
- attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
- getTypeOutAndElem((Oid) typeinfo->attrs[i]->atttypid,
- &typoutput, &typelem);
-
- 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] = DatumGetCString(OidFunctionCall3(typoutput,
- attr,
- ObjectIdGetDatum(typelem),
- Int32GetDatum(typeinfo->attrs[i]->atttypmod)));
- 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);
-}
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * be-pqexec.c
- * support for executing POSTGRES commands and functions from a
- * user-defined function in a backend.
- *
- * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-pqexec.c,v 1.36 2000/07/07 21:12:53 tgl Exp $
- *
- *-------------------------------------------------------------------------
- */
-/*
- * INTERFACE ROUTINES
- * PQfn - call a POSTGRES function
- * PQexec - execute a POSTGRES query
- *
- * NOTES
- * These routines are compiled into the postgres backend.
- */
-#include "postgres.h"
-
-#include "libpq/libpq.h"
-#include "tcop/fastpath.h"
-#include "tcop/tcopprot.h"
-#include "utils/builtins.h"
-
-static char *strmake(char *str, int len);
-
-/* ----------------------------------------------------------------
- * PQ interface routines
- * ----------------------------------------------------------------
- */
-
-/* ----------------
- * PQfn - Send a function call to the POSTGRES backend.
- *
- * fnid : function id
- * result_buf : pointer to result buffer (&int if integer)
- * result_len : length of return value.
- * result_is_int : If the result is an integer, this must be non-zero
- * args : pointer to an array of PQArgBlock items.
- * (length, if integer, and result-pointer)
- * nargs : # of arguments in args array.
- *
- * This code scavenged from HandleFunctionRequest() in tcop/fastpath.h
- * ----------------
- */
-char *
-PQfn(int fnid,
- int *result_buf, /* can't use void, dec compiler barfs */
- int result_len,
- int result_is_int,
- PQArgBlock *args,
- int nargs)
-{
- FmgrInfo flinfo;
- FunctionCallInfoData fcinfo;
- Datum retval;
- int i;
-
- if (nargs > FUNC_MAX_ARGS)
- elog(ERROR, "functions cannot have more than %d arguments",
- FUNC_MAX_ARGS);
-
- /* ----------------
- * set up the argument block for the function manager
- * ----------------
- */
- fmgr_info((Oid) fnid, &flinfo);
-
- MemSet(&fcinfo, 0, sizeof(fcinfo));
- fcinfo.flinfo = &flinfo;
- fcinfo.nargs = nargs;
-
- for (i = 0; i < nargs; i++)
- {
- if (args[i].len == VAR_LENGTH_ARG)
- fcinfo.arg[i] = (Datum) args[i].u.ptr;
- else if ((Size) args[i].len > sizeof(int4))
- elog(ERROR, "arg_length of argument %d too long", i);
- else
- fcinfo.arg[i] = (Datum) args[i].u.integer;
- }
-
- /* ----------------
- * call the postgres function manager
- * ----------------
- */
- retval = FunctionCallInvoke(&fcinfo);
-
- /* ----------------
- * put the result in the buffer the user specified and
- * return the proper code.
- * ----------------
- */
- if (fcinfo.isnull) /* void retval */
- return "0";
-
- if (result_is_int)
- *result_buf = DatumGetInt32(retval);
- else
- memmove(result_buf, DatumGetPointer(retval), result_len);
- return "G";
-}
-
-/* ----------------
- * PQexec - Send a query to the POSTGRES backend
- *
- * The return value is a string.
- * If 0 or more tuples fetched from the backend, return "P portal-name".
- * If a query is does not return tuples, return "C query-command".
- * If there is an error: return "E error-message".
- *
- * Note: if we get a serious error or an elog(ERROR), then PQexec never
- * returns because the system longjmp's back to the main loop.
- * ----------------
- */
-char *
-PQexec(char *query)
-{
- PortalEntry *entry = NULL;
- char *result = NULL;
-
- /* ----------------
- * create a new portal and put it on top of the portal stack.
- * ----------------
- */
- entry = (PortalEntry *) be_newportal();
- be_portalpush(entry);
-
- /* ----------------
- * pg_exec_query_dest will put the query results in a portal which will
- * end up on the top of the portal stack.
- *
- * XXX memory context manipulation is WRONG here --- the query needs
- * to be executed in a context different from CurrentMemoryContext,
- * perhaps a freshly created sub-context. If I were expecting that
- * this code needs to work again, then I'd fix it. But actually I'm
- * planning to rip out this entire module sometime soon... tgl 7/2000.
- * ----------------
- */
- pg_exec_query_dest(query, Local, CurrentMemoryContext);
-
- /* ----------------
- * pop the portal off the portal stack and return the
- * result. Note if result is null, we return C.
- * ----------------
- */
- entry = (PortalEntry *) be_portalpop();
- result = entry->result;
- if (result == NULL)
- {
- char *PQE = "Cnull PQexec result";
-
- result = pstrdup(PQE);
- }
-
- if (result[0] != 'P')
- {
-
- /*
- * some successful command was executed, but it's not one where we
- * return the portal name so here we should be sure to clear out
- * the portal (since the caller has no handle on it)
- */
- pbuf_close(entry->name);
-
- }
- return result;
-}
-
-/* ----------------------------------------------------------------
- * pqtest support
- * ----------------------------------------------------------------
- */
-
-/* ----------------
- * pqtest_PQexec takes a text query and returns the number of
- * tuples it returns. Note: there is no need to PQclear()
- * here - the memory will go away at end transaction.
- * ----------------
- */
-int
-pqtest_PQexec(char *q)
-{
- PortalBuffer *a;
- char *res;
- int t;
-
- /* ----------------
- * execute the postgres query
- * ----------------
- */
- res = PQexec(q);
-
- /* ----------------
- * return number of tuples in portal or 0 if command returns no tuples.
- * ----------------
- */
- t = 0;
- switch (res[0])
- {
- case 'P':
- a = PQparray(&res[1]);
- if (a == NULL)
- elog(ERROR, "pqtest_PQexec: PQparray could not find portal %s",
- res);
-
- t = PQntuples(a);
- break;
- case 'C':
- break;
- default:
- elog(NOTICE, "pqtest_PQexec: PQexec(%s) returns %s", q, res);
- break;
- }
-
- return t;
-}
-
-/* ----------------
- * utilities for pqtest_PQfn()
- * ----------------
- */
-static char *
-strmake(char *str, int len)
-{
- char *newstr;
-
- if (str == NULL)
- return NULL;
- if (len <= 0)
- len = strlen(str);
-
- newstr = (char *) palloc(len + 1);
- memcpy(newstr, str, len);
- newstr[len] = (char) 0;
- return newstr;
-}
-
-#define SKIP 0
-#define SCAN 1
-
-static char spacestr[] = " ";
-
-static int
-strparse(char *s, char **fields, int *offsets, int maxfields)
-{
- int len = strlen(s);
- char *cp = s,
- *end = cp + len,
- *ep;
- int parsed = 0;
- int mode = SKIP,
- i = 0;
-
- if (*(end - 1) == '\n')
- end--;
-
- for (i = 0; i < maxfields; i++)
- fields[i] = spacestr;
-
- i = 0;
- while (!parsed)
- {
- if (mode == SKIP)
- {
-
- while ((cp < end) &&
- (*cp == ' ' || *cp == '\t'))
- cp++;
- if (cp < end)
- mode = SCAN;
- else
- parsed = 1;
-
- }
- else
- {
-
- ep = cp;
- while ((ep < end) && (*ep != ' ' && *ep != '\t'))
- ep++;
-
- if (ep < end)
- mode = SKIP;
- else
- parsed = 1;
-
- fields[i] = strmake(cp, ep - cp);
- if (offsets != NULL)
- offsets[i] = cp - s;
-
- i++;
- cp = ep;
- if (i > maxfields)
- parsed = 1;
-
- }
- }
- return i;
-}
-
-/* ----------------
- * pqtest_PQfn converts its string into a PQArgBlock and
- * calls the specified function, which is assumed to return
- * an integer value.
- * ----------------
- */
-int
-pqtest_PQfn(char *q)
-{
- int k,
- j,
- i,
- v,
- f,
- offsets;
- char *fields[FUNC_MAX_ARGS];
- PQArgBlock pqargs[FUNC_MAX_ARGS];
- int res;
- char *pqres;
-
- /* ----------------
- * parse q into fields
- * ----------------
- */
- i = strparse(q, fields, &offsets, FUNC_MAX_ARGS);
- printf("pqtest_PQfn: strparse returns %d fields\n", i); /* debug */
- if (i == 0)
- return -1;
-
- /* ----------------
- * get the function id
- * ----------------
- */
- f = atoi(fields[0]);
- printf("pqtest_PQfn: func is %d\n", f); /* debug */
- if (f == 0)
- return -1;
-
- /* ----------------
- * build a PQArgBlock
- * ----------------
- */
- for (j = 1; j < i && j < FUNC_MAX_ARGS; j++)
- {
- k = j - 1;
- v = atoi(fields[j]);
- if (v != 0 || (v == 0 && fields[j][0] == '0'))
- {
- pqargs[k].len = sizeof(int4);
- pqargs[k].u.integer = v;
- printf("pqtest_PQfn: arg %d is int %d\n", k, v); /* debug */
- }
- else
- {
- pqargs[k].len = VAR_LENGTH_ARG;
- pqargs[k].u.ptr = (int *)
- DatumGetTextP(DirectFunctionCall1(textin,
- CStringGetDatum(fields[j])));
- printf("pqtest_PQfn: arg %d is text %s\n", k, fields[j]); /* debug */
- }
- }
-
- /* ----------------
- * call PQfn
- * ----------------
- */
- pqres = PQfn(f, &res, sizeof(int4), 1, pqargs, i - 1);
- printf("pqtest_PQfn: pqres is %s\n", pqres); /* debug */
-
- /* ----------------
- * free memory used
- * ----------------
- */
- for (j = 0; j < i; j++)
- {
- pfree(fields[j]);
- if (pqargs[j].len == VAR_LENGTH_ARG)
- pfree(pqargs[j].u.ptr);
- }
-
- /* ----------------
- * return result
- * ----------------
- */
- printf("pqtest_PQfn: res is %d\n", res); /* debugg */
- return res;
-}
-
-/* ----------------
- * pqtest looks at the first character of its test argument
- * and decides which of pqtest_PQexec or pqtest_PQfn to call.
- * ----------------
- */
-int32
-pqtest(struct varlena * vlena)
-{
- char *q;
-
- /* ----------------
- * get the query
- * ----------------
- */
- q = DatumGetCString(DirectFunctionCall1(textout,
- PointerGetDatum(vlena)));
-
- switch (q[0])
- {
- case '%':
- return pqtest_PQfn(&q[1]);
- break;
- default:
- return pqtest_PQexec(q);
- break;
- }
- return 0;
-}
* wherein you authenticate a user by seeing what IP address the system
* says he comes from and possibly using ident).
*
- * $Id: hba.c,v 1.52 2000/06/02 15:57:20 momjian Exp $
+ * $Id: hba.c,v 1.53 2000/07/08 03:04:39 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "libpq/libpq.h"
#include "miscadmin.h"
+#include "storage/fd.h"
#define MAX_TOKEN 80
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: password.c,v 1.30 2000/07/04 16:31:53 petere Exp $
+ * $Id: password.c,v 1.31 2000/07/08 03:04:40 tgl Exp $
*
*/
#include <unistd.h>
#include "postgres.h"
+
#ifdef HAVE_CRYPT_H
-#include "crypt.h"
+#include <crypt.h>
#endif
#include "libpq/libpq.h"
#include "libpq/password.h"
#include "libpq/crypt.h"
#include "miscadmin.h"
+#include "storage/fd.h"
+
int
verify_password(const Port *port, const char *user, const char *password)
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * portal.c
- * generalized portal support routines
- *
- * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * $Id: portal.c,v 1.30 2000/03/17 02:36:08 tgl Exp $
- *
- *-------------------------------------------------------------------------
- */
-/*
- * INTERFACE ROUTINES
- * PQnportals - Return the number of open portals.
- * PQpnames - Return all the portal names
- * PQparray - Return the portal buffer given a portal name
- * PQrulep - Return 1 if an asynchronous portal
- * PQntuples - Return the number of tuples in a portal buffer
- * PQninstances - same as PQntuples using object terminology
- * PQngroups - Return the number of tuple groups in a portal buffer
- * PQntuplesGroup - Return the number of tuples in a tuple group
- * PQninstancesGroup - same as PQntuplesGroup using object terminology
- * PQnfieldsGroup - Return the number of fields in a tuple group
- * PQfnumberGroup - Return field number given (group index, field name)
- * PQftypeGroup - Return field type given (group index, field index)
- * PQfsizeGroup - Return field size given (group index, field index)
- * PQfnameGroup - Return field name given (group index, field index)
- * PQgroup - Return the tuple group that a particular tuple is in
- * PQgetgroup - Return the index of the group that a tuple is in
- * PQnfields - Return the number of fields in a tuple
- * PQfnumber - Return the field index of a field name in a tuple
- * PQfname - Return the name of a field
- * PQftype - Return the type of a field
- * PQfsize - Return the size of a field
- * PQftype - Return the type of a field
- * PQsametype - Return 1 if the two tuples have the same type
- * PQgetvalue - Return an attribute (field) value
- * PQgetlength - Return an attribute (field) length
- * PQclear - free storage claimed by named portal
- *
- * NOTES
- * These functions may be used by both frontend routines which
- * communicate with a backend or by user-defined functions which
- * are compiled or dynamically loaded into a backend.
- *
- * the *portals array should be organized as a hash table for
- * quick portal-by-name lookup.
- *
- * Do not confuse "PortalEntry" (or "PortalBuffer") with "Portal"
- * see utils/mmgr/portalmem.c for why. -cim 2/22/91
- *
- */
-
-#include "postgres.h"
-
-#include "libpq/libpq.h"
-
-
-/* ----------------------------------------------------------------
- * Helper routines for PQ portal interface routines below
- * ----------------------------------------------------------------
- */
-
-static int
-in_range(char *msg, int value, int min, int max)
-{
- if (value < min || value >= max)
- {
- snprintf(PQerrormsg, PQERRORMSG_LENGTH,
- "FATAL: %s, %d is not in range [%d,%d)\n", msg, value, min, max);
- pqdebug("%s", PQerrormsg);
- fputs(PQerrormsg, stderr);
- return 0;
- }
- return 1;
-}
-
-static int
-valid_pointer(char *msg, void *ptr)
-{
- if (!ptr)
- {
- snprintf(PQerrormsg, PQERRORMSG_LENGTH, "FATAL: %s\n", msg);
- pqdebug("%s", PQerrormsg);
- fputs(PQerrormsg, stderr);
- return 0;
- }
- return 1;
-}
-
-
-/* ----------------------------------------------------------------
- * PQ portal interface routines
- * ----------------------------------------------------------------
- */
-
-/* --------------------------------
- * PQnportals - Return the number of open portals.
- * If rule_p, only return asynchronous portals.
- * --------------------------------
- */
-int
-PQnportals(int rule_p)
-{
- int i,
- n = 0;
-
- for (i = 0; i < (int) portals_array_size; ++i)
- {
- if (portals[i] && portals[i]->portal)
- {
- if (!rule_p || portals[i]->portal->rule_p)
- ++n;
- }
- }
- return n;
-}
-
-/* --------------------------------
- * PQpnames - Return all the portal names
- * If rule_p, only return asynchronous portals.
- *
- * the caller must have allocated sufficient memory for char** pnames
- * (an array of PQnportals strings of length PortalNameLength).
- *
- * notice that this assumes that the user is calling PQnportals and
- * PQpnames with the same rule_p argument, and with no intervening
- * portal closures. if not, you can get in heap big trouble..
- * --------------------------------
- */
-void
-PQpnames(char **pnames, int rule_p)
-{
- int i,
- cur_pname = 0;
-
- if (!valid_pointer("PQpnames: invalid name buffer", pnames))
- return;
-
- for (i = 0; i < (int) portals_array_size; ++i)
- {
- if (portals[i] && portals[i]->portal)
- {
- if (!rule_p || portals[i]->portal->rule_p)
- {
- strncpy(pnames[cur_pname], portals[i]->name, PortalNameLength + 1);
- ++cur_pname;
- }
- }
- }
-}
-
-/* --------------------------------
- * PQparray - Return the portal buffer given a portal name
- * --------------------------------
- */
-PortalBuffer *
-PQparray(char *pname)
-{
- int i;
-
- if (!valid_pointer("PQparray: invalid name buffer", pname))
- return NULL;
-
- if ((i = pbuf_getIndex(pname)) < 0)
- return (PortalBuffer *) NULL;
- return portals[i]->portal;
-}
-
-/* --------------------------------
- * PQrulep - Return 1 if an asynchronous portal
- * --------------------------------
- */
-int
-PQrulep(PortalBuffer *portal)
-{
- if (!valid_pointer("PQrulep: invalid portal pointer", portal))
- return -1;
-
- return portal->rule_p;
-}
-
-/* --------------------------------
- * PQntuples - Return the number of tuples in a portal buffer
- * --------------------------------
- */
-int
-PQntuples(PortalBuffer *portal)
-{
- if (!valid_pointer("PQntuples: invalid portal pointer", portal))
- return -1;
-
- return portal->no_tuples;
-}
-
-int
-PQninstances(PortalBuffer *portal)
-{
- return PQntuples(portal);
-}
-
-/* --------------------------------
- * PQngroups - Return the number of tuple groups in a portal buffer
- * --------------------------------
- */
-int
-PQngroups(PortalBuffer *portal)
-{
- if (!valid_pointer("PQngroups: invalid portal pointer", portal))
- return -1;
-
- return portal->no_groups;
-}
-
-/* --------------------------------
- * PQntuplesGroup - Return the number of tuples in a tuple group
- * --------------------------------
- */
-int
-PQntuplesGroup(PortalBuffer *portal, int group_index)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQntuplesGroup: invalid portal pointer", portal) ||
- !in_range("PQntuplesGroup: group index",
- group_index, 0, portal->no_groups))
- return -1;
-
- gbp = pbuf_findGroup(portal, group_index);
- if (gbp)
- return gbp->no_tuples;
- return -1;
-}
-
-int
-PQninstancesGroup(PortalBuffer *portal, int group_index)
-{
- return PQntuplesGroup(portal, group_index);
-}
-
-/* --------------------------------
- * PQnfieldsGroup - Return the number of fields in a tuple group
- * --------------------------------
- */
-int
-PQnfieldsGroup(PortalBuffer *portal, int group_index)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQnfieldsGroup: invalid portal pointer", portal) ||
- !in_range("PQnfieldsGroup: group index",
- group_index, 0, portal->no_groups))
- return -1;
- gbp = pbuf_findGroup(portal, group_index);
- if (gbp)
- return gbp->no_fields;
- return -1;
-}
-
-/* --------------------------------
- * PQfnumberGroup - Return the field number (index) given
- * the group index and the field name
- * --------------------------------
- */
-int
-PQfnumberGroup(PortalBuffer *portal, int group_index, char *field_name)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfnumberGroup: invalid portal pointer", portal) ||
- !valid_pointer("PQfnumberGroup: invalid field name pointer",
- field_name) ||
- !in_range("PQfnumberGroup: group index",
- group_index, 0, portal->no_groups))
- return -1;
- gbp = pbuf_findGroup(portal, group_index);
- if (gbp)
- return pbuf_findFnumber(gbp, field_name);
- return -1;
-}
-
-/* --------------------------------
- * PQfnameGroup - Return the field (attribute) name given
- * the group index and field index.
- * --------------------------------
- */
-char *
-PQfnameGroup(PortalBuffer *portal, int group_index, int field_number)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfnameGroup: invalid portal pointer", portal) ||
- !in_range("PQfnameGroup: group index",
- group_index, 0, portal->no_groups))
- return (char *) NULL;
-
- if ((gbp = pbuf_findGroup(portal, group_index)) &&
- in_range("PQfnameGroup: field number",
- field_number, 0, gbp->no_fields))
- return pbuf_findFname(gbp, field_number);
- return (char *) NULL;
-}
-
-/* --------------------------------
- * PQftypeGroup - Return the type of a field given
- * the group index and field index
- * --------------------------------
- */
-int
-PQftypeGroup(PortalBuffer *portal, int group_index, int field_number)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQftypeGroup: invalid portal pointer", portal) ||
- !in_range("PQftypeGroup: group index",
- group_index, 0, portal->no_groups))
- return -1;
-
- if ((gbp = pbuf_findGroup(portal, group_index)) &&
- in_range("PQftypeGroup: field number", field_number, 0, gbp->no_fields))
- return gbp->types[field_number].typid;
- return -1;
-}
-
-/* --------------------------------
- * PQfsizeGroup - Return the size of a field given
- * the group index and field index
- * --------------------------------
- */
-int
-PQfsizeGroup(PortalBuffer *portal, int group_index, int field_number)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfsizeGroup: invalid portal pointer", portal) ||
- !in_range("PQfsizeGroup: tuple index",
- group_index, 0, portal->no_groups))
- return -1;
-
- if ((gbp = pbuf_findGroup(portal, group_index)) &&
- in_range("PQfsizeGroup: field number", field_number, 0, gbp->no_fields))
- return gbp->types[field_number].typlen;
- return -1;
-}
-
-
-/* --------------------------------
- * PQgroup - Return the tuple group that a particular tuple is in
- * --------------------------------
- */
-GroupBuffer *
-PQgroup(PortalBuffer *portal, int tuple_index)
-{
- GroupBuffer *gbp;
- int tuple_count = 0;
-
- if (!valid_pointer("PQgroup: invalid portal pointer", portal) ||
- !in_range("PQgroup: tuple index",
- tuple_index, 0, portal->no_tuples))
- return (GroupBuffer *) NULL;
-
- for (gbp = portal->groups;
- gbp && tuple_index >= (tuple_count += gbp->no_tuples);
- gbp = gbp->next)
- ;
- if (!in_range("PQgroup: tuple not found: tuple index",
- tuple_index, 0, tuple_count))
- return (GroupBuffer *) NULL;
- return gbp;
-}
-
-/* --------------------------------
- * PQgetgroup - Return the index of the group that a
- * particular tuple is in
- * --------------------------------
- */
-int
-PQgetgroup(PortalBuffer *portal, int tuple_index)
-{
- GroupBuffer *gbp;
- int tuple_count = 0,
- group_count = 0;
-
- if (!valid_pointer("PQgetgroup: invalid portal pointer", portal) ||
- !in_range("PQgetgroup: tuple index",
- tuple_index, 0, portal->no_tuples))
- return -1;
-
- for (gbp = portal->groups;
- gbp && tuple_index >= (tuple_count += gbp->no_tuples);
- gbp = gbp->next)
- ++group_count;
- if (!gbp || !in_range("PQgetgroup: tuple not found: tuple index",
- tuple_index, 0, tuple_count))
- return -1;
- return group_count;
-}
-
-/* --------------------------------
- * PQnfields - Return the number of fields in a tuple
- * --------------------------------
- */
-int
-PQnfields(PortalBuffer *portal, int tuple_index)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQnfields: invalid portal pointer", portal) ||
- !in_range("PQnfields: tuple index",
- tuple_index, 0, portal->no_tuples))
- return -1;
- gbp = PQgroup(portal, tuple_index);
- if (gbp)
- return gbp->no_fields;
- return -1;
-}
-
-/* --------------------------------
- * PQfnumber - Return the field index of a given
- * field name within a tuple.
- * --------------------------------
- */
-int
-PQfnumber(PortalBuffer *portal, int tuple_index, char *field_name)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfnumber: invalid portal pointer", portal) ||
- !valid_pointer("PQfnumber: invalid field name pointer", field_name) ||
- !in_range("PQfnumber: tuple index",
- tuple_index, 0, portal->no_tuples))
- return -1;
- gbp = PQgroup(portal, tuple_index);
- if (gbp)
- return pbuf_findFnumber(gbp, field_name);
- return -1;
-}
-
-/* --------------------------------
- * PQfname - Return the name of a field
- * --------------------------------
- */
-char *
-PQfname(PortalBuffer *portal, int tuple_index, int field_number)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfname: invalid portal pointer", portal) ||
- !in_range("PQfname: tuple index",
- tuple_index, 0, portal->no_tuples))
- return (char *) NULL;
-
- if ((gbp = PQgroup(portal, tuple_index)) &&
- in_range("PQfname: field number",
- field_number, 0, gbp->no_fields))
- return pbuf_findFname(gbp, field_number);
- return (char *) NULL;
-}
-
-/* --------------------------------
- * PQftype - Return the type of a field
- * --------------------------------
- */
-int
-PQftype(PortalBuffer *portal, int tuple_index, int field_number)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQftype: invalid portal pointer", portal) ||
- !in_range("PQfname: tuple index",
- tuple_index, 0, portal->no_tuples))
- return -1;
-
- if ((gbp = PQgroup(portal, tuple_index)) &&
- in_range("PQftype: field number", field_number, 0, gbp->no_fields))
- return gbp->types[field_number].typid;
- return -1;
-}
-
-/* --------------------------------
- * PQfsize - Return the size of a field
- * --------------------------------
- */
-int
-PQfsize(PortalBuffer *portal, int tuple_index, int field_number)
-{
- GroupBuffer *gbp;
-
- if (!valid_pointer("PQfsize: invalid portal pointer", portal) ||
- !in_range("PQfsize: tuple index",
- tuple_index, 0, portal->no_tuples))
- return -1;
-
- if ((gbp = PQgroup(portal, tuple_index)) &&
- in_range("PQfsize: field number", field_number, 0, gbp->no_fields))
- return gbp->types[field_number].typlen;
- return -1;
-}
-
-
-
-/* --------------------------------
- * PQsametype - Return 1 if the two tuples have the same type
- * (in the same group)
- * --------------------------------
- */
-int
-PQsametype(PortalBuffer *portal, int tuple_index1, int tuple_index2)
-{
- GroupBuffer *gbp1,
- *gbp2;
-
- if (!valid_pointer("PQsametype: invalid portal pointer", portal) ||
- !in_range("PQsametype: tuple index 1",
- tuple_index1, 0, portal->no_tuples) ||
- !in_range("PQsametype: tuple index 2",
- tuple_index2, 0, portal->no_tuples))
- return -1;
-
- gbp1 = PQgroup(portal, tuple_index1);
- gbp2 = PQgroup(portal, tuple_index2);
- if (gbp1 && gbp2)
- return gbp1 == gbp2;
- return -1;
-}
-
-static TupleBlock *
-PQGetTupleBlock(PortalBuffer *portal,
- int tuple_index,
- int *tuple_offset)
-{
- GroupBuffer *gbp;
- TupleBlock *tbp;
- int tuple_count = 0;
-
- if (!valid_pointer("PQGetTupleBlock: invalid portal pointer", portal) ||
- !valid_pointer("PQGetTupleBlock: invalid offset pointer",
- tuple_offset) ||
- !in_range("PQGetTupleBlock: tuple index",
- tuple_index, 0, portal->no_tuples))
- return (TupleBlock *) NULL;
-
- for (gbp = portal->groups;
- gbp && tuple_index >= (tuple_count += gbp->no_tuples);
- gbp = gbp->next)
- ;
- if (!gbp ||
- !in_range("PQGetTupleBlock: tuple not found: tuple index",
- tuple_index, 0, tuple_count))
- return (TupleBlock *) NULL;
- tuple_count -= gbp->no_tuples;
- for (tbp = gbp->tuples;
- tbp && tuple_index >= (tuple_count += TupleBlockSize);
- tbp = tbp->next)
- ;
- if (!tbp ||
- !in_range("PQGetTupleBlock: tuple not found: tuple index",
- tuple_index, 0, tuple_count))
- return (TupleBlock *) NULL;
- tuple_count -= TupleBlockSize;
-
- *tuple_offset = tuple_index - tuple_count;
- return tbp;
-}
-
-/* --------------------------------
- * PQgetvalue - Return an attribute (field) value
- * --------------------------------
- */
-char *
-PQgetvalue(PortalBuffer *portal,
- int tuple_index,
- int field_number)
-{
- TupleBlock *tbp;
- int tuple_offset;
-
- tbp = PQGetTupleBlock(portal, tuple_index, &tuple_offset);
- if (tbp)
- return tbp->values[tuple_offset][field_number];
- return (char *) NULL;
-}
-
-/* --------------------------------
- * PQgetAttr - Return an attribute (field) value
- * this differs from PQgetvalue in that the value returned is
- * a copy. The CALLER is responsible for free'ing the data returned.
- * --------------------------------
- */
-char *
-PQgetAttr(PortalBuffer *portal,
- int tuple_index,
- int field_number)
-{
- TupleBlock *tbp;
- int tuple_offset;
- int len;
- char *result = NULL;
-
- tbp = PQGetTupleBlock(portal, tuple_index, &tuple_offset);
- if (tbp)
- {
- len = tbp->lengths[tuple_offset][field_number];
- result = palloc(len + 1);
- memcpy(result,
- tbp->values[tuple_offset][field_number],
- len);
- result[len] = '\0';
- }
- return result;
-}
-
-
-/* --------------------------------
- * PQgetlength - Return an attribute (field) length
- * --------------------------------
- */
-int
-PQgetlength(PortalBuffer *portal,
- int tuple_index,
- int field_number)
-{
- TupleBlock *tbp;
- int tuple_offset;
-
- tbp = PQGetTupleBlock(portal, tuple_index, &tuple_offset);
- if (tbp)
- return tbp->lengths[tuple_offset][field_number];
- return -1;
-}
-
-/* ----------------
- * PQclear - free storage claimed by named portal
- * ----------------
- */
-void
-PQclear(char *pname)
-{
- if (!valid_pointer("PQclear: invalid portal name pointer", pname))
- return;
- pbuf_close(pname);
-}
+++ /dev/null
-/*-------------------------------------------------------------------------
- *
- * portalbuf.c
- * portal buffer support routines for src/libpq/portal.c
- *
- * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/portalbuf.c,v 1.24 2000/04/12 17:15:14 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-/*
- * INTERFACE ROUTINES
- * pbuf_alloc - allocate memory for libpq routines
- * pbuf_free - free memory for libpq routines
- * pbuf_addPortal - Allocate a new portal buffer
- * pbuf_addGroup - Add a new tuple group to the portal
- * pbuf_addTypes - Allocate n type blocks
- * pbuf_addTuples - Allocate a tuple block
- * pbuf_addTuple - Allocate a tuple of n fields (attributes)
- * pbuf_addValues - Allocate n bytes for a value
- * pbuf_addEntry - Allocate a portal entry
- * pbuf_freeEntry - Free a portal entry in the portal table
- * pbuf_freeTypes - Free up the space used by a portal
- * pbuf_freeTuples - free space used by tuple block
- * pbuf_freeGroup - free space used by group, types and tuples
- * pbuf_freePortal - free space used by portal and portal's group
- * pbuf_getIndex - Return the index of the portal entry
- * pbuf_setup - Set up a portal for dumping data
- * pbuf_close - Close a portal, remove it from the portal table
- * pbuf_findGroup - Return group given the group_index
- * pbuf_findFnumber - Return field index of a given field within a group
- * pbuf_findFname - Find the field name given the field index
- * pbuf_checkFnumber - signal an error if field number is out of bounds
- *
- * NOTES
- * These functions may be used by both frontend routines which
- * communicate with a backend or by user-defined functions which
- * are compiled or dynamically loaded into a backend.
- *
- * the portals[] array should be organized as a hash table for
- * quick portal-by-name lookup.
- *
- * Do not confuse "PortalEntry" (or "PortalBuffer") with "Portal"
- * see utils/mmgr/portalmem.c for why. -cim 2/22/91
- *
- */
-#include <sys/types.h>
-
-#include "postgres.h"
-
-#include "libpq/libpq.h"
-
-PortalEntry **portals = (PortalEntry **) NULL;
-size_t portals_array_size = 0;
-
-/* portals array memory is palloc'd instead of using MemoryContexts */
-/* since it will be used by both front and backend programs*/
-/* GlobalMemory portals_mmcxt = (GlobalMemory) NULL; */
-
-/* -------------------------------
- * portals_realloc
- * grow the size of the portals array by size
- *
- * also ensures that elements are initially NULL
- */
-
-static void
-portals_realloc(size_t size)
-{
- size_t oldsize;
- int i;
- PortalEntry **newp;
-
- oldsize = portals_array_size;
-
- portals_array_size += size;
- if (portals)
- newp = (PortalEntry **) realloc(portals,
- portals_array_size * sizeof(PortalEntry *));
- else
- newp = (PortalEntry **) palloc(portals_array_size * sizeof(PortalEntry *));
-
- if (newp)
- portals = newp;
- else
- libpq_raise(&PortalError,
- vararg_format("Cannot alloc more memory in portals_realloc"));
-
- for (i = oldsize; i < (int) portals_array_size; i++)
- portals[i] = (PortalEntry *) NULL;
-
-}
-
-/* --------------------------------
- * pbuf_alloc - allocate memory for portal buffers
- *
- * remember: palloc() in the backend uses the postgres MemoryContext
- * library and palloc() in the frontend (fe-pqstubs.c) calls malloc().
- * --------------------------------
- */
-caddr_t
-pbuf_alloc(size_t size)
-{
- caddr_t addr;
-
- if (size <= 0)
- libpq_raise(&MemoryError, vararg_format("Invalid argument to pbuf_alloc()."));
-
- addr = (caddr_t) palloc(size);
- if (addr == (caddr_t) NULL)
- libpq_raise(&MemoryError, vararg_format("Cannot Allocate space."));
-
- return addr;
-}
-
-/* --------------------------------
- * pbuf_free - free memory for portal buffers
- *
- * remember: pfree() in the backend uses the postgres MemoryContext
- * library and pfree() in the frontend (fe-pqstubs.c) calls free().
- * --------------------------------
- */
-void
-pbuf_free(caddr_t pointer)
-{
- if (pointer)
- pfree(pointer);
- else
- libpq_raise(&MemoryError, vararg_format("Tried to free NULL memory pointer"));
-
-}
-
-/* --------------------------------
- * pbuf_addPortal - Allocate a new portal buffer
- * --------------------------------
- */
-PortalBuffer *
-pbuf_addPortal()
-{
- PortalBuffer *portal;
-
- portal = (PortalBuffer *)
- pbuf_alloc(sizeof(PortalBuffer));
-
- portal->rule_p = 0;
- portal->no_tuples = 0;
- portal->no_groups = 0;
- portal->groups = NULL;
-
- return portal;
-}
-
-/* --------------------------------
- * pbuf_addGroup - Add a new tuple group to the portal
- * --------------------------------
- */
-GroupBuffer *
-pbuf_addGroup(PortalBuffer *portal)
-{
- GroupBuffer *group,
- *group1;
-
- group = (GroupBuffer *)
- pbuf_alloc(sizeof(GroupBuffer));
-
- /* Initialize the new group buffer. */
- group->no_tuples = 0;
- group->no_fields = 0;
- group->types = NULL;
- group->tuples = NULL;
- group->next = NULL;
-
- if ((group1 = portal->groups) == NULL)
- portal->groups = group;
- else
- {
- while (group1->next != NULL)
- group1 = group1->next;
- group1->next = group;
- }
-
- return group;
-}
-
-/* --------------------------------
- * pbuf_addTypes - Allocate n type blocks
- * --------------------------------
- */
-TypeBlock *
-pbuf_addTypes(int n)
-{
- TypeBlock *types;
-
- types = (TypeBlock *)
- pbuf_alloc(n * sizeof(TypeBlock));
-
- return types;
-}
-
-/* --------------------------------
- * pbuf_addTuples - Allocate a tuple block
- * --------------------------------
- */
-TupleBlock *
-pbuf_addTuples()
-{
- TupleBlock *tuples;
-
- tuples = (TupleBlock *)
- pbuf_alloc(sizeof(TupleBlock));
-
- tuples->next = NULL;
- tuples->tuple_index = 0;
-
- return tuples;
-}
-
-/* --------------------------------
- * pbuf_addTuple - Allocate a tuple of n fields (attributes)
- * --------------------------------
- */
-char **
-pbuf_addTuple(int n)
-{
- return (char **)
- pbuf_alloc(n * sizeof(char *));
-}
-
-/* --------------------------------
- * pbuf_addTupleValueLengths - Allocate a tuple of n lengths (attributes)
- * --------------------------------
- */
-int *
-pbuf_addTupleValueLengths(int n)
-{
- return (int *)
- pbuf_alloc(n * sizeof(int));
-}
-
-/* --------------------------------
- * pbuf_addValues - Allocate n bytes for a value
- * --------------------------------
- */
-char *
-pbuf_addValues(int n)
-{
- return pbuf_alloc(n);
-}
-
-/* --------------------------------
- * pbuf_addEntry - Allocate a portal entry
- * --------------------------------
- */
-PortalEntry *
-pbuf_addEntry()
-{
- return (PortalEntry *)
- pbuf_alloc(sizeof(PortalEntry));
-}
-
-/* --------------------------------
- * pbuf_freeEntry - Free a portal entry in the portal table
- * the portal is freed separately.
- * --------------------------------
- */
-void
-pbuf_freeEntry(int i)
-{
- if (portals)
- {
- pbuf_free((caddr_t) portals[i]);
- portals[i] = NULL;
- }
-}
-
-
-/* --------------------------------
- * pbuf_freeTypes - Free up the space used by a portal
- * --------------------------------
- */
-void
-pbuf_freeTypes(TypeBlock *types)
-{
- pbuf_free((caddr_t) types);
-}
-
-/* --------------------------------
- * pbuf_freeTuples - free space used by tuple block
- * --------------------------------
- */
-void
-pbuf_freeTuples(TupleBlock *tuples,
- int no_tuples,
- int no_fields)
-{
- int i,
- j;
-
- if (no_tuples > TupleBlockSize)
- {
- pbuf_freeTuples(tuples->next, no_tuples - TupleBlockSize, no_fields);
- no_tuples = TupleBlockSize;
- }
-
- /* For each tuple, free all its attribute values. */
- for (i = 0; i < no_tuples; i++)
- {
- for (j = 0; j < no_fields; j++)
- if (tuples->values[i][j] != NULL)
- pbuf_free((caddr_t) tuples->values[i][j]);
- if (tuples->lengths[i])
- pbuf_free((caddr_t) tuples->lengths[i]);
- if (tuples->values[i])
- pbuf_free((caddr_t) tuples->values[i]);
- }
-
- pbuf_free((caddr_t) tuples);
-}
-
-/* --------------------------------
- * pbuf_freeGroup - free space used by group, types and tuples
- * --------------------------------
- */
-void
-pbuf_freeGroup(GroupBuffer *group)
-{
- if (group->next != NULL)
- pbuf_freeGroup(group->next);
-
- if (group->types != NULL)
- pbuf_freeTypes(group->types);
-
- if (group->tuples != NULL)
- pbuf_freeTuples(group->tuples, group->no_tuples, group->no_fields);
-
- pbuf_free((caddr_t) group);
-}
-
-/* --------------------------------
- * pbuf_freePortal - free space used by portal and portal's group
- * --------------------------------
- */
-void
-pbuf_freePortal(PortalBuffer *portal)
-{
- if (portal->groups != NULL)
- pbuf_freeGroup(portal->groups);
-
- pbuf_free((caddr_t) portal);
-}
-
-/* --------------------------------
- * pbuf_getIndex - Return the index of the portal entry
- * note: portals[] maps portal names to portal buffers.
- * --------------------------------
- */
-int
-pbuf_getIndex(char *pname)
-{
- int i;
-
- if (portals)
- {
- for (i = 0; i < (int) portals_array_size; i++)
- if (portals[i] != NULL &&
- strncmp(portals[i]->name, pname, PortalNameLength) == 0)
- return i;
- }
-
- return -1;
-}
-
-/* --------------------------------
- * pbuf_setportalname - assign a user given name to a portal
- * --------------------------------
- */
-void
-pbuf_setportalinfo(PortalEntry *entry, char *pname)
-{
- if (entry)
- StrNCpy(entry->name, pname, PortalNameLength);
-}
-
-/* --------------------------------
- * pbuf_setup - Set up a portal for dumping data
- * --------------------------------
- */
-PortalEntry *
-pbuf_setup(char *pname)
-{
- int i;
-
- if (!portals) /* the portals array has not been
- * allocated yet */
- {
- /* allocate portals[] array here */
- portals_realloc(PORTALS_INITIAL_SIZE);
- }
-
- /* If a portal with the same name already exists, close it. */
- /* else look for an empty entry in the portal table. */
- if ((i = pbuf_getIndex(pname)) != -1)
- pbuf_freePortal(portals[i]->portal);
- else
- {
- for (i = 0; i < (int) portals_array_size; i++)
- if (portals[i] == NULL)
- break;
-
- /* If the portal table is full, enlarge it */
- if (i >= (int) portals_array_size)
- portals_realloc(PORTALS_GROW_BY);
-
- portals[i] = pbuf_addEntry();
- strncpy(portals[i]->name, pname, PortalNameLength);
- }
- portals[i]->portal = pbuf_addPortal();
- portals[i]->portalcxt = NULL;
- portals[i]->result = NULL;
-
- return portals[i];
-}
-
-/* --------------------------------
- * pbuf_close - Close a portal, remove it from the portal table
- * and free up the space
- * --------------------------------
- */
-void
-pbuf_close(char *pname)
-{
- int i;
-
- if ((i = pbuf_getIndex(pname)) == -1)
- libpq_raise(&PortalError, vararg_format("Portal %s does not exist.", pname));
-
- pbuf_freePortal(portals[i]->portal);
- pbuf_freeEntry(i);
-}
-
-/* --------------------------------
- * pbuf_findGroup - Return the group given the group_index
- * --------------------------------
- */
-GroupBuffer *
-pbuf_findGroup(PortalBuffer *portal,
- int group_index)
-{
- GroupBuffer *group;
-
- group = portal->groups;
- while (group_index > 0 && group != NULL)
- {
- group = group->next;
- group_index--;
- }
-
- if (group == NULL)
- libpq_raise(&PortalError,
- vararg_format("Group index %d out of bound.", group_index));
-
- return group;
-}
-
-/* --------------------------------
- * pbuf_findFnumber - Return the field index of a given field within a group
- * --------------------------------
- */
-int
-pbuf_findFnumber(GroupBuffer *group,
- char *field_name)
-{
- TypeBlock *types;
- int i;
-
- types = group->types;
-
- for (i = 0; i < group->no_fields; i++)
- if (strncmp(types[i].name, field_name, NAMEDATALEN) == 0)
- return i;
-
- libpq_raise(&PortalError,
- vararg_format("Field-name %s does not exist.", field_name));
-
- /* not reached, here to make compiler happy */
- return 0;
-
-}
-
-/* --------------------------------
- * pbuf_checkFnumber - signal an error if field number is out of bounds
- * --------------------------------
- */
-void
-pbuf_checkFnumber(GroupBuffer *group,
- int field_number)
-{
- if (field_number < 0 || field_number >= group->no_fields)
- libpq_raise(&PortalError,
- vararg_format("Field number %d out of bound.", field_number));
-}
-
-/* --------------------------------
- * pbuf_findFname - Find the field name given the field index
- * --------------------------------
- */
-char *
-pbuf_findFname(GroupBuffer *group,
- int field_number)
-{
- pbuf_checkFnumber(group, field_number);
- return (group->types[field_number]).name;
-}
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pqcomm.c,v 1.99 2000/07/03 20:45:57 petere Exp $
+ * $Id: pqcomm.c,v 1.100 2000/07/08 03:04:40 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef SOMAXCONN
#define SOMAXCONN 5 /* from Linux listen(2) man page */
-#endif /* SOMAXCONN */
+#endif
-extern FILE *debug_port; /* in util.c */
/*
* Buffers for low-level I/O
{
PqSendPointer = PqRecvPointer = PqRecvLength = 0;
DoingCopyOut = false;
- if (getenv("LIBPQ_DEBUG"))
- debug_port = stderr;
}
/*-------------------------------------------------------------------------
*
* util.c
- * general routines for libpq backend
+ * general routines for backend libpq modules
*
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: util.c,v 1.15 2000/01/26 05:56:29 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/libpq/Attic/util.c,v 1.16 2000/07/08 03:04:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
* UTILITY ROUTINES
* pqdebug - send a string to the debugging output port
- * pqdebug2 - send two strings to stdout
* PQtrace - turn on pqdebug() tracing
* PQuntrace - turn off pqdebug() tracing
*/
-
#include "postgres.h"
+
#include "libpq/libpq.h"
*/
char PQerrormsg[PQERRORMSG_LENGTH];
+/*
+ * These are not really global --- they are referred to nowhere else.
+ * We declare them as global symbols to make them easier to set in a debugger.
+ */
+
int PQtracep = 0; /* 1 to print out debugging messages */
-FILE *debug_port = (FILE *) NULL;
-/* ----------------
- * exceptions
- * ----------------
- */
-Exception MemoryError = {"Memory Allocation Error"};
-Exception PortalError = {"Invalid arguments to portal functions"};
-Exception PostquelError = {"Sql Error"};
-Exception ProtocolError = {"Protocol Error"};
+FILE *debug_port = (FILE *) NULL;
/* ----------------------------------------------------------------
* PQ utility routines
*/
void
-pqdebug(char *target, char *msg)
-{
- if (!target)
- return;
-
- if (PQtracep)
- {
-
- /*
- * if nothing else was suggested default to stdout
- */
- if (!debug_port)
- debug_port = stdout;
- fprintf(debug_port, target, msg);
- fprintf(debug_port, "\n");
- }
-}
-
-void
-pqdebug2(char *target, char *msg1, char *msg2)
+pqdebug(char *fmt, char *msg)
{
- if (!target)
+ if (!fmt)
return;
if (PQtracep)
{
/*
- * if nothing else was suggested default to stdout
+ * if nothing else was suggested default to stderr
*/
if (!debug_port)
- debug_port = stdout;
- fprintf(debug_port, target, msg1, msg2);
+ debug_port = stderr;
+ fprintf(debug_port, fmt, msg);
fprintf(debug_port, "\n");
}
}
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.152 2000/07/03 20:45:58 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.153 2000/07/08 03:04:13 tgl Exp $
*
* NOTES
*
#include "storage/proc.h"
#include "access/xlog.h"
#include "tcop/tcopprot.h"
+#include "utils/exc.h"
#include "utils/guc.h"
/*
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.38 2000/01/26 05:57:07 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/dest.c,v 1.39 2000/07/08 03:04:15 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static DestReceiver printtup_internalDR = {
printtup_internal, donothingSetup, donothingCleanup
};
-static DestReceiver be_printtupDR = {
- be_printtup, donothingSetup, donothingCleanup
-};
static DestReceiver debugtupDR = {
debugtup, donothingSetup, donothingCleanup
};
char *tag,
CommandDest dest)
{
- PortalEntry *entry;
Form_pg_attribute *attrs = tupdesc->attrs;
int natts = tupdesc->natts;
int i;
- char *p;
switch (dest)
{
case Remote:
case RemoteInternal:
/* ----------------
- * if this is a "retrieve portal" query, done
+ * if this is a "retrieve into portal" query, done
* because nothing needs to be sent to the fe.
* ----------------
*/
}
break;
- case Local:
- /* ----------------
- * prepare local portal buffer for query results
- * and setup result for PQexec()
- * ----------------
- */
- entry = be_currentportal();
- if (pname != NULL)
- pbuf_setportalinfo(entry, pname);
-
- if (operation == CMD_SELECT && !isIntoRel)
- {
- be_typeinit(entry, tupdesc, natts);
- p = (char *) palloc(strlen(entry->name) + 2);
- p[0] = 'P';
- strcpy(p + 1, entry->name);
- }
- else
- {
- p = (char *) palloc(strlen(tag) + 2);
- p[0] = 'C';
- strcpy(p + 1, tag);
- }
- entry->result = p;
- break;
-
case Debug:
/* ----------------
* show the return type of the tuples
return &printtup_internalDR;
break;
- case Local:
- return &be_printtupDR;
- break;
-
case Debug:
return &debugtupDR;
break;
CommandInfo[0] = '\0';
break;
- case Local:
case Debug:
case None:
default:
pq_putbytes("I", 2);/* note we send I and \0 */
break;
- case Local:
case Debug:
case None:
default:
pq_flush();
break;
- case Local:
case Debug:
case None:
default:
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.166 2000/07/04 06:11:43 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.167 2000/07/08 03:04:15 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
#include "tcop/tcopprot.h"
#include "tcop/utility.h"
#include "storage/proc.h"
+#include "utils/exc.h"
+#include "utils/guc.h"
#include "utils/ps_status.h"
#include "utils/temprel.h"
-#include "utils/guc.h"
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
- puts("$Revision: 1.166 $ $Date: 2000/07/04 06:11:43 $\n");
+ puts("$Revision: 1.167 $ $Date: 2000/07/08 03:04:15 $\n");
}
/*
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.62 2000/07/03 03:27:31 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.63 2000/07/08 03:04:16 tgl Exp $
*
*
*-------------------------------------------------------------------------
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/pg_database.h"
-#include "libpq/libpq.h"
#include "miscadmin.h"
#include "storage/backendid.h"
#include "storage/proc.h"
{
bool bootstrap = IsBootstrapProcessingMode();
- /* ----------------
- * initialize the backend local portal stack used by
- * internal PQ function calls. see src/lib/libpq/be-dumpdata.c
- * This is different from the "portal manager" so this goes here.
- * -cim 2/12/91
- * ----------------
- */
- be_portalinit();
-
/* initialize the local buffer manager */
InitLocalBuffer();
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: pg_proc.h,v 1.145 2000/07/07 19:24:41 petere Exp $
+ * $Id: pg_proc.h,v 1.146 2000/07/08 03:04:21 tgl Exp $
*
* NOTES
* The script catalog/genbki.sh reads this file and generates .bki
DATA(insert OID = 729 ( poly_distance PGUID 11 f t t t 2 f 701 "604 604" 100 0 0 100 poly_distance - ));
DESCR("distance between");
-DATA(insert OID = 730 ( pqtest PGUID 11 f t f t 1 f 23 "25" 100 0 0 100 pqtest - ));
-DESCR("");
-
DATA(insert OID = 740 ( text_lt PGUID 12 f t t t 2 f 16 "25 25" 100 0 0 0 text_lt - ));
DESCR("less-than");
DATA(insert OID = 741 ( text_le PGUID 12 f t t t 2 f 16 "25 25" 100 0 0 0 text_le - ));
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: libpq.h,v 1.38 2000/06/06 16:04:32 petere Exp $
+ * $Id: libpq.h,v 1.39 2000/07/08 03:04:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#define LIBPQ_H
#include <sys/types.h>
-
#include <netinet/in.h>
#include "lib/stringinfo.h"
#include "libpq/libpq-be.h"
-#include "tcop/dest.h"
-#include "utils/exc.h"
/* ----------------
* PQArgBlock
* Information (pointer to array of this structure) required
- * for the PQfn() call.
+ * for the PQfn() call. (This probably ought to go somewhere else...)
* ----------------
*/
typedef struct
} u;
} PQArgBlock;
-/* ----------------
- * TypeBlock
- * Information about an attribute.
- * ----------------
- */
-#define NameLength NAMEDATALEN
-
-typedef struct TypeBlock
-{
- char name[NAMEDATALEN]; /* name of the attribute */
- int typid; /* typid of the type */
- int typlen; /* typlen of the type */
-} TypeBlock;
-
-/* ----------------
- * TupleBlock
- * Data of a tuple.
- * ----------------
- */
-#define TupleBlockSize 100
-
-typedef struct TupleBlock
-{
- char **values[TupleBlockSize]; /* an array of tuples */
- int *lengths[TupleBlockSize]; /* an array of length vec.
- * foreach tuple */
- struct TupleBlock *next; /* next tuple block */
- int tuple_index; /* current tuple index */
-} TupleBlock;
-
-/* ----------------
- * GroupBuffer
- * A group of tuples with the same attributes.
- * ----------------
- */
-typedef struct GroupBuffer
-{
- int no_tuples; /* number of tuples in this group */
- int no_fields; /* number of attributes */
- TypeBlock *types; /* types of the attributes */
- TupleBlock *tuples; /* tuples in this group */
- struct GroupBuffer *next; /* next group */
-} GroupBuffer;
-
-/* ----------------
- * PortalBuffer
- * Data structure of a portal buffer.
- * ----------------
- */
-typedef struct PortalBuffer
-{
- int rule_p; /* 1 if this is an asynchronized portal. */
- int no_tuples; /* number of tuples in this portal buffer */
- int no_groups; /* number of tuple groups */
- GroupBuffer *groups; /* linked list of tuple groups */
-} PortalBuffer;
-
-/* ----------------
- * PortalEntry
- * an entry in the global portal table
- *
- * Note: the portalcxt is only meaningful for PQcalls made from
- * within a postgres backend. frontend apps should ignore it.
- * ----------------
- */
-#define PortalNameLength 32
-
-typedef struct PortalEntry
-{
- char name[PortalNameLength]; /* name of this portal */
- PortalBuffer *portal; /* tuples contained in this portal */
- Pointer portalcxt; /* memory context (for backend) */
- Pointer result; /* result for PQexec */
-} PortalEntry;
-
-#define PORTALS_INITIAL_SIZE 32
-#define PORTALS_GROW_BY 32
-
-/* in portalbuf.c */
-extern PortalEntry **portals;
-extern size_t portals_array_size;
-
-/*
- * Exceptions.
- */
-
-#define libpq_raise(X, Y) ExcRaise((Exception *)(X), (ExcDetail) (Y),\
- (ExcData)0, (ExcMessage) 0)
-
-/* in portal.c */
-extern Exception MemoryError,
- PortalError,
- PostquelError,
- ProtocolError;
-
/*
* PQerrormsg[] is used only for error messages generated within backend
* libpq, none of which are remarkably long. Note that this length should
* External functions.
*/
-/*
- * prototypes for functions in portal.c
- */
-extern void pqdebug(char *target, char *msg);
-extern void pqdebug2(char *target, char *msg1, char *msg2);
-extern void PQtrace(void);
-extern void PQuntrace(void);
-extern int PQnportals(int rule_p);
-extern void PQpnames(char **pnames, int rule_p);
-extern PortalBuffer *PQparray(char *pname);
-extern int PQrulep(PortalBuffer *portal);
-extern int PQntuples(PortalBuffer *portal);
-extern int PQninstances(PortalBuffer *portal);
-extern int PQngroups(PortalBuffer *portal);
-extern int PQntuplesGroup(PortalBuffer *portal, int group_index);
-extern int PQninstancesGroup(PortalBuffer *portal, int group_index);
-extern int PQnfieldsGroup(PortalBuffer *portal, int group_index);
-extern int PQfnumberGroup(PortalBuffer *portal, int group_index, char *field_name);
-extern char *PQfnameGroup(PortalBuffer *portal, int group_index, int field_number);
-extern int PQftypeGroup(PortalBuffer *portal, int group_index,
- int field_number);
-extern int PQfsizeGroup(PortalBuffer *portal, int group_index,
- int field_number);
-extern GroupBuffer *PQgroup(PortalBuffer *portal, int tuple_index);
-extern int PQgetgroup(PortalBuffer *portal, int tuple_index);
-extern int PQnfields(PortalBuffer *portal, int tuple_index);
-extern int PQfnumber(PortalBuffer *portal, int tuple_index, char *field_name);
-extern char *PQfname(PortalBuffer *portal, int tuple_index, int field_number);
-extern int PQftype(PortalBuffer *portal, int tuple_index, int field_number);
-extern int PQfsize(PortalBuffer *portal, int tuple_index, int field_number);
-extern int PQsametype(PortalBuffer *portal, int tuple_index1, int tuple_index2);
-extern char *PQgetvalue(PortalBuffer *portal, int tuple_index, int field_number);
-extern char *PQgetAttr(PortalBuffer *portal, int tuple_index, int field_number);
-extern int PQgetlength(PortalBuffer *portal, int tuple_index, int field_number);
-extern void PQclear(char *pname);
-
-/*
- * prototypes for functions in portalbuf.c
- */
-extern caddr_t pbuf_alloc(size_t size);
-extern void pbuf_free(caddr_t pointer);
-extern PortalBuffer *pbuf_addPortal(void);
-extern GroupBuffer *pbuf_addGroup(PortalBuffer *portal);
-extern TypeBlock *pbuf_addTypes(int n);
-extern TupleBlock *pbuf_addTuples(void);
-extern char **pbuf_addTuple(int n);
-extern int *pbuf_addTupleValueLengths(int n);
-extern char *pbuf_addValues(int n);
-extern PortalEntry *pbuf_addEntry(void);
-extern void pbuf_freeEntry(int i);
-extern void pbuf_freeTypes(TypeBlock *types);
-extern void pbuf_freeTuples(TupleBlock *tuples, int no_tuples, int no_fields);
-extern void pbuf_freeGroup(GroupBuffer *group);
-extern void pbuf_freePortal(PortalBuffer *portal);
-extern int pbuf_getIndex(char *pname);
-extern void pbuf_setportalinfo(PortalEntry *entry, char *pname);
-extern PortalEntry *pbuf_setup(char *pname);
-extern void pbuf_close(char *pname);
-extern GroupBuffer *pbuf_findGroup(PortalBuffer *portal, int group_index);
-extern int pbuf_findFnumber(GroupBuffer *group, char *field_name);
-extern void pbuf_checkFnumber(GroupBuffer *group, int field_number);
-extern char *pbuf_findFname(GroupBuffer *group, int field_number);
-
-/* in be-dumpdata.c */
-extern void be_portalinit(void);
-extern void be_portalpush(PortalEntry *entry);
-extern PortalEntry *be_portalpop(void);
-extern PortalEntry *be_currentportal(void);
-extern PortalEntry *be_newportal(void);
-extern void be_typeinit(PortalEntry *entry, TupleDesc attrs,
- int natts);
-extern void be_printtup(HeapTuple tuple, TupleDesc typeinfo,
- DestReceiver *self);
-
-
-/* in be-pqexec.c */
-extern char *PQfn(int fnid, int *result_buf, int result_len, int result_is_int,
- PQArgBlock *args, int nargs);
-extern char *PQexec(char *query);
-extern int pqtest_PQexec(char *q);
-extern int pqtest_PQfn(char *q);
-extern int32 pqtest(struct varlena * vlena);
-
/*
* prototypes for functions in pqcomm.c
*/
extern void pq_startcopyout(void);
extern void pq_endcopyout(bool errorAbort);
+/*
+ * prototypes for functions in util.c
+ */
+extern void pqdebug(char *fmt, char *msg);
+extern void PQtrace(void);
+extern void PQuntrace(void);
+
#endif /* LIBPQ_H */
*
* dest.h
* Whenever the backend executes a query, the results
- * have to go someplace - either to the standard output,
- * to a local portal buffer or to a remote portal buffer.
+ * have to go someplace.
*
* - stdout is the destination only when we are running a
* backend without a postmaster and are returning results
- * back to the user.
+ * back to an interactive user.
*
- * - a local portal buffer is the destination when a backend
- * executes a user-defined function which calls PQexec() or
- * PQfn(). In this case, the results are collected into a
- * PortalBuffer which the user's function may diddle with.
- *
- * - a remote portal buffer is the destination when we are
+ * - a remote process is the destination when we are
* running a backend with a frontend and the frontend executes
* PQexec() or PQfn(). In this case, the results are sent
- * to the frontend via the pq_ functions.
+ * to the frontend via the functions in backend/libpq.
*
* - None is the destination when the system executes
* a query internally. This is not used now but it may be
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: dest.h,v 1.23 2000/01/26 05:58:35 momjian Exp $
+ * $Id: dest.h,v 1.24 2000/07/08 03:04:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
{
None, /* results are discarded */
Debug, /* results go to debugging output */
- Local, /* results go in local portal buffer */
Remote, /* results sent to frontend process */
RemoteInternal, /* results sent to frontend process in
* internal (binary) form */
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: builtins.h,v 1.121 2000/07/07 19:24:43 petere Exp $
+ * $Id: builtins.h,v 1.122 2000/07/08 03:04:36 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern POLYGON *rt_poly_union(POLYGON *a, POLYGON *b);
extern POLYGON *rt_poly_inter(POLYGON *a, POLYGON *b);
-/* projection utilities */
-/* extern char *GetAttributeByName();
- extern char *GetAttributeByNum(); ,
- in executor/executor.h*/
-
-
-extern int32 pqtest(struct varlena * vlena);
-
/* arrayfuncs.c */
/* filename.c */