mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 02:51:58 +00:00
db91c9eaf6
上一轮给派生来源(CTE、FROM 里的子查询)只编了位置编号,编号错开时再按不写编号的写法(派生来源一律写「@」)补配一遍。复验发现三处问题,根因相同:派生来源没有结构上的标识。一是漏报:两个 CTE 都算出 total(付款合计、退款合计),编号一致时 SUM(p.total) 对 SUM(r.total)、WHERE p.total > 100 对 r.total > 100、ORDER BY、HAVING、差值写反,都被补配吞掉、返回空列表。二是误报:盲算多一个排在前面的 CTE(vip),原流程的 t(@1)按编号配给了盲算的 vip(@1),报出「关联 t 表的条件是 orders.user_id = users.id,盲算是 users.id = users.id」「盲算关联了 t 表」。三是误报:内连接换了先后(FROM paid JOIN refunded 换成 FROM refunded JOIN paid),编号跟着对调,比较的两边按编号排成两个方向,报出两条自相矛盾的话。 现在 diff_facets 先给两边每个派生来源算一份结构标识(_Derived):里面读到的实表(FROM / JOIN,往里套着的也算)、选出来的各列规范化后的定义式(total 是 SUM(orders.amount))、分组键、里面的条件、整段规范化后的写法和起的名字;按从严到宽几级一对一地配:整段一样,表和各列定义、分组一样,表和列名一样,表和名字一样,最后三级只在两边各剩一个时才配(只是表一样、只是名字一样、只是列名一样);同一级几对都配得上时先配同名的、再配条件重合多的、最后看先后,哪一级都配不上的不配,没用到的 CTE 也参加配对。配好之后第二条 SQL 的派生来源改用第一条里对应的编号(配不上的另起编号),facets 记下原文(Facets._origin,不进比较和 as_dict),按共同的编号重新分析一遍再比:比较两边谁在前、关联条件的先后都按共同编号排,不再受位置编号左右。_Compare 去掉了不写编号的补配(删掉 Part.anon),loose 里派生来源的编号照写,筛选按同一列配对时列也带编号。 连接:内连接、CROSS JOIN 按涉及的来源和条件比(JoinFacet.sides),不按哪一侧是关联进来的,实表的内连接换了先后也不再报;配成一对的两边名字不同时两个名字都说;一边独有的内连接、关联进来的那一侧另一边也有时,报它接上的另一头(FROM stores JOIN orders、另一边只查 orders:多出来的是 stores,不是 orders;Facets.sources 记各段 FROM / JOIN 的来源拿来对照,条件里子查询的来源不算),已经说了「关联了」的表不再另说一遍「用到了」。取行:CTE、子查询里的取行按所属派生来源配好的编号(LimitFacet.scope_key)配对,一边多一个限了行数的 CTE 不再和另一边的 CTE 凑对;LATERAL 子查询照写它的别名。筛选、HAVING:两边各自独有、读起来却一样的条件(p.total > 100 和 r.total > 100 都只读得出 total > 100)配成一对、改用带来源名字的写法说,不再各说一句。 模块说明、Part / JoinFacet / LimitFacet / Facets、unmatched、joins 的文档按现在的做法改写,做不到的照实列出(外层按名字引用的列两边起名不同算两列;读同一张表、各列定义一样的两个派生来源两边都改了条件又改了名时可能配反;全换了的两个派生来源不配对;自连接分不出两个别名;LEFT JOIN 对调成 RIGHT JOIN、内连接的单表条件写在 ON 还是 WHERE、三张以上不带条件的表换先后仍算不同)。测试补上三处问题的反例(CTE、FROM 子查询、改名又改先后的写法)和上面各项,原有 99 项照旧通过。