digoal
2023-01-17
PostgreSQL , PolarDB , 表名 , 字段名 , 函数名 , 视图名 , 长度 , 128 , identifiers , sql server
babelfish文档中提到一个身份标识(表名、字段名、函数名、视图名等)的长度限制, sql server的标识长度允许128, 而PG是63字节. 实际上PG可以修改头文件支持更长的长度.
https://babelfishpg.org/docs/usage/interoperability/
身份标识
PostgreSQL 的最大标识符长度为 63 个字符,而 SQL Server 最多支持 128 个字符。此外,PostgreSQL 对索引名称的唯一性要求更严格。Babelfish 通过在内部附加或替换部分此类标识符来处理这些限制,其中包含 32 个字符的字符串,表示标识符的哈希值。虽然这对 T-SQL 是透明的,但从 PostgreSQL 看时,带哈希的标识符是对象名称。
例如,一个名为ix1on table的索引将在t1内部ix1t1a5111d2a1767bc43a700e9f2162be019由 Babelfish 命名。在这里,Babelfish 将索引名称与表名称沿着使用 MD5 作为小写索引名称生成的字符串连接起来。
其他参考:
- 《PostgeSQL sql server兼容性with babelfish - babelfish部署on mssql 2019 docker on ubuntu》
- 《PostgeSQL sql server兼容性with babelfish - babelfish部署on CentOS8 docker》
PG自动截断到63个字节为止。
postgres=# create table "德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥" (id int);
NOTICE: 42622: identifier "德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥" will be truncated to "德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德"
LOCATION: truncate_identifier, scansup.c:108
CREATE TABLE
postgres=# select octet_length('德哥德哥德哥德哥德哥德哥德哥德哥德哥德哥德');
octet_length
--------------
63
(1 row)
src/backend/parser/scansup.c
86 /*
87 * truncate_identifier() --- truncate an identifier to NAMEDATALEN-1 bytes.
88 *
89 * The given string is modified in-place, if necessary. A warning is
90 * issued if requested.
91 *
92 * We require the caller to pass in the string length since this saves a
93 * strlen() call in some common usages.
94 */
95 void
96 truncate_identifier(char *ident, int len, bool warn)
97 {
98 if (len >= NAMEDATALEN)
99 {
100 if (truncate_identifier_hook)
101 {
102 if ((*truncate_identifier_hook) (ident, len, warn))
103 return;
104 }
105
106 len = pg_mbcliplen(ident, len, NAMEDATALEN - 1);
107 if (warn)
108 ereport(NOTICE,
109 (errcode(ERRCODE_NAME_TOO_LONG),
110 errmsg("identifier \"%s\" will be truncated to \"%.*s\"",
111 ident, len, ident)));
112 ident[len] = '\0';
113 }
114 }
如果要超过63个字节,需要修改头文件,例如改成256, 允许255字节, 并重新编译软件,重新初始化数据库集群。
src/include/pg_config_manual.h
/*
* Maximum length for identifiers (e.g. table names, column names,
* function names). Names actually are limited to one less byte than this,
* because the length must include a trailing zero byte.
*
* Changing this requires an initdb.
*/
// #define NAMEDATALEN 64
#define NAMEDATALEN 256