On Mon, Nov 29, 2021 at 2:10 AM Andy Fan <zhihui.fan1213@gmail.com> wrote:
> 1. During the ExecutorRun & ExecutorEnd, the relcache will never by invalidated, if not
> the old relation->balabala will be lost. I assume this is correct since I didn't see any places
> where we handle such changes in Executor code.
It's not correct. We accept invalidation messages in a number of
different code paths, including whenever we acquire a lock on a
relation. That doesn't typically happen in the middle of a query, but
that's just because most queries don't happen to do anything that
would make it happen. They can, though.
Thanks for looking into this question.
Actually I think this would not happen. My reasons are:
1. I think the case which would cause the relcache reset needs a lock, after
the executor start, the executor lock is acquired so on one can really have chances
to send an invalidation message until the lock is released. (let me first ignore the 2
examples you talked about, and I will talk about it later).
2. _If_ the relation can be reset after we open it during Executor code, then would the
relation (RelationData *) pointed memory still validated after the relcache reset? For example
CREATE TABLE t(a int);
INSERT INTO t VALUES(1), (2);
UPDATE t set a = 100;
We need to update 2 tuples in the update statement, if the relcache is reset, can we still use the previous
(RelationData *) to do the following update? If not, what code is used to change the relation for the old relcache
address to the new relcache. I assumed (RelationData *) pointer. to the relcache directly, hope this is correct..
For example, the query can
call a user-defined function that accesses a table not previously
touched by the transaction. Or a built-in function that does the same
thing, like table_to_xml().
OK, this is something I missed before. but looks it would not caused different _in my case_;
IIUC, you are describing the thing like this:
CREATE FUNCTION udf()
...
SELECT * FROM t2;
$$;
SELECT udf() FROM t1;
then the relation t2 will not be opened at the beginning of ExecutorRun and it will be only opened
when we fetch the first tuple from t1; so we can have cache invalidation between ExecutorRun and
the first call of udf.
But in my case, my exception should be that the relcache should not be invalidated _after the first relation open_
in the executor (not the beginning of executorRun), this is something I didn't describe well when I post
my message since I didn't find out this situation at that time.