diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c index e947785..d1d0dd6 100644 --- a/src/backend/utils/adt/varbit.c +++ b/src/backend/utils/adt/varbit.c @@ -1187,7 +1187,7 @@ bit_overlay(VarBit *t1, VarBit *t2, int sp, int sl) Datum bitlength(PG_FUNCTION_ARGS) { - VarBit *arg = PG_GETARG_VARBIT_P(0); + VarBit *arg = PG_GETARG_VARBIT_P_SLICE(0,0,VARHDRSZ+VARBITHDRSZ); PG_RETURN_INT32(VARBITLEN(arg)); } diff --git a/src/include/utils/varbit.h b/src/include/utils/varbit.h index 2a4ec67..811efeb 100644 --- a/src/include/utils/varbit.h +++ b/src/include/utils/varbit.h @@ -36,9 +36,11 @@ typedef struct * BIT and BIT VARYING are toastable varlena types. They are the same * as far as representation goes, so we just have one set of macros. */ +#define DatumGetVarBitPSlice(X,m,n) ((VarBit *) PG_DETOAST_DATUM_SLICE(X,m,n)) #define DatumGetVarBitP(X) ((VarBit *) PG_DETOAST_DATUM(X)) #define DatumGetVarBitPCopy(X) ((VarBit *) PG_DETOAST_DATUM_COPY(X)) #define VarBitPGetDatum(X) PointerGetDatum(X) +#define PG_GETARG_VARBIT_P_SLICE(n,a,b) DatumGetVarBitPSlice(PG_GETARG_DATUM(n),a,b) #define PG_GETARG_VARBIT_P(n) DatumGetVarBitP(PG_GETARG_DATUM(n)) #define PG_GETARG_VARBIT_P_COPY(n) DatumGetVarBitPCopy(PG_GETARG_DATUM(n)) #define PG_RETURN_VARBIT_P(x) return VarBitPGetDatum(x) diff --git a/src/test/regress/expected/bit.out b/src/test/regress/expected/bit.out index 9c7d202..d440dbd 100644 --- a/src/test/regress/expected/bit.out +++ b/src/test/regress/expected/bit.out @@ -80,6 +80,20 @@ SELECT v, length(v) AS lv 01010101010 | 11 (4 rows) +SELECT length(string_agg('1','')::BIT VARYING) + FROM generate_series(1,1000) gs; + length +-------- + 1000 +(1 row) + +SELECT length(string_agg('1','')::BIT VARYING) + FROM generate_series(1,65536) gs; + length +-------- + 65536 +(1 row) + -- Substring SELECT b, SUBSTRING(b FROM 2 FOR 4) AS sub_2_4, diff --git a/src/test/regress/sql/bit.sql b/src/test/regress/sql/bit.sql index 419d47c..a60870c 100644 --- a/src/test/regress/sql/bit.sql +++ b/src/test/regress/sql/bit.sql @@ -40,6 +40,10 @@ SELECT b, length(b) AS lb FROM BIT_TABLE; SELECT v, length(v) AS lv FROM VARBIT_TABLE; +SELECT length(string_agg('1','')::BIT VARYING) + FROM generate_series(1,1000) gs; +SELECT length(string_agg('1','')::BIT VARYING) + FROM generate_series(1,65536) gs; -- Substring SELECT b,