【SQL引擎 - parse_type.cpp分析(二)】

SQL引擎 - parse_type.cpp分析(二)

数据库的SQL引擎是数据库重要的子系统之一,它对上负责承接应用程序发送过来的SQL语句对下负责指挥执行器运行执行计划。其中优化器作为SQL引擎中最重要、最复杂的模块,被称为数据库的“大脑”,优化器产生的执行计划的优劣直接决定数据库的性能。

SQL引擎主要包括查询解析(parser)、查询分流(traffic cop)、查询优化(optimizer)、查询执行(executor)。parser源码目录为/src/common/backend/parser:
在这里插入图片描述

在这里插入图片描述

parse_type.cpp 解析器处理类型操作

src/common/backend/parser/parse_type.cpp

qurer_string的检查

IsTypeSupportedByCStore,如果列存储支持该类型则返回true,这个函数的性能依赖于编译器来平化分支。但如果编译器没有完成它的工作,这是ok的,因为它不是在关键的代码路径。

bool IsTypeSupportedByCStore(Oid typeOid)
{
    switch (typeOid) {
        case BOOLOID:
        case HLL_OID: // 等同于BYTEA
        case BYTEAOID:
        case CHAROID:
        case HLL_HASHVAL_OID: // 等同于INT8
        case INT8OID:
        case INT2OID:
        case INT4OID:
        case INT1OID:
        case NUMERICOID:
        case BPCHAROID:
        case VARCHAROID:
        case NVARCHAR2OID:
        case SMALLDATETIMEOID:
        case TEXTOID:
        case OIDOID:
        case FLOAT4OID:
        case FLOAT8OID:
        case ABSTIMEOID:
        case RELTIMEOID:
        case TINTERVALOID:
        case INETOID:
        case DATEOID:
        case TIMEOID:
        case TIMESTAMPOID:
        case TIMESTAMPTZOID:
        case INTERVALOID:
        case TIMETZOID:
        case CASHOID:
        case CIDROID:
        case BITOID:
        case VARBITOID:
        case CLOBOID:
        case BOOLARRAYOID: // 数组
        case HLL_ARRAYOID:
        case BYTEARRAYOID:
        case CHARARRAYOID:
        case HLL_HASHVAL_ARRAYOID:
        case INT8ARRAYOID:
        case INT2ARRAYOID:
        case INT4ARRAYOID:
        case INT1ARRAYOID:
        case ARRAYNUMERICOID:
        case BPCHARARRAYOID:
        case VARCHARARRAYOID:
        case NVARCHAR2ARRAYOID:
        case SMALLDATETIMEARRAYOID:
        case TEXTARRAYOID:
        case FLOAT4ARRAYOID:
        case FLOAT8ARRAYOID:
        case ABSTIMEARRAYOID:
        case RELTIMEARRAYOID:
        case ARRAYTINTERVALOID:
        case INETARRAYOID:
        case DATEARRAYOID:
        case TIMEARRAYOID:
        case TIMESTAMPARRAYOID:
        case TIMESTAMPTZARRAYOID:
        case ARRAYINTERVALOID:
        case ARRAYTIMETZOID:
        case CASHARRAYOID:
        case CIDRARRAYOID:
        case BITARRAYOID:
        case VARBITARRAYOID:
        case BYTEAWITHOUTORDERCOLOID:
        case BYTEAWITHOUTORDERWITHEQUALCOLOID:
            return true;
        default:
            break;
    }

    return false;
}

bool IsTypeSupportedByVectorEngine(Oid typeOid)
{
    if (IsTypeSupportedByCStore(typeOid)) {
        return true;
    }

    switch (typeOid) {
        /* 名称,MacAddr和UUID也在rowtovec和vectorow中处理,
         * 但也可能导致结果不正确。所以不要在这里支持它.
         */
        case VOIDOID:
        case UNKNOWNOID:
        case CSTRINGOID: {
            return true;
        }
        default:
            break;
    }

    ereport(DEBUG2, (errmodule(MOD_OPT_PLANNER),
        errmsg("Vectorize plan failed due to unsupport type: %u", typeOid)));

    return false;
}

IsTypeSupportedByORCRelation

IsTypeSupportedByORCRelation 如果ORC格式关系支持该类型,则返回true。

bool IsTypeSupportedByORCRelation(_in_ Oid typeOid)
{
    /* 我们不支持用户定义类型 */
    if (typeOid >= FirstNormalObjectId) {
        return false;
    }

    static Oid supportType[] = {BOOLOID,
        OIDOID,
        INT8OID,
        INT2OID,
        INT4OID,
        INT1OID,
        NUMERICOID,
        CHAROID,
        BPCHAROID,
        VARCHAROID,
        NVARCHAR2OID,
        TEXTOID,
        CLOBOID,
        FLOAT4OID,
        FLOAT8OID,
        DATEOID,
        TIMESTAMPOID,
        INTERVALOID,
        TINTERVALOID,
        TIMESTAMPTZOID,
        TIMEOID,
        TIMETZOID,
        SMALLDATETIMEOID,
        CASHOID};
    if (DATEOID == typeOid && C_FORMAT == u_sess->attr.attr_sql.sql_compatibility) {
        ereport(ERROR,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                errmodule(MOD_HDFS),
                errmsg("Date type is unsupported for hdfs table in C-format database.")));
    }

    for (uint32 i = 0; i < sizeof(supportType) / sizeof(Oid); ++i) {
        if (supportType[i] == typeOid) {
            return true;
		}
    }
    return false;
}

static bool is_support_old_ts_style(int kvtype, Oid typeOid)
{
    if (kvtype == ATT_KV_TAG || kvtype == ATT_KV_HIDE) {       
        return typeOid == TEXTOID;
    } else if (kvtype == ATT_KV_FIELD) {
        return (typeOid == NUMERICOID || typeOid == TEXTOID);
    } else if (kvtype == ATT_KV_TIMETAG) {
        return (typeOid == TIMESTAMPTZOID || typeOid == TIMESTAMPOID);
    } else {
        /* unrecognized data type */
        return false;
    }
}

static bool is_support_new_ts_style(int kvtype, Oid typeOid)
{
    static Oid support_type[] = {BOOLOID,
        INT8OID,
        INT4OID,
        NUMERICOID,
        BPCHAROID,
        TEXTOID,
        FLOAT4OID,
        FLOAT8OID};
    /* 不支持数字 */
    static Oid tag_support_type[] = {BOOLOID,
        INT8OID,
        INT4OID,
        BPCHAROID,
        TEXTOID};
    if (kvtype == ATT_KV_TAG) {
        for (uint32 i = 0; i < sizeof(tag_support_type) / sizeof(Oid); ++i) {           
            if (tag_support_type[i] == typeOid) {
                return true;
            }
        }
        return false;
    } else if (kvtype == ATT_KV_FIELD) {
        for (uint32 i = 0; i < sizeof(support_type) / sizeof(Oid); ++i) {           
            if (support_type[i] == typeOid) {
                return true;
            }
        }
        return false;
    } else if (kvtype == ATT_KV_TIMETAG) {
        return (typeOid == TIMESTAMPTZOID || typeOid == TIMESTAMPOID);
    } else if (kvtype == ATT_KV_HIDE) {
        /* 显示标签列只支持类型char */
        if (typeOid == CHAROID) {
            return true;
        } else {
            ereport(LOG, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                    errmsg("Invalid hide column type: %u", typeOid)));
            return false;
        }
    } else {
        /* 识别数据类型 */
        return false;
    }
}

IsTypeSupportedByUStore

IsTypeSupportedByUStore如果UStore支持,则返回true。此函数的性能依赖于编译器来平铺分支。但是如果编译器没有完成它的工作也没关系,因为它不在关键代码路径中。

bool IsTypeSupportedByUStore(_in_ const Oid typeOid, _in_ const int32 typeMod)
{
    /* 我们不支持用户定义类型. */
    if (typeOid >= FirstNormalObjectId)
        return false;

    static Oid supportType[] = {
        BOOLOID,
        BYTEAOID,
        CHAROID,
        INT8OID,
        INT2OID,
        INT4OID,
        INT1OID,
        NUMERICOID,
        BPCHAROID,
        VARCHAROID,
        NVARCHAR2OID,
        SMALLDATETIMEOID,
        TEXTOID,
        OIDOID,
        FLOAT4OID,
        FLOAT8OID,
        ABSTIMEOID,
        RELTIMEOID,
        TINTERVALOID,
        INETOID,
        DATEOID,
        TIMEOID,
        TIMESTAMPOID,
        TIMESTAMPTZOID,
        INTERVALOID,
        TIMETZOID,
        CASHOID,
        CIDROID,
        BITOID,
        VARBITOID,
	NAMEOID,
        RAWOID,
        BLOBOID,
        CIRCLEOID,
        MACADDROID,
        UUIDOID,
        TSVECTOROID,
        TSQUERYOID,
        POINTOID,
        LSEGOID,
        BOXOID,
        PATHOID,
        POLYGONOID,
        INT4ARRAYOID
    };

    for(uint32 i = 0; i < sizeof(supportType)/sizeof(Oid); ++i) {
        if(supportType[i] == typeOid) {
            return true;
        }
    }

    return false;
}

/* 检查类型是否为黑名单. */
bool IsTypeInBlacklist(Oid typoid)
{
    bool isblack = false;

    switch (typoid) {
#ifdef ENABLE_MULTIPLE_NODES
        case XMLOID:
#endif /* ENABLE_MULTIPLE_NODES */
        case LINEOID:
        case PGNODETREEOID:
            isblack = true;
            break;
        default:
            break;
    }

    return isblack;
}

/* 检查类型是否在安装组中. */
bool IsTypeTableInInstallationGroup(const Type type_tup)
{
    if (type_tup && !IsInitdb && IS_PGXC_COORDINATOR) {
        Form_pg_type typeForm = (Form_pg_type)GETSTRUCT(type_tup);
        char* groupname = NULL;
        Oid groupoid = InvalidOid;

        if (OidIsValid(typeForm->typrelid)) {
            char relkind = get_rel_relkind(typeForm->typrelid);
            if (RELKIND_VIEW != relkind && RELKIND_CONTQUERY != relkind) {
                groupoid = ng_get_baserel_groupoid(typeForm->typrelid, relkind);
            }

            if (OidIsValid(groupoid)) {
                groupname = get_pgxc_groupname(groupoid);
            }

            char* installation_groupname = PgxcGroupGetInstallationGroup();
            if (groupname != NULL && installation_groupname != NULL && strcmp(groupname, installation_groupname) != 0) {
                return false;
            }
        }
    }
    return true;
}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值