Skip to content

如下SQL无法正常的提取到表名和字段数据信息 #212

Closed

Description

@xlorne
Image

执行的SQL

SELECT
id,
unit_name,
department_name,
employee_name,
sex,
former_name,
nationality_code,
person_nation_code,
card_type_code,
card_no,
card_birth_date,
present_address,
bron_place_desc,
native_place_desc,
household_type_code,
household_local,
political_affiliation_code,
join_date,
join_org_name,
introducer,
health_status_code,
marital_status_code,
whether_disabled,
staff_speciality,
sap_number,
remarks,
telephone,
email,
emergency_contact,
emergency_contact_relation_code,
emergency_contact_phone,
archive_birth_date,
orig_policy_retire_age_code,
is_use_new_policy_retire_age,
new_policy_retire_age,
start_work_date,
industry_entry_date,
entry_date,
company_entry_date,
industry_entry_type_code,
company_entry_type_code,
archival_custodian_code,
unit_center_record,
labor_type_code,
employment_form_code,
eoh_person_category_code,
whether_register,
contract_sign_unit,
full_time_diploma_code,
full_time_degree_code,
on_job_diploma_code,
on_job_degree_code,
highest_technology_name,
highest_technology_level_code,
highest_skill_name,
highest_skill_level_code,
employee_code,
person_code,
person_status_code,
post_type_code,
position_hierarchy_code
FROM
(
SELECT
emp.*,
org.SYSTEM_CODE AS orgCode,
edu.highest_diploma_code,
edu.highest_degree_code,
edu.full_time_diploma_code,
edu.full_time_degree_code,
edu.on_job_diploma_code,
edu.on_job_degree_code,
tech.highest_technology_name,
tech.highest_technology_level_code,
skill.highest_skill_name,
skill.highest_skill_level_code,
post.post_type_code AS post_type_code,
curpos.position_hierarchy_code AS position_hierarchy_code
FROM
T_DYNAMIC_BIZ_PBM_EMP_BASIC_INFO emp
LEFT JOIN BIZ_PBM_ORGANIZATION org ON org.id = emp.department_id
LEFT JOIN (
SELECT
e.employee_id,
e.highest_diploma_code,
e.highest_degree_code,
e.full_time_diploma_code,
e.full_time_degree_code,
e.on_job_diploma_code,
e.on_job_degree_code,
ROW_NUMBER() OVER (
PARTITION BY
e.employee_id
ORDER BY
e.id DESC
) AS rn
FROM
T_DYNAMIC_BIZ_PBM_EMP_EDUCATION_HIGHEST e
) edu ON edu.employee_id = emp.id
AND edu.rn = 1
LEFT JOIN (
SELECT
t.employee_id,
t.highest_technology_name,
t.highest_technology_level_code,
ROW_NUMBER() OVER (
PARTITION BY
t.employee_id
ORDER BY
t.id DESC
) AS rn
FROM
T_DYNAMIC_BIZ_PBM_EMP_TECHNOLOGY_HIGHEST t
) tech ON tech.employee_id = emp.id
AND tech.rn = 1
LEFT JOIN (
SELECT
s.employee_id,
s.highest_skill_name,
s.highest_skill_level_code,
ROW_NUMBER() OVER (
PARTITION BY
s.employee_id
ORDER BY
s.id DESC
) AS rn
FROM
T_DYNAMIC_BIZ_PBM_EMP_SKILL_HIGHEST s
) skill ON skill.employee_id = emp.id
AND skill.rn = 1
LEFT JOIN BIZ_PBM_POST post ON post.id = CAST(emp.post_id AS BIGINT)
LEFT JOIN (
SELECT
c.employee_id,
c.position_hierarchy_code,
c.current_hierarchy_date
FROM
(
SELECT
p.employee_id,
p.position_hierarchy_code,
p.current_hierarchy_date,
ROW_NUMBER() OVER (
PARTITION BY
p.employee_id
ORDER BY
p.current_position_date DESC NULLS LAST,
p.id DESC
) AS rn
FROM
T_DYNAMIC_BIZ_PBM_EMP_POSITION p
WHERE
p.whether_current = 1
) c
WHERE
c.rn = 1
) curpos ON curpos.employee_id = emp.id
WHERE
emp.sys_deleted = 0
ORDER BY
CASE
WHEN org.SYSTEM_CODE IS NULL THEN 1
ELSE 0
END,
org.tree_sort,
CASE
WHEN curpos.position_hierarchy_code IS NULL THEN 1
ELSE 0
END,
CASE
WHEN curpos.position_hierarchy_code LIKE 'dict_u_w_p_layer%' THEN CAST(
REPLACE (
curpos.position_hierarchy_code,
'dict_u_w_p_layer_',
''
) AS INT
)
ELSE 999
END,
CASE
WHEN curpos.current_hierarchy_date IS NULL THEN 1
ELSE 0
END,
curpos.current_hierarchy_date,
emp.id
) AS base
WHERE
1 = 1
LIMIT
?
OFFSET
?

Activity

  1. added 2 commits that reference this issue on Sep 11, 2026
    b2b6e9f
    d6358f5
  2. xlorne commented on Sep 11, 2026

    @xlorne
    ContributorAuthor

    已修复,感谢反馈 🙏

    根因定位

    复现后确认问题不在 SQL 解析层(该复杂 SQL 可被 JSqlParser 正常解析,行权限注入也正常),而在 ResultSet 列元数据 → 物理表字段的映射:

    查询引擎将业务 SQL 包装为 SELECT 裸列 FROM ( ... ) AS __base__ WHERE 1 = 1 LIMIT ? OFFSET ? 后,结果集元数据中列的表名变为派生表别名(如 H2 上报 __BASE__)或空串(PostgreSQL 场景,与截图调试现场一致),且外层投影是无表限定符的裸列名。框架原有逻辑拿派生表名/空串去查别名映射表时原样透传,导致 supportColumnAuthorization 收到 tableName=""、columnName="CARD_NO",无法映射回 T_DYNAMIC_BIZ_PBM_EMP_BASIC_INFO.card_no,列权限/脱敏失效。

    修复方式

    遍历 AST 时为每个派生表(FROM / JOIN 子查询)构建「输出列 → 物理表字段」的投影映射(DerivedTableProjection):

    • 支持多层派生链归因(如 curpos → c → T_DYNAMIC_BIZ_PBM_EMP_POSITION.position_hierarchy_code);
    • 单个 t.* 星号投影可将外层裸列归因到该物理表;
    • 函数/表达式 AS 别名列、多星号来源、多表归属歧义等场景保守跳过,不误归因;
    • 元数据表名命中派生表别名或为空/未知时走投影归因,已知物理表完全维持原行为,无回归风险。

    修复提交

    分支 提交
    17.3.x(JDK 17 / Spring Boot 3) b2b6e9f3
    8.2.x(JDK 8 / Spring Boot 2) d6358f5f

    均附带复现与验收测试:Issue212SQLTest(issue 原始完整 SQL 的链式归因)、Issue212ResultSetColumnTest(H2 端到端验证列权限回调收到正确的物理表/字段)。

    将随 17.3.1 / 8.2.1 补丁版本发布,欢迎验证反馈。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions