• 发文
  • 评论
  • 微博
  • 空间
  • 微信

GPDB - 内核特性 - 分区表如何处理表名超长

yzsDBA 2024-03-25 15:58 发文

GPDB - 内核特性 - 分区表如何处理表名超长

GPDB分区表创建时有可能表名已存在,此时报错退出。但当分区表名超过64字符时,会进行截断,仅保留前63字符,此时就可能出现分区表名不同,截断后创建的分区表名相同从而创建失败的情况;还会出现分区表父表创建成功,但分区子表名创建失败,报表名已存在等错误导致创建失败。本文基于GreenPlum7.0分区表经典语法详细分析分区表名及分区子表名生成机制。

1、分区表名超过64字符

在语法解析阶段将分区表名进行截断,保留前63个字符,并将第64个字符赋予”�”。该截断功能由函数truncate_identifier完成:

voidtruncate_identifier(char *ident, int len, bool warn){ if (len >= NAMEDATALEN) { len = pg_mbcliplen(ident, len, NAMEDATALEN - 1); if (warn) { * We avoid using %.*s here because it can misbehave if the data * is not valid in what libc thinks is the prevailing encoding. char buf[NAMEDATALEN];

memcpy(buf, ident, len); buf[len] = '�'; ereport(NOTICE, (errcode(ERRCODE_NAME_TOO_LONG), errmsg("identifier "%s" will be truncated to "%s"", ident, buf))); } ident[len] = '�'; }}2、子分区表名的生成

makePartitionCreateStmt函数生成每个层级所有分区创建的CreateStmt链表,当创建分区表时针对分区使用WITH子句指定子分区表名,那么就使用指定的子分区表名创建子分区表,否则调用ChoosePartitionName生成分区表名。

指定子分区表名建表案例如下所示:

CREATE TABLE update_gp_foo ( a_dist int, b int, c_part int, d int)WITH (appendonly=false) DISTRIBUTED BY (a_dist) PARTITION BY RANGE(c_part) ( PARTITION p20190305 START (1) END (2) WITH (tablename='update_gp_foo_1_prt_p20190305', appendonly=false) );CREATE TABLE update_gp_foo1 ( a_dist int, b int, c_part int, d int)WITH (appendonly=false) DISTRIBUTED BY (a_dist) PARTITION BY RANGE(c_part) ( PARTITION p20190305 START (1) END (2) WITH (tablename='update_gp_foo1_1_prt_p20190305', appendonly=false) );

ChoosePartitionName函数中对于指定分区名字的,直接将parentname、level和prt_partname通过函数makeObjectName函数组合起来,即形成子分区表名:parentname_level_prt_partname。当三者超过63字符(最后一个字符需要保存为�)就会发生截断,其中prt_partname部分不会截断,总是会保留下来;parentname和level两个截断长度较长者,知道三者长度最长不超过63字符。

对于没有指定分区名,则将当前分区层级分区序号(默认分区作为第一个)作为分区名,其中若默认分区指定了名字,而其他分区没有指定,那么其他分区序号从2开始,即prt_2作为分区名。由此parentname、level和prt_partnum通过makeObjectName函数组成的分区表名后,从pg_class中进行查询,若分区表名冲突,则在prt_partnum后追加冲突次数,比如冲突了23次,则形成分区表名为:parentname_level_prt_partnum23

生成分区表名后,通过heap_create_with_catalog创建磁盘文件前,首先根据分区表名在pg_class和pg_type中进行校验,若分区表名已存在则报错退出,否则创建成功后向pg_class中插入一条记录,pg_type中插入2条记录,其typname分别为分区表名和”_分区表名”,当然若超过63字符则分区表名会截断,若仍旧冲突,则继续在前部加”_”,比如“__分区表名”。

当然,若分区表主表名超过64字符,则在语法解析阶段就会阶段,通过函数truncate_identifier函数来完成。

声明:本文为OFweek维科号作者发布,不代表OFweek维科号立场。如有侵权或其他问题,请及时联系我们举报。
2
评论

评论

    相关阅读

    暂无数据

    yzsDBA

    专注于开源数据库原理与使用...

    举报文章问题

    ×
    • 营销广告
    • 重复、旧闻
    • 格式问题
    • 低俗
    • 标题夸张
    • 与事实不符
    • 疑似抄袭
    • 我有话要说
    确定 取消

    举报评论问题

    ×
    • 淫秽色情
    • 营销广告
    • 恶意攻击谩骂
    • 我要吐槽
    确定 取消

    用户登录×

    请输入用户名/手机/邮箱

    请输入密码