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;
}