Syntax error on attempt to create hash group index on list of expressions #3981
Description
Jira Link: DB-1954
Successful test no. 1
drop table if exists t;
create table t(k int primary key, v1 int, v2 int, doc jsonb);
create index i_classic on t(
(v1, v2) hash
);
Silently succeeds.
Successful test no. 2
create index i_json on t(
(doc->>'a'::text) desc, (doc->>'b'::text) desc
);
Silently succeeds. Notice that this test doesn't need rows in the table.
Failing test no. 3
Simply replace v2
in Test no. 1 withsqrt(v2)
from Test no. 2.
\set VERBOSITY verbose
create index i_bad on t(
(v1, sqrt(v2)) hash
);
Fails with this error:
ERROR: 42809: only column list is allowed
LINE 2: (v1, sqrt(v2)) hash
^
LOCATION: base_yyparse, gram.y:8053
The YB doc doesn't list error codes. The PG doc gives the name of the exception that you use in a PL/pgSQL handler: wrong_object_type
— so pretty non-specific. But the wording of the error can be taken as a literally correct description of the problem: the term "column list" does not include "expression list".
Failing test no. 4
Confirm that this is a parser error — triggered before semantic analysis.
drop table t;
create index i_bad on t(
(v1, sqrt(v2)) hash
);
Causes the same 42809 error.
Consequence
The ultimate business aim was to define the unique business key for:
table t(k... primary key..., doc jsonb)
where k
is a suitably defined surrogate primary key.
create unique index i_bad on t(
((doc->>'a'::text), (doc->>'b'::text)) hash
);
This reflects text-book proper practice coupled with common YB practice to use hash
index.
(You can use ordinary table-level constraints to enforce that each of the JSON expressions is not null.)
"Successful test no. 2" shows that you can meet the goal without specifying hash
.
It would seem that for the minor cost of extending the parser logic, this use case might be met straightforwardly. But do consider this:
create table t(k int primary key, v text);
create index i_bad on t((v::timestamp));
It causes this error:
42P17: functions in index expression must be marked IMMUTABLE
because ::timestamp
has volitility "stable" and not "immutable". I assume that "Successful test no. 2" shows that the proper semantic test for the volatility of JSON expressions is already in place.
Metadata
Assignees
Type
Projects
Status
No status