diff --git a/expected/add_agg.out b/expected/add_agg.out index 2bb4601..fad2aa5 100644 --- a/expected/add_agg.out +++ b/expected/add_agg.out @@ -77,10 +77,10 @@ select hll_print(hll_add_agg(hll_hash_integer(val), 10, 4, 512, 0)) -- Check range checking. select hll_print(hll_add_agg(hll_hash_integer(val), -1)) from test_khvengxf; -ERROR: log2m modifier must be between 0 and 31 +ERROR: log2m modifier must be between 0 and 17 select hll_print(hll_add_agg(hll_hash_integer(val), 32)) from test_khvengxf; -ERROR: log2m modifier must be between 0 and 31 +ERROR: log2m modifier must be between 0 and 17 select hll_print(hll_add_agg(hll_hash_integer(val), 10, -1)) from test_khvengxf; ERROR: regwidth modifier must be between 0 and 7 @@ -89,10 +89,10 @@ select hll_print(hll_add_agg(hll_hash_integer(val), 10, 8)) ERROR: regwidth modifier must be between 0 and 7 select hll_print(hll_add_agg(hll_hash_integer(val), 10, 4, -2)) from test_khvengxf; -ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: expthresh modifier must be between -1 and 16383 select hll_print(hll_add_agg(hll_hash_integer(val), 10, 4, 8589934592)) from test_khvengxf; -ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: expthresh modifier must be between -1 and 16383 select hll_print(hll_add_agg(hll_hash_integer(val), 10, 4, 512, -1)) from test_khvengxf; ERROR: sparseon modifier must be 0 or 1 diff --git a/expected/typmod.out b/expected/typmod.out index e9f65cd..1c1a885 100644 --- a/expected/typmod.out +++ b/expected/typmod.out @@ -59,9 +59,9 @@ LINE 1: CREATE TABLE test_qiundgkm (v1 hll(10, 4, 64, 0, 42)); -- ---------------------------------------------------------------- -- Range Check log2nregs -- ---------------------------------------------------------------- --- ERROR: log2m modifier must be between 0 and 31 +-- ERROR: log2m modifier must be between 0 and 17 CREATE TABLE test_qiundgkm (v1 hll(-1)); -ERROR: log2m modifier must be between 0 and 31 +ERROR: log2m modifier must be between 0 and 17 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(-1)); ^ CREATE TABLE test_qiundgkm (v1 hll(0)); @@ -73,16 +73,15 @@ CREATE TABLE test_qiundgkm (v1 hll(0)); DROP TABLE test_qiundgkm; CREATE TABLE test_qiundgkm (v1 hll(31)); +ERROR: log2m modifier must be between 0 and 17 +LINE 1: CREATE TABLE test_qiundgkm (v1 hll(31)); + ^ \d test_qiundgkm - Table "public.test_qiundgkm" - Column | Type | Collation | Nullable | Default ---------+----------------+-----------+----------+--------- - v1 | hll(31,5,-1,1) | | | - DROP TABLE test_qiundgkm; --- ERROR: log2m modifier must be between 0 and 31 +ERROR: table "test_qiundgkm" does not exist +-- ERROR: log2m modifier must be between 0 and 17 CREATE TABLE test_qiundgkm (v1 hll(32)); -ERROR: log2m modifier must be between 0 and 31 +ERROR: log2m modifier must be between 0 and 17 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(32)); ^ -- ---------------------------------------------------------------- @@ -117,9 +116,9 @@ LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 8)); -- ---------------------------------------------------------------- -- Range Check expthresh -- ---------------------------------------------------------------- --- ERROR: expthresh modifier must be between -1 and 2^32 +-- ERROR: expthresh modifier must be between -1 and 16383 CREATE TABLE test_qiundgkm (v1 hll(11, 5, -2)); -ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: expthresh modifier must be between -1 and 16383 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 5, -2)); ^ CREATE TABLE test_qiundgkm (v1 hll(11, 5, -1)); @@ -147,16 +146,15 @@ CREATE TABLE test_qiundgkm (v1 hll(11, 5, 128)); DROP TABLE test_qiundgkm; CREATE TABLE test_qiundgkm (v1 hll(11, 5, 4294967296)); +ERROR: expthresh modifier must be between -1 and 16383 +LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 5, 4294967296)); + ^ \d test_qiundgkm - Table "public.test_qiundgkm" - Column | Type | Collation | Nullable | Default ---------+------------------------+-----------+----------+--------- - v1 | hll(11,5,4294967296,1) | | | - DROP TABLE test_qiundgkm; --- ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: table "test_qiundgkm" does not exist +-- ERROR: expthresh modifier must be between -1 and 16383 CREATE TABLE test_qiundgkm (v1 hll(11, 5, 8589934592)); -ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: expthresh modifier must be between -1 and 16383 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 5, 8589934592)); ^ -- ---------------------------------------------------------------- diff --git a/expected/typmod_0.out b/expected/typmod_0.out index a90fb8c..13fa3b9 100644 --- a/expected/typmod_0.out +++ b/expected/typmod_0.out @@ -59,9 +59,9 @@ LINE 1: CREATE TABLE test_qiundgkm (v1 hll(10, 4, 64, 0, 42)); -- ---------------------------------------------------------------- -- Range Check log2nregs -- ---------------------------------------------------------------- --- ERROR: log2m modifier must be between 0 and 31 +-- ERROR: log2m modifier must be between 0 and 17 CREATE TABLE test_qiundgkm (v1 hll(-1)); -ERROR: log2m modifier must be between 0 and 31 +ERROR: log2m modifier must be between 0 and 17 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(-1)); ^ CREATE TABLE test_qiundgkm (v1 hll(0)); @@ -73,16 +73,15 @@ CREATE TABLE test_qiundgkm (v1 hll(0)); DROP TABLE test_qiundgkm; CREATE TABLE test_qiundgkm (v1 hll(31)); +ERROR: log2m modifier must be between 0 and 17 +LINE 1: CREATE TABLE test_qiundgkm (v1 hll(31)); + ^ \d test_qiundgkm - Table "public.test_qiundgkm" - Column | Type | Collation | Nullable | Default ---------+----------------+-----------+----------+--------- - v1 | hll(31,5,-1,1) | | | - DROP TABLE test_qiundgkm; --- ERROR: log2m modifier must be between 0 and 31 +ERROR: table "test_qiundgkm" does not exist +-- ERROR: log2m modifier must be between 0 and 17 CREATE TABLE test_qiundgkm (v1 hll(32)); -ERROR: log2m modifier must be between 0 and 31 +ERROR: log2m modifier must be between 0 and 17 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(32)); ^ -- ---------------------------------------------------------------- @@ -117,9 +116,9 @@ LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 8)); -- ---------------------------------------------------------------- -- Range Check expthresh -- ---------------------------------------------------------------- --- ERROR: expthresh modifier must be between -1 and 2^32 +-- ERROR: expthresh modifier must be between -1 and 16383 CREATE TABLE test_qiundgkm (v1 hll(11, 5, -2)); -ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: expthresh modifier must be between -1 and 16383 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 5, -2)); ^ CREATE TABLE test_qiundgkm (v1 hll(11, 5, -1)); @@ -147,16 +146,15 @@ CREATE TABLE test_qiundgkm (v1 hll(11, 5, 128)); DROP TABLE test_qiundgkm; CREATE TABLE test_qiundgkm (v1 hll(11, 5, 4294967296)); +ERROR: expthresh modifier must be between -1 and 16383 +LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 5, 4294967296)); + ^ \d test_qiundgkm - Table "public.test_qiundgkm" - Column | Type | Collation | Nullable | Default ---------+------------------------+-----------+----------+--------- - v1 | hll(11,5,4294967296,1) | | | - DROP TABLE test_qiundgkm; --- ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: table "test_qiundgkm" does not exist +-- ERROR: expthresh modifier must be between -1 and 16383 CREATE TABLE test_qiundgkm (v1 hll(11, 5, 8589934592)); -ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: expthresh modifier must be between -1 and 16383 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 5, 8589934592)); ^ -- ---------------------------------------------------------------- diff --git a/expected/typmod_1.out b/expected/typmod_1.out index aa644a8..28c85c3 100644 --- a/expected/typmod_1.out +++ b/expected/typmod_1.out @@ -59,9 +59,9 @@ LINE 1: CREATE TABLE test_qiundgkm (v1 hll(10, 4, 64, 0, 42)); -- ---------------------------------------------------------------- -- Range Check log2nregs -- ---------------------------------------------------------------- --- ERROR: log2m modifier must be between 0 and 31 +-- ERROR: log2m modifier must be between 0 and 17 CREATE TABLE test_qiundgkm (v1 hll(-1)); -ERROR: log2m modifier must be between 0 and 31 +ERROR: log2m modifier must be between 0 and 17 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(-1)); ^ CREATE TABLE test_qiundgkm (v1 hll(0)); @@ -73,16 +73,15 @@ CREATE TABLE test_qiundgkm (v1 hll(0)); DROP TABLE test_qiundgkm; CREATE TABLE test_qiundgkm (v1 hll(31)); +ERROR: log2m modifier must be between 0 and 17 +LINE 1: CREATE TABLE test_qiundgkm (v1 hll(31)); + ^ \d test_qiundgkm - Table "public.test_qiundgkm" - Column | Type | Modifiers ---------+----------------+----------- - v1 | hll(31,5,-1,1) | - DROP TABLE test_qiundgkm; --- ERROR: log2m modifier must be between 0 and 31 +ERROR: table "test_qiundgkm" does not exist +-- ERROR: log2m modifier must be between 0 and 17 CREATE TABLE test_qiundgkm (v1 hll(32)); -ERROR: log2m modifier must be between 0 and 31 +ERROR: log2m modifier must be between 0 and 17 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(32)); ^ -- ---------------------------------------------------------------- @@ -117,9 +116,9 @@ LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 8)); -- ---------------------------------------------------------------- -- Range Check expthresh -- ---------------------------------------------------------------- --- ERROR: expthresh modifier must be between -1 and 2^32 +-- ERROR: expthresh modifier must be between -1 and 16383 CREATE TABLE test_qiundgkm (v1 hll(11, 5, -2)); -ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: expthresh modifier must be between -1 and 16383 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 5, -2)); ^ CREATE TABLE test_qiundgkm (v1 hll(11, 5, -1)); @@ -147,16 +146,15 @@ CREATE TABLE test_qiundgkm (v1 hll(11, 5, 128)); DROP TABLE test_qiundgkm; CREATE TABLE test_qiundgkm (v1 hll(11, 5, 4294967296)); +ERROR: expthresh modifier must be between -1 and 16383 +LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 5, 4294967296)); + ^ \d test_qiundgkm - Table "public.test_qiundgkm" - Column | Type | Modifiers ---------+------------------------+----------- - v1 | hll(11,5,4294967296,1) | - DROP TABLE test_qiundgkm; --- ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: table "test_qiundgkm" does not exist +-- ERROR: expthresh modifier must be between -1 and 16383 CREATE TABLE test_qiundgkm (v1 hll(11, 5, 8589934592)); -ERROR: expthresh modifier must be between -1 and 2^32 +ERROR: expthresh modifier must be between -1 and 16383 LINE 1: CREATE TABLE test_qiundgkm (v1 hll(11, 5, 8589934592)); ^ -- ---------------------------------------------------------------- diff --git a/sql/typmod.sql b/sql/typmod.sql index e103b2c..f62e726 100644 --- a/sql/typmod.sql +++ b/sql/typmod.sql @@ -35,7 +35,7 @@ CREATE TABLE test_qiundgkm (v1 hll(10, 4, 64, 0, 42)); -- Range Check log2nregs -- ---------------------------------------------------------------- --- ERROR: log2m modifier must be between 0 and 31 +-- ERROR: log2m modifier must be between 0 and 17 CREATE TABLE test_qiundgkm (v1 hll(-1)); CREATE TABLE test_qiundgkm (v1 hll(0)); @@ -46,7 +46,7 @@ CREATE TABLE test_qiundgkm (v1 hll(31)); \d test_qiundgkm DROP TABLE test_qiundgkm; --- ERROR: log2m modifier must be between 0 and 31 +-- ERROR: log2m modifier must be between 0 and 17 CREATE TABLE test_qiundgkm (v1 hll(32)); -- ---------------------------------------------------------------- @@ -71,7 +71,7 @@ CREATE TABLE test_qiundgkm (v1 hll(11, 8)); -- Range Check expthresh -- ---------------------------------------------------------------- --- ERROR: expthresh modifier must be between -1 and 2^32 +-- ERROR: expthresh modifier must be between -1 and 16383 CREATE TABLE test_qiundgkm (v1 hll(11, 5, -2)); CREATE TABLE test_qiundgkm (v1 hll(11, 5, -1)); @@ -90,7 +90,7 @@ CREATE TABLE test_qiundgkm (v1 hll(11, 5, 4294967296)); \d test_qiundgkm DROP TABLE test_qiundgkm; --- ERROR: expthresh modifier must be between -1 and 2^32 +-- ERROR: expthresh modifier must be between -1 and 16383 CREATE TABLE test_qiundgkm (v1 hll(11, 5, 8589934592)); -- ---------------------------------------------------------------- diff --git a/src/hll.c b/src/hll.c index d800b47..f194293 100644 --- a/src/hll.c +++ b/src/hll.c @@ -586,6 +586,30 @@ typedef struct } bitstream_read_cursor_t; + +/* + * The result of mse_nelem_max()/msc_regs_idx_limit() is a const in a specific platform. + * But we couldn't hard code it explicitly because we do not know current alignment schema + * when compiling it. + */ +static size_t +mse_nelem_max(void) +{ + multiset_t *msp = NULL; /* Safely! */ + uint8_t *ms_data_start = (uint8_t*)(&msp->ms_data); + uint8_t *ms_data_end = ms_data_start + sizeof(msp->ms_data); + uint8_t *mse_elems_start = (uint8_t*)(&msp->ms_data.as_expl.mse_elems); + return ((size_t)(ms_data_end - mse_elems_start)) / sizeof(uint64_t); +} + +static size_t +msc_regs_idx_limit(void) +{ + multiset_t * o_msp = NULL; + uint8_t * const ms_data_limit = ((uint8_t*)&o_msp->ms_data) + sizeof(o_msp->ms_data); + return (ms_data_limit - (uint8_t*)&o_msp->ms_data.as_comp.msc_regs[0]) / sizeof(compreg_t); +} + static uint32_t bitstream_unpack(bitstream_read_cursor_t * brcp) { @@ -935,6 +959,8 @@ compressed_add(multiset_t * o_msp, uint64_t elem) size_t p_w = ss_val == 0 ? 0 : __builtin_ctzll(ss_val) + 1; + Assert(ndx < msc_regs_idx_limit()); + if (p_w > maxregval) p_w = maxregval; @@ -1170,6 +1196,7 @@ multiset_add(multiset_t * o_msp, uint64_t element) size_t expval = expthresh_value(o_msp->ms_expthresh, o_msp->ms_nbits, o_msp->ms_nregs); + Assert(expval <= mse_nelem_max()); switch (o_msp->ms_type) { @@ -1389,7 +1416,7 @@ multiset_unpack(multiset_t * o_msp, } // Make sure the explicit array fits in memory. - if ((i_size - hdrsz) > MS_MAXDATA) + if (nelem > mse_nelem_max()) { ereport(ERROR, (errcode(ERRCODE_DATA_EXCEPTION), @@ -1993,21 +2020,24 @@ hll_hashval_int4(PG_FUNCTION_ARGS) static void check_modifiers(int32 log2m, int32 regwidth, int64 expthresh, int32 sparseon) { + int64 expthresh_max = mse_nelem_max(); + int32 log2m_max = integer_log2(msc_regs_idx_limit()); /* const expression. */ + // Range check each of the modifiers. - if (log2m < 0 || log2m > MAX_BITVAL(LOG2M_BITS)) + if (log2m < 0 || log2m > log2m_max) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("log2m modifier must be between 0 and 31"))); + errmsg("log2m modifier must be between 0 and %d", log2m_max))); if (regwidth < 0 || regwidth > MAX_BITVAL(REGWIDTH_BITS)) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("regwidth modifier must be between 0 and 7"))); - if (expthresh < -1 || expthresh > 4294967296LL) + if (expthresh < -1 || expthresh > expthresh_max) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("expthresh modifier must be between -1 and 2^32"))); + errmsg("expthresh modifier must be between -1 and %ld", expthresh_max))); if (expthresh > 0 && (1LL << integer_log2(expthresh)) != expthresh) ereport(ERROR,