mirror of
https://github.com/postgres/postgres.git
synced 2025-06-14 18:42:34 +03:00
Remove long-dead support for invoking queries from dynamically loaded
backend functions via backend PQexec(). The SPI interface has long been our only documented way to do this, and the backend pqexec/portal code is unused and suffering bit-rot. I'm putting it out of its misery.
This commit is contained in:
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -87,6 +87,7 @@
|
|||||||
#include "libpq/libpq.h"
|
#include "libpq/libpq.h"
|
||||||
#include "libpq/pqformat.h"
|
#include "libpq/pqformat.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
#include "tcop/dest.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
#include "utils/ps_status.h"
|
#include "utils/ps_status.h"
|
||||||
#include "utils/syscache.h"
|
#include "utils/syscache.h"
|
||||||
|
@ -4,15 +4,17 @@
|
|||||||
# Makefile for libpq subsystem (backend half of libpq interface)
|
# Makefile for libpq subsystem (backend half of libpq interface)
|
||||||
#
|
#
|
||||||
# IDENTIFICATION
|
# 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 = ../..
|
SRCDIR = ../..
|
||||||
include ../../Makefile.global
|
include ../../Makefile.global
|
||||||
|
|
||||||
OBJS = be-dumpdata.o be-fsstubs.o be-pqexec.o portal.o portalbuf.o \
|
# be-fsstubs is here for historical reasons, probably belongs elsewhere
|
||||||
auth.o hba.o crypt.o password.o \
|
|
||||||
|
OBJS = be-fsstubs.o \
|
||||||
|
auth.o crypt.o hba.o password.o \
|
||||||
pqcomm.o pqformat.o pqpacket.o pqsignal.o util.o
|
pqcomm.o pqformat.o pqpacket.o pqsignal.o util.o
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,331 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
}
|
|
@ -1,423 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
@ -5,7 +5,7 @@
|
|||||||
* wherein you authenticate a user by seeing what IP address the system
|
* wherein you authenticate a user by seeing what IP address the system
|
||||||
* says he comes from and possibly using ident).
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "libpq/libpq.h"
|
#include "libpq/libpq.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
#include "storage/fd.h"
|
||||||
|
|
||||||
|
|
||||||
#define MAX_TOKEN 80
|
#define MAX_TOKEN 80
|
||||||
|
@ -2,21 +2,24 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 <unistd.h>
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#ifdef HAVE_CRYPT_H
|
#ifdef HAVE_CRYPT_H
|
||||||
#include "crypt.h"
|
#include <crypt.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libpq/libpq.h"
|
#include "libpq/libpq.h"
|
||||||
#include "libpq/password.h"
|
#include "libpq/password.h"
|
||||||
#include "libpq/crypt.h"
|
#include "libpq/crypt.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
|
#include "storage/fd.h"
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
verify_password(const Port *port, const char *user, const char *password)
|
verify_password(const Port *port, const char *user, const char *password)
|
||||||
|
@ -1,643 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
}
|
|
@ -1,517 +0,0 @@
|
|||||||
/*-------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* 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;
|
|
||||||
}
|
|
@ -29,7 +29,7 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -79,9 +79,8 @@
|
|||||||
|
|
||||||
#ifndef SOMAXCONN
|
#ifndef SOMAXCONN
|
||||||
#define SOMAXCONN 5 /* from Linux listen(2) man page */
|
#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
|
* Buffers for low-level I/O
|
||||||
@ -113,8 +112,6 @@ pq_init(void)
|
|||||||
{
|
{
|
||||||
PqSendPointer = PqRecvPointer = PqRecvLength = 0;
|
PqSendPointer = PqRecvPointer = PqRecvLength = 0;
|
||||||
DoingCopyOut = false;
|
DoingCopyOut = false;
|
||||||
if (getenv("LIBPQ_DEBUG"))
|
|
||||||
debug_port = stderr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,25 +1,24 @@
|
|||||||
/*-------------------------------------------------------------------------
|
/*-------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
* util.c
|
* util.c
|
||||||
* general routines for libpq backend
|
* general routines for backend libpq modules
|
||||||
*
|
*
|
||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* UTILITY ROUTINES
|
||||||
* pqdebug - send a string to the debugging output port
|
* pqdebug - send a string to the debugging output port
|
||||||
* pqdebug2 - send two strings to stdout
|
|
||||||
* PQtrace - turn on pqdebug() tracing
|
* PQtrace - turn on pqdebug() tracing
|
||||||
* PQuntrace - turn off pqdebug() tracing
|
* PQuntrace - turn off pqdebug() tracing
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
|
|
||||||
#include "libpq/libpq.h"
|
#include "libpq/libpq.h"
|
||||||
|
|
||||||
|
|
||||||
@ -29,17 +28,14 @@
|
|||||||
*/
|
*/
|
||||||
char PQerrormsg[PQERRORMSG_LENGTH];
|
char PQerrormsg[PQERRORMSG_LENGTH];
|
||||||
|
|
||||||
int PQtracep = 0; /* 1 to print out debugging messages */
|
/*
|
||||||
FILE *debug_port = (FILE *) NULL;
|
* 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.
|
||||||
/* ----------------
|
|
||||||
* exceptions
|
|
||||||
* ----------------
|
|
||||||
*/
|
*/
|
||||||
Exception MemoryError = {"Memory Allocation Error"};
|
|
||||||
Exception PortalError = {"Invalid arguments to portal functions"};
|
int PQtracep = 0; /* 1 to print out debugging messages */
|
||||||
Exception PostquelError = {"Sql Error"};
|
|
||||||
Exception ProtocolError = {"Protocol Error"};
|
FILE *debug_port = (FILE *) NULL;
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
* PQ utility routines
|
* PQ utility routines
|
||||||
@ -47,39 +43,20 @@ Exception ProtocolError = {"Protocol Error"};
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
pqdebug(char *target, char *msg)
|
pqdebug(char *fmt, char *msg)
|
||||||
{
|
{
|
||||||
if (!target)
|
if (!fmt)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (PQtracep)
|
if (PQtracep)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if nothing else was suggested default to stdout
|
* if nothing else was suggested default to stderr
|
||||||
*/
|
*/
|
||||||
if (!debug_port)
|
if (!debug_port)
|
||||||
debug_port = stdout;
|
debug_port = stderr;
|
||||||
fprintf(debug_port, target, msg);
|
fprintf(debug_port, fmt, msg);
|
||||||
fprintf(debug_port, "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
pqdebug2(char *target, char *msg1, char *msg2)
|
|
||||||
{
|
|
||||||
if (!target)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (PQtracep)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* if nothing else was suggested default to stdout
|
|
||||||
*/
|
|
||||||
if (!debug_port)
|
|
||||||
debug_port = stdout;
|
|
||||||
fprintf(debug_port, target, msg1, msg2);
|
|
||||||
fprintf(debug_port, "\n");
|
fprintf(debug_port, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -83,6 +83,7 @@
|
|||||||
#include "storage/proc.h"
|
#include "storage/proc.h"
|
||||||
#include "access/xlog.h"
|
#include "access/xlog.h"
|
||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
|
#include "utils/exc.h"
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -72,9 +72,6 @@ static DestReceiver donothingDR = {
|
|||||||
static DestReceiver printtup_internalDR = {
|
static DestReceiver printtup_internalDR = {
|
||||||
printtup_internal, donothingSetup, donothingCleanup
|
printtup_internal, donothingSetup, donothingCleanup
|
||||||
};
|
};
|
||||||
static DestReceiver be_printtupDR = {
|
|
||||||
be_printtup, donothingSetup, donothingCleanup
|
|
||||||
};
|
|
||||||
static DestReceiver debugtupDR = {
|
static DestReceiver debugtupDR = {
|
||||||
debugtup, donothingSetup, donothingCleanup
|
debugtup, donothingSetup, donothingCleanup
|
||||||
};
|
};
|
||||||
@ -95,18 +92,16 @@ BeginCommand(char *pname,
|
|||||||
char *tag,
|
char *tag,
|
||||||
CommandDest dest)
|
CommandDest dest)
|
||||||
{
|
{
|
||||||
PortalEntry *entry;
|
|
||||||
Form_pg_attribute *attrs = tupdesc->attrs;
|
Form_pg_attribute *attrs = tupdesc->attrs;
|
||||||
int natts = tupdesc->natts;
|
int natts = tupdesc->natts;
|
||||||
int i;
|
int i;
|
||||||
char *p;
|
|
||||||
|
|
||||||
switch (dest)
|
switch (dest)
|
||||||
{
|
{
|
||||||
case Remote:
|
case Remote:
|
||||||
case RemoteInternal:
|
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.
|
* because nothing needs to be sent to the fe.
|
||||||
* ----------------
|
* ----------------
|
||||||
*/
|
*/
|
||||||
@ -158,32 +153,6 @@ BeginCommand(char *pname,
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
case Debug:
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* show the return type of the tuples
|
* show the return type of the tuples
|
||||||
@ -219,10 +188,6 @@ DestToFunction(CommandDest dest)
|
|||||||
return &printtup_internalDR;
|
return &printtup_internalDR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Local:
|
|
||||||
return &be_printtupDR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Debug:
|
case Debug:
|
||||||
return &debugtupDR;
|
return &debugtupDR;
|
||||||
break;
|
break;
|
||||||
@ -266,7 +231,6 @@ EndCommand(char *commandTag, CommandDest dest)
|
|||||||
CommandInfo[0] = '\0';
|
CommandInfo[0] = '\0';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Local:
|
|
||||||
case Debug:
|
case Debug:
|
||||||
case None:
|
case None:
|
||||||
default:
|
default:
|
||||||
@ -329,7 +293,6 @@ NullCommand(CommandDest dest)
|
|||||||
pq_putbytes("I", 2);/* note we send I and \0 */
|
pq_putbytes("I", 2);/* note we send I and \0 */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Local:
|
|
||||||
case Debug:
|
case Debug:
|
||||||
case None:
|
case None:
|
||||||
default:
|
default:
|
||||||
@ -360,7 +323,6 @@ ReadyForQuery(CommandDest dest)
|
|||||||
pq_flush();
|
pq_flush();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Local:
|
|
||||||
case Debug:
|
case Debug:
|
||||||
case None:
|
case None:
|
||||||
default:
|
default:
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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
|
* NOTES
|
||||||
* this is the "main" module of the postgres backend and
|
* this is the "main" module of the postgres backend and
|
||||||
@ -54,9 +54,10 @@
|
|||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
#include "tcop/utility.h"
|
#include "tcop/utility.h"
|
||||||
#include "storage/proc.h"
|
#include "storage/proc.h"
|
||||||
|
#include "utils/exc.h"
|
||||||
|
#include "utils/guc.h"
|
||||||
#include "utils/ps_status.h"
|
#include "utils/ps_status.h"
|
||||||
#include "utils/temprel.h"
|
#include "utils/temprel.h"
|
||||||
#include "utils/guc.h"
|
|
||||||
#ifdef MULTIBYTE
|
#ifdef MULTIBYTE
|
||||||
#include "mb/pg_wchar.h"
|
#include "mb/pg_wchar.h"
|
||||||
#endif
|
#endif
|
||||||
@ -1414,7 +1415,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
|
|||||||
if (!IsUnderPostmaster)
|
if (!IsUnderPostmaster)
|
||||||
{
|
{
|
||||||
puts("\nPOSTGRES backend interactive interface ");
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* 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 $
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
@ -24,7 +24,6 @@
|
|||||||
#include "access/heapam.h"
|
#include "access/heapam.h"
|
||||||
#include "catalog/catname.h"
|
#include "catalog/catname.h"
|
||||||
#include "catalog/pg_database.h"
|
#include "catalog/pg_database.h"
|
||||||
#include "libpq/libpq.h"
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "storage/backendid.h"
|
#include "storage/backendid.h"
|
||||||
#include "storage/proc.h"
|
#include "storage/proc.h"
|
||||||
@ -228,15 +227,6 @@ InitPostgres(const char *dbname)
|
|||||||
{
|
{
|
||||||
bool bootstrap = IsBootstrapProcessingMode();
|
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 */
|
/* initialize the local buffer manager */
|
||||||
InitLocalBuffer();
|
InitLocalBuffer();
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
* NOTES
|
||||||
* The script catalog/genbki.sh reads this file and generates .bki
|
* The script catalog/genbki.sh reads this file and generates .bki
|
||||||
@ -965,9 +965,6 @@ DESCR("distance between");
|
|||||||
DATA(insert OID = 729 ( poly_distance PGUID 11 f t t t 2 f 701 "604 604" 100 0 0 100 poly_distance - ));
|
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");
|
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 - ));
|
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");
|
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 - ));
|
DATA(insert OID = 741 ( text_le PGUID 12 f t t t 2 f 16 "25 25" 100 0 0 0 text_le - ));
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -15,18 +15,15 @@
|
|||||||
#define LIBPQ_H
|
#define LIBPQ_H
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include "lib/stringinfo.h"
|
#include "lib/stringinfo.h"
|
||||||
#include "libpq/libpq-be.h"
|
#include "libpq/libpq-be.h"
|
||||||
#include "tcop/dest.h"
|
|
||||||
#include "utils/exc.h"
|
|
||||||
|
|
||||||
/* ----------------
|
/* ----------------
|
||||||
* PQArgBlock
|
* PQArgBlock
|
||||||
* Information (pointer to array of this structure) required
|
* 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
|
typedef struct
|
||||||
@ -40,101 +37,6 @@ typedef struct
|
|||||||
} u;
|
} u;
|
||||||
} PQArgBlock;
|
} 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
|
* PQerrormsg[] is used only for error messages generated within backend
|
||||||
* libpq, none of which are remarkably long. Note that this length should
|
* libpq, none of which are remarkably long. Note that this length should
|
||||||
@ -150,89 +52,6 @@ extern char PQerrormsg[PQERRORMSG_LENGTH]; /* in libpq/util.c */
|
|||||||
* External functions.
|
* 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
|
* prototypes for functions in pqcomm.c
|
||||||
*/
|
*/
|
||||||
@ -250,4 +69,11 @@ extern int pq_putmessage(char msgtype, const char *s, size_t len);
|
|||||||
extern void pq_startcopyout(void);
|
extern void pq_startcopyout(void);
|
||||||
extern void pq_endcopyout(bool errorAbort);
|
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 */
|
#endif /* LIBPQ_H */
|
||||||
|
@ -2,22 +2,16 @@
|
|||||||
*
|
*
|
||||||
* dest.h
|
* dest.h
|
||||||
* Whenever the backend executes a query, the results
|
* Whenever the backend executes a query, the results
|
||||||
* have to go someplace - either to the standard output,
|
* have to go someplace.
|
||||||
* to a local portal buffer or to a remote portal buffer.
|
|
||||||
*
|
*
|
||||||
* - stdout is the destination only when we are running a
|
* - stdout is the destination only when we are running a
|
||||||
* backend without a postmaster and are returning results
|
* 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
|
* - a remote process is the destination when we are
|
||||||
* 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
|
|
||||||
* running a backend with a frontend and the frontend executes
|
* running a backend with a frontend and the frontend executes
|
||||||
* PQexec() or PQfn(). In this case, the results are sent
|
* 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
|
* - None is the destination when the system executes
|
||||||
* a query internally. This is not used now but it may be
|
* a query internally. This is not used now but it may be
|
||||||
@ -45,7 +39,7 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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 $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -63,7 +57,6 @@ typedef enum
|
|||||||
{
|
{
|
||||||
None, /* results are discarded */
|
None, /* results are discarded */
|
||||||
Debug, /* results go to debugging output */
|
Debug, /* results go to debugging output */
|
||||||
Local, /* results go in local portal buffer */
|
|
||||||
Remote, /* results sent to frontend process */
|
Remote, /* results sent to frontend process */
|
||||||
RemoteInternal, /* results sent to frontend process in
|
RemoteInternal, /* results sent to frontend process in
|
||||||
* internal (binary) form */
|
* internal (binary) form */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $Id: builtins.h,v 1.121 2000/07/07 19:24:43 petere Exp $
|
* $Id: builtins.h,v 1.122 2000/07/08 03:04:36 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -184,14 +184,6 @@ extern Datum rt_poly_size(PG_FUNCTION_ARGS);
|
|||||||
extern POLYGON *rt_poly_union(POLYGON *a, POLYGON *b);
|
extern POLYGON *rt_poly_union(POLYGON *a, POLYGON *b);
|
||||||
extern POLYGON *rt_poly_inter(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 */
|
/* arrayfuncs.c */
|
||||||
|
|
||||||
/* filename.c */
|
/* filename.c */
|
||||||
|
Reference in New Issue
Block a user