Commit 5ecd4e3f authored by Tom Lane's avatar Tom Lane

Binary send/receive routines for a few basic datatypes --- enough for

testing purposes.
parent 4207d6bf
...@@ -15,10 +15,16 @@ ...@@ -15,10 +15,16 @@
* pq_getmessage, and then parsed and converted from that using the routines * pq_getmessage, and then parsed and converted from that using the routines
* in this module. * in this module.
* *
* These same routines support reading and writing of external binary formats
* (typsend/typreceive routines). The conversion routines for individual
* data types are exactly the same, only initialization and completion
* are different.
*
*
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Header: /cvsroot/pgsql/src/backend/libpq/pqformat.c,v 1.29 2003/05/08 18:16:36 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/libpq/pqformat.c,v 1.30 2003/05/09 15:44:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -28,14 +34,20 @@ ...@@ -28,14 +34,20 @@
* pq_beginmessage - initialize StringInfo buffer * pq_beginmessage - initialize StringInfo buffer
* pq_sendbyte - append a raw byte to a StringInfo buffer * pq_sendbyte - append a raw byte to a StringInfo buffer
* pq_sendint - append a binary integer to a StringInfo buffer * pq_sendint - append a binary integer to a StringInfo buffer
* pq_sendint64 - append a binary 8-byte int to a StringInfo buffer
* pq_sendbytes - append raw data to a StringInfo buffer * pq_sendbytes - append raw data to a StringInfo buffer
* pq_sendcountedtext - append a text string (with character set conversion) * pq_sendcountedtext - append a counted text string (with character set conversion)
* pq_sendtext - append a text string (with conversion)
* pq_sendstring - append a null-terminated text string (with conversion) * pq_sendstring - append a null-terminated text string (with conversion)
* pq_endmessage - send the completed message to the frontend * pq_endmessage - send the completed message to the frontend
* Note: it is also possible to append data to the StringInfo buffer using * Note: it is also possible to append data to the StringInfo buffer using
* the regular StringInfo routines, but this is discouraged since required * the regular StringInfo routines, but this is discouraged since required
* character set conversion may not occur. * character set conversion may not occur.
* *
* typsend support (construct a bytea value containing external binary data):
* pq_begintypsend - initialize StringInfo buffer
* pq_endtypsend - return the completed string as a "bytea*"
*
* Special-case message output: * Special-case message output:
* pq_puttextmessage - generate a character set-converted message in one step * pq_puttextmessage - generate a character set-converted message in one step
* pq_putemptymessage - convenience routine for message with empty body * pq_putemptymessage - convenience routine for message with empty body
...@@ -43,8 +55,10 @@ ...@@ -43,8 +55,10 @@
* Message parsing after input: * Message parsing after input:
* pq_getmsgbyte - get a raw byte from a message buffer * pq_getmsgbyte - get a raw byte from a message buffer
* pq_getmsgint - get a binary integer from a message buffer * pq_getmsgint - get a binary integer from a message buffer
* pq_getmsgint64 - get a binary 8-byte int from a message buffer
* pq_getmsgbytes - get raw data from a message buffer * pq_getmsgbytes - get raw data from a message buffer
* pq_copymsgbytes - copy raw data from a message buffer * pq_copymsgbytes - copy raw data from a message buffer
* pq_getmsgtext - get a counted text string (with conversion)
* pq_getmsgstring - get a null-terminated text string (with conversion) * pq_getmsgstring - get a null-terminated text string (with conversion)
* pq_getmsgend - verify message fully consumed * pq_getmsgend - verify message fully consumed
*/ */
...@@ -101,7 +115,7 @@ pq_sendbytes(StringInfo buf, const char *data, int datalen) ...@@ -101,7 +115,7 @@ pq_sendbytes(StringInfo buf, const char *data, int datalen)
} }
/* -------------------------------- /* --------------------------------
* pq_sendcountedtext - append a text string (with character set conversion) * pq_sendcountedtext - append a counted text string (with character set conversion)
* *
* The data sent to the frontend by this routine is a 4-byte count field * The data sent to the frontend by this routine is a 4-byte count field
* followed by the string. The count includes itself or not, as per the * followed by the string. The count includes itself or not, as per the
...@@ -132,6 +146,34 @@ pq_sendcountedtext(StringInfo buf, const char *str, int slen, ...@@ -132,6 +146,34 @@ pq_sendcountedtext(StringInfo buf, const char *str, int slen,
} }
} }
/* --------------------------------
* pq_sendtext - append a text string (with conversion)
*
* The passed text string need not be null-terminated, and the data sent
* to the frontend isn't either. Note that this is not actually useful
* for direct frontend transmissions, since there'd be no way for the
* frontend to determine the string length. But it is useful for binary
* format conversions.
* --------------------------------
*/
void
pq_sendtext(StringInfo buf, const char *str, int slen)
{
char *p;
p = (char *) pg_server_to_client((unsigned char *) str, slen);
if (p != str) /* actual conversion has been done? */
{
slen = strlen(p);
appendBinaryStringInfo(buf, p, slen);
pfree(p);
}
else
{
appendBinaryStringInfo(buf, str, slen);
}
}
/* -------------------------------- /* --------------------------------
* pq_sendstring - append a null-terminated text string (with conversion) * pq_sendstring - append a null-terminated text string (with conversion)
* *
...@@ -152,9 +194,11 @@ pq_sendstring(StringInfo buf, const char *str) ...@@ -152,9 +194,11 @@ pq_sendstring(StringInfo buf, const char *str)
slen = strlen(p); slen = strlen(p);
appendBinaryStringInfo(buf, p, slen + 1); appendBinaryStringInfo(buf, p, slen + 1);
pfree(p); pfree(p);
return;
} }
appendBinaryStringInfo(buf, str, slen + 1); else
{
appendBinaryStringInfo(buf, str, slen + 1);
}
} }
/* -------------------------------- /* --------------------------------
...@@ -188,6 +232,35 @@ pq_sendint(StringInfo buf, int i, int b) ...@@ -188,6 +232,35 @@ pq_sendint(StringInfo buf, int i, int b)
} }
} }
/* --------------------------------
* pq_sendint64 - append a binary 8-byte int to a StringInfo buffer
*
* It is tempting to merge this with pq_sendint, but we'd have to make the
* argument int64 for all data widths --- that could be a big performance
* hit on machines where int64 isn't efficient.
* --------------------------------
*/
void
pq_sendint64(StringInfo buf, int64 i)
{
uint32 n32;
/* High order half first, since we're doing MSB-first */
#ifdef INT64_IS_BUSTED
/* don't try a right shift of 32 on a 32-bit word */
n32 = (i < 0) ? -1 : 0;
#else
n32 = (uint32) (i >> 32);
#endif
n32 = htonl(n32);
appendBinaryStringInfo(buf, (char *) &n32, 4);
/* Now the low order half */
n32 = (uint32) i;
n32 = htonl(n32);
appendBinaryStringInfo(buf, (char *) &n32, 4);
}
/* -------------------------------- /* --------------------------------
* pq_endmessage - send the completed message to the frontend * pq_endmessage - send the completed message to the frontend
* *
...@@ -205,6 +278,44 @@ pq_endmessage(StringInfo buf) ...@@ -205,6 +278,44 @@ pq_endmessage(StringInfo buf)
buf->data = NULL; buf->data = NULL;
} }
/* --------------------------------
* pq_begintypsend - initialize for constructing a bytea result
* --------------------------------
*/
void
pq_begintypsend(StringInfo buf)
{
initStringInfo(buf);
/* Reserve four bytes for the bytea length word */
appendStringInfoCharMacro(buf, '\0');
appendStringInfoCharMacro(buf, '\0');
appendStringInfoCharMacro(buf, '\0');
appendStringInfoCharMacro(buf, '\0');
}
/* --------------------------------
* pq_endtypsend - finish constructing a bytea result
*
* The data buffer is returned as the palloc'd bytea value. (We expect
* that it will be suitably aligned for this because it has been palloc'd.)
* We assume the StringInfoData is just a local variable in the caller and
* need not be pfree'd.
* --------------------------------
*/
bytea *
pq_endtypsend(StringInfo buf)
{
bytea *result = (bytea *) buf->data;
/* Insert correct length into bytea length word */
Assert(buf->len >= VARHDRSZ);
VARATT_SIZEP(result) = buf->len;
return result;
}
/* -------------------------------- /* --------------------------------
* pq_puttextmessage - generate a character set-converted message in one step * pq_puttextmessage - generate a character set-converted message in one step
* *
...@@ -289,6 +400,38 @@ pq_getmsgint(StringInfo msg, int b) ...@@ -289,6 +400,38 @@ pq_getmsgint(StringInfo msg, int b)
return result; return result;
} }
/* --------------------------------
* pq_getmsgint64 - get a binary 8-byte int from a message buffer
*
* It is tempting to merge this with pq_getmsgint, but we'd have to make the
* result int64 for all data widths --- that could be a big performance
* hit on machines where int64 isn't efficient.
* --------------------------------
*/
int64
pq_getmsgint64(StringInfo msg)
{
int64 result;
uint32 h32;
uint32 l32;
pq_copymsgbytes(msg, (char *) &h32, 4);
pq_copymsgbytes(msg, (char *) &l32, 4);
h32 = ntohl(h32);
l32 = ntohl(l32);
#ifdef INT64_IS_BUSTED
/* just lose the high half */
result = l32;
#else
result = h32;
result <<= 32;
result |= l32;
#endif
return result;
}
/* -------------------------------- /* --------------------------------
* pq_getmsgbytes - get raw data from a message buffer * pq_getmsgbytes - get raw data from a message buffer
* *
...@@ -323,6 +466,39 @@ pq_copymsgbytes(StringInfo msg, char *buf, int datalen) ...@@ -323,6 +466,39 @@ pq_copymsgbytes(StringInfo msg, char *buf, int datalen)
msg->cursor += datalen; msg->cursor += datalen;
} }
/* --------------------------------
* pq_getmsgtext - get a counted text string (with conversion)
*
* Always returns a pointer to a freshly palloc'd result.
* The result has a trailing null, *and* we return its strlen in *nbytes.
* --------------------------------
*/
char *
pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes)
{
char *str;
char *p;
if (rawbytes < 0 || rawbytes > (msg->len - msg->cursor))
elog(ERROR, "pq_getmsgtext: insufficient data left in message");
str = &msg->data[msg->cursor];
msg->cursor += rawbytes;
p = (char *) pg_client_to_server((unsigned char *) str, rawbytes);
if (p != str) /* actual conversion has been done? */
{
*nbytes = strlen(p);
}
else
{
p = (char *) palloc(rawbytes + 1);
memcpy(p, str, rawbytes);
p[rawbytes] = '\0';
*nbytes = rawbytes;
}
return p;
}
/* -------------------------------- /* --------------------------------
* pq_getmsgstring - get a null-terminated text string (with conversion) * pq_getmsgstring - get a null-terminated text string (with conversion)
* *
......
...@@ -8,14 +8,16 @@ ...@@ -8,14 +8,16 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.53 2003/03/11 21:01:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.54 2003/05/09 15:44:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
/* /*
* OLD COMMENTS * OLD COMMENTS
* I/O routines: * I/O routines:
* int2in, int2out, int2vectorin, int2vectorout, int4in, int4out * int2in, int2out, int2recv, int2send
* int4in, int4out, int4recv, int4send
* int2vectorin, int2vectorout, int2vectorrecv, int2vectorsend
* Conversion routines: * Conversion routines:
* itoi, int2_text, int4_text * itoi, int2_text, int4_text
* Boolean operators: * Boolean operators:
...@@ -32,6 +34,7 @@ ...@@ -32,6 +34,7 @@
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include "libpq/pqformat.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#ifndef SHRT_MAX #ifndef SHRT_MAX
...@@ -69,6 +72,31 @@ int2out(PG_FUNCTION_ARGS) ...@@ -69,6 +72,31 @@ int2out(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
/*
* int2recv - converts external binary format to int2
*/
Datum
int2recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
PG_RETURN_INT16((int16) pq_getmsgint(buf, sizeof(int16)));
}
/*
* int2send - converts int2 to binary format
*/
Datum
int2send(PG_FUNCTION_ARGS)
{
int16 arg1 = PG_GETARG_INT16(0);
StringInfoData buf;
pq_begintypsend(&buf);
pq_sendint(&buf, arg1, sizeof(int16));
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/* /*
* int2vectorin - converts "num num ..." to internal form * int2vectorin - converts "num num ..." to internal form
* *
...@@ -131,6 +159,41 @@ int2vectorout(PG_FUNCTION_ARGS) ...@@ -131,6 +159,41 @@ int2vectorout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
/*
* int2vectorrecv - converts external binary format to int2vector
*/
Datum
int2vectorrecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
int16 *result = (int16 *) palloc(sizeof(int16[INDEX_MAX_KEYS]));
int slot;
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
{
result[slot] = (int16) pq_getmsgint(buf, sizeof(int16));
}
PG_RETURN_POINTER(result);
}
/*
* int2vectorsend - converts int2vector to binary format
*/
Datum
int2vectorsend(PG_FUNCTION_ARGS)
{
int16 *int2Array = (int16 *) PG_GETARG_POINTER(0);
StringInfoData buf;
int slot;
pq_begintypsend(&buf);
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
{
pq_sendint(&buf, int2Array[slot], sizeof(int16));
}
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/* /*
* We don't have a complete set of int2vector support routines, * We don't have a complete set of int2vector support routines,
* but we need int2vectoreq for catcache indexing. * but we need int2vectoreq for catcache indexing.
...@@ -173,6 +236,31 @@ int4out(PG_FUNCTION_ARGS) ...@@ -173,6 +236,31 @@ int4out(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
/*
* int4recv - converts external binary format to int4
*/
Datum
int4recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
PG_RETURN_INT32((int32) pq_getmsgint(buf, sizeof(int32)));
}
/*
* int4send - converts int4 to binary format
*/
Datum
int4send(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
StringInfoData buf;
pq_begintypsend(&buf);
pq_sendint(&buf, arg1, sizeof(int32));
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/* /*
* =================== * ===================
......
...@@ -7,36 +7,21 @@ ...@@ -7,36 +7,21 @@
* 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/utils/adt/int8.c,v 1.43 2003/03/11 21:01:33 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.44 2003/05/09 15:44:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
#include "postgres.h" #include "postgres.h"
#include <ctype.h> #include <ctype.h>
#include <time.h>
#include <math.h> #include <math.h>
#include <float.h>
#include <limits.h>
#include "libpq/pqformat.h"
#include "utils/int8.h" #include "utils/int8.h"
#define MAXINT8LEN 25 #define MAXINT8LEN 25
#ifndef INT_MAX
#define INT_MAX (0x7FFFFFFFL)
#endif
#ifndef INT_MIN
#define INT_MIN (-INT_MAX-1)
#endif
#ifndef SHRT_MAX
#define SHRT_MAX (0x7FFF)
#endif
#ifndef SHRT_MIN
#define SHRT_MIN (-SHRT_MAX-1)
#endif
/*********************************************************************** /***********************************************************************
** **
...@@ -160,6 +145,31 @@ int8out(PG_FUNCTION_ARGS) ...@@ -160,6 +145,31 @@ int8out(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
/*
* int8recv - converts external binary format to int8
*/
Datum
int8recv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
PG_RETURN_INT64(pq_getmsgint64(buf));
}
/*
* int8send - converts int8 to binary format
*/
Datum
int8send(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT64(0);
StringInfoData buf;
pq_begintypsend(&buf);
pq_sendint64(&buf, arg1);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/*---------------------------------------------------------- /*----------------------------------------------------------
* Relational operators for int8s, including cross-data-type comparisons. * Relational operators for int8s, including cross-data-type comparisons.
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.47 2002/06/20 20:29:38 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.48 2003/05/09 15:44:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include "libpq/pqformat.h"
#include "utils/builtins.h" #include "utils/builtins.h"
/***************************************************************************** /*****************************************************************************
* USER I/O ROUTINES * * USER I/O ROUTINES *
*****************************************************************************/ *****************************************************************************/
...@@ -108,6 +110,31 @@ oidout(PG_FUNCTION_ARGS) ...@@ -108,6 +110,31 @@ oidout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
/*
* oidrecv - converts external binary format to oid
*/
Datum
oidrecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
PG_RETURN_OID((Oid) pq_getmsgint(buf, sizeof(Oid)));
}
/*
* oidsend - converts oid to binary format
*/
Datum
oidsend(PG_FUNCTION_ARGS)
{
Oid arg1 = PG_GETARG_OID(0);
StringInfoData buf;
pq_begintypsend(&buf);
pq_sendint(&buf, arg1, sizeof(Oid));
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/* /*
* oidvectorin - converts "num num ..." to internal form * oidvectorin - converts "num num ..." to internal form
...@@ -119,11 +146,9 @@ Datum ...@@ -119,11 +146,9 @@ Datum
oidvectorin(PG_FUNCTION_ARGS) oidvectorin(PG_FUNCTION_ARGS)
{ {
char *oidString = PG_GETARG_CSTRING(0); char *oidString = PG_GETARG_CSTRING(0);
Oid *result; Oid *result = (Oid *) palloc(sizeof(Oid[INDEX_MAX_KEYS]));
int slot; int slot;
result = (Oid *) palloc(sizeof(Oid[INDEX_MAX_KEYS]));
for (slot = 0; slot < INDEX_MAX_KEYS; slot++) for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
{ {
while (*oidString && isspace((unsigned char) *oidString)) while (*oidString && isspace((unsigned char) *oidString))
...@@ -173,6 +198,42 @@ oidvectorout(PG_FUNCTION_ARGS) ...@@ -173,6 +198,42 @@ oidvectorout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
/*
* oidvectorrecv - converts external binary format to oidvector
*/
Datum
oidvectorrecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
Oid *result = (Oid *) palloc(sizeof(Oid[INDEX_MAX_KEYS]));
int slot;
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
{
result[slot] = (Oid) pq_getmsgint(buf, sizeof(Oid));
}
PG_RETURN_POINTER(result);
}
/*
* oidvectorsend - converts oidvector to binary format
*/
Datum
oidvectorsend(PG_FUNCTION_ARGS)
{
Oid *oidArray = (Oid *) PG_GETARG_POINTER(0);
StringInfoData buf;
int slot;
pq_begintypsend(&buf);
for (slot = 0; slot < INDEX_MAX_KEYS; slot++)
{
pq_sendint(&buf, oidArray[slot], sizeof(Oid));
}
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/***************************************************************************** /*****************************************************************************
* PUBLIC ROUTINES * * PUBLIC ROUTINES *
*****************************************************************************/ *****************************************************************************/
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.96 2003/04/24 21:16:43 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.97 2003/05/09 15:44:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -20,16 +20,20 @@ ...@@ -20,16 +20,20 @@
#include "miscadmin.h" #include "miscadmin.h"
#include "access/tuptoaster.h" #include "access/tuptoaster.h"
#include "lib/stringinfo.h" #include "lib/stringinfo.h"
#include "libpq/crypt.h"
#include "libpq/pqformat.h"
#include "utils/builtins.h" #include "utils/builtins.h"
#include "utils/pg_locale.h" #include "utils/pg_locale.h"
extern bool md5_hash(const void *buff, size_t len, char *hexsum);
typedef struct varlena unknown; typedef struct varlena unknown;
#define DatumGetUnknownP(X) ((unknown *) PG_DETOAST_DATUM(X)) #define DatumGetUnknownP(X) ((unknown *) PG_DETOAST_DATUM(X))
#define DatumGetUnknownPCopy(X) ((unknown *) PG_DETOAST_DATUM_COPY(X))
#define PG_GETARG_UNKNOWN_P(n) DatumGetUnknownP(PG_GETARG_DATUM(n)) #define PG_GETARG_UNKNOWN_P(n) DatumGetUnknownP(PG_GETARG_DATUM(n))
#define PG_GETARG_UNKNOWN_P_COPY(n) DatumGetUnknownPCopy(PG_GETARG_DATUM(n))
#define PG_RETURN_UNKNOWN_P(x) PG_RETURN_POINTER(x) #define PG_RETURN_UNKNOWN_P(x) PG_RETURN_POINTER(x)
#define PG_TEXTARG_GET_STR(arg_) \ #define PG_TEXTARG_GET_STR(arg_) \
DatumGetCString(DirectFunctionCall1(textout, PG_GETARG_DATUM(arg_))) DatumGetCString(DirectFunctionCall1(textout, PG_GETARG_DATUM(arg_)))
#define PG_TEXT_GET_STR(textp_) \ #define PG_TEXT_GET_STR(textp_) \
...@@ -111,10 +115,10 @@ byteain(PG_FUNCTION_ARGS) ...@@ -111,10 +115,10 @@ byteain(PG_FUNCTION_ARGS)
byte += VARHDRSZ; byte += VARHDRSZ;
result = (bytea *) palloc(byte); result = (bytea *) palloc(byte);
result->vl_len = byte; /* set varlena length */ VARATT_SIZEP(result) = byte; /* set varlena length */
tp = inputText; tp = inputText;
rp = result->vl_dat; rp = VARDATA(result);
while (*tp != '\0') while (*tp != '\0')
{ {
if (tp[0] != '\\') if (tp[0] != '\\')
...@@ -170,8 +174,8 @@ byteaout(PG_FUNCTION_ARGS) ...@@ -170,8 +174,8 @@ byteaout(PG_FUNCTION_ARGS)
int len; int len;
len = 1; /* empty string has 1 char */ len = 1; /* empty string has 1 char */
vp = vlena->vl_dat; vp = VARDATA(vlena);
for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++) for (i = VARSIZE(vlena) - VARHDRSZ; i != 0; i--, vp++)
{ {
if (*vp == '\\') if (*vp == '\\')
len += 2; len += 2;
...@@ -181,8 +185,8 @@ byteaout(PG_FUNCTION_ARGS) ...@@ -181,8 +185,8 @@ byteaout(PG_FUNCTION_ARGS)
len += 4; len += 4;
} }
rp = result = (char *) palloc(len); rp = result = (char *) palloc(len);
vp = vlena->vl_dat; vp = VARDATA(vlena);
for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++) for (i = VARSIZE(vlena) - VARHDRSZ; i != 0; i--, vp++)
{ {
if (*vp == '\\') if (*vp == '\\')
{ {
...@@ -207,6 +211,36 @@ byteaout(PG_FUNCTION_ARGS) ...@@ -207,6 +211,36 @@ byteaout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
/*
* bytearecv - converts external binary format to bytea
*/
Datum
bytearecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
bytea *result;
int nbytes;
nbytes = buf->len - buf->cursor;
result = (bytea *) palloc(nbytes + VARHDRSZ);
VARATT_SIZEP(result) = nbytes + VARHDRSZ;
pq_copymsgbytes(buf, VARDATA(result), nbytes);
PG_RETURN_BYTEA_P(result);
}
/*
* byteasend - converts bytea to binary format
*
* This is a special case: just copy the input...
*/
Datum
byteasend(PG_FUNCTION_ARGS)
{
bytea *vlena = PG_GETARG_BYTEA_P_COPY(0);
PG_RETURN_BYTEA_P(vlena);
}
/* /*
* textin - converts "..." to internal representation * textin - converts "..." to internal representation
...@@ -259,6 +293,39 @@ textout(PG_FUNCTION_ARGS) ...@@ -259,6 +293,39 @@ textout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
/*
* textrecv - converts external binary format to text
*/
Datum
textrecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
text *result;
char *str;
int nbytes;
str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
result = (text *) palloc(nbytes + VARHDRSZ);
VARATT_SIZEP(result) = nbytes + VARHDRSZ;
memcpy(VARDATA(result), str, nbytes);
pfree(str);
PG_RETURN_TEXT_P(result);
}
/*
* textsend - converts text to binary format
*/
Datum
textsend(PG_FUNCTION_ARGS)
{
text *t = PG_GETARG_TEXT_P(0);
StringInfoData buf;
pq_begintypsend(&buf);
pq_sendtext(&buf, VARDATA(t), VARSIZE(t) - VARHDRSZ);
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
}
/* /*
* unknownin - converts "..." to internal representation * unknownin - converts "..." to internal representation
...@@ -280,7 +347,6 @@ unknownin(PG_FUNCTION_ARGS) ...@@ -280,7 +347,6 @@ unknownin(PG_FUNCTION_ARGS)
PG_RETURN_UNKNOWN_P(result); PG_RETURN_UNKNOWN_P(result);
} }
/* /*
* unknownout - converts internal representation to "..." * unknownout - converts internal representation to "..."
*/ */
...@@ -299,6 +365,37 @@ unknownout(PG_FUNCTION_ARGS) ...@@ -299,6 +365,37 @@ unknownout(PG_FUNCTION_ARGS)
PG_RETURN_CSTRING(result); PG_RETURN_CSTRING(result);
} }
/*
* unknownrecv - converts external binary format to unknown
*/
Datum
unknownrecv(PG_FUNCTION_ARGS)
{
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
unknown *result;
int nbytes;
nbytes = buf->len - buf->cursor;
result = (unknown *) palloc(nbytes + VARHDRSZ);
VARATT_SIZEP(result) = nbytes + VARHDRSZ;
pq_copymsgbytes(buf, VARDATA(result), nbytes);
PG_RETURN_UNKNOWN_P(result);
}
/*
* unknownsend - converts unknown to binary format
*
* This is a special case: just copy the input, since it's
* effectively the same format as bytea
*/
Datum
unknownsend(PG_FUNCTION_ARGS)
{
unknown *vlena = PG_GETARG_UNKNOWN_P_COPY(0);
PG_RETURN_UNKNOWN_P(vlena);
}
/* ========== PUBLIC ROUTINES ========== */ /* ========== PUBLIC ROUTINES ========== */
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: catversion.h,v 1.187 2003/05/08 22:19:56 tgl Exp $ * $Id: catversion.h,v 1.188 2003/05/09 15:44:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 200305081 #define CATALOG_VERSION_NO 200305091
#endif #endif
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_type.h,v 1.141 2003/05/08 22:19:57 tgl Exp $ * $Id: pg_type.h,v 1.142 2003/05/09 15:44:41 tgl Exp $
* *
* NOTES * NOTES
* the genbki.sh script reads this file and generates .bki * the genbki.sh script reads this file and generates .bki
...@@ -242,7 +242,7 @@ DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b t \054 0 0 boolin boolout - - ...@@ -242,7 +242,7 @@ DATA(insert OID = 16 ( bool PGNSP PGUID 1 t b t \054 0 0 boolin boolout - -
DESCR("boolean, 'true'/'false'"); DESCR("boolean, 'true'/'false'");
#define BOOLOID 16 #define BOOLOID 16
DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b t \054 0 0 byteain byteaout - - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 17 ( bytea PGNSP PGUID -1 f b t \054 0 0 byteain byteaout bytearecv byteasend i x f 0 -1 0 _null_ _null_ ));
DESCR("variable-length string, binary values escaped"); DESCR("variable-length string, binary values escaped");
#define BYTEAOID 17 #define BYTEAOID 17
...@@ -254,19 +254,19 @@ DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b t \054 0 18 namein na ...@@ -254,19 +254,19 @@ DATA(insert OID = 19 ( name PGNSP PGUID NAMEDATALEN f b t \054 0 18 namein na
DESCR("31-character type for storing system identifiers"); DESCR("31-character type for storing system identifiers");
#define NAMEOID 19 #define NAMEOID 19
DATA(insert OID = 20 ( int8 PGNSP PGUID 8 f b t \054 0 0 int8in int8out - - d p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 20 ( int8 PGNSP PGUID 8 f b t \054 0 0 int8in int8out int8recv int8send d p f 0 -1 0 _null_ _null_ ));
DESCR("~18 digit integer, 8-byte storage"); DESCR("~18 digit integer, 8-byte storage");
#define INT8OID 20 #define INT8OID 20
DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b t \054 0 0 int2in int2out - - s p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 21 ( int2 PGNSP PGUID 2 t b t \054 0 0 int2in int2out int2recv int2send s p f 0 -1 0 _null_ _null_ ));
DESCR("-32 thousand to 32 thousand, 2-byte storage"); DESCR("-32 thousand to 32 thousand, 2-byte storage");
#define INT2OID 21 #define INT2OID 21
DATA(insert OID = 22 ( int2vector PGNSP PGUID INDEX_MAX_KEYS*2 f b t \054 0 21 int2vectorin int2vectorout - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 22 ( int2vector PGNSP PGUID INDEX_MAX_KEYS*2 f b t \054 0 21 int2vectorin int2vectorout int2vectorrecv int2vectorsend i p f 0 -1 0 _null_ _null_ ));
DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables"); DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables");
#define INT2VECTOROID 22 #define INT2VECTOROID 22
DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b t \054 0 0 int4in int4out - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 23 ( int4 PGNSP PGUID 4 t b t \054 0 0 int4in int4out int4recv int4send i p f 0 -1 0 _null_ _null_ ));
DESCR("-2 billion to 2 billion integer, 4-byte storage"); DESCR("-2 billion to 2 billion integer, 4-byte storage");
#define INT4OID 23 #define INT4OID 23
...@@ -274,11 +274,11 @@ DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b t \054 0 0 regprocin regpro ...@@ -274,11 +274,11 @@ DATA(insert OID = 24 ( regproc PGNSP PGUID 4 t b t \054 0 0 regprocin regpro
DESCR("registered procedure"); DESCR("registered procedure");
#define REGPROCOID 24 #define REGPROCOID 24
DATA(insert OID = 25 ( text PGNSP PGUID -1 f b t \054 0 0 textin textout - - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 25 ( text PGNSP PGUID -1 f b t \054 0 0 textin textout textrecv textsend i x f 0 -1 0 _null_ _null_ ));
DESCR("variable-length string, no limit specified"); DESCR("variable-length string, no limit specified");
#define TEXTOID 25 #define TEXTOID 25
DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b t \054 0 0 oidin oidout - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 26 ( oid PGNSP PGUID 4 t b t \054 0 0 oidin oidout oidrecv oidsend i p f 0 -1 0 _null_ _null_ ));
DESCR("object identifier(oid), maximum 4 billion"); DESCR("object identifier(oid), maximum 4 billion");
#define OIDOID 26 #define OIDOID 26
...@@ -294,7 +294,7 @@ DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b t \054 0 0 cidin cidout - - i ...@@ -294,7 +294,7 @@ DATA(insert OID = 29 ( cid PGNSP PGUID 4 t b t \054 0 0 cidin cidout - - i
DESCR("command identifier type, sequence in transaction id"); DESCR("command identifier type, sequence in transaction id");
#define CIDOID 29 #define CIDOID 29
DATA(insert OID = 30 ( oidvector PGNSP PGUID INDEX_MAX_KEYS*4 f b t \054 0 26 oidvectorin oidvectorout - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 30 ( oidvector PGNSP PGUID INDEX_MAX_KEYS*4 f b t \054 0 26 oidvectorin oidvectorout oidvectorrecv oidvectorsend i p f 0 -1 0 _null_ _null_ ));
DESCR("array of INDEX_MAX_KEYS oids, used in system tables"); DESCR("array of INDEX_MAX_KEYS oids, used in system tables");
#define OIDVECTOROID 30 #define OIDVECTOROID 30
...@@ -362,7 +362,7 @@ DESCR("relative, limited-range time interval (Unix delta time)"); ...@@ -362,7 +362,7 @@ DESCR("relative, limited-range time interval (Unix delta time)");
DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b t \054 0 0 tintervalin tintervalout - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 704 ( tinterval PGNSP PGUID 12 f b t \054 0 0 tintervalin tintervalout - - i p f 0 -1 0 _null_ _null_ ));
DESCR("(abstime,abstime), time interval"); DESCR("(abstime,abstime), time interval");
#define TINTERVALOID 704 #define TINTERVALOID 704
DATA(insert OID = 705 ( unknown PGNSP PGUID -1 f b t \054 0 0 unknownin unknownout - - i p f 0 -1 0 _null_ _null_ )); DATA(insert OID = 705 ( unknown PGNSP PGUID -1 f b t \054 0 0 unknownin unknownout unknownrecv unknownsend i p f 0 -1 0 _null_ _null_ ));
DESCR(""); DESCR("");
#define UNKNOWNOID 705 #define UNKNOWNOID 705
...@@ -477,7 +477,7 @@ DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b t \054 0 0 numeric_in num ...@@ -477,7 +477,7 @@ DATA(insert OID = 1700 ( numeric PGNSP PGUID -1 f b t \054 0 0 numeric_in num
DESCR("numeric(precision, decimal), arbitrary precision number"); DESCR("numeric(precision, decimal), arbitrary precision number");
#define NUMERICOID 1700 #define NUMERICOID 1700
DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b t \054 0 0 textin textout - - i x f 0 -1 0 _null_ _null_ )); DATA(insert OID = 1790 ( refcursor PGNSP PGUID -1 f b t \054 0 0 textin textout textrecv textsend i x f 0 -1 0 _null_ _null_ ));
DESCR("reference cursor (portal name)"); DESCR("reference cursor (portal name)");
#define REFCURSOROID 1790 #define REFCURSOROID 1790
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pqformat.h,v 1.16 2003/05/08 18:16:37 tgl Exp $ * $Id: pqformat.h,v 1.17 2003/05/09 15:44:42 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -20,17 +20,24 @@ extern void pq_sendbyte(StringInfo buf, int byt); ...@@ -20,17 +20,24 @@ extern void pq_sendbyte(StringInfo buf, int byt);
extern void pq_sendbytes(StringInfo buf, const char *data, int datalen); extern void pq_sendbytes(StringInfo buf, const char *data, int datalen);
extern void pq_sendcountedtext(StringInfo buf, const char *str, int slen, extern void pq_sendcountedtext(StringInfo buf, const char *str, int slen,
bool countincludesself); bool countincludesself);
extern void pq_sendtext(StringInfo buf, const char *str, int slen);
extern void pq_sendstring(StringInfo buf, const char *str); extern void pq_sendstring(StringInfo buf, const char *str);
extern void pq_sendint(StringInfo buf, int i, int b); extern void pq_sendint(StringInfo buf, int i, int b);
extern void pq_sendint64(StringInfo buf, int64 i);
extern void pq_endmessage(StringInfo buf); extern void pq_endmessage(StringInfo buf);
extern void pq_begintypsend(StringInfo buf);
extern bytea *pq_endtypsend(StringInfo buf);
extern void pq_puttextmessage(char msgtype, const char *str); extern void pq_puttextmessage(char msgtype, const char *str);
extern void pq_putemptymessage(char msgtype); extern void pq_putemptymessage(char msgtype);
extern int pq_getmsgbyte(StringInfo msg); extern int pq_getmsgbyte(StringInfo msg);
extern unsigned int pq_getmsgint(StringInfo msg, int b); extern unsigned int pq_getmsgint(StringInfo msg, int b);
extern int64 pq_getmsgint64(StringInfo msg);
extern const char *pq_getmsgbytes(StringInfo msg, int datalen); extern const char *pq_getmsgbytes(StringInfo msg, int datalen);
extern void pq_copymsgbytes(StringInfo msg, char *buf, int datalen); extern void pq_copymsgbytes(StringInfo msg, char *buf, int datalen);
extern char *pq_getmsgtext(StringInfo msg, int rawbytes, int *nbytes);
extern const char *pq_getmsgstring(StringInfo msg); extern const char *pq_getmsgstring(StringInfo msg);
extern void pq_getmsgend(StringInfo msg); extern void pq_getmsgend(StringInfo msg);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: builtins.h,v 1.212 2003/05/08 22:19:57 tgl Exp $ * $Id: builtins.h,v 1.213 2003/05/09 15:44:42 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -90,11 +90,17 @@ extern Datum cideq(PG_FUNCTION_ARGS); ...@@ -90,11 +90,17 @@ extern Datum cideq(PG_FUNCTION_ARGS);
/* int.c */ /* int.c */
extern Datum int2in(PG_FUNCTION_ARGS); extern Datum int2in(PG_FUNCTION_ARGS);
extern Datum int2out(PG_FUNCTION_ARGS); extern Datum int2out(PG_FUNCTION_ARGS);
extern Datum int2recv(PG_FUNCTION_ARGS);
extern Datum int2send(PG_FUNCTION_ARGS);
extern Datum int2vectorin(PG_FUNCTION_ARGS); extern Datum int2vectorin(PG_FUNCTION_ARGS);
extern Datum int2vectorout(PG_FUNCTION_ARGS); extern Datum int2vectorout(PG_FUNCTION_ARGS);
extern Datum int2vectorrecv(PG_FUNCTION_ARGS);
extern Datum int2vectorsend(PG_FUNCTION_ARGS);
extern Datum int2vectoreq(PG_FUNCTION_ARGS); extern Datum int2vectoreq(PG_FUNCTION_ARGS);
extern Datum int4in(PG_FUNCTION_ARGS); extern Datum int4in(PG_FUNCTION_ARGS);
extern Datum int4out(PG_FUNCTION_ARGS); extern Datum int4out(PG_FUNCTION_ARGS);
extern Datum int4recv(PG_FUNCTION_ARGS);
extern Datum int4send(PG_FUNCTION_ARGS);
extern Datum i2toi4(PG_FUNCTION_ARGS); extern Datum i2toi4(PG_FUNCTION_ARGS);
extern Datum i4toi2(PG_FUNCTION_ARGS); extern Datum i4toi2(PG_FUNCTION_ARGS);
extern Datum int2_text(PG_FUNCTION_ARGS); extern Datum int2_text(PG_FUNCTION_ARGS);
...@@ -324,6 +330,8 @@ extern Datum oidnotin(PG_FUNCTION_ARGS); ...@@ -324,6 +330,8 @@ extern Datum oidnotin(PG_FUNCTION_ARGS);
/* oid.c */ /* oid.c */
extern Datum oidin(PG_FUNCTION_ARGS); extern Datum oidin(PG_FUNCTION_ARGS);
extern Datum oidout(PG_FUNCTION_ARGS); extern Datum oidout(PG_FUNCTION_ARGS);
extern Datum oidrecv(PG_FUNCTION_ARGS);
extern Datum oidsend(PG_FUNCTION_ARGS);
extern Datum oideq(PG_FUNCTION_ARGS); extern Datum oideq(PG_FUNCTION_ARGS);
extern Datum oidne(PG_FUNCTION_ARGS); extern Datum oidne(PG_FUNCTION_ARGS);
extern Datum oidlt(PG_FUNCTION_ARGS); extern Datum oidlt(PG_FUNCTION_ARGS);
...@@ -336,6 +344,8 @@ extern Datum oid_text(PG_FUNCTION_ARGS); ...@@ -336,6 +344,8 @@ extern Datum oid_text(PG_FUNCTION_ARGS);
extern Datum text_oid(PG_FUNCTION_ARGS); extern Datum text_oid(PG_FUNCTION_ARGS);
extern Datum oidvectorin(PG_FUNCTION_ARGS); extern Datum oidvectorin(PG_FUNCTION_ARGS);
extern Datum oidvectorout(PG_FUNCTION_ARGS); extern Datum oidvectorout(PG_FUNCTION_ARGS);
extern Datum oidvectorrecv(PG_FUNCTION_ARGS);
extern Datum oidvectorsend(PG_FUNCTION_ARGS);
extern Datum oidvectoreq(PG_FUNCTION_ARGS); extern Datum oidvectoreq(PG_FUNCTION_ARGS);
extern Datum oidvectorne(PG_FUNCTION_ARGS); extern Datum oidvectorne(PG_FUNCTION_ARGS);
extern Datum oidvectorlt(PG_FUNCTION_ARGS); extern Datum oidvectorlt(PG_FUNCTION_ARGS);
...@@ -462,6 +472,8 @@ extern Datum varcharoctetlen(PG_FUNCTION_ARGS); ...@@ -462,6 +472,8 @@ extern Datum varcharoctetlen(PG_FUNCTION_ARGS);
/* varlena.c */ /* varlena.c */
extern Datum textin(PG_FUNCTION_ARGS); extern Datum textin(PG_FUNCTION_ARGS);
extern Datum textout(PG_FUNCTION_ARGS); extern Datum textout(PG_FUNCTION_ARGS);
extern Datum textrecv(PG_FUNCTION_ARGS);
extern Datum textsend(PG_FUNCTION_ARGS);
extern Datum textcat(PG_FUNCTION_ARGS); extern Datum textcat(PG_FUNCTION_ARGS);
extern Datum texteq(PG_FUNCTION_ARGS); extern Datum texteq(PG_FUNCTION_ARGS);
extern Datum textne(PG_FUNCTION_ARGS); extern Datum textne(PG_FUNCTION_ARGS);
...@@ -490,9 +502,13 @@ extern Datum md5_text(PG_FUNCTION_ARGS); ...@@ -490,9 +502,13 @@ extern Datum md5_text(PG_FUNCTION_ARGS);
extern Datum unknownin(PG_FUNCTION_ARGS); extern Datum unknownin(PG_FUNCTION_ARGS);
extern Datum unknownout(PG_FUNCTION_ARGS); extern Datum unknownout(PG_FUNCTION_ARGS);
extern Datum unknownrecv(PG_FUNCTION_ARGS);
extern Datum unknownsend(PG_FUNCTION_ARGS);
extern Datum byteain(PG_FUNCTION_ARGS); extern Datum byteain(PG_FUNCTION_ARGS);
extern Datum byteaout(PG_FUNCTION_ARGS); extern Datum byteaout(PG_FUNCTION_ARGS);
extern Datum bytearecv(PG_FUNCTION_ARGS);
extern Datum byteasend(PG_FUNCTION_ARGS);
extern Datum byteaoctetlen(PG_FUNCTION_ARGS); extern Datum byteaoctetlen(PG_FUNCTION_ARGS);
extern Datum byteaGetByte(PG_FUNCTION_ARGS); extern Datum byteaGetByte(PG_FUNCTION_ARGS);
extern Datum byteaGetBit(PG_FUNCTION_ARGS); extern Datum byteaGetBit(PG_FUNCTION_ARGS);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: int8.h,v 1.36 2002/10/25 22:08:44 tgl Exp $ * $Id: int8.h,v 1.37 2003/05/09 15:44:42 tgl Exp $
* *
* NOTES * NOTES
* These data types are supported on all 64-bit architectures, and may * These data types are supported on all 64-bit architectures, and may
...@@ -27,6 +27,8 @@ extern bool scanint8(const char *str, bool errorOK, int64 *result); ...@@ -27,6 +27,8 @@ extern bool scanint8(const char *str, bool errorOK, int64 *result);
extern Datum int8in(PG_FUNCTION_ARGS); extern Datum int8in(PG_FUNCTION_ARGS);
extern Datum int8out(PG_FUNCTION_ARGS); extern Datum int8out(PG_FUNCTION_ARGS);
extern Datum int8recv(PG_FUNCTION_ARGS);
extern Datum int8send(PG_FUNCTION_ARGS);
extern Datum int8eq(PG_FUNCTION_ARGS); extern Datum int8eq(PG_FUNCTION_ARGS);
extern Datum int8ne(PG_FUNCTION_ARGS); extern Datum int8ne(PG_FUNCTION_ARGS);
......
...@@ -148,14 +148,18 @@ WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT ...@@ -148,14 +148,18 @@ WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT
-----+---------+-----+--------- -----+---------+-----+---------
(0 rows) (0 rows)
-- As of 7.4, this check finds refcursor, which is borrowing
-- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT
(p1.typelem != 0 AND p1.typlen < 0) AND NOT (p1.typelem != 0 AND p1.typlen < 0) AND NOT
(p2.prorettype = p1.oid AND NOT p2.proretset); (p2.prorettype = p1.oid AND NOT p2.proretset)
oid | typname | oid | proname ORDER BY 1;
-----+---------+-----+--------- oid | typname | oid | proname
(0 rows) ------+-----------+------+----------
1790 | refcursor | 2414 | textrecv
(1 row)
-- Varlena array types will point to array_recv -- Varlena array types will point to array_recv
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT p1.oid, p1.typname, p2.oid, p2.proname
...@@ -168,15 +172,19 @@ WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND ...@@ -168,15 +172,19 @@ WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND
(0 rows) (0 rows)
-- Check for bogus typsend routines -- Check for bogus typsend routines
-- As of 7.4, this check finds refcursor, which is borrowing
-- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = p1.oid) OR ((p2.pronargs = 1 AND p2.proargtypes[0] = p1.oid) OR
(p2.oid = 'array_send'::regproc AND (p2.oid = 'array_send'::regproc AND
p1.typelem != 0 AND p1.typlen = -1)); p1.typelem != 0 AND p1.typlen = -1))
oid | typname | oid | proname ORDER BY 1;
-----+---------+-----+--------- oid | typname | oid | proname
(0 rows) ------+-----------+------+----------
1790 | refcursor | 2415 | textsend
(1 row)
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS p1, pg_proc AS p2
......
...@@ -116,11 +116,14 @@ FROM pg_type AS p1, pg_proc AS p2 ...@@ -116,11 +116,14 @@ FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT
(p2.pronargs = 1 AND p2.proargtypes[0] = 'internal'::regtype); (p2.pronargs = 1 AND p2.proargtypes[0] = 'internal'::regtype);
-- As of 7.4, this check finds refcursor, which is borrowing
-- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND NOT
(p1.typelem != 0 AND p1.typlen < 0) AND NOT (p1.typelem != 0 AND p1.typlen < 0) AND NOT
(p2.prorettype = p1.oid AND NOT p2.proretset); (p2.prorettype = p1.oid AND NOT p2.proretset)
ORDER BY 1;
-- Varlena array types will point to array_recv -- Varlena array types will point to array_recv
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT p1.oid, p1.typname, p2.oid, p2.proname
...@@ -131,12 +134,15 @@ WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND ...@@ -131,12 +134,15 @@ WHERE p1.typreceive = p2.oid AND p1.typtype in ('b', 'p') AND
-- Check for bogus typsend routines -- Check for bogus typsend routines
-- As of 7.4, this check finds refcursor, which is borrowing
-- other types' I/O routines
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS p1, pg_proc AS p2
WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT WHERE p1.typsend = p2.oid AND p1.typtype in ('b', 'p') AND NOT
((p2.pronargs = 1 AND p2.proargtypes[0] = p1.oid) OR ((p2.pronargs = 1 AND p2.proargtypes[0] = p1.oid) OR
(p2.oid = 'array_send'::regproc AND (p2.oid = 'array_send'::regproc AND
p1.typelem != 0 AND p1.typlen = -1)); p1.typelem != 0 AND p1.typlen = -1))
ORDER BY 1;
SELECT p1.oid, p1.typname, p2.oid, p2.proname SELECT p1.oid, p1.typname, p2.oid, p2.proname
FROM pg_type AS p1, pg_proc AS p2 FROM pg_type AS p1, pg_proc AS p2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment