---
name: pyspark-sql-guardrails
description: 当生成、展示、评审或执行 PySpark/Spark SQL 字符串时使用。它负责将 SQL 限制在 SELECT、WITH...SELECT、INSERT...SELECT 安全白名单内，并阻止危险 DDL/DML/维护语句、堆叠语句和未确认的 INSERT OVERWRITE。
---

# PySpark SQL Guardrails（SQL 安全闸门）

## 目标

在 SQL 被展示、写入 PySpark 脚本或交给 `spark.sql` 前，先通过白名单校验。通过本 skill 只代表 SQL 语句类型安全，不代表业务逻辑正确。

## 允许

- `SELECT ...`
- `WITH ... SELECT ...`
- `INSERT INTO ... SELECT ...`
- `INSERT OVERWRITE ... SELECT ...`，但必须拿到用户明确允许 overwrite 的确认，并使用 `allow_overwrite=true`

## 禁止

- `DROP`、`DELETE`、`UPDATE`、`MERGE`、`ALTER`、`CREATE`、`REPLACE`
- `TRUNCATE`、`MSCK`、`REFRESH`、`ANALYZE`、`CACHE`、`UNCACHE`
- `VACUUM`、`OPTIMIZE`、`CALL`、`GRANT`、`REVOKE`
- 用分号堆叠多条语句
- `INSERT ... VALUES` 或不基于 `SELECT` 的写入
- 未校验就直接进入 `spark.sql(sql)`

## 使用脚本

本 skill 自带脚本：

```text
scripts/sql_guard.py       校验库
scripts/validate_sql.py    命令行入口
scripts/test_sql_guard.py  标准测试集
```

校验一条 SQL：

```bash
python scripts/validate_sql.py "SELECT 1"
```

从文件校验：

```bash
python scripts/validate_sql.py --file query.sql
```

JSON 输出：

```bash
python scripts/validate_sql.py --json "SELECT 1"
```

允许 overwrite 时：

```bash
python scripts/validate_sql.py --allow-overwrite "INSERT OVERWRITE target SELECT * FROM source"
```

## 输出格式

```yaml
sql_guard:
  status: PASS | FAIL
  first_keyword: select | with | insert | unknown
  reason: "失败原因，PASS 时为空"
```

## 必须执行的关口

1. SQL 生成后、展示给用户前，先运行 guard。
2. PySpark 代码中出现 `spark.sql(...)` 时，SQL 字符串必须先通过 guard。
3. guard 失败时，回到 SQL 生成步骤修 SQL，不要削弱校验器。
4. guard 通过后仍然必须进入 `sql-review`。

## 规则

- 校验必须针对最终要展示或执行的那条 SQL。
- 肉眼看过不算通过。
- 一条类似 SQL 通过，不代表当前 SQL 通过。
- 字符串字面量和注释里的危险词不应误报。
- 反引号字段名里的危险词不应误报，但不建议这样命名。
- `INSERT OVERWRITE` 默认失败，除非用户明确确认 overwrite。
