1.如何查看查询树
第一种方式:修改postgres.conf配置文件中下列参数,之后执行的查询语句的查询树会在日志文件中显示。
debug_print_parse = on # 打印查询树debug_print_rewritten = off # 打印重写之后的查询树
debug_print_plan = off # 打印执行计划debug_pretty_print = on # 结构化方式显示查询树结构
第二种方式:elog_node_dispaly,在gdb的时候调用,或者代码中嵌入之后再编译。比第一种方式好在可以打印多次,对比变化。
if(Debug_print_parse) //debug模式,输出parse tree树
elog_node_display(LOG, "parse tree", root->parse,
Debug_pretty_print);
2. 通过具体sql看查询树
建表:
if(Debug_print_parse) //debug模式,输出parse tree树
elog_node_display(LOG, "parse tree", root->parse,
Debug_pretty_print);
SQL:
SELECT * FROM student LEFT JOIN SCORE ON TRUE LEFT JOIN COURSE ON SCORE.cno = COURSE.cno;
查询树结构:

查询树展开(有的字段没显示):
https://github.com/nullemp/postgres_notes/blob/master/image/sample13.node.jpg
3. 通过查询树认识查询树中的各个节点
RangeTblEntry:描述了查询中出现的表,即FROM子句中的表。
jointree:PG显示指定了两个表的关系,即使用了join关键字,使用JoinExpr来表示连接关系,表示连接关系需要使用表相关信息,需要RangeTblRef。
RangeTblRef:索引RangeTblEntry中表的位置的结构。
FromExpr:表示隐式的连接关系,PG中用逗号连接的两个表,比如下边:
SQL:
SELECT * FROM STUDENT, SCORE LEFT JOIN COURSE ON SCORE.cno = COURSE.cno;

join优先级高于逗号,上图中JOINEXPR表示表2 表3的连接关系,然后在跟表1做内连接。
优化器中子查询提升会对jointree指向的递归结构进行调整,递归的入口是FROMEXPR中的fromlist,出口是RangeTbLRef。
图中还有其它的节点类型,比如TARGETENTRY, VAR,在子连接提升中介绍。