diff --git a/contrib/ltree/expected/ltree.out b/contrib/ltree/expected/ltree.out index c6d8f3ef75..28c321a4cf 100644 --- a/contrib/ltree/expected/ltree.out +++ b/contrib/ltree/expected/ltree.out @@ -7821,10 +7821,15 @@ SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc; drop index tstidx; create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=0)); ERROR: value 0 out of bounds for option "siglen" -DETAIL: Valid values are between "1" and "2024". +DETAIL: Valid values are between "4" and "2024". create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2025)); ERROR: value 2025 out of bounds for option "siglen" -DETAIL: Valid values are between "1" and "2024". +DETAIL: Valid values are between "4" and "2024". +create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2028)); +ERROR: value 2028 out of bounds for option "siglen" +DETAIL: Valid values are between "4" and "2024". +create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2019)); +ERROR: siglen value must be a multiple of 4 create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2024)); SELECT count(*) FROM ltreetest WHERE t < '12.3'; count diff --git a/contrib/ltree/ltree_gist.c b/contrib/ltree/ltree_gist.c index 36874e9c72..1b893e9645 100644 --- a/contrib/ltree/ltree_gist.c +++ b/contrib/ltree/ltree_gist.c @@ -716,6 +716,18 @@ ltree_consistent(PG_FUNCTION_ARGS) PG_RETURN_BOOL(res); } +static void +ltree_gist_relopts_validator(void *parsed_options, relopt_value *vals, + int nvals) +{ + LtreeGistOptions *options = (LtreeGistOptions *) parsed_options; + + if (options->siglen != INTALIGN(options->siglen)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("siglen value must be a multiple of %d", ALIGNOF_INT))); +} + Datum ltree_gist_options(PG_FUNCTION_ARGS) { @@ -724,8 +736,11 @@ ltree_gist_options(PG_FUNCTION_ARGS) init_local_reloptions(relopts, sizeof(LtreeGistOptions)); add_local_int_reloption(relopts, "siglen", "signature length in bytes", - LTREE_SIGLEN_DEFAULT, 1, LTREE_SIGLEN_MAX, + LTREE_SIGLEN_DEFAULT, + INTALIGN(1), + LTREE_SIGLEN_MAX, offsetof(LtreeGistOptions, siglen)); + register_reloptions_validator(relopts, ltree_gist_relopts_validator); PG_RETURN_VOID(); } diff --git a/contrib/ltree/sql/ltree.sql b/contrib/ltree/sql/ltree.sql index bf733ed17b..2a612e347d 100644 --- a/contrib/ltree/sql/ltree.sql +++ b/contrib/ltree/sql/ltree.sql @@ -325,6 +325,8 @@ SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc; drop index tstidx; create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=0)); create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2025)); +create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2028)); +create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2019)); create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2024)); SELECT count(*) FROM ltreetest WHERE t < '12.3'; diff --git a/doc/src/sgml/ltree.sgml b/doc/src/sgml/ltree.sgml index 508f404ae8..1543432eec 100644 --- a/doc/src/sgml/ltree.sgml +++ b/doc/src/sgml/ltree.sgml @@ -636,7 +636,8 @@ Europe & Russia*@ & !Transportation path labels as a bitmap signature. Its optional integer parameter siglen determines the signature length in bytes. The default signature length is 8 bytes. - Valid values of signature length are between 1 and 2024 bytes. Longer + The length must be a positive multiple of int alignment + (4 bytes on most machines)) up to 2024. Longer signatures lead to a more precise search (scanning a smaller fraction of the index and fewer heap pages), at the cost of a larger index.