pg源代码之DefineRelation

调用DefineRelation的地方

1 create_ctas_internal - Reference to DefineRelation in createas.c (src\backend\commands) at line 115 --create table as
2 DefineSequence - Reference to DefineRelation in sequence.c (src\backend\commands) at line 215 --序列
3 DefineCompositeType - Reference to DefineRelation in typecmds.c (src\backend\commands) at line 2180--创建类型
4 ProcessUtilitySlow - Reference to DefineRelation in utility.c (src\backend\tcop) at line 1000--ddl slow流程
5 DefineVirtualRelation - Reference to DefineRelation in view.c (src\backend\commands) at line 253 --虚表,主要是view

主要步骤:

1、校验schema

namespaceId =
        RangeVarGetAndCheckCreationNamespace(stmt->relation, NoLock, NULL);

2、选择tablespace,不指定则选择默认的

    if (stmt->tablespacename)
    {
        tablespaceId = get_tablespace_oid(stmt->tablespacename, false);
    }
    else
    {
        tablespaceId = GetDefaultTablespace(stmt->relation->relpersistence);
        /* note InvalidOid is OK in this case */
    }

非默认,则校验是否有tablespace的权限 aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId()

3、不允许在pg_global上创建

if (tablespaceId == GLOBALTABLESPACE_OID)
        ereport(ERROR,...)

4、/* Identify user ID that will own the table 找到用户id */
    if (!OidIsValid(ownerId))
        ownerId = GetUserId();

5、解析和校验创建option

reloptions = transformRelOptions((Datum) 0, stmt->options, NULL, validnsps,
                                     true, false);

/*视图和表不一样*/

    if (relkind == RELKIND_VIEW)
        (void) view_reloptions(reloptions, true);
    else
        (void) heap_reloptions(relkind, reloptions, true);

/*create type分支*/

    if (stmt->ofTypename)
    {
        AclResult    aclresult;

        ofTypeId = typenameTypeId(NULL, stmt->ofTypename);

        aclresult = pg_type_aclcheck(ofTypeId, GetUserId(), ACL_USAGE);
        if (aclresult != ACLCHECK_OK)
            aclcheck_error_type(aclresult, ofTypeId);
    }
    else
        ofTypeId = InvalidOid;

有继承的情况处理,调用MergeAttributes,暂不展开。

6、创建元组描述符(主要包括列数量、列数组、tuple oid等)

descriptor = BuildDescForRelation(stmt->tableElts);/*构建了pg_attribute系统表中的相关内容*/

7、循环处理3类列

(1)RawColumnDefault:  /* default value (untransformed parse tree) */

(2)CookedConstraint: /* default value (transformed expr tree) */

(3)自增序列id

char        identity;        /* attidentity setting */
RangeVar   *identitySequence;    /* to store identity sequence name for

foreach(listptr, stmt->tableElts)

{

if (colDef->raw_default != NULL)

   rawDefaults = lappend(rawDefaults, rawEnt);

else if (colDef->cooked_default != NULL)

   cookedDefaults = lappend(cookedDefaults, cooked);

if (colDef->identity)
            attr->attidentity = colDef->identity;

}

8、创建表的物理文件并在相应的系统表中注册。会放入RelCache

relationId = heap_create_with_catalog(...),

添加的系统表包括:pg_type,pg_class,pg_constraint,pg_attrdef等

这个步骤最关键,后续单独展开下。TODO

9、使之可见 for opening:<并未真正可见,只有commit后才可见> CommandCounterIncrement();

10、Open the new relation and acquire exclusive lock on it.

rel = relation_open(relationId, AccessExclusiveLock);

11、分区表边界处理,暂时不展开。if (stmt->partbound)  ... 

12、分区表规格处理 (stmt->partbound)  ...

13、If we're creating a partition, create now all the indexes, triggers,FKs defined in the parent.

if (stmt->partbound)  ...

14、处理表中的默认值和约束

    if (rawDefaults || stmt->constraints)
        AddRelationNewConstraints(rel, rawDefaults, stmt->constraints,
                                  true, true, false);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值