From ea0cfca172713d6d1284380b01dc51938b726e05 Mon Sep 17 00:00:00 2001 From: Hari Date: Tue, 20 Dec 2016 17:23:01 +1100 Subject: [PATCH 2/3] Server minimal changes Hooks and minimal structure changes that are required for VCI to work properly --- src/backend/access/heap/heapam.c | 15 +++++++++++++++ src/backend/catalog/dependency.c | 6 ++++++ src/backend/catalog/index.c | 20 ++++++++++++++++++++ src/backend/commands/tablecmds.c | 15 +++++++++++++++ src/backend/executor/execQual.c | 6 ++++++ src/backend/executor/nodeModifyTable.c | 12 ++++++++++++ src/backend/nodes/params.c | 1 + src/backend/utils/cache/relcache.c | 16 ++++++++++++++++ src/include/access/heapam.h | 8 ++++++++ src/include/catalog/dependency.h | 4 ++++ src/include/catalog/index.h | 4 ++++ src/include/catalog/pg_class.h | 1 + src/include/commands/tablecmds.h | 13 +++++++++++++ src/include/executor/nodeModifyTable.h | 3 +++ src/include/nodes/extensible.h | 3 +++ src/include/nodes/params.h | 9 ++++++++- src/include/nodes/plannodes.h | 2 ++ src/include/utils/relcache.h | 3 +++ 18 files changed, 140 insertions(+), 1 deletion(-) diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index ea579a0..7226ac4 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -77,6 +77,8 @@ /* GUC variable */ bool synchronize_seqscans = true; +add_index_delete_hook_type add_index_delete_hook = NULL; +add_heap_rescan_skip_recounting_nblocks_hook_type add_heap_rescan_skip_recounting_nblocks_hook = NULL; static HeapScanDesc heap_beginscan_internal(Relation relation, Snapshot snapshot, @@ -229,10 +231,15 @@ initscan(HeapScanDesc scan, ScanKey key, bool keep_startblock) * results for a non-MVCC snapshot, the caller must hold some higher-level * lock that ensures the interesting tuple(s) won't change.) */ + if (keep_startblock) + if (add_heap_rescan_skip_recounting_nblocks_hook) + if (add_heap_rescan_skip_recounting_nblocks_hook(scan, key)) + goto skip_get_number_of_blocks; if (scan->rs_parallel != NULL) scan->rs_nblocks = scan->rs_parallel->phs_nblocks; else scan->rs_nblocks = RelationGetNumberOfBlocks(scan->rs_rd); +skip_get_number_of_blocks: /* * If the table is large relative to NBuffers, use a bulk-read access @@ -3003,6 +3010,7 @@ heap_delete(Relation relation, ItemPointer tid, bool all_visible_cleared = false; HeapTuple old_key_tuple = NULL; /* replica identity of the tuple */ bool old_key_copied = false; + TransactionId old_xmin; Assert(ItemPointerIsValid(tid)); @@ -3223,6 +3231,7 @@ l1: xid, LockTupleExclusive, true, &new_xmax, &new_infomask, &new_infomask2); + old_xmin = HeapTupleHeaderGetXmin(tp.t_data); START_CRIT_SECTION(); /* @@ -3358,6 +3367,8 @@ l1: if (old_key_tuple != NULL && old_key_copied) heap_freetuple(old_key_tuple); + if (add_index_delete_hook) + add_index_delete_hook(relation, tid, old_xmin); return HeapTupleMayBeUpdated; } @@ -3475,6 +3486,7 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, infomask2_old_tuple, infomask_new_tuple, infomask2_new_tuple; + TransactionId old_xmin; Assert(ItemPointerIsValid(otid)); @@ -3836,6 +3848,7 @@ l2: &xmax_old_tuple, &infomask_old_tuple, &infomask2_old_tuple); + old_xmin = HeapTupleHeaderGetRawXmin(oldtup.t_data); /* * And also prepare an Xmax value for the new copy of the tuple. If there * was no xmax previously, or there was one but all lockers are now gone, @@ -4271,6 +4284,8 @@ l2: bms_free(key_attrs); bms_free(id_attrs); + if (add_index_delete_hook) + add_index_delete_hook(relation, otid, old_xmin); return HeapTupleMayBeUpdated; } diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c index 18a14bf..d576809 100644 --- a/src/backend/catalog/dependency.c +++ b/src/backend/catalog/dependency.c @@ -79,6 +79,7 @@ #include "utils/syscache.h" #include "utils/tqual.h" +add_drop_relation_hook_type add_drop_relation_hook = NULL; /* * Deletion processing requires additional state for each ObjectAddress that @@ -1100,6 +1101,11 @@ doDeletion(const ObjectAddress *object, int flags) { char relKind = get_rel_relkind(object->objectId); + if (add_drop_relation_hook && object->objectSubId == 0) + { + if (add_drop_relation_hook(object->objectId, flags)) + break; + } if (relKind == RELKIND_INDEX) { bool concurrent = ((flags & PERFORM_DELETION_CONCURRENTLY) != 0); diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c index 08b0989..445d0b0 100644 --- a/src/backend/catalog/index.c +++ b/src/backend/catalog/index.c @@ -127,6 +127,13 @@ static void SetReindexPending(List *indexes); static void RemoveReindexPending(Oid indexOid); static void ResetReindexPending(void); +add_reindex_index_hook_type add_reindex_index_hook = NULL; + +/* + * Itempointer points to the actual heaptuple + * not to the root tuple used for index build callback + */ +ItemPointerData IndexingHeapTupleTid; /* * relationHasPrimaryKey @@ -2576,6 +2583,7 @@ IndexBuildHeapRangeScan(Relation heapRelation, * some index AMs want to do further processing on the data first. So * pass the values[] and isnull[] arrays, instead. */ + IndexingHeapTupleTid = heapTuple->t_self; if (HeapTupleIsHeapOnly(heapTuple)) { @@ -3329,6 +3337,18 @@ reindex_index(Oid indexId, bool skip_constraint_checks, char persistence, */ iRel = index_open(indexId, AccessExclusiveLock); + if(add_reindex_index_hook) + { + if (!add_reindex_index_hook(iRel)) + { + RemoveReindexPending(RelationGetRelid(iRel)); + + /* Close rels, but keep locks */ + index_close(iRel, NoLock); + heap_close(heapRelation, NoLock); + return; + } + } /* * Don't allow reindex on temp tables of other backends ... their local * buffer manager is not going to cope. diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index b0e3f28..94db866 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -100,6 +100,9 @@ #include "utils/tqual.h" #include "utils/typcache.h" +add_alter_tablespace_hook_type add_alter_tablespace_hook = NULL; +add_alter_table_change_owner_hook_type add_alter_table_change_owner_hook = NULL; +add_alter_table_change_schema_hook_type add_alter_table_change_schema_hook = NULL; /* * ON COMMIT action list @@ -9672,6 +9675,8 @@ ATExecChangeOwner(Oid relationOid, Oid newOwnerId, bool recursing, LOCKMODE lock /* If it has dependent sequences, recurse to change them too */ change_owner_recurse_to_sequences(relationOid, newOwnerId, lockmode); } + if (add_alter_table_change_owner_hook) + add_alter_table_change_owner_hook(relationOid, tuple_class->relkind, newOwnerId); } InvokeObjectPostAlterHook(RelationRelationId, relationOid, 0); @@ -10116,6 +10121,14 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) * Need lock here in case we are recursing to toast table or index */ rel = relation_open(tableOid, lockmode); + if (add_alter_tablespace_hook) + { + if (add_alter_tablespace_hook(rel)) + { + relation_close(rel, NoLock); + return; + } + } /* * No work if no change in tablespace. @@ -12191,6 +12204,8 @@ AlterRelationNamespaceInternal(Relation classRel, Oid relOid, { add_exact_object_address(&thisobj, objsMoved); + if (add_alter_table_change_schema_hook) + add_alter_table_change_schema_hook(relOid, classForm->relkind, newNspOid); InvokeObjectPostAlterHook(RelationRelationId, relOid, 0); } diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index ec1ca01..c8923af 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -4603,6 +4603,12 @@ ExecInitExpr(Expr *node, PlanState *parent) state->evalfunc = ExecEvalConst; break; case T_Param: + if (ExecInitParam_hook) + { + state = ExecInitParam_hook((Param *) node, parent); + if (state) + break; + } state = makeNode(ExprState); switch (((Param *) node)->paramkind) { diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c index 0d85b15..e89dfa2 100644 --- a/src/backend/executor/nodeModifyTable.c +++ b/src/backend/executor/nodeModifyTable.c @@ -52,6 +52,7 @@ #include "utils/rel.h" #include "utils/tqual.h" +add_should_index_insert_hook_type add_should_index_insert_hook = NULL; static bool ExecOnConflictUpdate(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo, @@ -1103,6 +1104,17 @@ lreplace:; if (resultRelInfo->ri_NumIndices > 0 && !HeapTupleIsHeapOnly(tuple)) recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self), estate, false, NULL, NIL); + else if( resultRelInfo->ri_NumIndices > 0 && HeapTupleIsHeapOnly(tuple) ) + { + /* + * But for VCI index, the newtuple needs to be inserted into VCI, + * Because of this reason, the HOT tuple gets inserted through the + * hook function + */ + if(add_should_index_insert_hook) + recheckIndexes = add_should_index_insert_hook(slot,&(tuple->t_self), + estate); + } } if (canSetTag) diff --git a/src/backend/nodes/params.c b/src/backend/nodes/params.c index f2e26b8..e88394a 100644 --- a/src/backend/nodes/params.c +++ b/src/backend/nodes/params.c @@ -21,6 +21,7 @@ #include "utils/datum.h" #include "utils/lsyscache.h" +ExecInitParam_hook_type ExecInitParam_hook; /* * Copy a ParamListInfo structure. diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 2a68359..6d7de3d 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -83,6 +83,7 @@ #include "utils/syscache.h" #include "utils/tqual.h" +add_skip_vci_index_hook_type add_skip_vci_index_hook = NULL; /* * name of relcache init file(s), used to speed up backend startup @@ -4790,6 +4791,21 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind) indexDesc = index_open(indexOid, AccessShareLock); + /* + * Check Whether the index is of type VCI or not? + * + * If it is VCI type Skip adding to the relation index list. + * VCI index's are not like normal indexes, so don't add them. + */ + if (add_skip_vci_index_hook) + { + if (add_skip_vci_index_hook(indexDesc)) + { + /* Skip if Index is VCI index */ + index_close(indexDesc, AccessShareLock); + continue; + } + } /* Extract index key information from the index's pg_index row */ indexInfo = BuildIndexInfo(indexDesc); diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 0d12bbb..b4daf68 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -196,4 +196,12 @@ extern BlockNumber ss_get_location(Relation rel, BlockNumber relnblocks); extern void SyncScanShmemInit(void); extern Size SyncScanShmemSize(void); +/* Hook for plugins to get control for heap delete operation */ +typedef void (*add_index_delete_hook_type)(Relation indexRelation, ItemPointer heap_tid, TransactionId xmin); +extern PGDLLIMPORT add_index_delete_hook_type add_index_delete_hook; + +/* Hook for plugins to get control in heap rescan */ +typedef bool (*add_heap_rescan_skip_recounting_nblocks_hook_type)(HeapScanDesc scan, ScanKey key); +extern PGDLLIMPORT add_heap_rescan_skip_recounting_nblocks_hook_type add_heap_rescan_skip_recounting_nblocks_hook; + #endif /* HEAPAM_H */ diff --git a/src/include/catalog/dependency.h b/src/include/catalog/dependency.h index e8a302f..f5ba30a 100644 --- a/src/include/catalog/dependency.h +++ b/src/include/catalog/dependency.h @@ -276,4 +276,8 @@ extern void shdepDropOwned(List *relids, DropBehavior behavior); extern void shdepReassignOwned(List *relids, Oid newrole); +/* Hook for plugins to get control for drop index operation */ +typedef bool (*add_drop_relation_hook_type)(Oid relOid, int flags); +extern PGDLLIMPORT add_drop_relation_hook_type add_drop_relation_hook; + #endif /* DEPENDENCY_H */ diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h index 37e6ef3..c784428 100644 --- a/src/include/catalog/index.h +++ b/src/include/catalog/index.h @@ -131,4 +131,8 @@ extern bool ReindexIsProcessingHeap(Oid heapOid); extern bool ReindexIsProcessingIndex(Oid indexOid); extern Oid IndexGetRelation(Oid indexId, bool missing_ok); +/* Hook for plugins to get control for reindex operation */ +typedef bool (*add_reindex_index_hook_type)(Relation); +extern PGDLLIMPORT add_reindex_index_hook_type add_reindex_index_hook; +extern PGDLLIMPORT ItemPointerData IndexingHeapTupleTid; #endif /* INDEX_H */ diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h index a61b7a2..f6f7dd4 100644 --- a/src/include/catalog/pg_class.h +++ b/src/include/catalog/pg_class.h @@ -166,6 +166,7 @@ DESCR(""); #define RELKIND_FOREIGN_TABLE 'f' /* foreign table */ #define RELKIND_MATVIEW 'm' /* materialized view */ #define RELKIND_PARTITIONED_TABLE 'P' /* partitioned table */ +#define RELKIND_CSTORE 'C' /* columnar store rel */ #define RELPERSISTENCE_PERMANENT 'p' /* regular table */ #define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent table */ diff --git a/src/include/commands/tablecmds.h b/src/include/commands/tablecmds.h index fa48f2e..8020a98 100644 --- a/src/include/commands/tablecmds.h +++ b/src/include/commands/tablecmds.h @@ -87,4 +87,17 @@ extern void RangeVarCallbackOwnsTable(const RangeVar *relation, extern void RangeVarCallbackOwnsRelation(const RangeVar *relation, Oid relId, Oid oldRelId, void *noCatalogs); + +/* Hook for plugins to get control for alter tablespace operation */ +typedef bool (*add_alter_tablespace_hook_type)(Relation rel); +extern PGDLLIMPORT add_alter_tablespace_hook_type add_alter_tablespace_hook; + +/* Hook for plugins to get control for alter table change owner operation */ +typedef void (*add_alter_table_change_owner_hook_type)(Oid relOid, char relKind, Oid newOwnerId); +extern PGDLLIMPORT add_alter_table_change_owner_hook_type add_alter_table_change_owner_hook; + +/* Hook for plugins to get control for alter table change schema operation */ +typedef void (*add_alter_table_change_schema_hook_type)(Oid relOid, char relKind, Oid newNspOid); +extern PGDLLIMPORT add_alter_table_change_schema_hook_type add_alter_table_change_schema_hook; + #endif /* TABLECMDS_H */ diff --git a/src/include/executor/nodeModifyTable.h b/src/include/executor/nodeModifyTable.h index 6b66353..8ef9167 100644 --- a/src/include/executor/nodeModifyTable.h +++ b/src/include/executor/nodeModifyTable.h @@ -20,4 +20,7 @@ extern TupleTableSlot *ExecModifyTable(ModifyTableState *node); extern void ExecEndModifyTable(ModifyTableState *node); extern void ExecReScanModifyTable(ModifyTableState *node); +/* Hook for plugins to get control for HOT update operation */ +typedef List* (*add_should_index_insert_hook_type)(TupleTableSlot*, ItemPointer, EState* ); +extern PGDLLIMPORT add_should_index_insert_hook_type add_should_index_insert_hook; #endif /* NODEMODIFYTABLE_H */ diff --git a/src/include/nodes/extensible.h b/src/include/nodes/extensible.h index 17afe58..f2a85de 100644 --- a/src/include/nodes/extensible.h +++ b/src/include/nodes/extensible.h @@ -144,6 +144,9 @@ typedef struct CustomExecMethods void (*ExplainCustomScan) (CustomScanState *node, List *ancestors, ExplainState *es); + /* added for vci */ + void (*SetBoundCustomScan)(const struct LimitState *limit,struct CustomScanState *cps); + void (*ExplainCustomPlanTargetRel) (struct CustomScanState *node, struct ExplainState *es); } CustomExecMethods; extern void RegisterCustomScanMethods(const CustomScanMethods *methods); diff --git a/src/include/nodes/params.h b/src/include/nodes/params.h index a8aa530..f215981 100644 --- a/src/include/nodes/params.h +++ b/src/include/nodes/params.h @@ -17,7 +17,9 @@ /* Forward declarations, to avoid including other headers */ struct Bitmapset; struct ParseState; - +struct Param; +struct ExprState; +struct PlanState; /* ---------------- * ParamListInfo @@ -99,6 +101,8 @@ typedef struct ParamExecData void *execPlan; /* should be "SubPlanState *" */ Datum value; bool isnull; + bool noNeedLoadFromMain; + bool loadedFromMain; } ParamExecData; @@ -108,4 +112,7 @@ extern Size EstimateParamListSpace(ParamListInfo paramLI); extern void SerializeParamList(ParamListInfo paramLI, char **start_address); extern ParamListInfo RestoreParamList(char **start_address); +/* Hook for plugins to get control Parameters in expressions */ +typedef struct ExprState *(*ExecInitParam_hook_type)(struct Param *param, struct PlanState *parent); +extern PGDLLIMPORT ExecInitParam_hook_type ExecInitParam_hook; #endif /* PARAMS_H */ diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index e2fbc7d..279b9d5 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -112,6 +112,8 @@ typedef struct Plan * information needed for parallel query */ bool parallel_aware; /* engage parallel-aware logic? */ + /* added for vci */ + AttrNumber plan_no; /* plan number (1-origin) in the Query */ /* * Common structural data for all Plan types. diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h index 6ea7dd2..b08ec93 100644 --- a/src/include/utils/relcache.h +++ b/src/include/utils/relcache.h @@ -128,4 +128,7 @@ extern bool criticalRelcachesBuilt; /* should be used only by relcache.c and postinit.c */ extern bool criticalSharedRelcachesBuilt; +/* Hook for plugins to get control for Relation build */ +typedef bool (*add_skip_vci_index_hook_type)(Relation rel); +extern PGDLLIMPORT bool (*add_skip_vci_index_hook)(Relation rel); #endif /* RELCACHE_H */ -- 2.7.4.windows.1