fix(Hive): normalize identifier quoting and stabilize metadata/query paths

Use Hive-compatible identifier handling and template defaults so generated SQL returns real column values, while also fixing table schema parsing and adding required Hive runtime dependencies.

Made-with: Cursor
This commit is contained in:
yym
2026-05-08 11:53:08 +08:00
committed by ulleo
parent d508040be8
commit eb587fce7b
5 changed files with 190 additions and 72 deletions
+86
View File
@@ -0,0 +1,86 @@
template:
quot_rule: |
<rule>
必须对数据库名、表名、字段名、别名外层加反引号(`)。
<note>
1. 点号(.)不能包含在引号内,必须写成 `database`.`table`
2. 即使标识符不含特殊字符或非关键字,也需强制加反引号
</note>
</rule>
limit_rule: |
<rule>
当需要限制行数时,必须使用标准的LIMIT语法
</rule>
other_rule: |
<rule>必须为每个表生成别名(不加AS)</rule>
{multi_table_condition}
<rule>禁止使用星号(*),必须明确字段名</rule>
<rule>中文/特殊字符字段需保留原名并添加英文别名</rule>
<rule>不能用 + 拼接字符串,字符串必须使用单引号</rule>
<rule>分组非常严格:SELECT 里的字段必须出现在 GROUP BY 里,或者是聚合函数</rule>
<rule>函数字段必须加别名</rule>
<rule>百分比字段保留两位小数并以%结尾</rule>
<rule>WHERE 条件中不能使用 >、<、>=、<= 等比较运算符,必须使用 =</rule>
<rule>HIVE 中没有 NOT IN 操作符,必须使用 LEFT JOIN 或 EXISTS 替代</rule>
<rule>判空使用 NVL()函数</rule>
<rule>避免与数据库关键字冲突</rule>
basic_example: |
<basic-examples>
<intro>
📌 以下示例严格遵循<Rules>中的 Hive 规范,展示符合要求的 SQL 写法与典型错误案例。
⚠️ 注意:示例中的表名、字段名均为演示虚构,实际使用时需替换为用户提供的真实标识符。
🔍 重点观察:
1. 反引号包裹所有数据库对象的规范用法
2. 中英别名/百分比/函数等特殊字段的处理
3. 关键字冲突的规避方式
</intro>
<example>
<input>查询 ods.orders 表的前100条订单(含中文字段和百分比)</input>
<output-bad>
SELECT * FROM ods.orders LIMIT 100 -- 错误:未加引号、使用星号
SELECT `订单ID`, `金额` FROM `ods`.`orders` `t1` LIMIT 100 -- 错误:缺少英文别名
SELECT COUNT(`订单ID`) FROM `ods`.`orders` `t1` -- 错误:函数未加别名
</output-bad>
<output-good>
SELECT
`t1`.`订单ID` AS `order_id`,
`t1`.`金额` AS `amount`,
COUNT(`t1`.`订单ID`) AS `total_orders`,
CONCAT(CAST(ROUND(`t1`.`折扣率` * 100, 2) AS STRING), '%') AS `discount_percent`
FROM `ods`.`orders` `t1`
LIMIT 100
</output-good>
</example>
<example>
<input>统计 dim.users(含关键字字段user)的活跃占比</input>
<output-bad>
SELECT user, status FROM dim.users -- 错误:未处理关键字和引号
SELECT `user`, ROUND(active_ratio) FROM `dim`.`users` -- 错误:百分比格式错误
</output-bad>
<output-good>
SELECT
`u`.`user` AS `username`,
CONCAT(CAST(ROUND(`u`.`active_ratio` * 100, 2) AS STRING), '%') AS `active_percent`
FROM `dim`.`users` `u`
WHERE `u`.`status` = 1
</output-good>
</example>
</basic-examples>
example_engine: Apache Hive 2.X
example_answer_1: |
{"success":true,"sql":"SELECT `country` AS `country_name`, `continent` AS `continent_name`, `year` AS `year`, `gdp` AS `gdp` FROM `Sample_Database`.`sample_country_gdp` ORDER BY `country`, `year`","tables":["sample_country_gdp"],"chart-type":"line"}
example_answer_1_with_limit: |
{"success":true,"sql":"SELECT `country` AS `country_name`, `continent` AS `continent_name`, `year` AS `year`, `gdp` AS `gdp` FROM `Sample_Database`.`sample_country_gdp` ORDER BY `country`, `year` LIMIT 1000","tables":["sample_country_gdp"],"chart-type":"line"}
example_answer_2: |
{"success":true,"sql":"SELECT `country` AS `country_name`, `gdp` AS `gdp` FROM `Sample_Database`.`sample_country_gdp` WHERE `year` = '2024' ORDER BY `gdp` DESC","tables":["sample_country_gdp"],"chart-type":"pie"}
example_answer_2_with_limit: |
{"success":true,"sql":"SELECT `country` AS `country_name`, `gdp` AS `gdp` FROM `Sample_Database`.`sample_country_gdp` WHERE `year` = '2024' ORDER BY `gdp` DESC LIMIT 1000","tables":["sample_country_gdp"],"chart-type":"pie"}
example_answer_3: |
{"success":true,"sql":"SELECT `country` AS `country_name`, `gdp` AS `gdp` FROM `Sample_Database`.`sample_country_gdp` WHERE `year` = '2025' AND `country` = '中国'","tables":["sample_country_gdp"],"chart-type":"table"}
example_answer_3_with_limit: |
{"success":true,"sql":"SELECT `country` AS `country_name`, `gdp` AS `gdp` FROM `Sample_Database`.`sample_country_gdp` WHERE `year` = '2025' AND `country` = '中国' LIMIT 1000","tables":["sample_country_gdp"],"chart-type":"table"}