You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL:求使j->quals为SubLink/and/not子句的SQL示例及递归必要性

问题背景

以下代码片段来自PostgreSQL 14.4的pull_up_sublinks_qual_recurse()函数:

if ((j = convert_ANY_sublink_to_join(root, sublink,
                                     available_rels1)) != NULL)
{
    /* Yes; insert the new join node into the join tree */
    j->larg = *jtlink1;
    *jtlink1 = (Node *) j;
    /* Recursively process pulled-up jointree nodes */
    j->rarg = pull_up_sublinks_jointree_recurse(root,
                                                j->rarg,
                                                &child_rels);

    /*
     * Now recursively process the pulled-up quals.  Any inserted
     * joins can get stacked onto either j->larg or j->rarg,
     * depending on which rels they reference.
     */
    j->quals = pull_up_sublinks_qual_recurse(root,
                                             j->quals,
                                             &j->larg,
                                             available_rels1,
                                             &j->rarg,
                                             child_rels);
    /* Return NULL representing constant TRUE */
    return NULL;
}

当convert_ANY_sublink_to_join()返回非空值时,pull_up_sublinks_qual_recurse()会递归调用自身,但只有当第二个参数为SubLink、and-clause或not-clause时,该递归调用才会产生有效操作。

我测试了如下SQL查询:

select a 
from A 
where a in (select b from B); 

在这个查询中,convert_ANY_sublink_to_join()返回后,j->quals为OpExpr类型。我找不到能使j->quals成为SubLink、and-clause或not-clause的SQL查询,因此质疑此处的递归调用是否有必要,希望能得到符合条件的SQL示例。

符合条件的SQL示例

通过构造包含逻辑组合、多层嵌套子查询的语句,就能让j->quals成为目标类型,以下是具体示例:

示例1:带AND逻辑的嵌套IN子查询

select a 
from A 
where a in (select b from B where c in (select d from C)) 
  and a > 10;

处理外层IN子查询后,j->quals会是BoolExpr(and-clause类型),包含a > 10条件和未处理的内层SubLink(第二层IN子查询),此时递归调用会继续处理内层SubLink,将其转换为连接节点。

示例2:带NOT的IN子查询

select a 
from A 
where not (a in (select b from B where b < 5));

此时j->quals会是BoolExpr(not-clause类型),包裹着IN子查询对应的表达式,递归调用会处理这个逻辑结构。

示例3:多层嵌套的IN子查询

select a 
from A 
where a in (
    select b 
    from B 
    where b in (select d from C where d > 0)
);

处理外层IN子查询后,j->quals会保留内层的SubLink(第二层IN子查询),递归调用会继续处理这个内层SubLink,完成连接转换。

这些场景下,递归调用会产生实际的处理动作,证明这段代码的必要性。

内容的提问来源于stack exchange,提问作者abigaile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 17:15:19