Re: Dimension limit in contrib/cube (dump/restore hazard?)

From: Andrey Borodin <x4mmm(at)yandex-team(dot)ru>
To: Andrew Gierth <andrew(at)tao11(dot)riddles(dot)org(dot)uk>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Dimension limit in contrib/cube (dump/restore hazard?)
Date: 2018-08-28 15:20:41
Message-ID: F0E1A404-A495-4F38-B817-06355B537E88@yandex-team.ru
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi!

> 28 авг. 2018 г., в 8:29, Andrew Gierth <andrew(at)tao11(dot)riddles(dot)org(dot)uk> написал(а):
>
> contrib/cube has an arbitrary limit of 100 on the number of dimensions
> in a cube, but it actually enforces that only in cube_in and
> cube_enlarge, with the other cube creation functions happy to create
> cubes of more dimensions.
>
> I haven't actually tested, but this implies that one can create cubes
> that will break dump/restore.
>
> Should this limit be kept, and if so what should it be? (There's
> obviously a limit on the size of indexable cubes)
>
> (Noticed because an irc user was trying to use cubes with 512
> dimensions with partial success)
+1
This can cause very unpleasant fails like

postgres=# create table y as select cube(array(SELECT random() as a FROM generate_series(1,1000))) from generate_series(1,1e3,1);
SELECT 1000
postgres=# create index on y using gist(cube );
ERROR: index row size 8016 exceeds maximum 8152 for index "y_cube_idx"

postgres=# create table y as select cube(array(SELECT random() as a FROM generate_series(1,800))) from generate_series(1,1e3,1);
SELECT 1000
postgres=# create index on y using gist(cube );
ERROR: failed to add item to index page in "y_cube_idx"

I belive cube construction from array\arrays should check size of arrays.

Also there are some unexpected cube dimensionality reduction like in cube_enlarge
if (n > CUBE_MAX_DIM)
n = CUBE_MAX_DIM;
You wanted larger cube, but got cube of another dimension.

I think we should something like this

diff --git a/contrib/cube/cube.c b/contrib/cube/cube.c
index dfa8465d74..38739b1df2 100644
--- a/contrib/cube/cube.c
+++ b/contrib/cube/cube.c
@@ -151,6 +151,12 @@ cube_a_f8_f8(PG_FUNCTION_ARGS)
errmsg("cannot work with arrays containing NULLs")));

dim = ARRNELEMS(ur);
+ if (dim > CUBE_MAX_DIM)
+ ereport(ERROR,
+ (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
+ errmsg("A cube cannot have more than %d dimensions.",
+ CUBE_MAX_DIM)));
+
if (ARRNELEMS(ll) != dim)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
@@ -208,6 +214,11 @@ cube_a_f8(PG_FUNCTION_ARGS)
errmsg("cannot work with arrays containing NULLs")));

dim = ARRNELEMS(ur);
+ if (dim > CUBE_MAX_DIM)
+ ereport(ERROR,
+ (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
+ errmsg("A cube cannot have more than %d dimensions.",
+ CUBE_MAX_DIM)));

dur = ARRPTR(ur);

Best regards, Andrey Borodin.

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Jonathan S. Katz 2018-08-28 15:21:47 Re: Expression errors with "FOR UPDATE" and postgres_fdw with partition wise join enabled.
Previous Message Jonathan S. Katz 2018-08-28 15:04:41 Re: Something's busted in plpgsql composite-variable handling