mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
Fix 3-parameter form of bit substring() to throw error for negative length,
as required by SQL standard.
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.62 2010/01/07 19:53:11 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/utils/adt/varbit.c,v 1.63 2010/01/07 20:17:43 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -23,6 +23,9 @@
|
||||
|
||||
#define HEXDIG(z) ((z)<10 ? ((z)+'0') : ((z)-10+'A'))
|
||||
|
||||
static VarBit *bitsubstring(VarBit *arg, int32 s, int32 l,
|
||||
bool length_not_specified);
|
||||
|
||||
|
||||
/* common code for bittypmodin and varbittypmodin */
|
||||
static int32
|
||||
@ -927,9 +930,23 @@ bitcat(PG_FUNCTION_ARGS)
|
||||
Datum
|
||||
bitsubstr(PG_FUNCTION_ARGS)
|
||||
{
|
||||
VarBit *arg = PG_GETARG_VARBIT_P(0);
|
||||
int32 s = PG_GETARG_INT32(1);
|
||||
int32 l = PG_GETARG_INT32(2);
|
||||
PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
|
||||
PG_GETARG_INT32(1),
|
||||
PG_GETARG_INT32(2),
|
||||
false));
|
||||
}
|
||||
|
||||
Datum
|
||||
bitsubstr_no_len(PG_FUNCTION_ARGS)
|
||||
{
|
||||
PG_RETURN_VARBIT_P(bitsubstring(PG_GETARG_VARBIT_P(0),
|
||||
PG_GETARG_INT32(1),
|
||||
-1, true));
|
||||
}
|
||||
|
||||
static VarBit *
|
||||
bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
|
||||
{
|
||||
VarBit *result;
|
||||
int bitlen,
|
||||
rbitlen,
|
||||
@ -947,14 +964,17 @@ bitsubstr(PG_FUNCTION_ARGS)
|
||||
bitlen = VARBITLEN(arg);
|
||||
s1 = Max(s, 1);
|
||||
/* If we do not have an upper bound, use end of string */
|
||||
if (l < 0)
|
||||
if (length_not_specified)
|
||||
{
|
||||
e1 = bitlen + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
e = s + l;
|
||||
/* guard against overflow, even though we don't allow L<0 here */
|
||||
/*
|
||||
* A negative value for L is the only way for the end position
|
||||
* to be before the start. SQL99 says to throw an error.
|
||||
*/
|
||||
if (e < s)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_SUBSTRING_ERROR),
|
||||
@ -1011,7 +1031,7 @@ bitsubstr(PG_FUNCTION_ARGS)
|
||||
}
|
||||
}
|
||||
|
||||
PG_RETURN_VARBIT_P(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* bitlength, bitoctetlength
|
||||
|
Reference in New Issue
Block a user