#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
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,
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),
}
}
- PG_RETURN_VARBIT_P(result);
+ return result;
}
/* bitlength, bitoctetlength
DATA(insert OID = 1698 ( position PGNSP PGUID 12 1 0 0 f f f t f i 2 0 23 "1560 1560" _null_ _null_ _null_ _null_ bitposition _null_ _null_ _null_ ));
DESCR("return position of sub-bitstring");
-DATA(insert OID = 1699 ( substring PGNSP PGUID 14 1 0 0 f f f t f i 2 0 1560 "1560 23" _null_ _null_ _null_ _null_ "select pg_catalog.substring($1, $2, -1)" _null_ _null_ _null_ ));
+DATA(insert OID = 1699 ( substring PGNSP PGUID 12 1 0 0 f f f t f i 2 0 1560 "1560 23" _null_ _null_ _null_ _null_ bitsubstr_no_len _null_ _null_ _null_ ));
DESCR("return portion of bitstring");
extern Datum bitshiftright(PG_FUNCTION_ARGS);
extern Datum bitcat(PG_FUNCTION_ARGS);
extern Datum bitsubstr(PG_FUNCTION_ARGS);
+extern Datum bitsubstr_no_len(PG_FUNCTION_ARGS);
extern Datum bitlength(PG_FUNCTION_ARGS);
extern Datum bitoctetlength(PG_FUNCTION_ARGS);
extern Datum bitfromint4(PG_FUNCTION_ARGS);