Skip to content

Enable functional index support#2642

Draft
fulghum wants to merge 2 commits into
mainfrom
fulghum/function_expr_index
Draft

Enable functional index support#2642
fulghum wants to merge 2 commits into
mainfrom
fulghum/function_expr_index

Conversation

@fulghum
Copy link
Copy Markdown
Contributor

@fulghum fulghum commented Apr 25, 2026

Related to #2298

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 25, 2026

Main PR
covering_index_scan_postgres 1345.65/s 1341.76/s -0.3%
index_join_postgres 190.12/s 190.18/s 0.0%
index_join_scan_postgres 198.88/s 199.02/s 0.0%
index_scan_postgres 12.22/s 12.20/s -0.2%
oltp_point_select 2495.85/s 2493.18/s -0.2%
oltp_read_only 1854.32/s 1853.16/s -0.1%
select_random_points 128.87/s 127.85/s -0.8%
select_random_ranges 1078.83/s 1075.42/s -0.4%
table_scan_postgres 11.83/s 11.83/s 0.0%
types_table_scan_postgres 5.46/s 5.40/s -1.1%

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 25, 2026

Main PR
Total 42090 42090
Successful 18017 18034
Failures 24073 24056
Partial Successes1 5372 5382
Main PR
Successful 42.8059% 42.8463%
Failures 57.1941% 57.1537%

${\color{red}Regressions (23)}$

create_table_like

QUERY:          CREATE TABLE ctlt13_inh () INHERITS (ctlt1, ctlt3);
RECEIVED ERROR: invalid column name: !hidden!ctlt3_fnidx!0!0 (errno 1105) (sqlstate HY000)

domain

QUERY:          insert into vc4table values(array['too long']::vc4[]);
RECEIVED ERROR: receiveMessage recovered panic: cannot get base type from: _vc4: goroutine 335244 [running]:
runtime/debug.Stack()
	/opt/hostedtoolcache/go/1.26.2/x64/src/runtime/debug/stack.go:26 +0x5e
github.com/dolthub/doltgresql/server.(*ConnectionHandler).receiveMessage.func1()
	/home/runner/work/doltgresql/doltgresql/server/connection_handler.go:351 +0x4c
panic({0x3bf9020?, 0x205bd7627200?})
	/opt/hostedtoolcache/go/1.26.2/x64/src/runtime/panic.go:860 +0x13a
github.com/dolthub/doltgresql/server/types.(*DoltgresType).ArrayBaseType(0x205b96bd51e0)
	/home/runner/work/doltgresql/doltgresql/server/types/type.go:162 +0x279
github.com/dolthub/doltgresql/server/functions/framework.getCast(0x2005ba7df2330?, 0x7fe7fc3ccfa0?, 0x205b96bd56c0, 0x205b96bd51e0, 0x4ec7ed8)
	/home/runner/work/doltgresql/doltgresql/server/functions/framework/cast.go:277 +0x111
github.com/dolthub/doltgresql/server/functions/framework.GetExplicitCast(0x205b96bd56c0, 0x205b96bd51e0)
	/home/runner/work/doltgresql/doltgresql/server/functions/framework/cast.go:127 +0x45
github.com/dolthub/doltgresql/server/expression.(*ExplicitCast).Eval(0x205ba44b6900, 0x205be139fae0, {0x205bd7627170, 0x1, 0x1})
	/home/runner/work/doltgresql/doltgresql/server/expression/explicit_cast.go:102 +0x2fb
github.com/dolthub/go-mysql-server/sql/rowexec.ProjectRow(0x205be139fae0, {0x205bd7626cf0, 0x1, 0x205ba7df2af0?}, {0x205bd7627170, 0x1, 0x1})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/rel_iters.go:320 +0x2b2
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildValues(0x205b6655e808?, 0x205be139fae0, 0x205bbe8b97d0, {0x0, 0x0, 0x0})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/rel.go:106 +0x12a
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExecNoAnalyze(0x205b664b2460, 0x205ba7df2850?, {0x4f68ed8?, 0x205bbe8b97d0}, {0x0, 0x0, 0x0})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/node_builder.gen.go:274 +0x262c
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExec(0x205b664b2460?, 0x205be139fae0?, {0x4f68ed8, 0x205bbe8b97d0}, {0x0?, 0x0?, 0x0?})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/node_builder.gen.go:36 +0xb8
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildProject(0x205b664b2460, 0x205be139fae0, 0x205bac37e3c0, {0x0, 0x0, 0x0})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/rel.go:317 +0x285
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExecNoAnalyze(0x205b664b2460, 0x2e2c8f2?, {0x4f67ae0?, 0x205bac37e3c0}, {0x0, 0x0, 0x0})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/node_builder.gen.go:252 +0xb09
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExec(0x205b664b2460?, 0x205be139fae0?, {0x4f67ae0, 0x205bac37e3c0}, {0x0?, 0x0?, 0x0?})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/node_builder.gen.go:36 +0xb8
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildInsertInto(0x205b664b2460, 0x205be139fae0, 0x205be24ef180, {0x0, 0x0, 0x0})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/dml.go:52 +0x1aa
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExecNoAnalyze(0x205b664b2460, 0x1?, {0x4f672e8?, 0x205be24ef180}, {0x0, 0x0, 0x0})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/node_builder.gen.go:296 +0x2e2c
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExec(0x205b664b2460?, 0x205be139fae0?, {0x4f672e8, 0x205be24ef180}, {0x0?, 0x0?, 0x0?})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/node_builder.gen.go:36 +0xb8
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).Build(0x205b664b2460, 0x205be139fae0, {0x4f672e8, 0x205be24ef180}, {0x0, 0x0, 0x0})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/builder.go:50 +0xd7
github.com/dolthub/doltgresql/server/node.(*ContextRootFinalizer).BuildRowIter(0xa?, 0x1?, {0x4ef9860?, 0x205b664b2460?}, {0x0?, 0x0?, 0x0?})
	/home/runner/work/doltgresql/doltgresql/server/node/context_root_finalizer.go:65 +0x34
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExecNoAnalyze(0x205b664b2460, 0x252c38e?, {0x4f6aea0?, 0x205bd7627140}, {0x0, 0x0, 0x0})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/node_builder.gen.go:387 +0x3357
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).buildNodeExec(0x205b664b2460?, 0x205be139fae0?, {0x4f6aea0, 0x205bd7627140}, {0x0?, 0x0?, 0x0?})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/node_builder.gen.go:36 +0xb8
github.com/dolthub/go-mysql-server/sql/rowexec.(*BaseBuilder).Build(0x205b664b2460, 0x205be139fae0, {0x4f6aea0, 0x205bd7627140}, {0x0, 0x0, 0x0})
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/sql/rowexec/builder.go:50 +0xd7
github.com/dolthub/go-mysql-server.(*Engine).QueryWithBindings(0x205b66a5e0c0, 0x205be139fae0, {0x205bef16ec00, 0x36}, {0x4f29e98, 0x205b93456000}, 0x0, 0x0)
	/home/runner/go/pkg/mod/github.com/dolthub/go-mysql-server@v0.20.1-0.20260505171600-5a9dda3f04ff/engine.go:385 +0x4aa
github.com/dolthub/doltgresql/server.(*DoltgresHandler).executeQuery(0x205bbf010870?, 0x205bdc7dda70?, {0x205bef16ec00?, 0x2a83620?}, {0x4f29e98?, 0x205b93456000?}, {0x2b4149f?, 0x205ba7df3638?})
	/home/runner/work/doltgresql/doltgresql/server/doltgres_handler.go:438 +0x2b
github.com/dolthub/doltgresql/server.(*DoltgresHandler).doQuery(0x205baedb93c0, {0x4f4c008?, 0x97f36c0?}, 0x205b6655e808?, {0x205bef16ec00, 0x36}, {0x4f29e98, 0x205b93456000}, {0x0, 0x0}, ...)
	/home/runner/work/doltgresql/doltgresql/server/doltgres_handler.go:376 +0x613
github.com/dolthub/doltgresql/server.(*DoltgresHandler).ComQuery(0x205baedb93c0, {0x4f4c008, 0x97f36c0}, 0x205bd6415320, {0x205bef16ec00, 0x36}, {0x4f29e98, 0x205b93456000}, 0x205b684ef7a0)
	/home/runner/work/doltgresql/doltgresql/server/doltgres_handler.go:231 +0x125
github.com/dolthub/doltgresql/server.(*ConnectionHandler).query(0x205baedb9400, {{0x205bef16ec00, 0x36}, {0x4f29e98, 0x205b93456000}, {0x44db968, 0x6}})
	/home/runner/work/doltgresql/doltgresql/server/connection_handler.go:996 +0x235
github.com/dolthub/doltgresql/server.(*ConnectionHandler).handleQuery(0x205baedb9400, 0x205b687d81a0)
	/home/runner/work/doltgresql/doltgresql/server/connection_handler.go:466 +0x22a
github.com/dolthub/doltgresql/server.(*ConnectionHandler).handleMessage(0x205b687d8000?, {0x4f282b8?, 0x205b687d81a0?})
	/home/runner/work/doltgresql/doltgresql/server/connection_handler.go:408 +0x7d
github.com/dolthub/doltgresql/server.(*ConnectionHandler).receiveMessage(0x205baedb9400)
	/home/runner/work/doltgresql/doltgresql/server/connection_handler.go:381 +0x2c5
github.com/dolthub/doltgresql/server.(*ConnectionHandler).HandleConnection(0x205baedb9400)
	/home/runner/work/doltgresql/doltgresql/server/connection_handler.go:186 +0x150
created by github.com/dolthub/doltgresql/server.(*Listener).Accept in goroutine 112
	/home/runner/work/doltgresql/doltgresql/server/listener.go:89 +0x11f

plpgsql

QUERY:          create function f1(x anyelement) returns anyarray as $$
begin
  return array[x + 1, x + 2];
end$$ language plpgsql;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          drop function f1(x anyelement);
RECEIVED ERROR: function f1 does not exist (errno 1105) (sqlstate HY000)
QUERY:          create function f1(x anyarray) returns anyelement as $$
begin
  return x[1];
end$$ language plpgsql;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          drop function f1(x anyarray);
RECEIVED ERROR: function f1 does not exist (errno 1105) (sqlstate HY000)
QUERY:          create function f1(x anyarray) returns anyarray as $$
begin
  return x;
end$$ language plpgsql;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          drop function f1(x anyarray);
RECEIVED ERROR: function f1 does not exist (errno 1105) (sqlstate HY000)
QUERY:          create function duplic(in i anyelement, out j anyelement, out k anyarray) as $$
begin
  j := i;
  k := array[j,j];
  return;
end$$ language plpgsql;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)

polymorphism

QUERY:          create function polyf(x anyelement) returns anyarray as $$
  select array[x + 1, x + 2]
$$ language sql;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          drop function polyf(x anyelement);
RECEIVED ERROR: function polyf does not exist (errno 1105) (sqlstate HY000)
QUERY:          create function polyf(x anyarray) returns anyelement as $$
  select x[1]
$$ language sql;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          drop function polyf(x anyarray);
RECEIVED ERROR: function polyf does not exist (errno 1105) (sqlstate HY000)
QUERY:          create function polyf(x anyarray) returns anyarray as $$
  select x
$$ language sql;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          drop function polyf(x anyarray);
RECEIVED ERROR: function polyf does not exist (errno 1105) (sqlstate HY000)
QUERY:          CREATE FUNCTION stfp(anyarray) RETURNS anyarray AS
'select $1' LANGUAGE SQL;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          CREATE FUNCTION tf1p(anyarray,int) RETURNS anyarray AS
'select $1' LANGUAGE SQL;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          CREATE FUNCTION ffp(anyarray) RETURNS anyarray AS
'select $1' LANGUAGE SQL;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          create function add_group(grp anyarray, ad anyelement, size integer)
  returns anyarray
  as $$
begin
  if grp is null then
    return array[ad];
  end if;
  if array_upper(grp, 1) < size then
    return grp || ad;
  end if;
  return grp;
end;
$$
  language plpgsql immutable;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          create function first_el(anyarray) returns anyelement as
'select $1[1]' language sql strict immutable;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          create function concat(text, variadic anyarray) returns text as $$
  select array_to_string($2, $1);
$$ language sql immutable strict;
RECEIVED ERROR: type "_anyelement" does not exist (errno 1105) (sqlstate HY000)
QUERY:          drop function concat(text, anyarray);
RECEIVED ERROR: function concat does not exist (errno 1105) (sqlstate HY000)

vacuum

QUERY:          INSERT INTO vaccluster VALUES (1), (2);
RECEIVED ERROR: expression does not result in a single value (errno 1105) (sqlstate HY000)

${\color{lightgreen}Progressions (41)}$

alter_table

QUERY: ALTER TABLE tt9 ADD CHECK(c > 2);

collate.icu.utf8

QUERY: CREATE INDEX collate_test1_idx3 ON collate_test1 ((b COLLATE "C"));
QUERY: CREATE INDEX collate_test1_idx4 ON collate_test1 (((b||'foo') COLLATE "POSIX"));

compression

QUERY: CREATE UNIQUE INDEX idx1 ON cmdata2 ((f1 || f2));

create_index

QUERY: CREATE UNIQUE INDEX func_index_index on func_index_heap (textcat(f1,f2));
QUERY: INSERT INTO func_index_heap VALUES('ABCD', 'EF');
QUERY: CREATE UNIQUE INDEX func_index_index on func_index_heap ((f1 || f2) text_ops);
QUERY: INSERT INTO func_index_heap VALUES('ABCD', 'EF');
QUERY: CREATE UNIQUE INDEX concur_reindex_ind3 ON concur_reindex_tab(abs(c1));
QUERY: CREATE UNIQUE INDEX concur_exprs_index_expr
  ON concur_exprs_tab ((c1::text COLLATE "C"));

create_table

QUERY: create index part_column_drop_b_expr on part_column_drop((b = 1));
QUERY: create index part_column_drop_d_expr on part_column_drop((d = 2));

create_table_like

QUERY: CREATE INDEX ctlt1_fnidx ON ctlt1 ((a || b));
QUERY: CREATE INDEX ctlt3_fnidx ON ctlt3 ((a || c));
QUERY: CREATE TABLE inh_error1 () INHERITS (ctlt1, ctlt4);

domain

QUERY: insert into vc4table values(array['too long']);
QUERY: insert into dcomptable values (null);
QUERY: select array[1,2]::orderedpair;

equivclass

QUERY: create unique index ec1_expr1 on ec1((ff + 1));
QUERY: create unique index ec1_expr2 on ec1((ff + 2 + 1));
QUERY: create unique index ec1_expr3 on ec1((ff + 3 + 1));
QUERY: create unique index ec1_expr4 on ec1((ff + 4));

generated

QUERY: CREATE INDEX gtest22c_expr_idx ON gtest22c ((b * 3));

hash_index

QUERY: create unique index hash_f8_index_1 on hash_f8_heap(abs(random));

indexing

QUERY: create index on idxpart1 ((a + 0));
QUERY: create index on idxpart ((a + b));
QUERY: create index on idxpart (abs(b));
QUERY: create index parted_isvalid_idx on parted_isvalid_tab ((a/b));

inherit

QUERY: alter table p2 add check (f2>0);
QUERY: create index matest0i on matest0 ((1-id));
QUERY: create index matest1i on matest1 ((1-id));
QUERY: create index matest3i on matest3 ((1-id));
QUERY: create index on permtest_parent (left(c, 3));

insert_conflict

QUERY: create unique index expr_key_index on insertconflicttest(lower(fruit));
QUERY: create unique index insertconflicti1 on insertconflict(coalesce(a, 0));

plpgsql

QUERY: select f1(stavalues1) from pg_statistic;
QUERY: select f1(stavalues1) from pg_statistic;

polymorphism

QUERY: select polyf(stavalues1) from pg_statistic;
QUERY: select polyf(stavalues1) from pg_statistic;

rangefuncs

QUERY: CREATE FUNCTION bad (f1 int, out f2 anyelement, out f3 anyarray)
AS 'select $1, array[$1,$1]' LANGUAGE sql;

Footnotes

  1. These are tests that we're marking as Successful, however they do not match the expected output in some way. This is due to small differences, such as different wording on the error messages, or the column names being incorrect while the data itself is correct.

@fulghum fulghum force-pushed the fulghum/function_expr_index branch from df4a5d9 to f389aca Compare April 30, 2026 18:59
@fulghum fulghum force-pushed the fulghum/function_expr_index branch from f389aca to 7a25f09 Compare May 11, 2026 19:08
@fulghum fulghum force-pushed the fulghum/function_expr_index branch from 7a25f09 to 3a3e1cd Compare May 11, 2026 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant