Thread: BUG #18705: Segmentation fault when create brin index on user-defined type.

BUG #18705: Segmentation fault when create brin index on user-defined type.

From
PG Bug reporting form
Date:
The following bug has been logged on the website:

Bug reference:      18705
Logged by:          shenzheng
Email address:      503699317@qq.com
PostgreSQL version: 15.5
Operating system:   centos
Description:

create table t_sva(sva text);
insert into t_sva values( 1118090878 );
insert into t_sva values( 2345010477 );
create or replace function normalize_si(text) RETURNS text AS $$ BEGIN
RETURN
substring($1,9,2) || substring($1,7,2) || substring($1,5,2) ||
substring($1,1,4);
END;$$ LANGUAGE plpgsql IMMUTABLE;
create or replace function si_lt(text,text) RETURNS boolean AS $$ BEGIN
RETURN
normalize_si($1) < normalize_si($2);
END;$$ LANGUAGE plpgsql IMMUTABLE;
create or replace function si_le(text,text) RETURNS boolean AS $$ BEGIN
RETURN
normalize_si($1) <= normalize_si($2);
END;$$ LANGUAGE plpgsql IMMUTABLE;
create or replace function si_ge(text,text) RETURNS boolean AS $$ BEGIN
RETURN
normalize_si($1) >= normalize_si($2);
END;$$ LANGUAGE plpgsql IMMUTABLE;
create or replace function si_gt(text,text) RETURNS boolean AS $$ BEGIN
RETURN
normalize_si($1) > normalize_si($2);
END;$$ LANGUAGE plpgsql IMMUTABLE;
create operator <# (PROCEDURE = si_lt, LEFTARG=text, RIGHTARG=text);
create operator <=# (PROCEDURE = si_le, LEFTARG=text, RIGHTARG=text);
create operator >=# (PROCEDURE = si_ge, LEFTARG=text, RIGHTARG=text);
create operator ># (PROCEDURE = si_gt, LEFTARG=text, RIGHTARG=text);
create or replace function si_same(text,text) RETURNS int AS $$ BEGIN IF
normalize_si($1) < normalize_si($2) THEN RETURN -1;
ELSIF normalize_si($1) > normalize_si($2) THEN RETURN +1;
ELSE RETURN 0;
END IF;
END; $$ LANGUAGE plpgsql IMMUTABLE;
CREATE OPERATOR CLASS sva_special_ops FOR TYPE text using brin AS OPERATOR 1
<#,
OPERATOR 2 <=#, OPERATOR 3 >=#, OPERATOR 4 >#, function 1
si_same(text,text);
CREATE INDEX idx_special1 ON t_sva using brin(sva sva_special_ops);


OUTPUT:
postgres=# CREATE INDEX idx_special1 ON t_sva using brin(sva
sva_special_ops);
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
The connection to the server was lost. Attempting reset: Failed.
!?>
!?>


On 11/14/24 03:40, PG Bug reporting form wrote:
> ...
>
> CREATE OPERATOR CLASS sva_special_ops FOR TYPE text using brin AS OPERATOR 1
> <#,
> OPERATOR 2 <=#, OPERATOR 3 >=#, OPERATOR 4 >#, function 1
> si_same(text,text);
> CREATE INDEX idx_special1 ON t_sva using brin(sva sva_special_ops);
> 

I think this is a bit confused about CREATE OPERATOR CLASS. For BRIN
indexes this expects these 4 functions:

Support Function 1     internal function brin_minmax_opcinfo()
Support Function 2     internal function brin_minmax_add_value()
Support Function 3     internal function brin_minmax_consistent()
Support Function 4     internal function brin_minmax_union()

No wonder it crashes if CREATE OPERATOR CLASS passes si_same() instead
of brin_minmax_opcinfo.

The operators seem a bit off too, because there's no 'equality'
operator, and if I add '=#' as equality operator, then this seems to
work for me:

CREATE OPERATOR CLASS sva_special_ops FOR TYPE text using brin AS
  FUNCTION 1 brin_minmax_opcinfo(internal),
  FUNCTION 2 brin_minmax_add_value(internal, internal, internal, internal),
  FUNCTION 3 brin_minmax_consistent(internal, internal, internal),
  FUNCTION 4 brin_minmax_union(internal, internal, internal),
  OPERATOR 1 <#,
  OPERATOR 2 <=#,
  OPERATOR 3 =#,
  OPERATOR 4 >=#,
  OPERATOR 5 >#;



regards

-- 
Tomas Vondra






Tomas Vondra <tomas@vondra.me> 于2024年11月14日周四 21:48写道:
On 11/14/24 03:40, PG Bug reporting form wrote:
> ...
>
> CREATE OPERATOR CLASS sva_special_ops FOR TYPE text using brin AS OPERATOR 1
> <#,
> OPERATOR 2 <=#, OPERATOR 3 >=#, OPERATOR 4 >#, function 1
> si_same(text,text);
> CREATE INDEX idx_special1 ON t_sva using brin(sva sva_special_ops);
>

I think this is a bit confused about CREATE OPERATOR CLASS. For BRIN
indexes this expects these 4 functions:

Support Function 1      internal function brin_minmax_opcinfo()
Support Function 2      internal function brin_minmax_add_value()
Support Function 3      internal function brin_minmax_consistent()
Support Function 4      internal function brin_minmax_union()

No wonder it crashes if CREATE OPERATOR CLASS passes si_same() instead
of brin_minmax_opcinfo.

Can we report errors not crash if users pass an unexpected function?


--
Thanks,
Tender Wang

On 11/15/24 07:17, Tender Wang wrote:
> 
> 
> Tomas Vondra <tomas@vondra.me <mailto:tomas@vondra.me>> 于2024年11月14日
> 周四 21:48写道:
> 
>     On 11/14/24 03:40, PG Bug reporting form wrote:
>     > ...
>     >
>     > CREATE OPERATOR CLASS sva_special_ops FOR TYPE text using brin AS
>     OPERATOR 1
>     > <#,
>     > OPERATOR 2 <=#, OPERATOR 3 >=#, OPERATOR 4 >#, function 1
>     > si_same(text,text);
>     > CREATE INDEX idx_special1 ON t_sva using brin(sva sva_special_ops);
>     >
> 
>     I think this is a bit confused about CREATE OPERATOR CLASS. For BRIN
>     indexes this expects these 4 functions:
> 
>     Support Function 1      internal function brin_minmax_opcinfo()
>     Support Function 2      internal function brin_minmax_add_value()
>     Support Function 3      internal function brin_minmax_consistent()
>     Support Function 4      internal function brin_minmax_union()
> 
>     No wonder it crashes if CREATE OPERATOR CLASS passes si_same() instead
>     of brin_minmax_opcinfo.
> 
> 
> Can we report errors not crash if users pass an unexpected function?
> 

I think it might be improved to do some checks, yes. The CREATE OPERATOR
CLASS should be able to signatures of the functions - it's AM-specific,
and there's a limit how much can be checked. For example these functions
have "internal" arguments, which can be an arbitrary pointer.

That being said, I'm not aware of anyone working on such checks. Might
be a nice first patch, though.


regards

-- 
Tomas Vondra




Tomas Vondra <tomas@vondra.me> writes:
> On 11/15/24 07:17, Tender Wang wrote:
>> Can we report errors not crash if users pass an unexpected function?

Read up on the halting problem.

> I think it might be improved to do some checks, yes. The CREATE OPERATOR
> CLASS should be able to signatures of the functions - it's AM-specific,
> and there's a limit how much can be checked. For example these functions
> have "internal" arguments, which can be an arbitrary pointer.

We already have amvalidate, which would certainly have caught anything
as egregiously wrong as this example.  I do not remember why that's
not a forced step of CREATE OPERATOR CLASS, but I'm sure there
was a good reason for making it separate.

            regards, tom lane