PgSQL-執(zhí)行器機(jī)制-Unique算子
PgSQL中輸出去重的元組有多種方法,比如通過HashAgg或者GroupAgg。這里我們介紹第三種方法,通過Unique算子來完成這個(gè)功能。當(dāng)然語句上可以是:select distinct(id1) from t;
1、ExecUnique
執(zhí)行器執(zhí)行算子的函數(shù)都是ExecXXX,其中XXX代表某個(gè)算子。Unique算子的執(zhí)行是由函數(shù)ExecUnqiue完成,當(dāng)然這個(gè)函數(shù)執(zhí)行的前提是Unique節(jié)點(diǎn)的子節(jié)點(diǎn)傳來的元組是有序的,比如子節(jié)點(diǎn)是Sort算子。
執(zhí)行邏輯比較簡(jiǎn)單:
ExecUnique
outerPlan = outerPlanState(node);//子計(jì)劃節(jié)點(diǎn)
resultTupleSlot = node->ps.ps_ResultTupleSlot;//返回的元組存在此處
for (;;){//for循環(huán)找到最后一個(gè)重復(fù)的值
slot = ExecProcNode(outerPlan);//從子節(jié)點(diǎn)拉取數(shù)據(jù)
if (TupIsNull(slot)){//子節(jié)點(diǎn)拉取完
return NULL;//執(zhí)行結(jié)束
}
//總是返回第一個(gè)元組,第一個(gè)元組時(shí)resultTupleSlot為空
if (TupIsNull(resultTupleSlot))
break;
//后面相同的記錄進(jìn)行Qual比較
econtext->ecxt_innertuple = slot;
econtext->ecxt_outertuple = resultTupleSlot;
if (!ExecQualAndReset(node->eqfunction, econtext))
break;//直到元組不同時(shí)結(jié)束循環(huán)
}
//將獲取的元組拷貝到resultTupleSlot中并返回
return ExecCopySlot(resultTupleSlot, slot);
1)獲取第一個(gè)元組時(shí),node->ps.ps_ResultTupleSlot中沒有數(shù)值,即為NULL
2)從子節(jié)點(diǎn)拉取一個(gè)元組值,此時(shí)直接中斷循環(huán),將該元組值賦值給node->ps.ps_ResultTupleSlot并返回
3)再次迭代進(jìn)入ExecUnique函數(shù),node->ps.ps_ResultTupleSlot仍舊是上次保存的元組值,不為空。For循環(huán)從子節(jié)點(diǎn)再拉取一個(gè)元組值,需要和上次保存的值進(jìn)行比較,若相同則繼續(xù)循環(huán)拉取下個(gè)值進(jìn)行比較,直到和node->ps.ps_ResultTupleSlot值不相等
4)退出循環(huán)后,將下一組的第一個(gè)值保存到node->ps.ps_ResultTupleSlot返回。
這樣就完成了數(shù)值的去重,這里重申下,使用ExecUnique的前提是子節(jié)點(diǎn)的元組是有序的。
2、ExecQualAndReset
看下實(shí)現(xiàn)的關(guān)鍵函數(shù)ExecQualAndReset,該函數(shù)通過表達(dá)式計(jì)算完成數(shù)值比較。
表達(dá)式的計(jì)算步驟為ExprState *eqfunction。由函數(shù)ExecInitUnique進(jìn)行初始化:文章來源:http://www.zghlxwxcb.cn/news/detail-734406.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-734406.html
到了這里,關(guān)于PgSQL-執(zhí)行器機(jī)制-Unique算子的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!