mirror of
https://github.com/postgres/postgres.git
synced 2025-07-15 19:21:59 +03:00
Change typreceive function API so that receive functions get the same
optional arguments as text input functions, ie, typioparam OID and atttypmod. Make all the datatypes that use typmod enforce it the same way in typreceive as they do in typinput. This fixes a problem with failure to enforce length restrictions during COPY FROM BINARY.
This commit is contained in:
@ -9,7 +9,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.44 2004/12/31 22:01:22 pgsql Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.45 2005/07/10 21:13:59 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -221,8 +221,49 @@ bit_out(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
bit_recv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
/* Exactly the same as varbit_recv, so share code */
|
||||
return varbit_recv(fcinfo);
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
#ifdef NOT_USED
|
||||
Oid typelem = PG_GETARG_OID(1);
|
||||
#endif
|
||||
int32 atttypmod = PG_GETARG_INT32(2);
|
||||
VarBit *result;
|
||||
int len,
|
||||
bitlen;
|
||||
int ipad;
|
||||
bits8 mask;
|
||||
|
||||
bitlen = pq_getmsgint(buf, sizeof(int32));
|
||||
if (bitlen < 0)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid length in external bit string")));
|
||||
|
||||
/*
|
||||
* Sometimes atttypmod is not supplied. If it is supplied we need to
|
||||
* make sure that the bitstring fits.
|
||||
*/
|
||||
if (atttypmod > 0 && bitlen != atttypmod)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
|
||||
errmsg("bit string length %d does not match type bit(%d)",
|
||||
bitlen, atttypmod)));
|
||||
|
||||
len = VARBITTOTALLEN(bitlen);
|
||||
result = (VarBit *) palloc(len);
|
||||
VARATT_SIZEP(result) = len;
|
||||
VARBITLEN(result) = bitlen;
|
||||
|
||||
pq_copymsgbytes(buf, (char *) VARBITS(result), VARBITBYTES(result));
|
||||
|
||||
/* Make sure last byte is zero-padded if needed */
|
||||
ipad = VARBITPAD(result);
|
||||
if (ipad > 0)
|
||||
{
|
||||
mask = BITMASK << ipad;
|
||||
*(VARBITS(result) + VARBITBYTES(result) - 1) &= mask;
|
||||
}
|
||||
|
||||
PG_RETURN_VARBIT_P(result);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -459,6 +500,10 @@ Datum
|
||||
varbit_recv(PG_FUNCTION_ARGS)
|
||||
{
|
||||
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
|
||||
#ifdef NOT_USED
|
||||
Oid typelem = PG_GETARG_OID(1);
|
||||
#endif
|
||||
int32 atttypmod = PG_GETARG_INT32(2);
|
||||
VarBit *result;
|
||||
int len,
|
||||
bitlen;
|
||||
@ -471,6 +516,16 @@ varbit_recv(PG_FUNCTION_ARGS)
|
||||
(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
|
||||
errmsg("invalid length in external bit string")));
|
||||
|
||||
/*
|
||||
* Sometimes atttypmod is not supplied. If it is supplied we need to
|
||||
* make sure that the bitstring fits.
|
||||
*/
|
||||
if (atttypmod > 0 && bitlen > atttypmod)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
|
||||
errmsg("bit string too long for type bit varying(%d)",
|
||||
atttypmod)));
|
||||
|
||||
len = VARBITTOTALLEN(bitlen);
|
||||
result = (VarBit *) palloc(len);
|
||||
VARATT_SIZEP(result) = len;
|
||||
|
Reference in New Issue
Block a user