Commit Graph

4 Commits

Author SHA1 Message Date
ThearchyHelios d5e9ef39ae SQL 语义复核修正(第 2 轮):CTE、子查询起的名字不再进比较,条件里的子查询选出来的列名也不算;派生来源按位置编号,编号错开时再按不写编号的写法配一遍
上一轮只去掉了条件里子查询的表别名,子查询整段写进外层条件的 key 时还带着各自起的名字:标量子查询、IN 子查询给选出来的列起的名字(AVG(amount) AS avg_amount),子查询里 FROM 的子查询别名(s 换成 agg),以及外层引用 CTE、FROM 里的子查询算出来的列时的来源名(派生来源的 key 就是别名)。CTE 改个名,外层的 total > 100 就被报成两边各有一个、互相矛盾的条件;双盲复算里盲算的名字本来就是自己起的,会被说成换了口径。

现在派生来源(引用 CTE 的表、FROM / JOIN 里的子查询和 LATERAL 子查询)按位置编号作比较用的 key:从外往里一层一层地编,CTE 在第一次用到的地方编号,写成 CTE 还是 FROM 里的子查询、CTE 定义的先后都不影响;给人看的写法照写名字。不拿里面那段查询的写法作 key:里面差一个条件,外层按它的列写的条件就全跟着变,同一处不同会报好几遍。条件里的子查询写进外层 key 时,引用 CTE 的表、子查询(含 LATERAL)、子查询自带的 CTE 定义都换成编号,只看取值的子查询(IN、EXISTS、标量子查询)去掉选出来的列名;FROM 里的子查询、CTE 定义选出来的列名留着,外层按名字引用它们。LATERAL 的别名原来没登记成来源,按「别名写错了」照写,一并改成派生来源。

编号只看位置:一边多出一个排在前面的 CTE(比如盲算先关联一个筛 VIP 的 CTE),后面的编号就错开了,同名的 CTE 反倒比原来按名字比时多报出两条自相矛盾的话。Part 加 anon(派生来源一律写「@」、不写编号),diff_facets 每个方面先按编号比,比不上的再按 anon 一对一地配,配上的不算不同;比较两边的先后先按 anon 排、分不出再按编号;连接先配完全一样的再按关联的表配,免得错开的两个 CTE 被配成一对、说成关联条件不同。编号对得上时照样分得清是哪个 CTE 的同名列(p.total > r.total 写反成 r.total > p.total 照报)。筛选条件配对改按列的比较写法(Part.column_keys,CTE、子查询的列写「@.列」),CTE 名不同、阈值不同时说成「按 total > 100 筛选,盲算按 total > 200 筛选」,不再拆成两条各说各的。

仍按名字比的只有 CTE、子查询选出来、外层按名字引用的列(一边叫 total、一边叫 sum_amt),写进了模块说明。
2026-10-05 02:37:33 +08:00
ThearchyHelios a427b53874 SQL 语义复核修正:同一个口径不再因为子查询里的别名、HAVING 里的别名被报成不同;取哪几行逐段比,连同 OFFSET 和取前几行时的排序
条件里套着的子查询(EXISTS、IN (SELECT …))原来按外层的来源整个照抄进外层那个条件,别名原样留着:带别名和不带别名的同一条 NOT EXISTS 被报成两处筛选不同,双盲复算就会说盲算换了口径。现在每段 SELECT 在语法树上记段号(复制出来的子查询靠它找回原树上那一段算好的来源,相关子查询照样到外层找),改写时每一列按它所在那一段认,子查询里的表去掉别名;比较两边排序时也按那一段的来源排。HAVING 引用 SELECT 别名(HAVING s > 100)换成别名指的表达式,和 GROUP BY 别名一个读法,聚合函数里的同名列不换。

取哪几行原来只看最外层 LIMIT 的行数:CTE 里 LIMIT 10 和 LIMIT 100、OFFSET 0 和 OFFSET 10、取前 10 行时降序和升序都报成没有不同,取到的却是不同的行。Facets 加 limits,逐段收集(最外层、CTE、FROM 里的子查询;条件里的子查询已经整个写在条件里,不单算,免得报两遍)行数、跳过的行数,以及这一段的排序(ORDER BY 1、别名换成 SELECT 里的表达式);OFFSET 0 算没写,排序只在限了行的段里比。原来的 limit(最外层行数)照旧保留。
2026-10-05 01:46:55 +08:00
ThearchyHelios f1c068d6a9 核查工具箱收尾:连接的方面补上另一侧(关联条件里出现的别的表,CROSS JOIN 写它之前的来源),双盲复算对照数据目录里的关系时用得上;只读 agent 收尾前先拿到收尾用的模型再预留金额,模型拿不到时不在每日账上白记一次调用;收尾消息的参数改名 limit_words,说清是哪个上限的说法 2026-10-05 00:42:02 +08:00
ThearchyHelios 031aae9343 SQL 语义:data/sql_semantics.py 给双盲复算、运行对比、反方审稿共用。normalize_sql 按方言解析、重新生成(去注释、统一关键字和空白、按方言转换不加引号的名字),再把字符串和数字换成占位符:只改了字面量的两条 SQL 规范文本相同(定时运行每期日期不同,不算模板变了),字面量按规范文本里的先后列出;解析不了退回逐词规范化,照样认得出只改了字面量。facets 把查询拆成表、连接(类型 / 关联进来的表 / ON 条件)、WHERE 合取式、时间条件(列 / 运算符 / 取值)、分组、聚合(函数 / 参数 / 去重)、HAVING、LIMIT:别名换成真实表名,比较两边排好顺序,GROUP BY 1 和别名换成表达式,CTE、子查询逐段收集,只透出一张表的 CTE 换回那张表的列,逗号连接写在 WHERE 里的等式算关联条件,相关子查询到外层找别名;解析不了带 parse_error,从不抛。diff_facets 每处不同给一句中文(「A 按支付时间 paid_at 筛时间,B 按下单时间 created_at」「A 排除了 is_deleted = 1 的行,B 没有」「A 对 order_id 去重计数,B 没去重」),两边叫法可以换成「原流程」「盲算」,列的中文名可以用 catalog_labels 从数据目录取;只换了一张表时说一次「查的是哪张表」,其余按不写表名的写法比。复用 sqlcheck 的 dialect_of、_conjuncts、_bare_column、_unparen 2026-10-05 00:22:51 +08:00