更新时间:2026-07-28 GMT+08:00
分享

DSL规则示例与说明

本章节内容为DSL规则匹配的示例与说明,执行结果不为实际执行结果。

规则示例场景描述

  • 简要描述:两个包含Count聚集函数的表达式子链接进行等值比较时,如果其中一个子链接可以表示为另一个子链接的子结构,且过滤条件仅相差一个EXISTS子链接条件时,可以对其进行优化。因为在此场景下,实际是想找到EXISTS条件返回FALSE的情况,在这种情况下两个count值是否相等取决于其他条件是否为TRUE。当其他条件为TRUE时,根据AND条件的语义,两个子链接的过滤条件相反,count()取值一定不同;否则取值相同。因此,对于这种场景可以使用NOT EXISTS等价改写消减子链接的数量。
  • SQL示例:
    改写前:
    SELECT t1.a,
        t1.b
    FROM table1 as t1,
        table2 as t2
    WHERE t1.a = t2.a
        AND t1.b = t1.b
        AND (
            SELECT COUNT(*)
            FROM table1 as t11
            WHERE t11.a = t1.a
                AND t11.b = t1.b
        ) = (
            SELECT COUNT(*)
            FROM table1 as t21
            WHERE t21.a = t1.a
                AND t21.b = t1.b
                AND EXISTS(
                    SELECT 1
                    FROM t3
                    WHERE t1.a = t3.a
                )
        );
    改写后:
    SELECT t1.a,
        t1.b
    FROM table1 as t1,
        table2 as t2
    WHERE t1.a = t2.a
        AND t1.b = t1.b
        AND NOT EXISTS (
            SELECT 1
            FROM table1 as t11
            WHERE t11.a = t1.a
                AND t11.b = t1.b
                AND NOT EXISTS(
                    SELECT 1
                    FROM t3
                    WHERE t1.a = t3.a
                )
        );

规则示例场景DSL规则

QUERY <> {
    FILTER: $exprs: * &&
                    (AND<>{
                        ARGS: $and_exp: * && ($eq_expr: OPERATOR<EQ>{
                            LEFT: SUBLINK<EXPRSUBLINK>{
                                QUERY: $ori_query: QUERY<>{
                                PROJECT: $proj1: AGG<COUNT>{ARGS: $agg_args1: *}
                                FROM: $input1: * && ($sub_l_t: (find_tables $input1 ALL))
                                FILTER: $FILTER1 : * && (AND<> {ARGS: $f_1 : * && (OPERATOR<EQ>{
                                    LEFT:$f_1_l : *
                                    RIGHT:$f_1_r : *
                                    CONSTRAINTS: ((check_has_constraint $f_1_l UPPERVAR) 
                                        && !(check_has_constraint $f_1_r UPPERVAR)) ||
                                        (!(check_has_constraint $f_1_l UPPERVAR) 
                                        && (check_has_constraint $f_1_r UPPERVAR)) &&
                                        !(check_has_constraint THIS MODIFYCTE | VOLATILE)
                                    })})
                                GROUP: GROUP<> {
                                    GROUP: $gr1: * && ($att_list: (find_attributes $gr1 THIS))
                                    FILTER: $h_c1: *
                                    GROUPSET: $gr_s1: *
                                    }
                                SORT: $s1 : *
                                        }
                                        }
                            RIGHT: SUBLINK<EXPRSUBLINK>{
                                QUERY: QUERY<>{
                                    PROJECT: $proj2 : AGG<COUNT>{ARGS: $agg_args2: *}
                                    FROM: $input2: * && ($sub_r_t: (find_tables $input2 ALL))
                                    FILTER: $FILTER2 : * && (AND<> {ARGS: $f_2 : *
                                            && ($orther_f: SUBLINK<existssublink>{QUERY: $ssub_query: *})})
                                        && ($same_set : (find_expr_without $f_2 $orther_f))
                                    GROUP: GROUP<> {
                                        GROUP: $gr2: *
                                        FILTER: $h_c2: *
                                        GROUPSET: $gr_s2: *
                                    }
                                    SORT: $s2 : *
                                    CONSTRAINTS: (check_is_equal $same_set $f_1) 
                                        && (check_is_equal $gr1 $gr2)
                                        && (check_is_equal $h_c1 $h_c2) && (check_is_equal $gr_s1 $gr_s2)
                                        && (check_is_equal $s1 $s2) 
                                        && (((check_type_foreach $proj1 COUNT_STAR) 
                                        && (check_type_foreach $proj2 COUNT_STAR)) ||
                                        ((check_type_foreach (expr_compute $agg_args1) CONST) 
                                        && (check_type_foreach (expr_compute $agg_args2) CONST)) ||
                                        ((check_type_foreach $agg_args1 COL) 
                                        && (check_type_foreach $agg_args2 COL) 
                                        && (check_is_equal $agg_args1 $agg_args2)))
                                        && !(check_has_constraint THIS MODIFYCTE | VOLATILE)
                                }
                            }
                            IGNORESIDE:true
                        })
                    }) && ($orther_expr: (find_expr_without $and_exp $eq_expr))
    CONSTRAINTS: (check_has_constraint ROOT SUBLINK) &&
                (check_type_foreach $exprs AND) 
                && (check_type_foreach $FILTER1 AND) && (check_type_foreach $FILTER2 AND) &&
                (check_is_same_table $sub_l_t $sub_r_t) 
                && !(check_has_constraint ROOT MODIFYCTE | VOLATILE)
}
=>
QUERY <> {
    FILTER: (append $orther_expr NOT<>{
            ARGS: SUBLINK<existsSUBLINK>{
                    QUERY: QUERY<SELECT>{
                        PROJECT: CONST<INTEGER>{ARGS:1}
                        FROM: (build_fromexpr_by_query $ori_query $input1)
                        FILTER: AND <> { ARGS : (append $same_set NOT<>{
                                ARGS: $orther_f
                            })
                        }
                        GROUP: GROUP<> {
                        GROUP: (build_group $att_list)
                        FILTER: $h_c1
                        GROUPSET: $gr_s1
                        }
                        SORT: $s1
                        }
                    }
                }
        )
}

规则示例场景DSL规则详细解析

  • 匹配部分:
    • QUERY<>:表示匹配的是默认类型的QUERY,即SELECT类型的QUERY。
    • FILTER<>:表示匹配的是约束条件。
    • ARGS: $exprs: * :表示约束条件的所有内容映射到变量exprs上;&&表示进一步匹配。
    • AND<> :表示仅匹配AND条件。
    • ARGS: $and_exp: *:表示将匹配的AND表达式的所有内容与变量and_expr做映射。ARGS: OPERATOR<EQ>:表示匹配等值表达式。
    • LEFT: SUBLINK<EXPRSUBLINK>、RIGHT: SUBLINK<EXPRSUBLINK>表示等值表达式的左右取值必须是子链接,且子链接中PROJECT: $proj1: AGG<COUNT>{}:表示投影列必须是COUNT()。
    • ((check_has_constraint $f_1_l UPPERVAR) && !(check_has_constraint $f_1_r UPPERVAR)) ||

      (!(check_has_constraint $f_1_l UPPERVAR) && (check_has_constraint $f_1_r UPPERVAR)):约束检查等值表达式一侧包含上层的VAR,即包含相关性条件。

    • GROUP,SORT:匹配子链接中的GROUP及SORT部分。
    • AND<> {ARGS: $f_2 : * && ($orther_f: SUBLINK<EXISTSSUBLINK>{QUERY: $ssub_query: *})}:对于右SUBLINK在约束里的AND条件中存在一个EXISTSSUBLINK。
    • $same_set : (find_expr_without $f_2 $orther_f):表示提取$f_2中排除$orther_f的部分,映射到变量$same_set上。
    • IGNORESIDE:true:表示左右两侧值可以互换进行模板匹配。
    • CONSTRAINTS: (check_is_equal $same_set $f_1):表示两个子链接除右侧子链接的EXISTSSUBLINK外,其余部分都相同。
    • ($orther_expr: (find_expr_without $and_exp $eq_expr)): 同样表示从约束中提取非匹配的部分。
    • (((check_type_foreach $proj1 COUNT_STAR) && (check_type_foreach $proj2 COUNT_STAR)) || ((check_type_foreach (expr_compute $agg_args1) CONST) && (check_type_foreach (expr_compute $agg_args2) CONST)) || ((check_type_foreach $agg_args1 COL) && (check_type_foreach $agg_args2 COL) && (check_is_equal $agg_args1 $agg_args2))):表示左右子链接的count()函数的参数只能为count(*)、count(常量)或count相同的列。
  • 改写部分:
    • QUERY<>和原模板一致。
    • Filter<>和原模板一致。
    • ARGS:表示成员变量;append是内部函数表达将两个表达式组成链表;append $orther_expr NOT<>表示$orther_expr所映射的表达式和NOT后续表示的表达式做组合。
    • ARGS: SUBLINK<EXISTSSUBLINK>: Not下是一个EXISTS子链接。
    • GROUP,SORT:构建子链接的GROUP或SORT部分。
    • QUERY: QUERY<SELECT> 表示子链接的QUERY成员为一个QUERY表达式。
    • PROJECT: CONST<INTEGER>{ARGS:1}:表示投影列为整数1。
    • FROM: (build_from_expr_from_query $ori_query $input1):表示使用函数build_from_expr_from_query构造FROM部分。
    • FILTER: AND <> { ARGS : (append $same_set NOT<>:{ARGS: $orther_f}表示FILTER是AND表达式,表达式内容由append函数将$same_set所映射的表达式与$orther_f映射表达式构造NOT后进行组合。

规则示例执行结果演示

EXPLAIN (costs off)SELECT t1.C, t1.b, t2.b FROM t1, t2 WHERE t1.a = t2.a AND (SELECT COUNT(*) FROM t1 as t11 WHERE t11.a = t1.a AND t11.b = t1.b) = (SELECT COUNT(*) FROM t1 AS t21 WHERE t21.a = t1.a AND t21.b = t1.b AND EXISTS(SELECT 1 FROM t3 WHERE t1.a = t3.a));
NOTICE:  Query with blockname(sel$1) is rewritten by Gs_Rewriter: SELECT t1.c, t1.b, t2.b FROM dsl_exprsublink_elimination.t1, dsl_exprsublink_elimination.t2 WHERE t1.a = t2.a AND NOT (EXISTS (SELECT 1::bigint FROM dsl_exprsublink_elimination.t1 t11 WHERE t11.a = t1.a AND t11.b = t1.b AND NOT (EXISTS (SELECT 1 AS "?column?" FROM dsl_exprsublink_elimination.t3 WHERE t1.a = t3.a)))); with rule_name sublink_compare_elimination
                                                   QUERY PLAN                                                   
----------------------------------------------------------------------------------------------------------------
 Hash Join
   Hash Cond: (t2.a = t1.a), (Expression Flatten Optimized)
   ->  Seq Scan on t2
   ->  Hash
         ->  Merge Anti Join
               Merge Cond: ((t1.a = t11.a) AND (t1.b = t11.b)), (Expression Flatten Optimized)
               Join Filter: (NOT (alternatives: SubPlan 1 or hashed SubPlan 2)), (Expression Flatten Optimized)
               ->  Sort
                     Sort Key: t1.a, t1.b
                     ->  Seq Scan on t1
               ->  Sort
                     Sort Key: t11.a, t11.b
                     ->  Seq Scan on t1 t11
               SubPlan 1
                 ->  Seq Scan on t3
                       Filter: (t1.a = a), (Expression Flatten Optimized)
               SubPlan 2
                 ->  Seq Scan on t3
(18 rows)

相关文档