first commit for openGauss server

This commit is contained in:
lishifu
2020-06-30 17:38:27 +08:00
parent bcb52078d5
commit 815a9771fb
7975 changed files with 9646516 additions and 61 deletions

View File

@ -0,0 +1,187 @@
/*
* Copyright (c) 2020 Huawei Technologies Co.,Ltd.
*
* openGauss is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* ---------------------------------------------------------------------------------------
*
* nodeExtensible.cpp
* ExtensiblePlan is an extended plan node which supports various customize operations.
* Normally we built our ExtensiblePlan on the upper level of the original plan.
* To implement the ExtensiblePlan, we should first implement BeginExtensiblePlan() method,
* ExecExtensiblePlan() method, EndExtensiblePlan() method ReScanExtensiblePlan() method.
*
* IDENTIFICATION
* src/gausskernel/runtime/executor/nodeExtensible.cpp
*
* ---------------------------------------------------------------------------------------
*/
#include "postgres.h"
#include "knl/knl_variable.h"
#include "executor/executor.h"
#include "executor/nodeExtensible.h"
#include "nodes/execnodes.h"
#include "nodes/plannodes.h"
#include "parser/parsetree.h"
#include "utils/hsearch.h"
#include "utils/memutils.h"
#include "utils/rel.h"
const int EXTNODENAME_MAX_LEN = 64;
static HTAB* g_extensible_plan_methods = NULL;
const int HASHTABLE_LENGTH = 100;
typedef struct {
char extnodename[EXTNODENAME_MAX_LEN];
void* extnodemethods;
} ExtensibleNodeEntry;
ExtensiblePlanState* ExecInitExtensiblePlan(ExtensiblePlan* eplan, EState* estate, int eflags)
{
ExtensiblePlanState* extensionPlanState;
Relation scan_rel = NULL;
Index scanrelid = eplan->scan.scanrelid;
Index tlistvarno;
/*
* Allocate the ExtensiblePlanState object. We let the extensible scan provider
* do the palloc, in case it wants to make a larger object that embeds
* ExtensiblePlanState as the first field. It must set the node tag and the
* methods field correctly at this time. Other standard fields should be
* set to zero.
*/
extensionPlanState = (ExtensiblePlanState*)eplan->methods->CreateExtensiblePlanState(eplan);
/* ensure flags is filled correctly */
extensionPlanState->flags = eplan->flags;
/* fill up fields of ScanState */
extensionPlanState->ss.ps.plan = &eplan->scan.plan;
extensionPlanState->ss.ps.state = estate;
/* create expression context for node */
ExecAssignExprContext(estate, &extensionPlanState->ss.ps);
extensionPlanState->ss.ps.ps_TupFromTlist = false;
/* initialize child expressions */
extensionPlanState->ss.ps.targetlist =
(List*)ExecInitExpr((Expr*)eplan->scan.plan.targetlist, (PlanState*)extensionPlanState);
extensionPlanState->ss.ps.qual = (List*)ExecInitExpr((Expr*)eplan->scan.plan.qual, (PlanState*)extensionPlanState);
/* tuple table initialization */
ExecInitScanTupleSlot(estate, &extensionPlanState->ss);
ExecInitResultTupleSlot(estate, &extensionPlanState->ss.ps);
/*
* open the base relation, if any, and acquire an appropriate lock on it
*/
if (scanrelid > 0) {
scan_rel = ExecOpenScanRelation(estate, scanrelid);
extensionPlanState->ss.ss_currentRelation = scan_rel;
}
/*
* Determine the scan tuple type. If the extensible scan provider provided a
* targetlist describing the scan tuples, use that; else use base
* relation's rowtype.
*/
if (eplan->extensible_plan_tlist != NIL || scan_rel == NULL) {
TupleDesc scan_tupdesc;
scan_tupdesc = ExecTypeFromTL(eplan->extensible_plan_tlist, false);
ExecAssignScanType(&extensionPlanState->ss, scan_tupdesc);
/* Node's targetlist will contain Vars with varno = INDEX_VAR */
tlistvarno = INDEX_VAR;
} else {
ExecAssignScanType(&extensionPlanState->ss, RelationGetDescr(scan_rel));
/* Node's targetlist will contain Vars with varno = scanrelid */
tlistvarno = scanrelid;
}
/*
* Initialize result tuple type and projection info.
*/
ExecAssignResultTypeFromTL(&extensionPlanState->ss.ps);
ExecAssignScanProjectionInfoWithVarno(&extensionPlanState->ss, tlistvarno);
/*
* The callback of extensible-scan provider applies the final initialization
* of the extensible-scan-state node according to its logic.
*/
extensionPlanState->methods->BeginExtensiblePlan(extensionPlanState, estate, eflags);
return extensionPlanState;
}
TupleTableSlot* ExecExtensiblePlan(ExtensiblePlanState* node)
{
Assert(node->methods->ExecExtensiblePlan != NULL);
return node->methods->ExecExtensiblePlan(node);
}
void ExecEndExtensiblePlan(ExtensiblePlanState* node)
{
Assert(node->methods->EndExtensiblePlan != NULL);
node->methods->EndExtensiblePlan(node);
/* Free the exprcontext */
ExecFreeExprContext(&node->ss.ps);
/* Clean out the tuple table */
(void)ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
(void)ExecClearTuple(node->ss.ss_ScanTupleSlot);
/* Close the heap relation */
if (node->ss.ss_currentRelation) {
ExecCloseScanRelation(node->ss.ss_currentRelation);
}
}
void ExecReScanExtensiblePlan(ExtensiblePlanState* node)
{
Assert(node->methods->ReScanExtensiblePlan != NULL);
node->methods->ReScanExtensiblePlan(node);
}
/*
* An internal routine to get an ExtensibleNodeEntry by the given identifier
*/
static void* GetExtensibleNodeEntry(HTAB* htable, const char* extnodename, bool missing_ok)
{
ExtensibleNodeEntry* entry = NULL;
if (htable != NULL) {
entry = (ExtensibleNodeEntry*)hash_search(htable, extnodename, HASH_FIND, NULL);
}
if (entry != NULL) {
if (missing_ok) {
return NULL;
}
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("ExtensibleNodeMethods \"%s\" was not registered", extnodename)));
}
if (entry != NULL) {
return entry->extnodemethods;
} else {
return NULL;
}
}
/*
* Get the methods for a given name of ExtensiblePlanMethods
*/
ExtensiblePlanMethods* GetExtensiblePlanMethods(const char* ExtensibleName, bool missing_ok)
{
return (ExtensiblePlanMethods*)GetExtensibleNodeEntry(g_extensible_plan_methods, ExtensibleName, missing_ok);
}