aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/varbit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/varbit.c')
-rw-r--r--src/backend/utils/adt/varbit.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
index f0c6a44b842..de3852045b1 100644
--- a/src/backend/utils/adt/varbit.c
+++ b/src/backend/utils/adt/varbit.c
@@ -1059,7 +1059,7 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
len,
ishift,
i;
- int e,
+ int32 e,
s1,
e1;
bits8 *r,
@@ -1072,18 +1072,24 @@ bitsubstring(VarBit *arg, int32 s, int32 l, bool length_not_specified)
{
e1 = bitlen + 1;
}
- else
+ else if (l < 0)
+ {
+ /* SQL99 says to throw an error for E < S, i.e., negative length */
+ ereport(ERROR,
+ (errcode(ERRCODE_SUBSTRING_ERROR),
+ errmsg("negative substring length not allowed")));
+ e1 = -1; /* silence stupider compilers */
+ }
+ else if (pg_add_s32_overflow(s, l, &e))
{
- e = s + l;
-
/*
- * A negative value for L is the only way for the end position to be
- * before the start. SQL99 says to throw an error.
+ * L could be large enough for S + L to overflow, in which case the
+ * substring must run to end of string.
*/
- if (e < s)
- ereport(ERROR,
- (errcode(ERRCODE_SUBSTRING_ERROR),
- errmsg("negative substring length not allowed")));
+ e1 = bitlen + 1;
+ }
+ else
+ {
e1 = Min(e, bitlen + 1);
}
if (s1 > bitlen || e1 <= s1)