Re: Can I assume relation would not be invalid during from ExecutorRun to ExecutorEnd - Mailing list pgsql-hackers

From Andy Fan
Subject Re: Can I assume relation would not be invalid during from ExecutorRun to ExecutorEnd
Date
Msg-id CAKU4AWonyG2_5V+vKaD6GETNNDKbKFL=otwWSEA3UXOJ=rS_wQ@mail.gmail.com
Whole thread Raw
In response to Re: Can I assume relation would not be invalid during from ExecutorRun to ExecutorEnd  (Robert Haas <robertmhaas@gmail.com>)
Responses Re: Can I assume relation would not be invalid during from ExecutorRun to ExecutorEnd
List pgsql-hackers


On Mon, Nov 29, 2021 at 10:56 PM Robert Haas <robertmhaas@gmail.com> wrote:
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. 

 
--
Best Regards
Andy Fan

pgsql-hackers by date:

Previous
From: Cary Huang
Date:
Subject: Re: add checkpoint stats of snapshot and mapping files of pg_logical dir
Next
From: Andy Fan
Date:
Subject: Re: Can I assume relation would not be invalid during from ExecutorRun to ExecutorEnd