一、概述
联接执行通过嵌套循环算法来实现,可以支持内联接,外联接两种操作,自然联接可以用前两种来代替。
二、嵌套循环框架
联接执行算子的函数定义如下,它由嵌套循环方式来实现,整体包含两层无限循环,每次联接都会包含外表和内表两个数据源表。
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineNode* ExecNestLoop(Node *planNode){/* outer */for( ; ; ){/* inner */for( ; ; ){}}return NULL;}
两层循环都是无限循环,何时才能跳出循环呢?
对于外表,当作为外表的数据源表到达了结尾时,外层循环就会结束,也就意味着当前联接执行完成。 对于内表来说,它的退出条件有两个, 一是作为内表的数据源表达到了结尾; 二是内表的查询结果符合联接条件,此时就会将外表和内表查询结果返回给上层。
三、外表处理
当needOuter标志为1时,会执行左子节点的执行函数,获取查询结果。
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineif(nlNode->needOuter){lresult = ExecNodeProc(nlNode->leftplan);if(lresult == NULL){break;}nlNode->lresult = lresult;nlNode->needOuter = 0;nlNode->outerOnce = 0;ExecReSeqScan(nlNode->rightplan);}elselresult = nlNode->lresult;
外表的处理主要有:
当需要新的外表查询结果时,从左子节点获取查询结果; 将查询结果记录到当前执行节点当中; 每当外表获取新结果后,重置内表的扫描信息; 当不需要外表的查询结果时,将记录到执行节点中的外表查询记录取出。
四、内表处理
当外表获得新的查询结果之后,就开始内表的处理。
内表的处理主要有两大部分:
一是获取内表的查询结果; 二是执行联接表达式过滤。
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(linerresult = ExecNodeProc(nlNode->rightplan);if(rresult == NULL){break;}nlNode->rresult = rresult;
当从右子节点获取到查询结果后,将它记录到联接节点当中;
如果右子节点查询结果为空时,说明内表已经到了结尾,退出内表的循环,并将需要外表查询标志置为1。
ounter(linenlNode->needOuter = 1;
在进行联接表达计算之前,需要将左右子节点的查询结果存入到结果列表中当,并传递给表达式计算函数。
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineresultList = (List*)MergeResult(lresult, rresult);isJunk = ExecJoinExpr(nlNode, (Node*)resultList);if(isJunk){return (Node*)resultList;}
根据表达式计算结果,当结果为真时,返回当前结果集作为联接查询结果。
五、总结
本节内容实现位于exam_52目录下的excutor.c文件中。
文章转载自开源无限,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




