Skip to content

[BUG] 带 WITH/CTE 的查询触发无权限报错,校验误将 CTE 别名识别为物理数据表 #1278

Description

@Fit111

SQLBot Version
1.10.0 专业版
Run Mode
安装包

Describe the bug

当 AI 生成包含WITH CTE多段聚合 SQL 时,系统表权限校验抛出异常:
SQL contains unauthorized tables: xxx_agg. Allowed tables: xxx
其中提示的未授权表均为 SQL 内自定义 CTE 别名,并非数据库真实物理表,
CTE 别名不应参与白名单校验;仅等物理表需校验

Image Image

下面是示例 SQL
WITH
sales_base AS (
SELECT
o.order_no,
o.order_date,
o.bu_code,
o.dept_code,
o.region_code,
o.customer_code,
o.owner_account,
o.channel,
o.order_status,
o.order_amount,
o.gross_profit,
o.cost_amount,
SUM(i.qty) AS item_qty,
SUM(i.line_amount) AS item_amount,
COUNT(DISTINCT i.product_code) AS sku_cnt
FROM fact_sales_order o
INNER JOIN fact_sales_order_item i
ON o.order_no = i.order_no
WHERE o.order_date >= '2025-01-01'
AND o.order_date < '2026-01-01'
AND o.order_status <> '已取消'
GROUP BY
o.order_no, o.order_date, o.bu_code, o.dept_code, o.region_code,
o.customer_code, o.owner_account, o.channel, o.order_status,
o.order_amount, o.gross_profit, o.cost_amount
),
exp_agg AS (
SELECT
bu_code, dept_code, owner_account,
ROUND(SUM(amount), 2) AS expense_amt,
COUNT() AS expense_cnt
FROM fact_expense
WHERE expense_date >= '2025-01-01'
AND expense_date < '2026-01-01'
AND status = '已报销'
GROUP BY bu_code, dept_code, owner_account
),
visit_agg AS (
SELECT
bu_code, dept_code, customer_code, owner_account,
COUNT(
) AS visit_cnt,
SUM(CASE WHEN result_level = '成功' THEN 1 ELSE 0 END) AS visit_ok_cnt,
ROUND(SUM(opportunity_amt), 2) AS opportunity_amt
FROM fact_customer_visit
WHERE visit_date >= '2025-01-01'
AND visit_date < '2026-01-01'
GROUP BY bu_code, dept_code, customer_code, owner_account
),
inv_agg AS (
SELECT
i.bu_code,
i.dept_code,
i.product_code,
ROUND(AVG(i.stock_amount), 2) AS avg_stock_amt,
ROUND(MAX(i.qty_onhand), 0) AS max_onhand
FROM fact_inventory_daily i
INNER JOIN dim_warehouse w
ON i.warehouse_code = w.warehouse_code
WHERE i.biz_date >= '2025-01-01'
AND i.biz_date < '2026-01-01'
GROUP BY i.bu_code, i.dept_code, i.product_code
),
att_agg AS (
SELECT
bu_code, dept_code, owner_account,
COUNT(*) AS attend_days,
SUM(CASE WHEN attend_status = '迟到' THEN 1 ELSE 0 END) AS late_cnt,
ROUND(SUM(overtime_hours), 2) AS ot_hours
FROM fact_hr_attendance
WHERE attend_date >= '2025-03-01'
AND attend_date < '2026-07-01'
GROUP BY bu_code, dept_code, owner_account
),
joined AS (
SELECT
bu.bu_name,
d.dept_name,
r.region_name,
c.customer_name,
c.customer_level,
c.industry,
e.emp_name AS owner_name,
e.job_title,
s.channel,
DATE_FORMAT(s.order_date, '%Y-%m') AS order_month,
s.order_no,
s.order_amount,
s.gross_profit,
s.item_qty,
s.sku_cnt,
COALESCE(x.expense_amt, 0) AS expense_amt,
COALESCE(v.visit_cnt, 0) AS visit_cnt,
COALESCE(v.visit_ok_cnt, 0) AS visit_ok_cnt,
COALESCE(v.opportunity_amt, 0) AS opportunity_amt,
COALESCE(a.late_cnt, 0) AS late_cnt,
COALESCE(a.ot_hours, 0) AS ot_hours,
ROUND(s.gross_profit / NULLIF(s.order_amount, 0), 4) AS gross_margin,
ROUND(
COALESCE(v.visit_ok_cnt, 0) / NULLIF(COALESCE(v.visit_cnt, 0), 0),
4
) AS visit_success_rate,
ROW_NUMBER() OVER (
PARTITION BY bu.bu_code
ORDER BY s.order_amount DESC
) AS bu_sales_rank
FROM sales_base s
INNER JOIN dim_bu bu
ON s.bu_code = bu.bu_code
INNER JOIN dim_dept d
ON s.dept_code = d.dept_code
AND s.bu_code = d.bu_code
LEFT JOIN dim_region r
ON s.region_code = r.region_code
INNER JOIN dim_customer c
ON s.customer_code = c.customer_code
INNER JOIN dim_employee e
ON s.owner_account = e.account
LEFT JOIN exp_agg x
ON s.bu_code = x.bu_code
AND s.dept_code = x.dept_code
AND s.owner_account = x.owner_account
LEFT JOIN visit_agg v
ON s.bu_code = v.bu_code
AND s.dept_code = v.dept_code
AND s.customer_code = v.customer_code
AND s.owner_account = v.owner_account
LEFT JOIN att_agg a
ON s.bu_code = a.bu_code
AND s.dept_code = a.dept_code
AND s.owner_account = a.owner_account
)
SELECT
bu_name AS 事业群,
dept_name AS 部门,
region_name AS 区域,
customer_level AS 客户等级,
customer_name AS 客户,
owner_name AS 负责人,
job_title AS 岗位,
channel AS 渠道,
order_month AS 月份,
order_no AS 订单号,
ROUND(order_amount, 2) AS 销售额,
ROUND(gross_profit, 2) AS 毛利,
gross_margin AS 毛利率,
item_qty AS 销量,
sku_cnt AS SKU数,
expense_amt AS 费用金额,
visit_cnt AS 拜访次数,
visit_success_rate AS 拜访成功率,
opportunity_amt AS 商机金额,
late_cnt AS 迟到次数,
ot_hours AS 加班工时,
bu_sales_rank AS 事业群内销售排名
FROM joined
WHERE bu_sales_rank <= 20
ORDER BY 事业群, 事业群内销售排名, 销售额 DESC
To Reproduce

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions