代码注释 #36

Open
Lohax wants to merge 18 commits from Lohax/openGauss-server:master into master
9 changed files with 571 additions and 15 deletions

View File

@ -231,8 +231,20 @@ void print_parameters(const QueryDesc *queryDesc, ExplainState es)
}
}
}
/* exec_explain_plan
* parameter: queryDesc
* QueryDesc contains query information, such as operation type,
* query plan tree, and execution status.
*
* This function outputs the EXPLAIN information for the query
* plan and, if the EXPLAIN ANALYZE option is enabled, collects
* and displays execution statistics.
*
*/
void exec_explain_plan(QueryDesc *queryDesc)
{
/* Store interpretation information*/
ExplainState es;
if (is_valid_query(queryDesc) && auto_explain_plan()) {
INSTR_TIME_SET_CURRENT(plan_time);
@ -243,14 +255,19 @@ void exec_explain_plan(QueryDesc *queryDesc)
es.verbose = true;
es.analyze = false;
es.timing = false;
/* Save the current performance mode*/
int old_explain_perf_mode = t_thrd.explain_cxt.explain_perf_mode;
/* Set the performance mode in the current thread to EXPLAIN_NORMAL
* to output the explain information in normal mode*/
t_thrd.explain_cxt.explain_perf_mode = (int)EXPLAIN_NORMAL;
appendStringInfo(es.str, "\n---------------------------"
"-NestLevel:%d----------------------------\n", u_sess->exec_cxt.nesting_level);
ExplainQueryText(&es, queryDesc);
appendStringInfo(es.str, "Name: %s\n", g_instance.attr.attr_common.PGXCNodeName);
ExplainBeginOutput(&es);
/* Save the current memory information*/
MemoryContext current_ctx = CurrentMemoryContext;
/* exception handling*/
PG_TRY();
{
ExplainPrintPlan(&es, queryDesc);
@ -258,6 +275,7 @@ void exec_explain_plan(QueryDesc *queryDesc)
}
PG_CATCH();
{
/*Switch to previously saved memory information to avoid memory leaks*/
MemoryContextSwitchTo(current_ctx);
ErrorData* edata = CopyErrorData();
FlushErrorState();

View File

@ -591,7 +591,8 @@ void InstrEndLoop(Instrumentation* instr)
/* Skip if nothing has happened, or already shut down */
if (!instr->running)
return;
/*If the "starttime" field of the node is not 0, the node has not called the InstrStopNode function to stop the timing, and an error may have occurred*/
if (!INSTR_TIME_IS_ZERO(instr->starttime)) {
elog(DEBUG2, "InstrEndLoop called on running node");
}

View File

@ -95,6 +95,9 @@ static TupleTableSlot* IndexNext(IndexScanState* node)
break;
}
} else {
/* Depending on how the table is stored, call scan_handler_idx_getnext
*to select a different API and return the result to the tuple
*/
if ((tuple = scan_handler_idx_getnext(scandesc, direction)) == NULL) {
break;
}

View File

@ -189,6 +189,25 @@ static TupleTableSlot* SeqNext(SeqScanState* node);
static void ExecInitNextPartitionForSeqScan(SeqScanState* node);
/* ------------------------------------------------------
* seq_scan_getnext_template
* ------------------------------------------------------
* Param
* scanthe description of the status of atable scan
* slottores the tuple obtained from the table
* directionIndicates the direction of the table scan
* ------------------------------------------------------
* Note
* First determine how to read tuples (1) hashBucket mode
* (2) heap mode (3) uheap mode (UHeap provides a different
* data storage and management mode from the traditional Heap
* It may contain some optimizations and improvements to improve
* the performance of certain types of database workloads).
* Then call each mode of the read function, read a tuple.
* Finally, call UHeapSlotStoreUHeapTuple or heap_slot_store_heap_tuple
* to store the returned tuple tuple into the slot.
* ------------------------------------------------------
*/
template<TableAmType type, bool hashBucket>
FORCE_INLINE
void seq_scan_getnext_template(TableScanDesc scan, TupleTableSlot* slot, ScanDirection direction)
@ -288,6 +307,19 @@ void ExecStoreTupleBatchMode(TableScanDesc scanDesc, TupleTableSlot** slot)
}
}
/* --------------------------------------------------------
* SeqNextBatchMode
* --------------------------------------------------------
* Param:
* node:SeqScanState类型的结点
* --------------------------------------------------------
* Note:
* First, obtain some status and description information of
* the scanned node, then update the node information, and
* then call ExecStoreTupleBatchMode to store the read
* utuple into the slot.
* --------------------------------------------------------
*/
static ScanBatchResult *SeqNextBatchMode(SeqScanState *node)
{
TableScanDesc scanDesc;
@ -301,10 +333,11 @@ static ScanBatchResult *SeqNextBatchMode(SeqScanState *node)
direction = estate->es_direction;
slot = &(node->scanBatchState->scanBatch.scanTupleSlotInBatch[0]);
/* get tuples from the table. */
/* update node information */
scanDesc->rs_maxScanRows = node->scanBatchState->scanTupleSlotMaxNum;
node->scanBatchState->scanfinished = tableam_scan_gettuplebatchmode(scanDesc, direction);
/* store the read utuple into the slot */
if (slot[0]->tts_tupslotTableAm == TAM_USTORE) {
ExecStoreTupleBatchMode<TAM_USTORE>(scanDesc, slot);
} else {
@ -382,13 +415,41 @@ void SeqScan_Init(TableScanDesc scan, SeqScanAccessor* p_accessor, Relation rela
SeqScan_Pref_Quantity(scan, p_accessor, relation);
}
/* -----------------------------------------------------------------
* reset_scan_qual
* -----------------------------------------------------------------
* Param:
* curr_heap_rel: current realation stored in heap storage
* node: ScanState type structure which indicates the scanning status
* isRangeScanInRedis: if it is a range scan in the redistribution process
* -----------------------------------------------------------------
* Note:
* This code basically returns a RangeScanInRedis structure, which
* stores three fields.You can see the specific comments in the
* struct definition.
*
* First, if node is empty, the plain value is returned. Then,
* if the cluster size is allowed and the relation is in
* redistribution process,the init function gets the new qual and
* selects a different qual based on whether or not the node is
* vectorized reading (call ExecInitVecExpr if ScanBatch, Otherwise
* call ExecInitExpr); If the qual field in node has not been
* initialized, different qual initialization functions are called
* according to whether the node is reading vectorized (ExecInitVecExpr
* is called if it is canBatch, and ExecInitExpr is called Sotherwise).
* Concatenate rangeScanInRedis to the plain value. Finally return
* node->rangeScanInRedis.
* -----------------------------------------------------------------
*/
RangeScanInRedis reset_scan_qual(Relation curr_heap_rel, ScanState* node, bool isRangeScanInRedis)
{
if (node == NULL) {
return {isRangeScanInRedis, 0, 0};
}
/* if the cluster size is allowed and the relation is in redistribution process */
if (u_sess->attr.attr_sql.enable_cluster_resize && RelationInRedistribute(curr_heap_rel)) {
List* new_qual = eval_ctid_funcs(curr_heap_rel, node->ps.plan->qual, &node->rangeScanInRedis);
/* select a different Init function depending on whether it is ScanBatch */
if (!node->scanBatchMode) {
node->ps.qual = (List*)ExecInitExpr((Expr*)new_qual, (PlanState*)&node->ps);
} else {
@ -396,6 +457,7 @@ RangeScanInRedis reset_scan_qual(Relation curr_heap_rel, ScanState* node, bool i
}
node->ps.qual_is_inited = true;
} else if (!node->ps.qual_is_inited) {
/* select a different Init function depending on whether it is ScanBatch */
if (!node->scanBatchMode) {
node->ps.qual = (List*)ExecInitExpr((Expr*)node->ps.plan->qual, (PlanState*)&node->ps);
} else {
@ -407,6 +469,23 @@ RangeScanInRedis reset_scan_qual(Relation curr_heap_rel, ScanState* node, bool i
return node->rangeScanInRedis;
}
/* -------------------------------------------------------------
* InitBeginScan
* -------------------------------------------------------------
* Param:
* node: SeqScanState Type structure, which represents scan status information
* current_relation: current relation to handle
* -------------------------------------------------------------
* Note:
* This code is used to initialize the Scan information (ScanDesc),
* and it depends on whether the node corresponds to Sample Scan or
* not to select a different initialization function. (Sample Scan
* is a scanning mode that can extract some samples from a query with
* a large amount of data, query these samples, and then calculate
* the query cost and optimize the query method according to the
* query cost.)
* -------------------------------------------------------------
*/
static TableScanDesc InitBeginScan(SeqScanState* node, Relation current_relation)
{
TableScanDesc current_scan_desc = NULL;
@ -466,6 +545,19 @@ TableScanDesc BeginScanRelation(SeqScanState* node, Relation relation, Transacti
return current_scan_desc;
}
/* -------------------------------------------------------------
* GetPartitionPruningResultInInitScanRelation
* -------------------------------------------------------------
* Param:
* plan: SeqScan type structure which indicates the node type
* estate: Execution State
* current_relation: current relation need execute
* -------------------------------------------------------------
* Note:
* return a PruningResult pointer, which store related
* information about partition running result
*
*/
static PruningResult *GetPartitionPruningResultInInitScanRelation(SeqScan *plan, EState *estate,
Relation current_relation)
{
@ -621,6 +713,18 @@ void InitScanRelation(SeqScanState* node, EState* estate, int eflags)
ExecAssignScanType(node, RelationGetDescr(current_relation));
}
/* ----------------------------------------------------------------
* InitRelationBatchScanEnv
* ----------------------------------------------------------------
* Param:
* state: structure of type SeqScanState,which contains state
* information when excuting
* ----------------------------------------------------------------
* Note:
* Initializes the column number that needs to be projected, and
* sets the column number that needs to be late read.
* ----------------------------------------------------------------
*/
static void InitRelationBatchScanEnv(SeqScanState *state)
{
/* so use MemContext which is not freed at all until the end. */
@ -632,6 +736,7 @@ static void InitRelationBatchScanEnv(SeqScanState *state)
return;
}
/* Gets the column that needs to be projected */
List *pColList = proj->pi_acessedVarNumbers;
batchstate->colNum = list_length(pColList);
@ -749,6 +854,44 @@ static SeqScanState *ExecInitSeqScanBatchMode(SeqScan *node, SeqScanState* scans
return scanstate;
}
/* ----------------------------------------------------------------
* InitSeqNextMtd
* ----------------------------------------------------------------
* Param:
* node:
* scanstate:
* ----------------------------------------------------------------
* Note:
* This code initializes the ScanNextMtd and fillNextSlotFunc
* members of the SeqScanState struct. These two members define
* how to get the next record and how to fill the next slot
* respectively.
*
* Specifically, the code first checks whether node->tablesample
* is NULL. If NULL, it means that this is not a table sample scan,
* but a regular sequential scan. In this case, it sets ScanNextMtd
* to funciton SeqNext, which means that the usual sequential scan
* method is used to get the next record.
*
* Then checks whether the current relationship has a bucket
* (by calling the RELATION_OWN_BUCKET). If the current relationship
* owns the bucket, it selects the appropriate fill slot function
* based on the storage type (specified by rd_tam_type).
*
* If the current relationship does not own the bucket, then the
* choice of fill slot function is similar to the above.
*
* If node->tablesample is not NULL, then this is a tablesample
* scan. In this case, if the current relationship owns the bucket,
* set ScanNextMtd to function HbktSeqSampleNext; Otherwise, set
* it to function SeqSampleNext.
*
* In general, the purpose of this code is to initialize the
* sequential scan state based on the type of scan (regular
* sequential scan or table sample scan) and whether the current
* relationship owns the bucket.
* ----------------------------------------------------------------
*/
static inline void InitSeqNextMtd(SeqScan* node, SeqScanState* scanstate)
{
if (!node->tablesample) {

View File

@ -2148,6 +2148,21 @@ static BlockNumber HeapParallelscanNextpage(HeapScanDesc scan)
return page;
}
/* -----------------------------------------------------------
* heap_getnext
* -----------------------------------------------------------
* Param
* sscanthe description of the status of a table scan
* directionthe description of the direction of the table scan
* -----------------------------------------------------------
* Note
* If rs_pageatatime is true, then the heapgettup_pagemode function is called
* to read one page, otherwise the heapgettup function is called to read
* one tuple at a time.
* If the next tuple scanned is empty, returne NULL.
* Finally, increase the number of returned tuples by 1
* ------------------------------------------------------------
*/
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
{
HeapScanDesc scan = (HeapScanDesc) sscan;
@ -2170,7 +2185,8 @@ HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
* the proper return buffer and return the tuple.
*/
HEAPDEBUG_3; /* heap_getnext returning tuple */
/* increase the number of returned tuples by 1 */
pgstat_count_heap_getnext(scan->rs_base.rs_rd);
Assert(!HEAP_TUPLE_IS_COMPRESSED(scan->rs_ctup.t_data));

View File

@ -54,6 +54,24 @@
#include "storage/tcap.h"
#include "catalog/pg_constraint.h"
/*
* TvIsContainsForeignKey() ---
* Checks whether a given relation (table) with the specified
* OID (object identifier) contains a foreign key constraint.
*
* The expected behavior of this function is to return 'true' if
* the relationship specified by 'relid' contains foreign key
* constraints, and 'false' otherwise. The implementation of this
* function would involve querying the catalog table of the database
* system to check for foreign key constraints associated with a
* given relational OID.
*
* Param [IN] relid: It accepts a parameter called 'relid' of type
* 'Oid'. 'Oid' is commonly used in database systems to represent
* object identifiers.
* Returns [OUT]: A variable of type bool. True indicates that it
* contains foreign keys.
*/
static bool TvIsContainsForeignKey(Oid relid)
{
Relation rbRel;
@ -69,6 +87,12 @@ static bool TvIsContainsForeignKey(Oid relid)
sd = systable_beginscan(rbRel, ConstraintRelidIndexId, true, SnapshotNow, 1, &key);
/* For each tuple, check that the constraint type (contype) is
* CONSTRAINT_FOREIGN and that the constraint's relationship
* identifier (conrelid) matches the relid of the input. If
* both conditions are met, the relationship contains a foreign
* key constraint, so set isContainsForeignKey to true and break
* out of the loop. */
while ((tup = systable_getnext(sd)) != NULL) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup);
@ -85,6 +109,23 @@ static bool TvIsContainsForeignKey(Oid relid)
return isContainsForeignKey;
}
/*
* TvIsReferencedByForeignKey() ---
* Checks whether the specified relationship (table) is referenced
* by a foreign key.
*
* Foreign key reference relationships are often used to ensure data
* integrity, they indicate that a column in one table references a
* column in another table, and those references need to follow
* specific constraint rules.
*
* Param [IN] relid: This is the argument list of the function, which
* accepts a parameter named 'relid' of type 'Oid', the object
* identifier. This parameter is used to specify the identifier
* of the relationship (table) to be checked.
* Returns [OUT]: Return 'true' if the relation is referenced by a
* foreign key, or 'false' otherwise.
*/
static bool TvIsReferencedByForeignKey(Oid relid)
{
Relation rbRel;
@ -96,6 +137,10 @@ static bool TvIsReferencedByForeignKey(Oid relid)
sd = systable_beginscan(rbRel, InvalidOid, false, SnapshotNow, 0, NULL);
/* For each tuple, check that the constraint's reference relation
* identifier (confrelid) matches the input relid. If the condition
* is met, the relation is referenced by a foreign key constraint,
* so set isReferencedByForeignKey to true and out of the loop. */
while ((tup = systable_getnext(sd)) != NULL) {
Form_pg_constraint con = (Form_pg_constraint)GETSTRUCT(tup);
@ -117,6 +162,27 @@ static bool TvForeignKeyCheck(Oid relid)
return (TvIsContainsForeignKey(relid) || TvIsReferencedByForeignKey(relid));
}
/*
* TvFeatureSupport() ---
* Its function is to check whether a table supports the timecapsule
* feature. timecapsule is a feature that allows tables to backtrack data
* at different points in time.
*
* This function determines whether the table to be checked supports
* the timecapsule feature based on a set of criteria, and returns the
* corresponding result and error message (if any).
*
* Param [IN] relid: an integer parameter that represents the OID (object
* identifier) of the table to be checked.
* Param [IN] errstr: a pointer to a string pointer that returns an error message.
* Param [IN] isTimecapsuleTable: A Boolean parameter that indicates whether
* the table to check has the timecapsule feature enabled. If it is,
* more stringent checks are carried out, such as not including or
* referencing foreign keys.
* Returns [OUT]: True indicates the table to check supports timecapsule related
* features, otherwise return false.
*/
static bool TvFeatureSupport(Oid relid, char **errstr, bool isTimecapsuleTable)
{
Relation rel = RelationIdGetRelation(relid);
@ -128,6 +194,7 @@ static bool TvFeatureSupport(Oid relid, char **errstr, bool isTimecapsuleTable)
errmsg("could not open relation with OID %u", relid)));
}
/* perform a series of correlation checks */
classForm = rel->rd_rel;
if (classForm->relkind != RELKIND_RELATION) {
*errstr = "timecapsule feature does not support non-ordinary table";
@ -164,7 +231,18 @@ static bool TvFeatureSupport(Oid relid, char **errstr, bool isTimecapsuleTable)
return *errstr == NULL;
}
/*
* TvCheckVersionScan() ---
* This function is to check if a table supports the timecapsule feature
* and report an error if it does not.
*
* Call TvFeatureSupport to determine if the table to check supports the
* timecapsule feature, and if not, use the ereport function to throw an
* error.
*
* Param [IN] rte: Describes the tables that appear in the query.
* Returns [OUT]: void
*/
void TvCheckVersionScan(RangeTblEntry *rte)
{
char *errstr = NULL;
@ -178,6 +256,15 @@ void TvCheckVersionScan(RangeTblEntry *rte)
return;
}
/*
* TvIsVersionScan() ---
* Check if a scan is a "timecapsule" version scan.
*
* Param [IN] ss: A pointer to the ScanState structure, which contains
* information about the scan.
* Returns [OUT]: Return true if the scan is the "timecapsule" version scan;
* Otherwise, return false.
*/
bool TvIsVersionScan(const ScanState *ss)
{
EState *estate = ss->ps.state;
@ -188,7 +275,14 @@ bool TvIsVersionScan(const ScanState *ss)
}
/*
* Whether the plan contains version table scan.
* TvIsVersionPlan() ---
* Check if a schedule statement contains the "timecapsule" version
* of the table.
*
* Param [IN] stmt: A pointer to the PlannedStmt structure that contains
* information about the planned statement.
* Returns [OUT]: Return true if the schedule statement contains the
* "timecapsule" version of the table; Otherwise, return false.
*/
bool TvIsVersionPlan(const PlannedStmt *stmt)
{
@ -204,6 +298,30 @@ bool TvIsVersionPlan(const PlannedStmt *stmt)
return false;
}
/*
* TvTransformVersionExpr() ---
* The function converts the given "timecapsule" version of the
* expression (specified by tvver) to a specific type of expression
* and checks if the expression contains a sublink.
*
* The function first calls the transformExpr function to convert the
* "timecapsule" version expression. It then checks whether the converted
* expression contains sublinks. The function casts the expression to a
* specific type based on the "timecapsule" version type (specified by
* tvtype). If the version type is a timestamp, it casts the expression
* to the TIMESTAMPTZOID type; Otherwise, it casts the expression to
* INT8OID type. Finally, the function calls assign_expr_collations
* to assign the sorting of the expression and returns the converted
* expression.
*
* Param [IN] pstate: A pointer to the ParseState structure, which
* contains information about the parsing state.
* Param [IN] tvtype: This is an enumeration value that represents
* the "timecapsule" version type, which can be timestamp
* (TV_VERSION_TIMESTAMP) or CSN (TV_VERSION_CSN).
* Param [IN] tvver: Represents the "timecapsule" version expression.
* Returns [OUT]: Represents the converted "timecapsule" version expression.
*/
Node *TvTransformVersionExpr(ParseState *pstate, TvVersionType tvtype, Node *tvver)
{
Node *verExpr = tvver;
@ -225,7 +343,23 @@ Node *TvTransformVersionExpr(ParseState *pstate, TvVersionType tvtype, Node *tvv
return verExpr;
}
/*
* TvEvalVerExpr() ---
* The main purpose is to evaluate the "timecapsule" version expressions.
*
* First try to convert tvver to a constant. If successful, it will return
* the constant directly. Otherwise, it creates a new ParseState, then calls
* the TvTransformVersionExpr function to convert the "timecapsule" version
* expression, and releases the parsing state. Next, the function calls the
* evaluate_expr function to evaluate the converted expression and convert
* the result to a constant. Double check that result is indeed Const.
*
* Param [IN] tvtype: This is an enumeration value that represents the
* "timecapsule" version type, which can be timestamp (TV_VERSION_TIMESTAMP)
* or CSN (TV_VERSION_CSN).
* Param [IN] tvver: Represents the "timecapsule" version expression.
* Returns [OUT]: Represents the evaluated "timecapsule" version expression.
*/
static Const *TvEvalVerExpr(TvVersionType tvtype, Node *tvver)
{
Const *result = (Const *)tvver;
@ -394,6 +528,21 @@ static void TvFetchSnapCsn(int64 csn, Snapshot snap)
return;
}
/*
* TvFetchSnap() ---
* Get a snapshot of the "timecapsule" version.
*
* Call the function based on the "timecapsule" version type to get the
* snapshot. If the version type is timestamp, it calls the TvFetchSnapTz
* function; Otherwise, it calls the TvFetchSnapCsn function.
*
* Param [IN] type: Represents the "timecapsule" version type, which can
* be timestamp (TV_VERSION_TIMESTAMP) or CSN (TV_VERSION_CSN).
* Param [IN] value: Values that represent information about the "timecapsule"
* version.
* Returns [OUT]: Returns a pointer to the Snapshot. This snapshot represents
* the obtained "timecapsule" version snapshot.
*/
static Snapshot TvFetchSnap(TvVersionType type, Const *value)
{
Snapshot snap = (Snapshot)palloc0(sizeof(SnapshotData));
@ -409,6 +558,20 @@ static Snapshot TvFetchSnap(TvVersionType type, Const *value)
return snap;
}
/*
* TvGetSnap() ---
* The main purpose is to call the TvFetchSnap function to get
* the "timecapsule" version snapshot of the specified table and
* check for errors.
*
* Param [IN] relation: A pointer to the Relation structure, which
* contains information about the table.
* Param [IN] tvtype: Represents the "timecapsule" version type, which
* can be timestamp (TV_VERSION_TIMESTAMP) or CSN (TV_VERSION_CSN).
* Param [IN] tvver: Represents the "timecapsule" version expression.
* Returns [OUT]: Returns a pointer to the Snapshot. This snapshot represents
* the obtained "timecapsule" version snapshot.
*/
static Snapshot TvGetSnap(Relation relation, TvVersionType tvtype, Node *tvver)
{
Const *value;
@ -426,6 +589,18 @@ static Snapshot TvGetSnap(Relation relation, TvVersionType tvtype, Node *tvver)
return snap;
}
/*
* TvValidateRelDDL() ---
* Check that the definition of the given table (specified by relid)
* has changed.
*
* Param [IN] relid: It accepts a parameter called 'relid' of type
* 'Oid'. 'Oid' is commonly used in database systems to represent
* object identifiers.
* Param [IN] snapcsn: This is a commit sequence number that represents
* the value to be compared with the table's change sequence number.
* Returns [OUT]: void
*/
static void TvValidateRelDDL(Oid relid, CommitSeqNo snapcsn)
{
Relation rel = RelationIdGetRelation(relid);
@ -447,8 +622,18 @@ static void TvValidateRelDDL(Oid relid, CommitSeqNo snapcsn)
}
/*
* Choose user-specified snapshot if TimeCapsule clause exists, otherwise
* estate->es_snapshot instead.
* TvChooseScanSnap() ---
* Select the appropriate snapshot to scan based on the given table,
* scan, and scan states (specified by relation, scan, and ss).
*
* Param [IN] relation: A pointer to the Relation structure, which contains
* information about the table.
* Param [IN] scan: A pointer to the Scan structure that contains information
* about the scan.
* Param [IN] ss: A pointer to the ScanState structure that contains information
* about the state of the scan.
* Returns [OUT]: Returns a pointer to the Snapshot. This snapshot represents
* the selected snapshot.
*/
Snapshot TvChooseScanSnap(Relation relation, Scan *scan, ScanState *ss)
{
@ -481,6 +666,22 @@ Snapshot TvChooseScanSnap(Relation relation, Scan *scan, ScanState *ss)
return snap;
}
/*
* TvDeleteDelta() ---
* Deletes all tuples for a given table (specified by relid).
*
* The function first opens the relationship (that is, the table) specified by
* relid. It then scans the relationship and gets the next tuple. If a tuple
* is found, it deletes the tuple. This process repeats until there are no
* more tuples. Finally, the function ends the scan and closes the relationship.
*
* Param [IN] relid: It accepts a parameter called 'relid' of type 'Oid'.
* 'Oid' is commonly used in database systems to represent object
* identifiers.
* Param [IN] snap: A pointer to the Snapshot structure that contains
* information about the snapshot.
* Returns [OUT]: void
*/
void TvDeleteDelta(Oid relid, Snapshot snap)
{
Relation rel;
@ -500,6 +701,19 @@ void TvDeleteDelta(Oid relid, Snapshot snap)
return;
}
/*
* TvUheapDeleteDeltaRel() ---
* If partRel is NULL, all tuples of the rel table are deleted, otherwise all
* tuples of the partRel table are deleted.
*
* Param [IN] rel & partRel: A pointer to the Relation structure, which contains
* information about the table.
* Param [IN] p: A pointer to a Partition structure that contains information about
* the partition.
* Param [IN] snap: A pointer to the Snapshot structure that contains
* information about the snapshot.
* Returns [OUT]: void
*/
void TvUheapDeleteDeltaRel(Relation rel, Relation partRel, Partition p, Snapshot snap)
{
TableScanDesc sd;
@ -597,6 +811,18 @@ void TvUheapDeleteDeltaPart(Relation rel, Oid relid, Snapshot snap)
return;
}
/*
* TvUheapDeleteDelta() ---
* Deletes all tuples for a given table (specified by relid).This function
* is used to process tables stored in Uheap mode.
*
* Param [IN] relid: It accepts a parameter called 'relid' of type 'Oid'.
* 'Oid' is commonly used in database systems to represent object
* identifiers.
* Param [IN] snap: A pointer to the Snapshot structure that contains
* information about the snapshot.
* Returns [OUT]: void
*/
void TvUheapDeleteDelta(Oid relid, Snapshot snap)
{
Relation rel = heap_open(relid, NoLock);
@ -609,6 +835,16 @@ void TvUheapDeleteDelta(Oid relid, Snapshot snap)
heap_close(rel, NoLock);
}
/*
* TvFetchTuple() ---
* Gets the next tuple pointed to by the table scan descriptor and returns
* a copy of that tuple. If there are no more tuples, it will return NULL.
*
* Param [IN] arg: A pointer to any type, which will be converted to type
* TableScanDesc and used to get the next tuple.
* Returns [OUT]: A pointer of type TvFetchTupleHook. If the next tuple is obtained,
* a copy of that tuple is returned. Otherwise, NULL is returned.
*/
typedef HeapTuple (*TvFetchTupleHook)(void *arg);
static HeapTuple TvFetchTuple(void *arg)
{
@ -617,12 +853,43 @@ static HeapTuple TvFetchTuple(void *arg)
return tup ? (HeapTuple)tableam_tops_copy_tuple(tup) : NULL;
}
/*
* TvUheapFetchTuple() ---
* Gets the next tuple pointed to by the table scan descriptor and returns
* a copy of that tuple. If there are no more tuples, it will return NULL.
*/
typedef UHeapTuple (*TvUheapFetchTupleHook)(void *arg);
static UHeapTuple TvUheapFetchTuple(void *arg)
{
return (UHeapTuple)tableam_scan_getnexttuple((TableScanDesc)arg, ForwardScanDirection);
}
/*
* TvBatchInsert() ---
* Batch inserts tuples into a table and updates any associated indexes.
*
* The function first switches to a short memory context to prevent memory leaks
* when calling tableam_tuple_multi_insert. It then calls tableam_tuple_multi_insert
* to insert all tuples in the buffer into the table. After that, it switches back
* to its original memory context.
* If the table has any indexes, the function traverses all inserted tuples and
* calls ExecInsertIndexTuples on each tuple to update the index. Finally, it
* frees the list returned by ExecInsertIndexTuples.
*
* Param [IN] rel: A pointer to the Relation structure, which contains information
* about the table.
* Param [IN] estate: An execution state object that contains all the information
* needed to execute the query.
* Param [IN] mycid: ID of the inserted column
* Param [IN] hiOptions: An option flag that controls the behavior of an insert operation.
* Param [IN] resultRelInfo: A result relationship information object that contains
* information about the target relation(table).
* Param [IN] myslot: Stores the tuple to be inserted.
* Param [IN] bistate: Select different policies and manage batch insert operations.
* Param [IN] nBufferedTuples: Represents the number of tuples in the buffer.
* Param [IN] bufferedTuples: A pointer to a heap tuple array, indicating the tuple to be inserted.
* Returns [OUT]:void
*/
static void TvBatchInsert(Relation rel, EState *estate, CommandId mycid,
int hiOptions, ResultRelInfo *resultRelInfo,
TupleTableSlot *myslot, BulkInsertState bistate,
@ -666,6 +933,31 @@ static void TvBatchInsert(Relation rel, EState *estate, CommandId mycid,
return;
}
/*
* TvInsertLostImpl
* Batch inserts lost tuples into a table and updates any associated indexes.
*
* The function first creates an execution state object and a result relationship
* information object, and opens all indexes of the table. It then initializes a
* tuple table slot and allocates memory to store the tuple to be inserted.
* Then enters an infinite loop, in which it uses the fetchTupleHook function to
* fetch the next tuple and store it in the tuple table slot. If the tuple
* satisfies all the constraints of the table, it adds the tuple to the buffer.
* When the buffer is full or the total size of all tuples in the buffer exceeds
* the preset maximum, the function calls TvBatchInsert to insert all tuples in
* the buffer into the table and empty the buffer.
* When there are no more tuples to fetch, the function exits the loop and inserts
* any tuples remaining in the buffer into the table. Finally, the function releases
* all allocated resources and returns.
*
* Param [IN] rel: A pointer to the Relation structure, which contains information
* about the table.
* Param [IN] snap: A pointer to the Snapshot structure that contains information
* about the snapshot.
* Param [IN] fetchTupleHook: A function pointer to a function that gets a tuple.
* Param [IN] arg: It should be a pointer to a bunch of tuples.
* Returns [OUT]: void
*/
const int MAX_BUFFERED_TUPLES_TCAP = 1000;
const int MAX_BUFFERED_TUPLES_NUM_TCAP = 65535;
static void TvInsertLostImpl(Relation rel, Snapshot snap, TvFetchTupleHook fetchTupleHook, void *arg)
@ -773,6 +1065,10 @@ static void TvInsertLostImpl(Relation rel, Snapshot snap, TvFetchTupleHook fetch
return;
}
/*
* TvUheapInsertLostImpl() ---
* As for TvInsertLostImpl, please read the notes for TvInsertLostImpl.
*/
static void TvUheapInsertLostImpl(Relation rel, Relation partRel, Partition p,
Snapshot snap, TvUheapFetchTupleHook fetchTupleHook, void *arg)
{
@ -847,6 +1143,21 @@ static void TvUheapInsertLostImpl(Relation rel, Relation partRel, Partition p,
return;
}
/*
* TvInsertLost---
* Call the TvInsertLostImpl function to insert the "missing" tuple into a table.
*
* First opens the table specified by relid and starts a table scan. It then calls
* the TvInsertLostImpl function to get and insert the "missing" tuple. Finally, it
* ends the table scan and closes the table.
*
* Param [IN] relid: It accepts a parameter called 'relid' of type 'Oid'.
* 'Oid' is commonly used in database systems to represent object
* identifiers.
* Param [IN] snap: A pointer to the Snapshot structure that contains
* information about the snapshot.
* Returns [OUT]: void
*/
void TvInsertLost(Oid relid, Snapshot snap)
{
Relation rel;
@ -865,6 +1176,23 @@ void TvInsertLost(Oid relid, Snapshot snap)
return;
}
/*
* TvUheapInsertLostRel() ---
* Inserts a lost tuple into a table(rel) or a part table(partRel).
*
* First check if partRel is NULL. If so, it starts scanning the tables specified
* by relid; Otherwise, it starts scanning the table parts specified by partRel.
* It then calls the TvUheapInsertLostImpl function to get and insert the "lost"
* tuple.
*
* Param [IN] rel & partRel: A pointer to the Relation structure, which contains
* information about the table.
* Param [IN] p: A pointer to a Partition structure that contains information about
* the partition.
* Param [IN] snap: A pointer to the Snapshot structure that contains information
* about the snapshot.
* Returns [OUT]: void
*/
void TvUheapInsertLostRel(Relation rel, Relation partRel, Partition p, Snapshot snap)
{
TableScanDesc sd;
@ -879,6 +1207,29 @@ void TvUheapInsertLostRel(Relation rel, Relation partRel, Partition p, Snapshot
return;
}
/*
* TvUheapInsertLostPart() ---
* Insert the lost tuple into the partition of a table.
*
* The function first gets all the partitions of the table specified by relid.
* It then traverses all partitions and does the following for each partition:
* 1. Opens the partition and gets its relational objects.
* 2. Check whether the partition has subpartitions. If so, it gets all the
* subpartitions and calls the TvUheapInsertLostRel function on each subpartition
* to insert the "lost" tuple. It then closes the subpartition and frees the
* relational object.
* 3. If the partition has no subpartitions, it directly calls the TvUheapInsertLostRel
* function to insert the "lost" tuple.
* 4. Finally, it closes the partition and frees the relational object.
*
* Param [IN] rel: A pointer to the Relation structure, which contains information
* about the table.
* Param [IN] relid: It accepts a parameter called 'relid' of type 'Oid'.'Oid'
* is commonly used in database systems to represent object identifiers.
* Param [IN] snap: A pointer to the Snapshot structure that contains information
* about the snapshot.
* Returns [OUT]: void
*/
void TvUheapInsertLostPart(Relation rel, Oid relid, Snapshot snap)
{
List* partTupleList = NIL;
@ -934,6 +1285,14 @@ void TvUheapInsertLost(Oid relid, Snapshot snap)
return;
}
/*
* TvCheckVersionRestore() ---
* Check whether the version of the table is allowed to be restored,
* and check whether the current user has permission to do so.
*
* Param [IN] rel: Represents the version of the table to be recovered.
* Returns [OUT]: void
*/
static void TvCheckVersionRestore(Relation rel)
{
char *errstr = NULL;
@ -957,6 +1316,13 @@ static void TvCheckVersionRestore(Relation rel)
return;
}
/*
* TvRestoreVersion() ---
* Restores a version of a table.
*
* Param [IN] stmt: Contains information and version information about the table to be recovered.
* Retuens [OUT]: void
*/
void TvRestoreVersion(TimeCapsuleStmt *stmt)
{
Relation rel;

View File

@ -46,10 +46,17 @@ typedef struct SeqScanAccessor {
uint32 sa_prefetch_trigger; /* the prefetch-trigger distance bewteen last prefetched buffer and currently accessed buffer */
} SeqScanAccessor;
/* -----------------------------------------------------------------
* RangeScanInRedis
* -----------------------------------------------------------------
* Note:
* This structure is used to store some information in redistrition.
* -----------------------------------------------------------------
*/
typedef struct RangeScanInRedis{
uint8 isRangeScanInRedis;
uint8 sliceTotal;
uint8 sliceIndex;
uint8 isRangeScanInRedis; /* if it is a range scan in Redistribution */
uint8 sliceTotal; /* total number of slices */
uint8 sliceIndex; /* current slice index */
} RangeScanInRedis;
/*
@ -98,8 +105,8 @@ typedef struct TableScanDescData
TupleTableSlot *slot; /* For begin scan of CopyTo */
/* variables for batch mode scan */
int rs_ctupRows;
int rs_maxScanRows;
int rs_ctupRows; /* current line number scanned */
int rs_maxScanRows; /* maximum number of rows that can be scanned */
} TableScanDescData;
/* struct definition appears in relscan.h */

View File

@ -1668,8 +1668,8 @@ typedef struct ScanState {
List* partitions; /* list of Partition */
List* subpartitions; /* list of SubPartition */
LOCKMODE lockMode;
List* runTimeParamPredicates;
bool runTimePredicatesReady;
List* runTimeParamPredicates; /* list of predicates to be filtered*/
bool runTimePredicatesReady; /* whether the filter predicate is ready to run*/
bool is_scan_end; /* @hdfs Mark whether iterator is over or not, if the scan uses informational constraint. */
SeqScanAccessor* ss_scanaccessor; /* prefetch related */
int part_id;

View File

@ -41,9 +41,11 @@ typedef struct MemoryContextMethods {
void (*init)(MemoryContext context);
void (*reset)(MemoryContext context);
void (*delete_context)(MemoryContext context);
/* Gets the MemoryContext block size*/
Size (*get_chunk_space)(MemoryContext context, void* pointer);
bool (*is_empty)(MemoryContext context);
void (*stats)(MemoryContext context, int level);
/* MemoryContext exception check*/
#ifdef MEMORY_CONTEXT_CHECKING
void (*check)(MemoryContext context);
#endif