Re: BUG #18314: PARALLEL UNSAFE function does not prevent parallel index build - Mailing list pgsql-bugs

From Tender Wang
Subject Re: BUG #18314: PARALLEL UNSAFE function does not prevent parallel index build
Date
Msg-id CAHewXNkSYVYktt0KW8RtfNMDYi4Stn7OJtuTqeo+c3He1xoFXQ@mail.gmail.com
Whole thread Raw
In response to Re: BUG #18314: PARALLEL UNSAFE function does not prevent parallel index build  (Tender Wang <tndrwang@gmail.com>)
Responses Re: BUG #18314: PARALLEL UNSAFE function does not prevent parallel index build
List pgsql-bugs
In pg document, I found this:

Also, a block containing an EXCEPTION clause effectively forms a subtransaction that can be rolled back without affecting the outer transaction.

So it will report error for this case even though we replace PARALLEL UNSAFE with PARALLEL SAFE.

I think if PARALLEL UNSAFE is specified by users,  PG internal should not choose to build index parallel, even if the function is
too simply that can be transform to Const node.

Attached patch will fix Alexander reported issue. I choose pass the raw index expression to is_parallel_safe(). 
The comments of RelationGetIndexExpressions() doesn't say it will return optimized expression. So I add a bool argument to RelationGetIndexExpressions().
I don't decide to write a new function like RelationGetIndexRawExpression. I think the RelationGetIndexExpressions() is enough after adding a bool argument to indicate
whether caller needing a raw index expression.

But if users specify PARALLEL SAFE, like I said before, it also reports error. But I think it is another thing. Maybe it is reasonable?



Tender Wang <tndrwang@gmail.com> 于2024年1月29日周一 22:36写道:
Thanks for reporting this issue.

I debug the process of creating index, and in plan_create_index_workers() func, which use the planner to
decide if use parallel building index.

But the index expression passed to is_parallel_safe() has already simplified by RelationGetIndexExpressions() func.
In this case, FunExpr node will be simplified to Const node. So the check in is_parallel_safe() will return true.

The goal of plan_create_index_workers() is to decide whether it's safe to build index parallelly. I think we just check the raw index
expression no need to simplify the index expression.


PG Bug reporting form <noreply@postgresql.org> 于2024年1月29日周一 19:02写道:
The following bug has been logged on the website:

Bug reference:      18314
Logged by:          Alexander Lakhin
Email address:      exclusion@gmail.com
PostgreSQL version: 16.1
Operating system:   Ubuntu 22.04
Description:       

When planner chooses to perform parallel index build, it doesn't
check whether functions used in an index expression or predicate are
parallel-safe. For example:
CREATE FUNCTION f() RETURNS int IMMUTABLE PARALLEL UNSAFE
AS $$
BEGIN   
    RETURN 0;
EXCEPTION WHEN OTHERS THEN
    RETURN 1;
END$$ LANGUAGE plpgsql;

CREATE TABLE t(i int);
INSERT INTO t SELECT g FROM generate_series(1, 300000) g;
CREATE INDEX ON t((i + f()));

results in:
ERROR:  cannot start subtransactions during a parallel operation
CONTEXT:  PL/pgSQL function f() line 2 during statement block entry
parallel worker

Although with 200000 records, the index created with no error.

Reproduced on REL_12_STABLE .. master.



--
Tender Wang
OpenPie:  https://en.openpie.com/


--
Tender Wang
OpenPie:  https://en.openpie.com/
Attachment

pgsql-bugs by date:

Previous
From: just madhu
Date:
Subject: Re: pgjdbc is not working with PKCS8 certificates with password
Next
From: Ivan Kalafatić
Date:
Subject: Re: BUG #18315: Segmentation fault on connection (repmgr, psql)