聊聊PG中的关键字类别-2
·
#define PG_KEYWORD(kwname, value, category, collabel)
在PG源码中有这样一个宏定义,聊聊PG中的关键字类别-1中解析的是collabel的底层逻辑和设计原理,本章主要是看category,关键字大类的设计和底层原理。
unreserved_keyword
col_name_keyword
reserved_keyword
type_func_name_keyword
这四种关键字有什么区别,用处是什么?
这是 PostgreSQL 中关键字的四种分类,区别在于使用限制和允许的场景:
1. reserved_keyword(保留关键字) 🔴
最严格的类别,不能用作标识符(表名、列名、函数名等)。
SELECT * FROM select; -- ❌ 错误!select 是保留字
SELECT * FROM "select"; -- ✅ 必须加双引号
常见例子:SELECT, FROM, WHERE, INSERT, UPDATE, DELETE, JOIN, ON
用途:SQL 语法的核心结构,解析器需要明确识别它们。
2. unreserved_keyword(非保留关键字) 🟢
最宽松的类别,几乎可以随意用作标识符,无需引号。
用途:有语义但不会造成语法歧义的关键字。
3. col_name_keyword(列名关键字) 🟡
中等限制,可以用作列名,但在其他上下文可能有限制。
用途:这些词在某些上下文中是关键字,但作为列名时可以通过上下文区分。
4. type_func_name_keyword(类型/函数名关键字) 🔵
特殊类别,可以用作类型名或函数名,但不能作列名(会歧义)。
用途:这些词在表达式中用作类型或函数时是明确的,但作列名会与变量/表达式混淆。
📊 对比表
| 类别 | 作表名 | 作列名 | 作函数名 | 作类型名 | 需引号 |
|---|---|---|---|---|---|
| reserved | ❌ | ❌ | ❌ | ❌ | 必须 |
| unreserved | ✅ | ✅ | ✅ | ✅ | 不需要 |
| col_name | ⚠️ | ✅ | ⚠️ | ⚠️ | 视情况 |
| type_func_name | ⚠️ | ❌ | ✅ | ✅ | 视情况 |
🎯 区分unreserved,col_name,type_func_name?
语法中如是,列名中包含了unreserved,类型或者函数中也包含了unreserved,所以unreserved,所以其最宽松。剩下的拿到某个关键字就根据函数或者列名放置到合适位置即可,正常情况下不确定选取非保留关键字。
🎯 为什么这样设计?
- 避免语法歧义:解析器需要明确区分关键字和标识符
- 向后兼容:随着 SQL 标准演进,新关键字不能破坏现有代码
- 灵活性:给开发者尽可能多的命名自由,同时保证语法清晰
实用建议:避免用任何关键字作标识符,除非必要。如果必须用,加双引号最安全。
更多推荐
所有评论(0)