Skip to content

Syntax error on attempt to create hash group index on list of expressions #3981

Open
@bllewell

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

No one assigned

    Labels

    Type

    No type

    Projects

    • Status

      No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions