根据 nodeTag (parsetree) 的值来确定 sql 的操作类型

根据 nodeTag (parsetree) 的值来确定 sql 的操作类型 …… case T_CreateStmt: { //create table #ifdef PGXC CreateCommand ((CreateStmt*) parse_tree, query_string, params, is_top_level, sent_to_remote, isCTAS); #else CreateCommand ((CreateStmt*) parse_tree, query_string, params, is_top_level, isCTAS); #endif } break; ……

`

CreateCommand 函数先解析 parse_tree 获取 stmt,如果 stmt 为空则表明表已经存在。如果 stmt 不为空对 stmts 进行遍历,如果是 CreateStmt 就调用 DefineRelation。AlterTableCreateToastTable 判断是否需要创建 toast 表并创建,AlterCStoreCreateTables 判断是否需要创建列存表并创建。

`#ifdef PGXC void CreateCommand(CreateStmt *parse_tree, const char *query_string, ParamListInfo params, bool is_top_level, bool sent_to_remote, bool isCTAS) #else void CreateCommand(CreateStmt parse_tree, const char query_string, ParamListInfo params, bool is_top_level, bool isCTAS) #endif { …… / Run parse analysis ... /if (u_sess->attr.attr_sql.enable_parallel_ddl) // 先解析 parse_tree 获取 stmt stmts = transformCreateStmt ((CreateStmt)parse_tree, query_string, NIL, true, &namespace_id, is_first_node); else stmts = transformCreateStmt((CreateStmt)parse_tree, query_string, NIL, false, &namespace_id);

/*
 * If stmts is NULL, then the table is exists.
 * we need record that for searching the group of table.
 */
if (stmts == NIL) { // 如果stmt为空则表明表已经存在
    table_is_exist = true;

…… /* ... and do it /foreach (l, stmts) { // 遍历 stmts Node stmt = (Node*)lfirst(l);

    if (IsA(stmt, CreateStmt)) {  // 如果是 CreateStmt就调用DefineRelation
        Datum toast_options;
        static const char* const validnsps[] = HEAP_RELOPT_NAMESPACES;

        /* forbid user to set or change inner options */
        ForbidOutUsersToSetInnerOptions(((CreateStmt*)stmt)->options);

        /* Create the table itself */
        rel_oid = DefineRelation((CreateStmt*)stmt,
                                ((CreateStmt*)stmt)->relkind == RELKIND_MATVIEW ?
                                                                RELKIND_MATVIEW : RELKIND_RELATION,
                                InvalidOid, isCTAS);

…… AlterTableCreateToastTable(rel_oid, toast_options, AccessShareLock); AlterCStoreCreateTables(rel_oid, toast_options, (CreateStmt*)stmt); AlterDfsCreateTables(rel_oid, toast_options, (CreateStmt*)stmt); AlterCreateChainTables(rel_oid, toast_options, (CreateStmt *)stmt); ……

`

DefineRelation 函数获取到表名 relname、名字空间 relnamespace、表空间 reltablespace、表类型 relkind 和 relpersistence 等信息后调用 heap_create_with_catalog 创建 relation。

(gdb) f 0 #0 heap_create_with_catalog (relname=0x7fb4fa872140 "t100", relnamespace=2200, reltablespace=0, relid=0, reltypeid=0, reloftypeid=0, ownerid=10, tupdesc=0x7fb4ff2e2e50, cooked_constraints=0x0, relkind=114 'r', relpersistence=112 'p', shared_relation=false, mapped_relation=false, oidislocal=false, oidinhcount=0, oncommit=ONCOMMIT_NOOP, reloptions=140415352057720, use_user_acl=true, allow_system_table_mods=false, partTableState=0x0, row_compress=1 '\001', bucketinfo=0x0, record_dependce=true, ceLst=0x0, storage_type=HEAP_DISK, partLockMode=1) at heap.cpp:2521

heap_create_with_catalog 主要完成表物理文件的创建和表元信息注册到系统表中,涉及系统包包括 pg_class,pg_attribute,pg_depend,pg_object,pg_type,pg_index 和 pg_partition。

其中 heap_create 内部首先调用了 RelationBuildLocalRelation 创建 RelationData,并加入到 relCache,RelationData 表示一个表的元信息,这些信息都可以由系统表元组中的信息构造得到。然后根据这些信息通过调用 RelalionCreateStorage 函数创建物理文件。

附:创建表 create table 的函数调用栈 #0 RelationCreateStorage #1 heap_create #2 heap_create_with_catalog #3 DefineRelation #4 CreateCommand #5 standard_ProcessUtility #6 gsaudit_ProcessUtility_hook #7 pgaudit_ProcessUtility #8 hypo_utility_hook #9 ProcessUtility #10 PortalRunUtility #11 PortalRunMulti #12 PortalRun #13 exec_simple_query #14 PostgresMain

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值