Skip to content

Latest commit

 

History

History
120 lines (83 loc) · 5.38 KB

20230117_03.md

File metadata and controls

120 lines (83 loc) · 5.38 KB

PostgeSQL sql server兼容性之 - 扩展表名、字段名、函数名、视图名等长度至128

作者

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 作为小写索引名称生成的字符串连接起来。

其他参考:

扩展表名、字段名、函数名、视图名等长度至128

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  

digoal's wechat