Thread: Analyze plan of foreign data wrapper
Hello!
I'am writing a foreign data wrapper. To avoid returning data for a column that is not used, I parse 'targetlist' and 'qual' of the Plan.
I'am able to find Var nodes but I can't figure out how i could now if this node is related to a column my foreign table.
I guess that the field 'location' is the solution but I don't understand how to use it to retrieve target table oid and column index.
I hope someone could help me.
Thanks in advance
Mathieu PUJOL
Backend Leader
Tel : 05.81.33.13.36
REAL FUSIO - 3D Computer Graphics
3 rue Dieudonné Costes 31700 Blagnac
mathieu.pujol@realfusio.com - http://www.realfusio.com
Tel : 05.81.33.13.36
REAL FUSIO - 3D Computer Graphics
3 rue Dieudonné Costes 31700 Blagnac
mathieu.pujol@realfusio.com - http://www.realfusio.com
Mathieu PUJOL wrote: > I'am writing a foreign data wrapper. To avoid returning data for a column that is not used, I parse 'targetlist' and 'qual'of the Plan. > I'am able to find Var nodes but I can't figure out how i could now if this node is related to a column my foreign table. For a Var v, v->varattno contains the attribute number of the column. That is the same as the attnum column in pg_attribute. If v->varattno == 0, it is a whole-row reference, like in SELECT mytab FROM mytab; Yours, Laurenz Albe -- Cybertec | https://www.cybertec-postgresql.com
Hi,
I understand that I should also use varno to check which table is referenced by varattno. In case of Join, aggregation, etc. Sometimes I get a number or INNER_VAR or OUTER_VAR.
I am lost on how i could resolve this.
I understand that OUTER_VAR/INNER_VAR are related to joins sub plans. Is outer related to left plan and inner to right plan ? In this case varattno is index of target list of subplan ?
When varno is an index how to retrieve table info ?
Regards
Mathieu
Le jeu. 28 juin 2018 à 23:17, Laurenz Albe <laurenz.albe@cybertec.at> a écrit :
Mathieu PUJOL wrote:
> I'am writing a foreign data wrapper. To avoid returning data for a column that is not used, I parse 'targetlist' and 'qual' of the Plan.
> I'am able to find Var nodes but I can't figure out how i could now if this node is related to a column my foreign table.
For a Var v, v->varattno contains the attribute number of the column.
That is the same as the attnum column in pg_attribute.
If v->varattno == 0, it is a whole-row reference, like in
SELECT mytab FROM mytab;
Yours,
Laurenz Albe
--
Cybertec | https://www.cybertec-postgresql.com
Mathieu PUJOL wrote: > I understand that I should also use varno to check which table is referenced by varattno. In case of Join, aggregation,etc. Sometimes I get a number or INNER_VAR or OUTER_VAR. > I am lost on how i could resolve this. > I understand that OUTER_VAR/INNER_VAR are related to joins sub plans. Is outer related to left plan and inner to rightplan ? In this case varattno is index of target list of subplan ? > When varno is an index how to retrieve table info ? I have no deep understanding of these things. Maybe the following comment from include/nodes/primnodes.h can help: /* * Var - expression node representing a variable (ie, a table column) * * Note: during parsing/planning, varnoold/varoattno are always just copies * of varno/varattno. At the tail end of planning, Var nodes appearing in * upper-level plan nodes are reassigned to point to the outputs of their * subplans; for example, in a join node varno becomes INNER_VAR or OUTER_VAR * and varattno becomes the index of the proper element of that subplan's * target list. Similarly, INDEX_VAR is used to identify Vars that reference * an index column rather than a heap column. (In ForeignScan and CustomScan * plan nodes, INDEX_VAR is abused to signify references to columns of a * custom scan tuple type.) In all these cases, varnoold/varoattno hold the * original values. The code doesn't really need varnoold/varoattno, but they * are very useful for debugging and interpreting completed plans, so we keep * them around. */ #define INNER_VAR 65000 /* reference to inner subplan */ #define OUTER_VAR 65001 /* reference to outer subplan */ #define INDEX_VAR 65002 /* reference to index column */ #define IS_SPECIAL_VARNO(varno) ((varno) >= INNER_VAR) Yours, Laurenz Albe -- Cybertec | https://www.cybertec-postgresql.com
I read it many times but I'am not entirely familiar with concepts of range table and I'am not sure to fully understant all implications.
For now I have a workaround by parsing only plan's target list and by checking if resorigtbl is equal to oid of my table. The main drawback is that I can't detect column if it is used in a function or an aggregator.
Thanks anyway for your help.
Le mar. 3 juil. 2018 à 12:38, Laurenz Albe <laurenz.albe@cybertec.at> a écrit :
Mathieu PUJOL wrote:
> I understand that I should also use varno to check which table is referenced by varattno. In case of Join, aggregation, etc. Sometimes I get a number or INNER_VAR or OUTER_VAR.
> I am lost on how i could resolve this.
> I understand that OUTER_VAR/INNER_VAR are related to joins sub plans. Is outer related to left plan and inner to right plan ? In this case varattno is index of target list of subplan ?
> When varno is an index how to retrieve table info ?
I have no deep understanding of these things.
Maybe the following comment from include/nodes/primnodes.h can help:
/*
* Var - expression node representing a variable (ie, a table column)
*
* Note: during parsing/planning, varnoold/varoattno are always just copies
* of varno/varattno. At the tail end of planning, Var nodes appearing in
* upper-level plan nodes are reassigned to point to the outputs of their
* subplans; for example, in a join node varno becomes INNER_VAR or OUTER_VAR
* and varattno becomes the index of the proper element of that subplan's
* target list. Similarly, INDEX_VAR is used to identify Vars that reference
* an index column rather than a heap column. (In ForeignScan and CustomScan
* plan nodes, INDEX_VAR is abused to signify references to columns of a
* custom scan tuple type.) In all these cases, varnoold/varoattno hold the
* original values. The code doesn't really need varnoold/varoattno, but they
* are very useful for debugging and interpreting completed plans, so we keep
* them around.
*/
#define INNER_VAR 65000 /* reference to inner subplan */
#define OUTER_VAR 65001 /* reference to outer subplan */
#define INDEX_VAR 65002 /* reference to index column */
#define IS_SPECIAL_VARNO(varno) ((varno) >= INNER_VAR)
Yours,
Laurenz Albe
--
Cybertec | https://www.cybertec-postgresql.com