From 589a14161680e6e369e74249e33bf7d55fab99fd Mon Sep 17 00:00:00 2001 From: Mijamind Date: Mon, 27 Nov 2023 09:47:44 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E8=B5=84=E6=BA=90=E6=B1=A0=E5=8C=96?= =?UTF-8?q?=E3=80=91=20SPQ=E5=A4=9A=E6=9C=BA=E5=B9=B6=E8=A1=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E7=B4=A2=E5=BC=95=E7=B1=BB=E6=89=AB=E6=8F=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/nodes/copyfuncs.cpp | 84 +++++-- src/common/backend/nodes/nodes.cpp | 3 + src/common/backend/nodes/outfuncs.cpp | 236 +++++++++++------- src/common/backend/nodes/readfuncs.cpp | 42 ++++ .../backend/pgxc_single/pool/execRemote.cpp | 6 +- src/common/backend/utils/adt/ruleutils.cpp | 4 + src/common/backend/utils/cache/lsyscache.cpp | 11 + .../optimizer/commands/explain.cpp | 39 +++ src/gausskernel/optimizer/plan/setrefs.cpp | 9 + .../optimizer/plan/streamplan_single.cpp | 8 +- .../optimizer/util/learn/encoding.cpp | 5 +- src/gausskernel/optimizer/util/optcommon.cpp | 21 ++ .../optimizer/util/planmem_walker.cpp | 10 +- src/gausskernel/runtime/executor/Makefile | 2 +- .../runtime/executor/execProcnode.cpp | 27 +- src/gausskernel/runtime/executor/execScan.cpp | 4 + .../runtime/executor/instrument.cpp | 21 ++ .../runtime/executor/nodeBitmapHeapscan.cpp | 18 +- .../executor/nodeSpqBitmapHeapscan.cpp | 19 ++ .../runtime/executor/nodeSpqIndexonlyscan.cpp | 19 ++ .../runtime/executor/nodeSpqIndexscan.cpp | 19 ++ src/gausskernel/runtime/executor/nodeStub.cpp | 7 + .../storage/access/heap/heapam.cpp | 4 + .../storage/access/index/indexam.cpp | 19 +- src/include/access/relscan.h | 19 ++ .../executor/node/nodeBitmapHeapscan.h | 9 + .../executor/node/nodeSpqBitmapHeapscan.h | 24 ++ .../executor/node/nodeSpqIndexonlyscan.h | 24 ++ src/include/executor/node/nodeSpqIndexscan.h | 24 ++ src/include/executor/node/nodeSpqSeqscan.h | 16 +- .../knl/knl_guc/knl_session_attr_spq.h | 4 +- src/include/nodes/nodes.h | 5 +- src/include/nodes/plannodes.h | 67 ++++- src/include/optimizer/pgxc_plan_remote.h | 1 + src/include/optimizer/stream_util.h | 2 +- src/include/utils/lsyscache.h | 1 + src/test/regress/pg_regress.cpp | 2 +- 37 files changed, 681 insertions(+), 154 deletions(-) create mode 100644 src/gausskernel/runtime/executor/nodeSpqBitmapHeapscan.cpp create mode 100644 src/gausskernel/runtime/executor/nodeSpqIndexonlyscan.cpp create mode 100644 src/gausskernel/runtime/executor/nodeSpqIndexscan.cpp create mode 100644 src/include/executor/node/nodeSpqBitmapHeapscan.h create mode 100644 src/include/executor/node/nodeSpqIndexonlyscan.h create mode 100644 src/include/executor/node/nodeSpqIndexscan.h diff --git a/src/common/backend/nodes/copyfuncs.cpp b/src/common/backend/nodes/copyfuncs.cpp index 4f66e93c4..6182b7390 100644 --- a/src/common/backend/nodes/copyfuncs.cpp +++ b/src/common/backend/nodes/copyfuncs.cpp @@ -188,6 +188,19 @@ static PlannedStmt* _copyPlannedStmt(const PlannedStmt* from) COPY_SCALAR_FIELD(current_id); COPY_SCALAR_FIELD(enable_adaptive_scan); COPY_SCALAR_FIELD(is_spq_optmized); + COPY_SCALAR_FIELD(numSlices); + if (from->numSlices > 0) { + newnode->slices = (PlanSlice*)palloc0(from->numSlices * sizeof(PlanSlice)); + for (int i = 0; i < from->numSlices; i++) { + COPY_SCALAR_FIELD(slices[i].sliceIndex); + COPY_SCALAR_FIELD(slices[i].parentIndex); + COPY_SCALAR_FIELD(slices[i].gangType); + COPY_SCALAR_FIELD(slices[i].numsegments); + COPY_SCALAR_FIELD(slices[i].worker_idx); + COPY_SCALAR_FIELD(slices[i].directDispatch.isDirectDispatch); + COPY_NODE_FIELD(slices[i].directDispatch.contentIds); + } + } #endif /* * Not copy ng_queryMem to avoid memory leak in CachedPlan context, @@ -282,7 +295,9 @@ static void CopyPlanFields(const Plan* from, Plan* newnode) COPY_SCALAR_FIELD(pred_total_time); COPY_SCALAR_FIELD(pred_max_memory); CopyNdpPlan(from, newnode); - +#ifdef USE_SPQ + COPY_SCALAR_FIELD(spq_scan_partial); +#endif newnode->rightRefState = CopyRightRefState(from->rightRefState); } @@ -695,27 +710,6 @@ static SeqScan* _copySeqScan(const SeqScan* from) return newnode; } -#ifdef USE_SPQ -/* - * _copySpqSeqScan - */ -static SpqSeqScan* _copySpqSeqScan(const SpqSeqScan* from) -{ - SpqSeqScan* newnode = makeNode(SpqSeqScan); - - /* - * copy node superclass fields - */ - CopyScanFields((const Scan*)from, &newnode->scan); - - newnode->isFullTableScan = from->isFullTableScan; - newnode->isAdaptiveScan = from->isAdaptiveScan; - newnode->isDirectRead = from->isDirectRead; - - return newnode; -} -#endif - /* * _copyIndexScan */ @@ -2336,6 +2330,10 @@ static RemoteQuery* _copyRemoteQuery(const RemoteQuery* from) newnode->isCustomPlan = from->isCustomPlan; newnode->isFQS = from->isFQS; COPY_NODE_FIELD(relationOids); +#ifdef USE_SPQ + COPY_SCALAR_FIELD(streamID); + COPY_SCALAR_FIELD(nodeCount); +#endif return newnode; } @@ -7446,6 +7444,40 @@ static AutoIncrement *_copyAutoIncrement(const AutoIncrement *from) return newnode; } #ifdef USE_SPQ +static SpqSeqScan* _copySpqSeqScan(const SpqSeqScan* from) +{ + SpqSeqScan* newnode = makeNode(SpqSeqScan); + + CopyScanFields((const Scan*)from, &newnode->scan); + + newnode->isFullTableScan = from->isFullTableScan; + newnode->isAdaptiveScan = from->isAdaptiveScan; + newnode->isDirectRead = from->isDirectRead; + + return newnode; +} + +static SpqIndexScan* _copySpqIndexScan(const SpqIndexScan* from) +{ + SpqIndexScan* newnode = (SpqIndexScan *)_copyIndexScan((IndexScan *)from); + newnode->scan.scan.plan.type = T_SpqIndexScan; + return newnode; +} + +static SpqIndexOnlyScan* _copySpqIndexOnlyScan(const SpqIndexOnlyScan* from) +{ + SpqIndexOnlyScan* newnode = (SpqIndexOnlyScan *)_copyIndexOnlyScan((IndexOnlyScan *)from); + newnode->scan.scan.plan.type = T_SpqIndexOnlyScan; + return newnode; +} + +static SpqBitmapHeapScan* _copySpqBitmapHeapScan(const SpqBitmapHeapScan* from) +{ + SpqBitmapHeapScan* newnode = (SpqBitmapHeapScan*)_copyBitmapHeapScan((BitmapHeapScan *)from); + newnode->scan.scan.plan.type = T_SpqBitmapHeapScan; + return newnode; +} + static Motion* _copyMotion(const Motion *from) { Motion *newnode = makeNode(Motion); @@ -7725,6 +7757,14 @@ void* copyObject(const void* from) case T_Result: retval = _copyResult((Result*)from); break; + case T_SpqIndexScan: + retval = _copySpqIndexScan((SpqIndexScan*)from); + break; + case T_SpqIndexOnlyScan: + retval = _copySpqIndexOnlyScan((SpqIndexOnlyScan*)from); + case T_SpqBitmapHeapScan: + retval = _copySpqBitmapHeapScan((SpqBitmapHeapScan*)from); + break; #endif case T_IndexScan: retval = _copyIndexScan((IndexScan*)from); diff --git a/src/common/backend/nodes/nodes.cpp b/src/common/backend/nodes/nodes.cpp index 4d1d8b7f1..12d3ce0dd 100755 --- a/src/common/backend/nodes/nodes.cpp +++ b/src/common/backend/nodes/nodes.cpp @@ -52,6 +52,9 @@ static const TagStr g_tagStrArr[] = {{T_Invalid, "Invalid"}, {T_AssertOp, "AssertOp"}, {T_ShareInputScan, "ShareInputScan"}, {T_Sequence, "Sequence"}, + {T_SpqIndexScan, "SpqIndexScan"}, + {T_SpqIndexOnlyScan, "SpqIndexOnlyScan"}, + {T_SpqBitmapHeapScan, "SpqBitmapHeapScan"}, #endif {T_IndexScan, "IndexScan"}, {T_IndexOnlyScan, "IndexOnlyScan"}, diff --git a/src/common/backend/nodes/outfuncs.cpp b/src/common/backend/nodes/outfuncs.cpp index ee560259e..f93dba317 100755 --- a/src/common/backend/nodes/outfuncs.cpp +++ b/src/common/backend/nodes/outfuncs.cpp @@ -707,6 +707,11 @@ static void _outPlanInfo(StringInfo str, Plan* node) WRITE_FLOAT_FIELD(pred_max_memory, "%ld"); } } +#ifdef USE_SPQ + if (t_thrd.proc->workingVersionNum >= SPQ_VERSION_NUM) { + WRITE_BOOL_FIELD(spq_scan_partial); + } +#endif } static void _outPruningResult(StringInfo str, PruningResult* node) @@ -775,6 +780,72 @@ static void _outScanInfo(StringInfo str, Scan* node) } } +template +static void _outCommonIndexScanPart(StringInfo str, T* node) +{ + _outScanInfo(str, (Scan*)node); + WRITE_OID_FIELD(indexid); +#ifdef STREAMPLAN + if (node->indexid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->indexid)) { + appendStringInfo(str, " :indexname "); + _outToken(str, get_rel_name(node->indexid)); + appendStringInfo(str, " :indexnamespace "); + _outToken(str, get_namespace_name(get_rel_namespace(node->indexid))); + } +#endif // STREAMPLAN + WRITE_NODE_FIELD(indexqual); + WRITE_NODE_FIELD(indexqualorig); + WRITE_NODE_FIELD(indexorderby); + WRITE_NODE_FIELD(indexorderbyorig); + WRITE_ENUM_FIELD(indexorderdir, ScanDirection); +} + +static void _outIndexScanInfo(StringInfo str, IndexScan* node) +{ + _outCommonIndexScanPart(str, node); + if (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM) { + WRITE_BOOL_FIELD(is_ustore); + } + if (t_thrd.proc->workingVersionNum >= PLAN_SELECT_VERSION_NUM) { + if (u_sess->opt_cxt.out_plan_stat) { + WRITE_FLOAT_FIELD(selectivity, "%.4f"); + } + WRITE_BOOL_FIELD(is_partial); + } +} + +static void _outIndexOnlyScanInfo(StringInfo str, IndexOnlyScan* node) +{ + _outScanInfo(str, (Scan*)node); + + WRITE_OID_FIELD(indexid); + if (node->indexid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->indexid)) { + /* + * For inherit table, the relname will be different + */ + appendStringInfo(str, " :indexname "); + _outToken(str, get_rel_name(node->indexid)); + appendStringInfo(str, " :indexnamespace "); + _outToken(str, get_namespace_name(get_rel_namespace(node->indexid))); + } + WRITE_NODE_FIELD(indexqual); + WRITE_NODE_FIELD(indexorderby); + WRITE_NODE_FIELD(indextlist); + WRITE_ENUM_FIELD(indexorderdir, ScanDirection); + if (t_thrd.proc->workingVersionNum >= PLAN_SELECT_VERSION_NUM) { + if (u_sess->opt_cxt.out_plan_stat) { + WRITE_FLOAT_FIELD(selectivity, "%.4f"); + } + WRITE_BOOL_FIELD(is_partial); + } +} + +static void _outBitmapHeapScanInfo(StringInfo str, BitmapHeapScan* node) +{ + _outScanInfo(str, (Scan*)node); + WRITE_NODE_FIELD(bitmapqualorig); +} + /* * print the basic stuff of all nodes that inherit from Join */ @@ -1085,79 +1156,11 @@ static void _outSeqScan(StringInfo str, SeqScan* node) _outScanInfo(str, (Scan*)node); } -#ifdef USE_SPQ -static void _outSpqSeqScan(StringInfo str, SpqSeqScan* node) -{ - WRITE_NODE_TYPE("SPQSEQSCAN"); - - _outScanInfo(str, (Scan*)node); - WRITE_BOOL_FIELD(isFullTableScan); - WRITE_BOOL_FIELD(isAdaptiveScan); - WRITE_BOOL_FIELD(isDirectRead); -} - -static void _outAssertOp(StringInfo str, const AssertOp *node) -{ - WRITE_NODE_TYPE("ASSERTOP"); - _outPlanInfo(str, (Plan *) node); - WRITE_INT_FIELD(errcode); - WRITE_NODE_FIELD(errmessage); -} - -static void _outShareInputScan(StringInfo str, const ShareInputScan *node) -{ - WRITE_NODE_TYPE("SHAREINPUTSCAN"); - - WRITE_BOOL_FIELD(cross_slice); - WRITE_INT_FIELD(share_id); - WRITE_INT_FIELD(producer_slice_id); - WRITE_INT_FIELD(this_slice_id); - WRITE_INT_FIELD(nconsumers); - - _outPlanInfo(str, (Plan *) node); -} - -static void _outSequence(StringInfo str, const Sequence *node) -{ - WRITE_NODE_TYPE("SEQUENCE"); - _outPlanInfo(str, (Plan *)node); - WRITE_NODE_FIELD(subplans); -} -#endif - -template -static void _outCommonIndexScanPart(StringInfo str, T* node) -{ - _outScanInfo(str, (Scan*)node); - WRITE_OID_FIELD(indexid); -#ifdef STREAMPLAN - if (node->indexid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->indexid)) { - appendStringInfo(str, " :indexname "); - _outToken(str, get_rel_name(node->indexid)); - appendStringInfo(str, " :indexnamespace "); - _outToken(str, get_namespace_name(get_rel_namespace(node->indexid))); - } -#endif // STREAMPLAN - WRITE_NODE_FIELD(indexqual); - WRITE_NODE_FIELD(indexqualorig); - WRITE_NODE_FIELD(indexorderby); - WRITE_NODE_FIELD(indexorderbyorig); - WRITE_ENUM_FIELD(indexorderdir, ScanDirection); -} static void _outIndexScan(StringInfo str, IndexScan* node) { WRITE_NODE_TYPE("INDEXSCAN"); - _outCommonIndexScanPart(str, node); - if (t_thrd.proc->workingVersionNum >= INPLACE_UPDATE_VERSION_NUM) { - WRITE_BOOL_FIELD(is_ustore); - } - if (t_thrd.proc->workingVersionNum >= PLAN_SELECT_VERSION_NUM) { - if (u_sess->opt_cxt.out_plan_stat) { - WRITE_FLOAT_FIELD(selectivity, "%.4f"); - } - WRITE_BOOL_FIELD(is_partial); - } + _outIndexScanInfo(str, node); } static void _outCStoreIndexScan(StringInfo str, CStoreIndexScan* node) @@ -1386,29 +1389,7 @@ static void _outExecNodes(StringInfo str, ExecNodes* node) static void _outIndexOnlyScan(StringInfo str, IndexOnlyScan* node) { WRITE_NODE_TYPE("INDEXONLYSCAN"); - - _outScanInfo(str, (Scan*)node); - - WRITE_OID_FIELD(indexid); - if (node->indexid >= FirstBootstrapObjectId && IsStatisfyUpdateCompatibility(node->indexid)) { - /* - * For inherit table, the relname will be different - */ - appendStringInfo(str, " :indexname "); - _outToken(str, get_rel_name(node->indexid)); - appendStringInfo(str, " :indexnamespace "); - _outToken(str, get_namespace_name(get_rel_namespace(node->indexid))); - } - WRITE_NODE_FIELD(indexqual); - WRITE_NODE_FIELD(indexorderby); - WRITE_NODE_FIELD(indextlist); - WRITE_ENUM_FIELD(indexorderdir, ScanDirection); - if (t_thrd.proc->workingVersionNum >= PLAN_SELECT_VERSION_NUM) { - if (u_sess->opt_cxt.out_plan_stat) { - WRITE_FLOAT_FIELD(selectivity, "%.4f"); - } - WRITE_BOOL_FIELD(is_partial); - } + _outIndexOnlyScanInfo(str, node); } static void _outBitmapIndexScan(StringInfo str, BitmapIndexScan* node) @@ -1443,11 +1424,67 @@ static void _outBitmapHeapScan(StringInfo str, BitmapHeapScan* node) { WRITE_NODE_TYPE("BITMAPHEAPSCAN"); - _outScanInfo(str, (Scan*)node); - - WRITE_NODE_FIELD(bitmapqualorig); + _outBitmapHeapScanInfo(str, node); } +#ifdef USE_SPQ +static void _outSpqSeqScan(StringInfo str, SpqSeqScan* node) +{ + WRITE_NODE_TYPE("SPQSEQSCAN"); + + _outScanInfo(str, (Scan*)node); + WRITE_BOOL_FIELD(isFullTableScan); + WRITE_BOOL_FIELD(isAdaptiveScan); + WRITE_BOOL_FIELD(isDirectRead); +} + +static void _outAssertOp(StringInfo str, const AssertOp *node) +{ + WRITE_NODE_TYPE("ASSERTOP"); + _outPlanInfo(str, (Plan *) node); + WRITE_INT_FIELD(errcode); + WRITE_NODE_FIELD(errmessage); +} + +static void _outShareInputScan(StringInfo str, const ShareInputScan *node) +{ + WRITE_NODE_TYPE("SHAREINPUTSCAN"); + + WRITE_BOOL_FIELD(cross_slice); + WRITE_INT_FIELD(share_id); + WRITE_INT_FIELD(producer_slice_id); + WRITE_INT_FIELD(this_slice_id); + WRITE_INT_FIELD(nconsumers); + + _outPlanInfo(str, (Plan *) node); +} + +static void _outSequence(StringInfo str, const Sequence *node) +{ + WRITE_NODE_TYPE("SEQUENCE"); + _outPlanInfo(str, (Plan *)node); + WRITE_NODE_FIELD(subplans); +} + +static void _outSpqIndexScan(StringInfo str, SpqIndexScan* node) +{ + WRITE_NODE_TYPE("SPQINDEXSCAN"); + _outIndexScanInfo(str, &node->scan); +} + +static void _outSpqIndexOnlyScan(StringInfo str, SpqIndexOnlyScan* node) +{ + WRITE_NODE_TYPE("SPQINDEXONLYSCAN"); + _outIndexOnlyScanInfo(str, &node->scan); +} + +static void _outSpqBitmapHeapScan(StringInfo str, SpqBitmapHeapScan* node) +{ + WRITE_NODE_TYPE("SPQBITMAPHEAPSCAN"); + _outBitmapHeapScanInfo(str, &node->scan); +} +#endif + static void _outCStoreIndexCtidScan(StringInfo str, CStoreIndexCtidScan* node) { WRITE_NODE_TYPE("CSTOREINDEXCTIDSCAN"); @@ -6260,6 +6297,15 @@ static void _outNode(StringInfo str, const void* obj) case T_Sequence: _outSequence(str, (Sequence*)obj); break; + case T_SpqIndexScan: + _outSpqIndexScan(str, (SpqIndexScan*)obj); + break; + case T_SpqIndexOnlyScan: + _outSpqIndexOnlyScan(str, (SpqIndexOnlyScan*)obj); + break; + case T_SpqBitmapHeapScan: + _outSpqBitmapHeapScan(str, (SpqBitmapHeapScan*)obj); + break; #endif #ifdef PGXC case T_RemoteQuery: diff --git a/src/common/backend/nodes/readfuncs.cpp b/src/common/backend/nodes/readfuncs.cpp index 80cec675a..1b1495aa1 100755 --- a/src/common/backend/nodes/readfuncs.cpp +++ b/src/common/backend/nodes/readfuncs.cpp @@ -3436,6 +3436,11 @@ static Plan* _readPlan(Plan* local_node) READ_FLOAT_FIELD(pred_total_time); READ_LONG_FIELD(pred_max_memory); } +#ifdef USE_SPQ + if (t_thrd.proc->workingVersionNum >= SPQ_VERSION_NUM) { + READ_BOOL_FIELD(spq_scan_partial); + } +#endif READ_DONE(); } @@ -4767,6 +4772,37 @@ static SpqSeqScan* _readSpqSeqScan(void) READ_END(); } + +static SpqIndexScan* _readSpqIndexScan(void) +{ + READ_LOCALS_NO_FIELDS(SpqIndexScan); + READ_TEMP_LOCALS(); + + _readIndexScan(&local_node->scan); + + READ_END(); +} + +static SpqIndexOnlyScan* _readSpqIndexOnlyScan(void) +{ + READ_LOCALS_NO_FIELDS(SpqIndexOnlyScan); + READ_TEMP_LOCALS(); + + _readIndexOnlyScan(&local_node->scan); + + READ_END(); +} + +static SpqBitmapHeapScan* _readSpqBitmapHeapScan(void) +{ + READ_LOCALS_NO_FIELDS(SpqBitmapHeapScan); + READ_TEMP_LOCALS(); + + _readBitmapHeapScan(&local_node->scan); + + READ_END(); +} + /* * _readAssertOp */ @@ -6475,6 +6511,12 @@ Node* parseNodeString(void) return_value = _readShareInputScan(); } else if (MATCH("SEQUENCE", 8)) { return_value = _readSequence(); + } else if (MATCH("SPQINDEXSCAN", 12)) { + return_value = _readSpqIndexScan(); + } else if (MATCH("SPQINDEXONLYSCAN", 16)) { + return_value = _readSpqIndexOnlyScan(); + } else if (MATCH("SPQBITMAPHEAPSCAN", 17)) { + return_value = _readSpqBitmapHeapScan(); #endif } else if (MATCH("BITMAPHEAPSCAN", 14)) { return_value = _readBitmapHeapScan(NULL); diff --git a/src/common/backend/pgxc_single/pool/execRemote.cpp b/src/common/backend/pgxc_single/pool/execRemote.cpp index 38a14705a..221a0a4e0 100755 --- a/src/common/backend/pgxc_single/pool/execRemote.cpp +++ b/src/common/backend/pgxc_single/pool/execRemote.cpp @@ -1416,11 +1416,10 @@ PGXCNodeHandle** spq_get_exec_connections( /* Set datanode list and DN number */ /* Set Coordinator list and Coordinator number */ // QD count - dn_conn_count = planstmt->num_nodes; + dn_conn_count = planstate->node_count; PGXCNodeHandle** connections = (PGXCNodeHandle **)palloc(dn_conn_count * sizeof(PGXCNodeHandle *)); planstate->spq_connections_info = (PGXCNodeHandle **)palloc(dn_conn_count * sizeof(PGXCNodeHandle *)); planstate->nodeCons = (PGconn **)palloc0(sizeof(PGconn *) * dn_conn_count); - planstate->node_count = dn_conn_count; Oid *dnNode = (Oid *)palloc0(sizeof(Oid) * dn_conn_count); PGconn **nodeCons = planstate->nodeCons; @@ -1533,6 +1532,7 @@ void spq_do_query(RemoteQueryState* node) planstmt->spq_session_id = u_sess->debug_query_id; planstmt->current_id = step->streamID; node->queryId = generate_unique_id64(>_queryId); + node->node_count = step->nodeCount; spq_startQcThread(node); @@ -1586,7 +1586,7 @@ void spq_do_query(RemoteQueryState* node) const_cast(t_thrd.postgres_cxt.debug_query_string ? t_thrd.postgres_cxt.debug_query_string : ""); /* Flag 'Z' to indicate it's serialized plan */ /* todo: SerializePlan DISTRIBUTED_FEATURE_NOT_SUPPORTED */ - SpqSerializePlan(step->scan.plan.lefttree, planstmt, &str_remoteplan, step->num_stream, step->num_gather, true, node->queryId); + SpqSerializePlan(step->scan.plan.lefttree, planstmt, &str_remoteplan, step, true, node->queryId); node->serializedPlan = str_remoteplan.data; /* Compress the 'Z' plan here. */ diff --git a/src/common/backend/utils/adt/ruleutils.cpp b/src/common/backend/utils/adt/ruleutils.cpp index 691c6dc4a..30032df3e 100644 --- a/src/common/backend/utils/adt/ruleutils.cpp +++ b/src/common/backend/utils/adt/ruleutils.cpp @@ -5289,6 +5289,10 @@ static void set_deparse_planstate(deparse_namespace* dpns, PlanState* ps) /* index_tlist is set only if it's an IndexOnlyScan */ if (IsA(ps->plan, IndexOnlyScan)) dpns->index_tlist = ((IndexOnlyScan*)ps->plan)->indextlist; +#ifdef USE_SPQ + else if IsA(ps->plan, SpqIndexOnlyScan) + dpns->index_tlist = ((IndexOnlyScan*)ps->plan)->indextlist; +#endif else if (IsA(ps->plan, ForeignScan)) dpns->index_tlist = ((ForeignScan *)ps->plan)->fdw_scan_tlist; else if (IsA(ps->plan, ExtensiblePlan)) diff --git a/src/common/backend/utils/cache/lsyscache.cpp b/src/common/backend/utils/cache/lsyscache.cpp index 2a2d59bca..d8127630f 100644 --- a/src/common/backend/utils/cache/lsyscache.cpp +++ b/src/common/backend/utils/cache/lsyscache.cpp @@ -6452,6 +6452,17 @@ void spq_free_attstatsslot(AttStatsSlot *sslot) if (sslot->numbers_arr) pfree(sslot->numbers_arr); } + +bool spq_relation_not_partitioned(Oid relid) +{ + HeapTuple tuple; + tuple = SearchSysCache1(PARTRELID, ObjectIdGetDatum(relid)); + if (HeapTupleIsValid(tuple)) { + ReleaseSysCache(tuple); + return false; + } else + return true; +} #endif Oid get_array_internal_depend_type_oid(Oid arrTypOid) diff --git a/src/gausskernel/optimizer/commands/explain.cpp b/src/gausskernel/optimizer/commands/explain.cpp index 6837b3eea..8a801e917 100755 --- a/src/gausskernel/optimizer/commands/explain.cpp +++ b/src/gausskernel/optimizer/commands/explain.cpp @@ -1880,6 +1880,24 @@ static void ExplainNodePartition(const Plan* plan, ExplainState* es) flag = 1; } break; + case T_SpqIndexScan: + if (((SpqIndexScan*)plan->lefttree)->scan.scan.pruningInfo->expr != NULL) { + appendStringInfo(es->str, "Iterations: %s", "PART"); + flag = 1; + } + break; + case T_SpqIndexOnlyScan: + if (((SpqIndexOnlyScan*)plan->lefttree)->scan.scan.pruningInfo->expr != NULL) { + appendStringInfo(es->str, "Iterations: %s", "PART"); + flag = 1; + } + break; + case T_SpqBitmapHeapScan: + if (((SpqBitmapHeapScan*)plan->lefttree)->scan.scan.pruningInfo->expr != NULL) { + appendStringInfo(es->str, "Iterations: %s", "PART"); + flag = 1; + } + break; #endif case T_IndexScan: if (((IndexScan*)plan->lefttree)->scan.pruningInfo->expr != NULL) { @@ -1947,6 +1965,9 @@ static bool GetSubPartitionIterations(const Plan* plan, const ExplainState* es, case T_SeqScan: #ifdef USE_SPQ case T_SpqSeqScan: + case T_SpqIndexScan: + case T_SpqIndexOnlyScan: + case T_SpqBitmapHeapScan: #endif case T_IndexScan: case T_IndexOnlyScan: @@ -2129,6 +2150,7 @@ static void ExplainNode( case T_SeqScan: #ifdef USE_SPQ case T_SpqSeqScan: + case T_SpqBitmapHeapScan: #endif case T_CStoreScan: #ifdef ENABLE_MULTIPLE_NODES @@ -2192,6 +2214,9 @@ static void ExplainNode( #endif ExplainScanTarget((Scan*)plan, es); break; +#endif +#ifdef USE_SPQ + case T_SpqIndexScan: #endif case T_IndexScan: { IndexScan* indexscan = (IndexScan*)plan; @@ -2202,6 +2227,9 @@ static void ExplainNode( pt_index_name = explain_get_index_name(indexscan->indexid); pt_index_owner = get_namespace_name(get_rel_namespace(indexscan->indexid)); } break; +#ifdef USE_SPQ + case T_SpqIndexOnlyScan: +#endif case T_IndexOnlyScan: { IndexOnlyScan* indexonlyscan = (IndexOnlyScan*)plan; @@ -2612,6 +2640,9 @@ static void ExplainNode( /* quals, sort keys, etc */ switch (nodeTag(plan)) { +#ifdef USE_SPQ + case T_SpqIndexScan: +#endif case T_IndexScan: show_scan_qual(((IndexScan*)plan)->indexqualorig, "Index Cond", planstate, ancestors, es); if (((IndexScan*)plan)->indexqualorig) @@ -2621,6 +2652,9 @@ static void ExplainNode( if (plan->qual) show_instrumentation_count("Rows Removed by Filter", 1, planstate, es); break; +#ifdef USE_SPQ + case T_SpqIndexOnlyScan: +#endif case T_IndexOnlyScan: show_scan_qual(((IndexOnlyScan*)plan)->indexqual, "Index Cond", planstate, ancestors, es); if (((IndexOnlyScan*)plan)->indexqual) @@ -2726,6 +2760,9 @@ static void ExplainNode( case T_ModifyTable: show_modifytable_info((ModifyTableState*)planstate, es); break; +#endif +#ifdef USE_SPQ + case T_SpqBitmapHeapScan: #endif case T_BitmapHeapScan: case T_CStoreIndexHeapScan: @@ -3141,6 +3178,8 @@ static void ExplainNode( #endif /* ENABLE_MULTIPLE_NODES */ #ifdef USE_SPQ case T_SpqSeqScan: + case T_SpqIndexScan: + case T_SpqIndexOnlyScan: #endif case T_IndexScan: case T_IndexOnlyScan: diff --git a/src/gausskernel/optimizer/plan/setrefs.cpp b/src/gausskernel/optimizer/plan/setrefs.cpp index f2e2b7431..67653c84e 100644 --- a/src/gausskernel/optimizer/plan/setrefs.cpp +++ b/src/gausskernel/optimizer/plan/setrefs.cpp @@ -331,6 +331,9 @@ static Plan* set_plan_refs(PlannerInfo* root, Plan* plan, int rtoffset) splan->tablesample = (TableSampleClause*)fix_scan_expr(root, (Node*)splan->tablesample, rtoffset); } } break; +#ifdef USE_SPQ + case T_SpqIndexScan: +#endif case T_IndexScan: { IndexScan* splan = (IndexScan*)plan; @@ -345,6 +348,9 @@ static Plan* set_plan_refs(PlannerInfo* root, Plan* plan, int rtoffset) splan->indexorderby = fix_scan_list(root, splan->indexorderby, rtoffset); splan->indexorderbyorig = fix_scan_list(root, splan->indexorderbyorig, rtoffset); } break; +#ifdef USE_SPQ + case T_SpqIndexOnlyScan: +#endif case T_IndexOnlyScan: { IndexOnlyScan* splan = (IndexOnlyScan*)plan; if (splan->scan.plan.distributed_keys != NIL) { @@ -369,6 +375,9 @@ static Plan* set_plan_refs(PlannerInfo* root, Plan* plan, int rtoffset) splan->baserelcstorequal = fix_scan_list(root, splan->baserelcstorequal, rtoffset); splan->indextlist = fix_scan_list(root, splan->indextlist, rtoffset); } break; +#ifdef USE_SPQ + case T_SpqBitmapHeapScan: +#endif case T_BitmapIndexScan: { BitmapIndexScan* splan = (BitmapIndexScan*)plan; diff --git a/src/gausskernel/optimizer/plan/streamplan_single.cpp b/src/gausskernel/optimizer/plan/streamplan_single.cpp index 0f6334e85..57db49ec0 100644 --- a/src/gausskernel/optimizer/plan/streamplan_single.cpp +++ b/src/gausskernel/optimizer/plan/streamplan_single.cpp @@ -447,7 +447,7 @@ static void set_node_ref_subplan(Plan* plan, PlannedStmt* planned_stmt, PlannedS * Serialized the plan tree to string */ void SpqSerializePlan(Plan* node, PlannedStmt* planned_stmt, StringInfoData* str, - int num_stream, int num_gather, bool push_subplan, uint64 queryId) + RemoteQuery* step, bool push_subplan, uint64 queryId) { PlannedStmt* ShipPlannedStmt = NULL; ShipPlannedStmt = makeNode(PlannedStmt); @@ -506,9 +506,9 @@ void SpqSerializePlan(Plan* node, PlannedStmt* planned_stmt, StringInfoData* str ShipPlannedStmt->relationOids = planned_stmt->relationOids; ShipPlannedStmt->invalItems = planned_stmt->invalItems; ShipPlannedStmt->nParamExec = planned_stmt->nParamExec; - ShipPlannedStmt->num_streams = num_stream; - ShipPlannedStmt->gather_count = num_gather; - ShipPlannedStmt->num_nodes = planned_stmt->num_nodes; + ShipPlannedStmt->num_streams = step->num_stream; + ShipPlannedStmt->gather_count = step->num_gather; + ShipPlannedStmt->num_nodes = step->nodeCount; ShipPlannedStmt->nodesDefinition = planned_stmt->nodesDefinition; /* We don't send instrument option to datanode for un-stream plan. * For un-stream plan, we can not finalize node id and parent node id for result plan. diff --git a/src/gausskernel/optimizer/util/learn/encoding.cpp b/src/gausskernel/optimizer/util/learn/encoding.cpp index 0a539cfe3..4697cacb3 100644 --- a/src/gausskernel/optimizer/util/learn/encoding.cpp +++ b/src/gausskernel/optimizer/util/learn/encoding.cpp @@ -49,7 +49,7 @@ typedef struct { } OperationInfo; #ifdef USE_SPQ -const unsigned int G_MAX_OPERATION_NUMBER = 66; +const unsigned int G_MAX_OPERATION_NUMBER = 69; #else const unsigned int G_MAX_OPERATION_NUMBER = 65; #endif @@ -77,6 +77,9 @@ const OperationInfo G_OPERATION_INFO_TABLE[G_MAX_OPERATION_NUMBER] = { {T_SeqScan, TEXT_OPTNAME_SCAN, TEXT_STRATEGY_SCAN_SEQ}, #ifdef USE_SPQ {T_SpqSeqScan, TEXT_OPTNAME_SCAN, TEXT_STRATEGY_SCAN_SEQ}, + {T_SpqIndexScan, TEXT_OPTNAME_SCAN, TEXT_STRATEGY_SCAN_INDEX}, + {T_SpqIndexOnlyScan, TEXT_OPTNAME_SCAN, TEXT_STRATEGY_SCAN_INDEX_ONLY}, + {T_SpqBitmapHeapScan, TEXT_OPTNAME_SCAN, TEXT_STRATEGY_SCAN_BITMAP_HEAP}, #endif {T_IndexScan, TEXT_OPTNAME_SCAN, TEXT_STRATEGY_SCAN_INDEX}, {T_CStoreIndexScan, TEXT_OPTNAME_SCAN, TEXT_STRATEGY_SCAN_INDEX}, diff --git a/src/gausskernel/optimizer/util/optcommon.cpp b/src/gausskernel/optimizer/util/optcommon.cpp index 0330f915e..f2b4018d2 100755 --- a/src/gausskernel/optimizer/util/optcommon.cpp +++ b/src/gausskernel/optimizer/util/optcommon.cpp @@ -156,6 +156,27 @@ void GetPlanNodePlainText( case T_Sequence: *pname = *sname = *pt_operation = "Sequence"; break; + case T_SpqIndexScan: + *pt_operation = "INDEX"; + if (((IndexScan*)plan)->scan.isPartTbl) + *pname = *sname = *pt_options = "Partitioned Index Scan"; + else + *pname = *sname = *pt_options = "Spq Index Scan"; + break; + case T_SpqIndexOnlyScan: + *pt_operation = "INDEX"; + if (((IndexOnlyScan*)plan)->scan.isPartTbl) + *pname = *sname = *pt_options = "Partitioned Index Only Scan"; + else + *pname = *sname = *pt_options = "Spq Index Only Scan"; + break; + case T_SpqBitmapHeapScan: + *pt_operation = "TABLE ACCESS"; + if (((Scan*)plan)->isPartTbl) + *pname = *sname = *pt_options = "Partitioned Bitmap Heap Scan"; + else + *pname = *sname = *pt_options = "Spq Bitmap Heap Scan"; + break; #endif case T_CStoreScan: *pt_operation = "TABLE ACCESS"; diff --git a/src/gausskernel/optimizer/util/planmem_walker.cpp b/src/gausskernel/optimizer/util/planmem_walker.cpp index 2ac4ab804..72c998635 100644 --- a/src/gausskernel/optimizer/util/planmem_walker.cpp +++ b/src/gausskernel/optimizer/util/planmem_walker.cpp @@ -295,6 +295,9 @@ bool plan_tree_walker(Node* node, MethodWalker walker, void* context) if (p2walker((Node*)((ExtensiblePlan*)node)->extensible_exprs, context)) return true; break; +#ifdef USE_SPQ + case T_SpqIndexScan: +#endif case T_IndexScan: if (walk_scan_node_fields((Scan*)node, walker, context)) return true; @@ -302,7 +305,9 @@ bool plan_tree_walker(Node* node, MethodWalker walker, void* context) return true; /* Other fields are lists of basic items, nothing to walk. */ break; - +#ifdef USE_SPQ + case T_SpqIndexOnlyScan: +#endif case T_IndexOnlyScan: if (walk_scan_node_fields((Scan*)node, walker, context)) return true; @@ -336,6 +341,9 @@ bool plan_tree_walker(Node* node, MethodWalker walker, void* context) break; case T_CStoreIndexHeapScan: +#ifdef USE_SPQ + case T_SpqBitmapHeapScan: +#endif case T_BitmapHeapScan: if (walk_scan_node_fields((Scan*)node, walker, context)) return true; diff --git a/src/gausskernel/runtime/executor/Makefile b/src/gausskernel/runtime/executor/Makefile index 4c3ad668d..75189777c 100644 --- a/src/gausskernel/runtime/executor/Makefile +++ b/src/gausskernel/runtime/executor/Makefile @@ -50,7 +50,7 @@ OBJS = execAmi.o execCurrent.o execGrouping.o execJunk.o execMain.o \ nodePartIterator.o nodeStub.o execClusterResize.o lightProxy.o execMerge.o \ nodeExtensible.o route.o nodeTrainModel.o db4ai_common.o spiDbesql.o \ nodeProjectSet.o nodeSortGroup.o nodeAssertOp.o nodeSequence.o \ - nodeShareInputScan.o nodeSpqSeqscan.o + nodeShareInputScan.o nodeSpqSeqscan.o nodeSpqIndexscan.o nodeSpqIndexonlyscan.o nodeSpqBitmapHeapscan.o override CPPFLAGS += -D__STDC_FORMAT_MACROS diff --git a/src/gausskernel/runtime/executor/execProcnode.cpp b/src/gausskernel/runtime/executor/execProcnode.cpp index 7e94c8717..911c0b923 100755 --- a/src/gausskernel/runtime/executor/execProcnode.cpp +++ b/src/gausskernel/runtime/executor/execProcnode.cpp @@ -165,6 +165,9 @@ #include "executor/node/nodeAssertOp.h" #include "executor/node/nodeShareInputScan.h" #include "executor/node/nodeSequence.h" +#include "executor/node/nodeSpqIndexscan.h" +#include "executor/node/nodeSpqIndexonlyscan.h" +#include "executor/node/nodeSpqBitmapHeapscan.h" #endif #define NODENAMELEN 64 static TupleTableSlot *ExecProcNodeFirst(PlanState *node); @@ -287,7 +290,8 @@ PlanState* ExecInitNodeByType(Plan* node, EState* estate, int eflags) if (init_spqscan_hook) { return (PlanState*)init_spqscan_hook((SpqSeqScan*)node, estate, eflags); } else { - ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("spqscan hook init_spqscan_hook uninited."))); + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("spqscan hook init_spqscan_hook uninited."))); } case T_AssertOp: return (PlanState *) ExecInitAssertOp((AssertOp *) node, estate, eflags); @@ -295,6 +299,27 @@ PlanState* ExecInitNodeByType(Plan* node, EState* estate, int eflags) return (PlanState *)ExecInitShareInputScan((ShareInputScan *)node, estate, eflags); case T_Sequence: return (PlanState *)ExecInitSequence((Sequence *)node, estate, eflags); + case T_SpqIndexScan: + if (init_indexscan_hook) { + return (PlanState*)init_indexscan_hook((SpqIndexScan*)node, estate, eflags); + } else { + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("spqindexscan hook init_spqindexscan_hook uninited."))); + } + case T_SpqIndexOnlyScan: + if (init_indexonlyscan_hook) { + return (PlanState*)init_indexonlyscan_hook((SpqIndexOnlyScan*)node, estate, eflags); + } else { + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("spqindexonlyscan hook init_spqindexonlyscan_hook uninited."))); + } + case T_SpqBitmapHeapScan: + if (init_bitmapheapscan_hook) { + return (PlanState*)init_bitmapheapscan_hook((SpqBitmapHeapScan*)node, estate, eflags); + } else { + ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("spqbitmapheapscan hook init_spqbitmapheapscan_hook uninited."))); + } #endif case T_IndexScan: return (PlanState*)ExecInitIndexScan((IndexScan*)node, estate, eflags); diff --git a/src/gausskernel/runtime/executor/execScan.cpp b/src/gausskernel/runtime/executor/execScan.cpp index c767070b7..8c9a8aa7e 100755 --- a/src/gausskernel/runtime/executor/execScan.cpp +++ b/src/gausskernel/runtime/executor/execScan.cpp @@ -304,6 +304,10 @@ void ExecAssignScanProjectionInfo(ScanState* node) /* Vars in an index-only scan's tlist should be INDEX_VAR */ if (IsA(scan, IndexOnlyScan)) var_no = INDEX_VAR; +#ifdef USE_SPQ + else if (IsA(scan, SpqIndexOnlyScan)) + var_no = INDEX_VAR; +#endif else var_no = scan->scanrelid; diff --git a/src/gausskernel/runtime/executor/instrument.cpp b/src/gausskernel/runtime/executor/instrument.cpp index aec6b1ab7..bcef542ce 100644 --- a/src/gausskernel/runtime/executor/instrument.cpp +++ b/src/gausskernel/runtime/executor/instrument.cpp @@ -1033,6 +1033,27 @@ Instrumentation* ThreadInstrumentation::allocInstrSlot(int plan_node_id, int par pname = "Sequence"; plan_type = UTILITY_OP; break; + case T_SpqIndexScan: + if (((IndexScan*)plan)->scan.isPartTbl) + pname = "Partitioned Index Scan"; + else + pname = "Spq Index Scan"; + plan_type = IO_OP; + break; + case T_SpqIndexOnlyScan: + if (((IndexOnlyScan*)plan)->scan.isPartTbl) + pname = "Partitioned Index Only Scan"; + else + pname = "Spq Index Only Scan"; + plan_type = IO_OP; + break; + case T_SpqBitmapHeapScan: + if (((Scan*)plan)->isPartTbl) + pname = "Partitioned Bitmap Heap Scan"; + else + pname = "Spq Bitmap Heap Scan"; + plan_type = IO_OP; + break; #endif case T_SeqScan: if (!((Scan*)plan)->tablesample) { diff --git a/src/gausskernel/runtime/executor/nodeBitmapHeapscan.cpp b/src/gausskernel/runtime/executor/nodeBitmapHeapscan.cpp index d0df2e7df..d6fdb7cf4 100644 --- a/src/gausskernel/runtime/executor/nodeBitmapHeapscan.cpp +++ b/src/gausskernel/runtime/executor/nodeBitmapHeapscan.cpp @@ -63,12 +63,12 @@ #include "nodes/makefuncs.h" #include "optimizer/pruning.h" -static TupleTableSlot* ExecBitmapHeapScan(PlanState* state); -static TupleTableSlot* BitmapHbucketTblNext(BitmapHeapScanState* node); +TupleTableSlot* ExecBitmapHeapScan(PlanState* state); +TupleTableSlot* BitmapHbucketTblNext(BitmapHeapScanState* node); static TupleTableSlot* BitmapHeapTblNext(BitmapHeapScanState* node); bool heapam_scan_bitmap_next_block(TableScanDesc scan, TBMIterateResult* tbmres, bool* has_cur_xact_write = NULL); -static void ExecInitPartitionForBitmapHeapScan(BitmapHeapScanState* scanstate, EState* estate); +void ExecInitPartitionForBitmapHeapScan(BitmapHeapScanState* scanstate, EState* estate); static void ExecInitNextPartitionForBitmapHeapScan(BitmapHeapScanState* node); void BitmapHeapPrefetchNext( BitmapHeapScanState* node, TableScanDesc scan, const TIDBitmap* tbm, TBMIterator** prefetch_iterator); @@ -96,7 +96,7 @@ void BitmapHeapFree(BitmapHeapScanState* node) } node->tbmres = NULL; } -static TupleTableSlot* BitmapHbucketTblNext(BitmapHeapScanState* node) +TupleTableSlot* BitmapHbucketTblNext(BitmapHeapScanState* node) { Assert(node->ss.ss_currentScanDesc != NULL); HBktTblScanDesc hpScan = (HBktTblScanDesc)node->ss.ss_currentScanDesc; @@ -167,7 +167,7 @@ bool HeapamScanBitmapNextTuple(TableScanDesc scan, return true; } -static bool TableScanBitmapNextTuple(TableScanDesc scan, TBMIterateResult *tbmres, TupleTableSlot *slot) +bool TableScanBitmapNextTuple(TableScanDesc scan, TBMIterateResult *tbmres, TupleTableSlot *slot) { bool isUstore = RelationIsUstoreFormat(scan->rs_rd); if (isUstore) { @@ -177,7 +177,7 @@ static bool TableScanBitmapNextTuple(TableScanDesc scan, TBMIterateResult *tbmre } } -static bool TableScanBitmapNextBlock(TableScanDesc scan, TBMIterateResult *tbmres, bool* has_cur_xact_write) +bool TableScanBitmapNextBlock(TableScanDesc scan, TBMIterateResult *tbmres, bool* has_cur_xact_write) { bool isUstore = RelationIsUstoreFormat(scan->rs_rd); if (isUstore) { @@ -193,7 +193,7 @@ static bool TableScanBitmapNextBlock(TableScanDesc scan, TBMIterateResult *tbmre * * Return values: 0: success; -1: fail; 1: need to prefetch. */ -static int TableScanBitmapNextTargetRel(TableScanDesc scan, BitmapHeapScanState *node) +int TableScanBitmapNextTargetRel(TableScanDesc scan, BitmapHeapScanState *node) { Assert(scan != NULL); Assert(node != NULL); @@ -613,7 +613,7 @@ static bool BitmapHeapRecheck(BitmapHeapScanState* node, TupleTableSlot* slot) * ExecBitmapHeapScan(node) * ---------------------------------------------------------------- */ -static TupleTableSlot* ExecBitmapHeapScan(PlanState* state) +TupleTableSlot* ExecBitmapHeapScan(PlanState* state) { BitmapHeapScanState* node = castNode(BitmapHeapScanState, state); return ExecScan(&node->ss, node->ss.ScanNextMtd, (ExecScanRecheckMtd)BitmapHeapRecheck); @@ -1002,7 +1002,7 @@ static void ExecInitNextPartitionForBitmapHeapScan(BitmapHeapScanState* node) * Output : * Notes : */ -static void ExecInitPartitionForBitmapHeapScan(BitmapHeapScanState* scanstate, EState* estate) +void ExecInitPartitionForBitmapHeapScan(BitmapHeapScanState* scanstate, EState* estate) { BitmapHeapScan* plan = NULL; Relation currentRelation = NULL; diff --git a/src/gausskernel/runtime/executor/nodeSpqBitmapHeapscan.cpp b/src/gausskernel/runtime/executor/nodeSpqBitmapHeapscan.cpp new file mode 100644 index 000000000..b7c0641ef --- /dev/null +++ b/src/gausskernel/runtime/executor/nodeSpqBitmapHeapscan.cpp @@ -0,0 +1,19 @@ +/* ------------------------------------------------------------------------- +* +* nodeSpqBitmapHeapscan.cpp +* Support routines for sequential scans of relations. +* +* Portions Copyright (c) 2023 Huawei Technologies Co.,Ltd. +* +* +* IDENTIFICATION +* src/gausskernel/runtime/executor/nodeSpqBitmapHeapscan.cpp +* +* ------------------------------------------------------------------------- + */ +#ifdef USE_SPQ +#include "executor/node/nodeSpqBitmapHeapscan.h" + +THR_LOCAL init_spqbitmapheapscan_hook_type init_bitmapheapscan_hook = nullptr; +THR_LOCAL exec_spqbitmapheapscan_hook_type exec_bitmapheapscan_hook = nullptr; +#endif diff --git a/src/gausskernel/runtime/executor/nodeSpqIndexonlyscan.cpp b/src/gausskernel/runtime/executor/nodeSpqIndexonlyscan.cpp new file mode 100644 index 000000000..6182f212d --- /dev/null +++ b/src/gausskernel/runtime/executor/nodeSpqIndexonlyscan.cpp @@ -0,0 +1,19 @@ +/* ------------------------------------------------------------------------- +* +* nodeSpqIndexonlyscan.cpp +* Support routines for sequential scans of relations. +* +* Portions Copyright (c) 2023 Huawei Technologies Co.,Ltd. +* +* +* IDENTIFICATION +* src/gausskernel/runtime/executor/nodeSpqIndexonlyscan.cpp +* +* ------------------------------------------------------------------------- + */ +#ifdef USE_SPQ +#include "executor/node/nodeSpqIndexonlyscan.h" + +THR_LOCAL init_spqindexonlyscan_hook_type init_indexonlyscan_hook = nullptr; +THR_LOCAL exec_spqindexonlyscan_hook_type exec_indexonlyscan_hook = nullptr; +#endif diff --git a/src/gausskernel/runtime/executor/nodeSpqIndexscan.cpp b/src/gausskernel/runtime/executor/nodeSpqIndexscan.cpp new file mode 100644 index 000000000..0dd319404 --- /dev/null +++ b/src/gausskernel/runtime/executor/nodeSpqIndexscan.cpp @@ -0,0 +1,19 @@ +/* ------------------------------------------------------------------------- +* +* nodeSpqIndexscan.cpp +* Support routines for sequential scans of relations. +* +* Portions Copyright (c) 2023 Huawei Technologies Co.,Ltd. +* +* +* IDENTIFICATION +* src/gausskernel/runtime/executor/nodeSpqIndexscan.cpp +* +* ------------------------------------------------------------------------- + */ +#ifdef USE_SPQ +#include "executor/node/nodeSpqIndexscan.h" + +THR_LOCAL init_spqindexscan_hook_type init_indexscan_hook = nullptr; +THR_LOCAL exec_spqindexscan_hook_type exec_indexscan_hook = nullptr; +#endif \ No newline at end of file diff --git a/src/gausskernel/runtime/executor/nodeStub.cpp b/src/gausskernel/runtime/executor/nodeStub.cpp index c8dd97490..760185b3e 100644 --- a/src/gausskernel/runtime/executor/nodeStub.cpp +++ b/src/gausskernel/runtime/executor/nodeStub.cpp @@ -164,13 +164,20 @@ void ExecEndNodeStubScan(PlanState* node) } break; } + case T_SpqIndexScan: #endif case T_IndexScan: ExecEndIndexScan((IndexScanState*)node); break; +#ifdef USE_SPQ + case T_SpqIndexOnlyScan: +#endif case T_IndexOnlyScan: ExecEndIndexOnlyScan((IndexOnlyScanState*)node); break; +#ifdef USE_SPQ + case T_SpqBitmapHeapScan: +#endif case T_BitmapIndexScan: ExecEndBitmapIndexScan((BitmapIndexScanState*)node); break; diff --git a/src/gausskernel/storage/access/heap/heapam.cpp b/src/gausskernel/storage/access/heap/heapam.cpp index e950e2e47..fa43969c3 100755 --- a/src/gausskernel/storage/access/heap/heapam.cpp +++ b/src/gausskernel/storage/access/heap/heapam.cpp @@ -1889,6 +1889,10 @@ TableScanDesc heap_beginscan_internal(Relation relation, Snapshot snapshot, int initscan(scan, key, false); +#ifdef USE_SPQ + scan->spq_scan = NULL; +#endif + return (TableScanDesc)scan; } diff --git a/src/gausskernel/storage/access/index/indexam.cpp b/src/gausskernel/storage/access/index/indexam.cpp index 10527848a..a1c33554a 100644 --- a/src/gausskernel/storage/access/index/indexam.cpp +++ b/src/gausskernel/storage/access/index/indexam.cpp @@ -286,7 +286,9 @@ IndexScanDesc index_beginscan_bitmap(Relation index_relation, Snapshot snapshot, * up by RelationGetIndexScan. */ scan->xs_snapshot = snapshot; - +#ifdef USE_SPQ + scan->spq_scan = NULL; +#endif return scan; } @@ -318,6 +320,9 @@ static IndexScanDesc index_beginscan_internal(Relation index_relation, int nkeys scan = (IndexScanDesc)DatumGetPointer( FunctionCall3(procedure, PointerGetDatum(index_relation), Int32GetDatum(nkeys), Int32GetDatum(norderbys))); } +#ifdef USE_SPQ + scan->spq_scan = NULL; +#endif return scan; } @@ -487,7 +492,9 @@ ItemPointer index_getnext_tid(IndexScanDesc scan, ScanDirection direction) GET_SCAN_PROCEDURE(amgettuple); Assert(TransactionIdIsValid(u_sess->utils_cxt.RecentGlobalXmin)); - +#ifdef USE_SPQ +rescan: +#endif /* * The AM's amgettuple proc finds the next index entry matching the scan * keys, and puts the TID into scan->xs_ctup.t_self. It should also set @@ -515,7 +522,13 @@ ItemPointer index_getnext_tid(IndexScanDesc scan, ScanDirection direction) } return NULL; } - +#ifdef USE_SPQ + if (IS_SPQ_EXECUTOR && scan->spq_scan != NULL) { + BlockNumber unitno = SPQSCAN_BlockNum2UnitNum(ItemPointerGetBlockNumber(&scan->xs_ctup.t_self)); + if ((unitno % scan->spq_scan->slice_num) != scan->spq_scan->instance_id) + goto rescan; + } +#endif pgstat_count_index_tuples(scan->indexRelation, 1); /* Return the TID of the tuple we found. */ diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h index 18d038076..f151c7c01 100644 --- a/src/include/access/relscan.h +++ b/src/include/access/relscan.h @@ -47,6 +47,18 @@ typedef struct ParallelHeapScanDescData { bool isplain; /* is plain table or not */ } ParallelHeapScanDescData; +#ifdef USE_SPQ +typedef struct SPQScanDescData { + int instance_id; /* local segment index for current spq workers */ + int slice_num; /* local segment total count for current spq workers */ +} SPQScanDescData; + +typedef SPQScanDescData* SPQScanDesc; + +#define SPQSCAN_UNIT_BIT (u_sess->attr.attr_spq.spq_scan_unit_bit) +#define SPQSCAN_BlockNum2UnitNum(blockno) ((blockno) >> SPQSCAN_UNIT_BIT) +#endif + typedef struct HeapScanDescData { TableScanDescData rs_base; /* AM independent part of the descriptor */ @@ -70,6 +82,10 @@ typedef struct HeapScanDescData { HeapTupleData* rs_ctupBatch; +#ifdef USE_SPQ + SPQScanDesc spq_scan; +#endif + /* this must be the end of this sturcture */ HeapTupleHeaderData rs_ctbuf_hdr; } HeapScanDescData; @@ -146,6 +162,9 @@ typedef struct IndexScanDescData { /* state data for traversing HOT chains in index_getnext */ bool xs_continue_hot; /* T if must keep walking HOT chain */ +#ifdef USE_SPQ + SPQScanDesc spq_scan; +#endif IndexFetchTableData *xs_heapfetch; /* put decompressed heap tuple data into xs_ctbuf_hdr be careful! when malloc memory should give extra mem for *xs_ctbuf_hdr. t_bits which is varlength arr diff --git a/src/include/executor/node/nodeBitmapHeapscan.h b/src/include/executor/node/nodeBitmapHeapscan.h index 09c156020..0b0f1a411 100644 --- a/src/include/executor/node/nodeBitmapHeapscan.h +++ b/src/include/executor/node/nodeBitmapHeapscan.h @@ -19,5 +19,14 @@ extern BitmapHeapScanState* ExecInitBitmapHeapScan(BitmapHeapScan* node, EState* estate, int eflags); extern void ExecEndBitmapHeapScan(BitmapHeapScanState* node); extern void ExecReScanBitmapHeapScan(BitmapHeapScanState* node); +extern void BitmapHeapPrefetchNext(BitmapHeapScanState* node, TableScanDesc scan, const TIDBitmap* tbm, + TBMIterator** prefetch_iterator); +extern void ExecInitPartitionForBitmapHeapScan(BitmapHeapScanState* scanstate, EState* estate); +extern TupleTableSlot* BitmapHbucketTblNext(BitmapHeapScanState* node); +extern bool TableScanBitmapNextTuple(TableScanDesc scan, TBMIterateResult *tbmres, TupleTableSlot *slot); +extern bool TableScanBitmapNextBlock(TableScanDesc scan, TBMIterateResult *tbmres, bool* has_cur_xact_write); +extern int TableScanBitmapNextTargetRel(TableScanDesc scan, BitmapHeapScanState *node); +extern TupleTableSlot* ExecBitmapHeapScan(PlanState* state); +extern void ExecInitPartitionForBitmapHeapScan(BitmapHeapScanState* scanstate, EState* estate); #endif /* NODEBITMAPHEAPSCAN_H */ diff --git a/src/include/executor/node/nodeSpqBitmapHeapscan.h b/src/include/executor/node/nodeSpqBitmapHeapscan.h new file mode 100644 index 000000000..b0802ce81 --- /dev/null +++ b/src/include/executor/node/nodeSpqBitmapHeapscan.h @@ -0,0 +1,24 @@ +/* ------------------------------------------------------------------------- + * + * nodeSpqBitmapHeapscan.h + * + * Portions Copyright (c) 2023 Huawei Technologies Co.,Ltd. + * + * src/include/executor/node/nodeSpqBitmapHeapscan.h + * + * ------------------------------------------------------------------------- + */ +#ifdef USE_SPQ +#ifndef NODESPQBITMAPHEAPSCAN_H +#define NODESPQBITMAPHEAPSCAN_H + +#include "nodes/execnodes.h" + +typedef BitmapHeapScanState* (*init_spqbitmapheapscan_hook_type)(SpqBitmapHeapScan* node, EState* estate, int eflags); +typedef TupleTableSlot* (*exec_spqbitmapheapscan_hook_type)(PlanState* node); + +extern THR_LOCAL init_spqbitmapheapscan_hook_type init_bitmapheapscan_hook; +extern THR_LOCAL exec_spqbitmapheapscan_hook_type exec_bitmapheapscan_hook; + +#endif // NODESPQBITMAPHEAPSCAN_H +#endif diff --git a/src/include/executor/node/nodeSpqIndexonlyscan.h b/src/include/executor/node/nodeSpqIndexonlyscan.h new file mode 100644 index 000000000..cf29b415d --- /dev/null +++ b/src/include/executor/node/nodeSpqIndexonlyscan.h @@ -0,0 +1,24 @@ +/* ------------------------------------------------------------------------- +* +* nodeSpqIndexonlyscan.h +* +* Portions Copyright (c) 2023 Huawei Technologies Co.,Ltd. +* +* src/include/executor/node/nodeSpqIndexonlyscan.h +* +* ------------------------------------------------------------------------- + */ +#ifdef USE_SPQ +#ifndef NODESPQINDEXONLYSCAN_H +#define NODESPQINDEXONLYSCAN_H + +#include "nodes/execnodes.h" + +typedef IndexOnlyScanState* (*init_spqindexonlyscan_hook_type)(SpqIndexOnlyScan* node, EState* estate, int eflags); +typedef TupleTableSlot* (*exec_spqindexonlyscan_hook_type)(PlanState* node); + +extern THR_LOCAL init_spqindexonlyscan_hook_type init_indexonlyscan_hook; +extern THR_LOCAL exec_spqindexonlyscan_hook_type exec_indexonlyscan_hook; + +#endif // NODESPQINDEXONLYSCAN_H +#endif \ No newline at end of file diff --git a/src/include/executor/node/nodeSpqIndexscan.h b/src/include/executor/node/nodeSpqIndexscan.h new file mode 100644 index 000000000..a7b8e4fd2 --- /dev/null +++ b/src/include/executor/node/nodeSpqIndexscan.h @@ -0,0 +1,24 @@ +/* ------------------------------------------------------------------------- + * + * nodeSpqIndexscan.h + * + * Portions Copyright (c) 2023 Huawei Technologies Co.,Ltd. + * + * src/include/executor/node/nodeSpqIndexscan.h + * + * ------------------------------------------------------------------------- + */ +#ifdef USE_SPQ +#ifndef NODESPQINDEXSCAN_H +#define NODESPQINDEXSCAN_H + +#include "nodes/execnodes.h" + +typedef IndexScanState* (*init_spqindexscan_hook_type)(SpqIndexScan* node, EState* estate, int eflags); +typedef TupleTableSlot* (*exec_spqindexscan_hook_type)(PlanState* node); + +extern THR_LOCAL init_spqindexscan_hook_type init_indexscan_hook; +extern THR_LOCAL exec_spqindexscan_hook_type exec_indexscan_hook; + +#endif // NODESPQINDEXSCAN_H +#endif diff --git a/src/include/executor/node/nodeSpqSeqscan.h b/src/include/executor/node/nodeSpqSeqscan.h index c3cff808c..33819276f 100644 --- a/src/include/executor/node/nodeSpqSeqscan.h +++ b/src/include/executor/node/nodeSpqSeqscan.h @@ -1,12 +1,12 @@ /* ------------------------------------------------------------------------- -* -* nodeSpqSeqscan.h -* -* Portions Copyright (c) 2023 Huawei Technologies Co.,Ltd. -* -* src/include/executor/node/nodeSpqSeqscan.h -* -* ------------------------------------------------------------------------- + * + * nodeSpqSeqscan.h + * + * Portions Copyright (c) 2023 Huawei Technologies Co.,Ltd. + * + * src/include/executor/node/nodeSpqSeqscan.h + * + * ------------------------------------------------------------------------- */ #ifdef USE_SPQ #ifndef NODESPQSEQSCAN_H diff --git a/src/include/knl/knl_guc/knl_session_attr_spq.h b/src/include/knl/knl_guc/knl_session_attr_spq.h index a7ca4e8a5..225875226 100644 --- a/src/include/knl/knl_guc/knl_session_attr_spq.h +++ b/src/include/knl/knl_guc/knl_session_attr_spq.h @@ -162,6 +162,7 @@ typedef struct knl_session_attr_spq { bool spq_optimizer_force_expanded_distinct_aggs; bool spq_optimizer_force_agg_skew_avoidance; bool spq_optimizer_penalize_skew; + bool spq_enable_left_index_nestloop_join; bool spq_optimizer_prune_computed_columns; bool spq_optimizer_push_requirements_from_consumer_to_producer; bool spq_optimizer_enforce_subplans; @@ -186,7 +187,8 @@ typedef struct knl_session_attr_spq { bool spq_debug_cancel_print; bool spq_print_direct_dispatch_info; bool spq_log_dispatch_stats; - + bool spq_debug_slice_print; + int spq_scan_unit_size; int spq_scan_unit_bit; char *gauss_cluster_map; diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h index d0e4ac754..dad691b01 100755 --- a/src/include/nodes/nodes.h +++ b/src/include/nodes/nodes.h @@ -63,6 +63,9 @@ typedef enum NodeTag { T_SeqScan, #ifdef USE_SPQ T_SpqSeqScan, + T_SpqIndexScan, + T_SpqIndexOnlyScan, + T_SpqBitmapHeapScan, #endif T_IndexScan, T_IndexOnlyScan, @@ -124,8 +127,6 @@ typedef enum NodeTag { #endif #ifdef USE_SPQ T_Sequence, - T_DynamicSeqScan, - T_DynamicBitmapHeapScan, T_Motion, T_ShareInputScan, T_SplitUpdate, diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 730e9f0b8..7fba1981e 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -199,6 +199,9 @@ typedef struct PlannedStmt { int current_id; bool enable_adaptive_scan; bool is_spq_optmized; + int numSlices; + struct PlanSlice *slices; + int *subplan_sliceIds; #endif } PlannedStmt; @@ -372,6 +375,9 @@ typedef struct Plan { * -> SeqScan->ndp_pushdown_condition save ndp condition * */ Node* ndp_pushdown_condition; +#ifdef USE_SPQ + bool spq_scan_partial; +#endif } Plan; typedef struct NdpScanCondition { // for each scan node @@ -1595,7 +1601,66 @@ typedef struct Result { AttrNumber *hashFilterColIdx; Oid *hashFilterFuncs; } Result; - + +typedef struct SpqIndexScan { + IndexScan scan; +} SpqIndexScan; + +typedef struct SpqIndexOnlyScan { + IndexOnlyScan scan; +} SpqIndexOnlyScan; + +typedef struct SpqBitmapHeapScan { + BitmapHeapScan scan; +} SpqBitmapHeapScan; + +typedef struct DirectDispatchInfo { + /** + * if true then this Slice requires an n-gang but the gang can be targeted to + * fewer segments than the entire cluster. + * + * When true, directDispatchContentId and directDispathCount will combine to indicate + * the content ids that need segments. + */ + bool isDirectDispatch; + List *contentIds; + + /* only used while planning, in createplan.c */ + bool haveProcessedAnyCalculations; +} DirectDispatchInfo; + +typedef enum GangType { + /* a root slice executed by the qDisp */ + GANGTYPE_UNALLOCATED, + /* a 1-gang with read access to the entry db */ + GANGTYPE_ENTRYDB_READER, + /* a 1-gang to read the segment dbs */ + GANGTYPE_SINGLETON_READER, + /* a 1-gang or N-gang to read the segment dbs */ + GANGTYPE_PRIMARY_READER, + /* the N-gang that can update the segment dbs */ + GANGTYPE_PRIMARY_WRITER +} GangType; + +/* + * PlanSlice represents one query slice, to be executed by a separate gang + * of executor processes. + */ +typedef struct PlanSlice { + int sliceIndex; + int parentIndex; + + GangType gangType; + + /* # of segments in the gang, for PRIMARY_READER/WRITER slices */ + int numsegments; + /* segment to execute on, for SINGLETON_READER slices */ + int worker_idx; + + /* direct dispatch information, for PRIMARY_READER/WRITER slices */ + DirectDispatchInfo directDispatch; +} PlanSlice; + /* ------------------------- * motion node structs * ------------------------- diff --git a/src/include/optimizer/pgxc_plan_remote.h b/src/include/optimizer/pgxc_plan_remote.h index a327f92e6..be5321417 100644 --- a/src/include/optimizer/pgxc_plan_remote.h +++ b/src/include/optimizer/pgxc_plan_remote.h @@ -146,6 +146,7 @@ typedef struct { List* relationOids; /* contain OIDs of relations the plan depends on */ #ifdef USE_SPQ int streamID; /* required by AMS */ + int nodeCount; #endif } RemoteQuery; diff --git a/src/include/optimizer/stream_util.h b/src/include/optimizer/stream_util.h index 6ad712e29..5aab494b3 100644 --- a/src/include/optimizer/stream_util.h +++ b/src/include/optimizer/stream_util.h @@ -85,6 +85,6 @@ extern void StreamPlanWalker(PlannedStmt *pstmt, Plan *plan, bool *need); extern void mark_distribute_setop_remotequery(PlannerInfo* root, Node* node, Plan* plan, List* subPlans); #ifdef USE_SPQ extern void SpqSerializePlan(Plan* node, PlannedStmt* planned_stmt, StringInfoData* str, - int num_stream, int num_gather, bool push_subplan, uint64 queryId); + RemoteQuery* step, bool push_subplan, uint64 queryId); #endif #endif /* STREAM_UTIL_H */ diff --git a/src/include/utils/lsyscache.h b/src/include/utils/lsyscache.h index a63f20a00..8d97d6076 100644 --- a/src/include/utils/lsyscache.h +++ b/src/include/utils/lsyscache.h @@ -288,6 +288,7 @@ extern void spq_free_attstatsslot(AttStatsSlot *sslot); extern char * get_type_name(Oid typid); extern int32 get_trigger_type(Oid triggerid); extern HeapTuple get_att_stats(Oid relid, AttrNumber attrnum); +extern bool spq_relation_not_partitioned(Oid relid); #endif #define type_is_array(typid) (get_element_type(typid) != InvalidOid) diff --git a/src/test/regress/pg_regress.cpp b/src/test/regress/pg_regress.cpp index e16f74a1d..d9e08c2a6 100644 --- a/src/test/regress/pg_regress.cpp +++ b/src/test/regress/pg_regress.cpp @@ -5468,7 +5468,7 @@ static void CheckCleanCodeWarningInfo(const int baseNum, const int currentNum, return; } -#define BASE_GLOBAL_VARIABLE_NUM 229 +#define BASE_GLOBAL_VARIABLE_NUM 235 #define CMAKE_CMD_BUF_LEN 1000