Validate ltree siglen GiST option to be int-aligned
Unaligned siglen could lead to an unaligned access to subsequent key fields. Backpatch to 13, where opclass options were introduced. Reported-by: Alexander Lakhin Bug: 17847 Discussion: https://postgr.es/m/17847-171232970bea406b%40postgresql.org Reviewed-by: Tom Lane, Pavel Borisov, Alexander Lakhin Backpatch-through: 13
This commit is contained in:
parent
02191136cb
commit
48c6825d0e
|
@ -7821,10 +7821,15 @@ SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc;
|
||||||
drop index tstidx;
|
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=0));
|
||||||
ERROR: value 0 out of bounds for option "siglen"
|
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));
|
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2025));
|
||||||
ERROR: value 2025 out of bounds for option "siglen"
|
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));
|
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2024));
|
||||||
SELECT count(*) FROM ltreetest WHERE t < '12.3';
|
SELECT count(*) FROM ltreetest WHERE t < '12.3';
|
||||||
count
|
count
|
||||||
|
|
|
@ -716,6 +716,18 @@ ltree_consistent(PG_FUNCTION_ARGS)
|
||||||
PG_RETURN_BOOL(res);
|
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
|
Datum
|
||||||
ltree_gist_options(PG_FUNCTION_ARGS)
|
ltree_gist_options(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
@ -724,8 +736,11 @@ ltree_gist_options(PG_FUNCTION_ARGS)
|
||||||
init_local_reloptions(relopts, sizeof(LtreeGistOptions));
|
init_local_reloptions(relopts, sizeof(LtreeGistOptions));
|
||||||
add_local_int_reloption(relopts, "siglen",
|
add_local_int_reloption(relopts, "siglen",
|
||||||
"signature length in bytes",
|
"signature length in bytes",
|
||||||
LTREE_SIGLEN_DEFAULT, 1, LTREE_SIGLEN_MAX,
|
LTREE_SIGLEN_DEFAULT,
|
||||||
|
INTALIGN(1),
|
||||||
|
LTREE_SIGLEN_MAX,
|
||||||
offsetof(LtreeGistOptions, siglen));
|
offsetof(LtreeGistOptions, siglen));
|
||||||
|
register_reloptions_validator(relopts, ltree_gist_relopts_validator);
|
||||||
|
|
||||||
PG_RETURN_VOID();
|
PG_RETURN_VOID();
|
||||||
}
|
}
|
||||||
|
|
|
@ -325,6 +325,8 @@ SELECT * FROM ltreetest WHERE t ? '{23.*.1,23.*.2}' order by t asc;
|
||||||
drop index tstidx;
|
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=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=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));
|
create index tstidx on ltreetest using gist (t gist_ltree_ops(siglen=2024));
|
||||||
|
|
||||||
SELECT count(*) FROM ltreetest WHERE t < '12.3';
|
SELECT count(*) FROM ltreetest WHERE t < '12.3';
|
||||||
|
|
|
@ -636,7 +636,8 @@ Europe & Russia*@ & !Transportation
|
||||||
path labels as a bitmap signature. Its optional integer parameter
|
path labels as a bitmap signature. Its optional integer parameter
|
||||||
<literal>siglen</literal> determines the
|
<literal>siglen</literal> determines the
|
||||||
signature length in bytes. The default signature length is 8 bytes.
|
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 <type>int</type> 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
|
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.
|
fewer heap pages), at the cost of a larger index.
|
||||||
</para>
|
</para>
|
||||||
|
|
Loading…
Reference in New Issue