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?
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.