blob: 67e1059d7d2408224b3373b851c0915ec8e37764 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
//---------------------------------------------------------------------------
// @filename:
// gpdbwrappers.h
//
// @doc:
// Definition of GPDB function wrappers
//
// @test:
//
//
//---------------------------------------------------------------------------
#ifndef GPDB_gpdbwrappers_H
#define GPDB_gpdbwrappers_H
#include "postgres.h"
#include "access/attnum.h"
#include "utils/faultinjector.h"
// fwd declarations
typedef struct SysScanDescData *SysScanDesc;
typedef struct SnapshotData *Snapshot;
typedef int LOCKMODE;
typedef struct _FuncCandidateList *FuncCandidateList;
struct TypeCacheEntry;
typedef struct NumericData *Numeric;
typedef struct HeapTupleData *HeapTuple;
struct PartitionNode;
typedef struct RelationData *Relation;
struct Value;
typedef struct tupleDesc *TupleDesc;
struct Query;
typedef struct ScanKeyData *ScanKey;
typedef uint16 StrategyNumber;
struct Bitmapset;
struct Plan;
struct ListCell;
struct TargetEntry;
struct Expr;
struct ExtTableEntry;
struct Uri;
struct CdbComponentDatabases;
struct StringInfoData;
typedef StringInfoData *StringInfo;
struct LogicalIndexes;
struct LogicalIndexInfo;
struct ParseState;
struct DefElem;
struct GpPolicy;
struct PartitionSelector;
struct SelectedParts;
struct Motion;
struct QueryResource;
namespace gpdb {
// convert datum to bool
bool FBoolFromDatum(Datum d);
// convert bool to datum
Datum DDatumFromBool(bool b);
// convert datum to char
char CCharFromDatum(Datum d);
// convert char to datum
Datum DDatumFromChar(char c);
// convert datum to int8
int8 CInt8FromDatum(Datum d);
// convert int8 to datum
Datum DDatumFromInt8(int8 i8);
// convert datum to uint8
uint8 UcUint8FromDatum(Datum d);
// convert uint8 to datum
Datum DDatumFromUint8(uint8 ui8);
// convert datum to int16
int16 SInt16FromDatum(Datum d);
// convert int16 to datum
Datum DDatumFromInt16(int16 i16);
// convert datum to uint16
uint16 UsUint16FromDatum(Datum d);
// convert uint16 to datum
Datum DDatumFromUint16(uint16 ui16);
// convert datum to int32
int32 IInt32FromDatum(Datum d);
// convert int32 to datum
Datum DDatumFromInt32(int32 i32);
// convert datum to uint32
uint32 UlUint32FromDatum(Datum d);
// convert uint32 to datum
Datum DDatumFromUint32(uint32 ui32);
// convert datum to int64
int64 LlInt64FromDatum(Datum d);
// convert int64 to datum
Datum DDatumFromInt64(int64 i64);
// convert datum to uint64
uint64 UllUint64FromDatum(Datum d);
// convert uint64 to datum
Datum DDatumFromUint64(uint64 ui64);
// convert datum to oid
Oid OidFromDatum(Datum d);
// convert datum to generic object with pointer handle
void *PvPointerFromDatum(Datum d);
// convert datum to float4
float4 FpFloat4FromDatum(Datum d);
// convert datum to float8
float8 DFloat8FromDatum(Datum d);
// convert pointer to datum
Datum DDatumFromPointer(const void *p);
// does an aggregate exist with the given oid
bool FAggregateExists(Oid oid);
// add member to Bitmapset
Bitmapset *PbmsAddMember(Bitmapset *a, int x);
// create a copy of an object
void *PvCopyObject(void *from);
// datum size
Size SDatumSize(Datum value, bool typByVal, int typLen);
// expression type
Oid OidExprType(Node *expr);
// expression type modifier
int32 IExprTypeMod(Node *expr);
// extract nodes with specific tag from a plan tree
List *PlExtractNodesPlan(Plan *pl, int nodeTag, bool descendIntoSubqueries);
// extract nodes with specific tag from an expression tree
List *PlExtractNodesExpression(Node *node, int nodeTag, bool descendIntoSubqueries);
// intermediate result type of given aggregate
Oid OidAggIntermediateResultType(Oid aggid);
// replace Vars that reference JOIN outputs with references to the original
// relation variables instead
Query *PqueryFlattenJoinAliasVar(Query *pquery, gpos::ULONG ulQueryLevel);
// is aggregate ordered
bool FOrderedAgg(Oid aggid);
// does aggregate have a preliminary function
bool FAggHasPrelimFunc(Oid aggid);
// does aggregate have a prelim or inverse prelim function
bool FAggHasPrelimOrInvPrelimFunc(Oid aggid);
// intermediate result type of given aggregate
Oid OidAggregate(const char*szArg, Oid oidType);
// array type oid
Oid OidArrayType(Oid typid);
// deconstruct array
void DeconstructArray(struct ArrayType *array, Oid elmtype, int elmlen, bool elmbyval,
char elmalign, Datum **elemsp, bool **nullsp, int *nelemsp);
// attribute stats slot
bool FGetAttrStatsSlot(HeapTuple statstuple, Oid atttype, int32 atttypmod, int reqkind,
Oid reqop, Datum **values, int *nvalues, float4 **numbers, int *nnumbers);
// free attribute stats slot
void FreeAttrStatsSlot(Oid atttype, Datum *values, int nvalues, float4 *numbers, int nnumbers);
// attribute statistics
HeapTuple HtAttrStats(Oid relid, AttrNumber attnum);
// function oids
List *PlFunctionOids(void);
// does a function exist with the given oid
bool FFunctionExists(Oid oid);
// is the given function strict
bool FFuncStrict(Oid funcid);
// stability property of given function
char CFuncStability(Oid funcid);
// data access property of given function
char CFuncDataAccess(Oid funcid);
// list of candidate functions with the given names
FuncCandidateList FclFuncCandidates(List *names, int nargs);
// trigger name
char *SzTriggerName(Oid triggerid);
// trigger relid
Oid OidTriggerRelid(Oid triggerid);
// trigger funcid
Oid OidTriggerFuncid(Oid triggerid);
// trigger type
int32 ITriggerType(Oid triggerid);
// is trigger enabled
bool FTriggerEnabled(Oid triggerid);
// does trigger exist
bool FTriggerExists(Oid oid);
// does check constraint exist
bool FCheckConstraintExists(Oid oidCheckConstraint);
// check constraint name
char *SzCheckConstraintName(Oid oidCheckConstraint);
// check constraint relid
Oid OidCheckConstraintRelid(Oid oidCheckConstraint);
// check constraint expression tree
Node *PnodeCheckConstraint(Oid oidCheckConstraint);
// get the list of check constraints for a given relation
List *PlCheckConstraint(Oid oidRel);
// part constraint expression tree
Node *PnodePartConstraintRel(Oid oidRel, List **pplDefaultLevels);
// get the cast function for the specified source and destination types
bool FCastFunc(Oid oidSrc, Oid oidDest, bool *is_binary_coercible, Oid *oidCastFunc);
// get type of operator
uint UlCmpt(Oid oidOp, Oid oidLeft, Oid oidRight);
// get scalar comparison between given types
Oid OidScCmp(Oid oidLeft, Oid oidRight, uint ulCmpt);
// function name
char *SzFuncName(Oid funcid);
// output argument types of the given function
List *PlFuncOutputArgTypes(Oid funcid);
// argument types of the given function
List *PlFuncArgTypes(Oid funcid);
// does a function return a set of rows
bool FFuncRetset(Oid funcid);
// return type of the given function
Oid OidFuncRetType(Oid funcid);
// commutator operator of the given operator
Oid OidCommutatorOp(Oid opno);
// inverse operator of the given operator
Oid OidInverseOp(Oid opno);
// function oid corresponding to the given operator oid
RegProcedure OidOpFunc(Oid opno);
// operator name
char *SzOpName(Oid opno);
// parts of a partitioned table
bool FLeafPartition(Oid oid);
// find the oid of the root partition given partition oid belongs to
Oid OidRootPartition(Oid oid);
// partition attributes
List *PlPartitionAttrs(Oid oid);
// parts of a partitioned table
PartitionNode *PpnParts(Oid relid, int2 level, Oid parent, bool inctemplate, MemoryContext mcxt, bool includesubparts);
// keys of the relation with the given oid
List *PlRelationKeys(Oid relid);
// relid of a composite type
Oid OidTypeRelid(Oid typid);
// name of the type with the given oid
char *SzTypeName(Oid typid);
// number of GP segments
int UlSegmentCountGP(void);
// heap attribute is null
bool FHeapAttIsNull(HeapTuple tup, int attnum);
// free heap tuple
void FreeHeapTuple(HeapTuple htup);
// does an index exist with the given oid
bool FIndexExists(Oid oid);
// check if given oid is hashable internally in Greenplum Database
bool FGreenplumDbHashable(Oid typid);
// append an element to a list
List *PlAppendElement(List *list, void *datum);
// append an integer to a list
List *PlAppendInt(List *list, int datum);
// append an oid to a list
List *PlAppendOid(List *list, Oid datum);
// prepend a new element to the list
List *PlPrependElement(void *datum, List *list);
// prepend an integer to the list
List *PlPrependInt(int datum, List *list);
// prepend an oid to a list
List *PlPrependOid(Oid datum, List *list);
// concatenate lists
List *PlConcat(List *list1, List *list2);
// copy list
List *PlCopy(List *list);
// first cell in a list
ListCell *PlcListHead(List *l);
// last cell in a list
ListCell *PlcListTail(List *l);
// number of items in a list
int UlListLength(List *l);
// return the nth element in a list of pointers
void *PvListNth(List *list, int n);
// return the nth element in a list of ints
int IListNth(List *list, int n);
// return the nth element in a list of oids
Oid OidListNth(List *list, int n);
// check whether the given oid is a member of the given list
bool FMemberOid(List *list, Oid oid);
// free list
void FreeList(List *plist);
// deep free of a list
void FreeListDeep(List *plist);
// if pplist is non-NULL, and *pplist is non-NULL then free the list and set
// *pplist to NULL
void FreeListAndNull(List **pplist);
// is this a Gather motion
bool FMotionGather(const Motion *pmotion);
// does a multi-level partitioned table have uniform partitioning hierarchy
bool FMultilevelPartitionUniform(Oid rootOid);
// lookup type cache
TypeCacheEntry *PtceLookup(Oid type_id, int flags);
// create a value node for a string
Value *PvalMakeString(char *str);
// create a value node for an integer
Value *PvalMakeInteger(long i);
// create a bool constant
Node *PnodeMakeBoolConst(bool value, bool isnull);
// make a NULL constant of the given type
Node *PnodeMakeNULLConst(Oid oidType);
// create a new target entry
TargetEntry *PteMakeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk);
// create a new var node
Var *PvarMakeVar(Index varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Index varlevelsup);
// memory allocation functions
void *PvMemoryContextAllocImpl(MemoryContext context, Size size, const char* file, const char * func, int line);
void *PvMemoryContextAllocZeroAlignedImpl(MemoryContext context, Size size, const char* file, const char * func, int line);
void *PvMemoryContextAllocZeroImpl(MemoryContext context, Size size, const char* file, const char * func, int line);
void *PvMemoryContextReallocImpl(void *pointer, Size size, const char* file, const char * func, int line);
void *GPDBAlloc(Size size);
void GPDBFree(void *ptr);
// create a duplicate of the given string in the given memory context
char *SzMemoryContextStrdup(MemoryContext context, const char *string);
// string representation of a node
char *SzNodeToString(void *obj);
// node representation from a string
Node *Pnode(char *string);
// return the default value of the type
Node *PnodeTypeDefault(Oid typid);
// convert numeric to double; if out of range, return +/- HUGE_VAL
double DNumericToDoubleNoOverflow(Numeric num);
// convert time-related datums to double for stats purpose
double DConvertTimeValueToScalar(Datum datum, Oid typid);
// convert network-related datums to double for stats purpose
double DConvertNetworkToScalar(Datum datum, Oid typid);
// is the given operator hash-joinable
bool FOpHashJoinable(Oid opno);
// is the given operator merge-joinable
bool FOpMergeJoinable(Oid opno, Oid *leftOp, Oid *rightOp);
// is the given operator strict
bool FOpStrict(Oid opno);
// get input types for a given operator
void GetOpInputTypes(Oid opno, Oid *lefttype, Oid *righttype);
// does an operator exist with the given oid
bool FOperatorExists(Oid oid);
// fetch detoasted copies of toastable datatypes
struct varlena *PvlenDetoastDatum(struct varlena * datum);
// expression tree walker
bool FWalkExpressionTree(Node *node, bool(*walker)(), void *context);
// query or expression tree walker
bool FWalkQueryOrExpressionTree(Node *node, bool(*walker)(), void *context, int flags);
// modify a query tree
Query *PqueryMutateQueryTree(Query *query, Node *(*mutator)(), void *context, int flags);
// modify an expression tree
Node *PnodeMutateExpressionTree(Node *node, Node *(*mutator)(), void *context);
// modify a query or an expression tree
Node *PnodeMutateQueryOrExpressionTree(Node *node, Node *(*mutator)(), void *context, int flags);
// the part of PqueryMutateQueryTree that processes a query's rangetable
List *PlMutateRangeTable(List *rtable, Node *(*mutator)(), void *context, int flags);
// check whether the part with the given oid is the root of a partition table
bool FRelPartIsRoot(Oid relid);
// check whether the part with the given oid is an interior subpartition
bool FRelPartIsInterior(Oid relid);
// check whether table with the given oid is a regular table and not part of a partitioned table
bool FRelPartIsNone(Oid relid);
// check whether partitioning type encodes hash partitioning
bool FHashPartitioned(char c);
// check whether a relation is inherited
bool FHasSubclass(Oid oidRel);
// check whether a relation has parquet children
bool FHasParquetChildren(Oid oidRel);
// return the distribution policy of a relation; if the table is partitioned
// and the parts are distributed differently, return Random distribution
GpPolicy *Pdistrpolicy(Relation rel);
// return active relation distribution types
List *PlActiveRelTypes(void);
// return active query resource
QueryResource *PqrActiveQueryResource(void);
// return true if the table is partitioned and hash-distributed, and one of
// the child partitions is randomly distributed
gpos::BOOL FChildPartDistributionMismatch(Relation rel);
// return true if the table is partitioned and any of the child partitions
// have a trigger of the given type
gpos::BOOL FChildTriggers(Oid oid, int triggerType);
// does a relation exist with the given oid
bool FRelationExists(Oid oid);
// extract all relation oids from the catalog
List *PlRelationOids(void);
// estimate the relation size using the real number of blocks and tuple density
void EstimateRelationSize(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples);
// close the given relation
void CloseRelation(Relation rel);
// return the logical indexes for a partitioned table
LogicalIndexes *Plgidx(Oid oid);
// return the logical info structure for a given logical index oid
LogicalIndexInfo *Plgidxinfo(Oid rootOid, Oid indexOid);
// return a list of index oids for a given relation
List *PlRelationIndexes(Relation relation);
// build an array of triggers for this relation
void BuildRelationTriggers(Relation rel);
// get relation with given oid
Relation RelGetRelation(Oid relationId);
// get external table entry with given oid
ExtTableEntry *Pexttable(Oid relationId);
// return the first member of the given targetlist whose expression is
// equal to the given expression, or NULL if no such member exists
TargetEntry *PteMember(Node *node, List *targetlist);
// return a list of members of the given targetlist whose expression is
// equal to the given expression, or NULL if no such member exists
List *PteMembers(Node *node, List *targetlist);
// check if two gpdb objects are equal
bool FEqual(void *p1, void *p2);
// does a type exist with the given oid
bool FTypeExists(Oid oid);
// check whether a type is composite
bool FCompositeType(Oid typid);
// get integer value from an Integer value node
int IValue(Node *node);
// parse external table URI
Uri *PuriParseExternalTable(const char *szUri);
// check if the given uri is a HADOOP protocol - pxf
bool FPxfProtocol(Uri *pUri);
// calculate max_participants_allowed for pxf
int IMaxParticipantsPxf(int total_segments);
// generate the mapping of the Hadoop data fragments to the segments
char** RgszMapHdDataToSegments(char *uri, int total_segs, int working_segs, Relation relation, List* quals);
// release the memory allocated for the mapping of the Hadoop data fragments to the segments
void FreeHdDataToSegmentsMapping(char **segs_work_map, int total_segs);
// returns ComponentDatabases
List *PcdbComponentDatabases(void);
// compare two strings ignoring case
int IStrCmpIgnoreCase(const char *sz1, const char *sz2);
// construct random segment map
bool *RgfRandomSegMap(int total_primaries, int total_to_skip);
// initialize a StringInfoData struct with data buffer of 'size' bytes
void InitStringInfoOfSize(StringInfo str, int bufsize);
// create an empty 'StringInfoData' & return a pointer to it
StringInfo SiMakeStringInfo(void);
// append the two given strings to the StringInfo object
void AppendStringInfo(StringInfo str, const char *str1, const char *str2);
// append a null-terminated string to str
void AppendStringInfoString(StringInfo str, const char *s);
// append a single character to str
void AppendStringInfoChar(StringInfo str, char c);
// look for the given node tags in the given tree and return the index of
// the first one found, or -1 if there are none
int IFindNodes(Node *node, List *nodeTags);
Node *PnodeCoerceToCommonType(ParseState *pstate, Node *pnode, Oid oidTargetType, const char *context);
// deduce an individual actual datatype on the assumption that the rules for ANYARRAY/ANYELEMENT are being followed
Oid OidResolveGenericType(Oid declared_type, Oid context_actual_type, Oid context_declared_type);
// hash a const value with GPDB's hash function
int32 ICdbHash(Const *pconst, int iSegments);
// hash a list of const values with GPDB's hash function
int32 ICdbHashList(List *plConsts, int iSegments);
// check permissions on range table
void CheckRTPermissions(List *plRangeTable);
// get index operator properties
void IndexOpProperties(Oid opno, Oid opclass, int *strategy, Oid *subtype, bool *recheck);
// get oids of classes this operator belongs to
List *PlScOpOpClasses(Oid opno);
// get oids of op classes for the index keys
List *PlIndexOpClasses(Oid oidIndex);
// returns the result of evaluating 'pexpr' as an Expr. Caller keeps ownership of 'pexpr'
// and takes ownership of the result
Expr *PexprEvaluate(Expr *pexpr, Oid oidResultType);
// interpret the value of "With oids" option from a list of defelems
bool FInterpretOidsOption(List *plOptions);
// extract string value from defelem's value
char *SzDefGetString(DefElem *pdefelem, bool *fNeedFree);
// fold array expression constant values
Node *PnodeFoldArrayexprConstants(ArrayExpr *parrayexpr);
// static partition selection given a PartitionSelector node
SelectedParts *SpStaticPartitionSelection(PartitionSelector *ps);
// simple fault injector used by COptTasks.cpp to inject GPDB fault
FaultInjectorType_e OptTasksFaultInjector(FaultInjectorIdentifier_e identifier);
// return the number of leaf partition for a given table oid
gpos::ULONG UlLeafPartitions(Oid oidRelation);
// requests version for object from MD Versioning component
void MdVerRequestVersion(Oid key, uint64 *ddl_version, uint64 *dml_version);
} //namespace gpdb
#define ForEach(cell, l) \
for ((cell) = gpdb::PlcListHead(l); (cell) != NULL; (cell) = lnext(cell))
#define ForBoth(cell1, list1, cell2, list2) \
for ((cell1) = gpdb::PlcListHead(list1), (cell2) = gpdb::PlcListHead(list2); \
(cell1) != NULL && (cell2) != NULL; \
(cell1) = lnext(cell1), (cell2) = lnext(cell2))
#define ForEachWithCount(cell, list, counter) \
for ((cell) = gpdb::PlcListHead(list), (counter)=0; \
(cell) != NULL; \
(cell) = lnext(cell), ++(counter))
#define ListMake1(x1) gpdb::PlPrependElement(x1, NIL)
#define ListMake2(x1,x2) gpdb::PlPrependElement(x1, ListMake1(x2))
#define ListMake1Int(x1) gpdb::PlPrependInt(x1, NIL)
#define ListMake1Oid(x1) gpdb::PlPrependOid(x1, NIL)
#define ListMake2Oid(x1,x2) gpdb::PlPrependOid(x1, ListMake1Oid(x2))
#define LInitial(l) lfirst(gpdb::PlcListHead(l))
#define LInitialOID(l) lfirst_oid(gpdb::PlcListHead(l))
#define Palloc0Fast(sz) \
( MemSetTest(0, (sz)) ? \
gpdb::PvMemoryContextAllocZeroAlignedImpl(CurrentMemoryContext, (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__) : \
gpdb::PvMemoryContextAllocZeroImpl(CurrentMemoryContext, (sz), __FILE__, PG_FUNCNAME_MACRO, __LINE__))
#ifdef __GNUC__
/* With GCC, we can use a compound statement within an expression */
#define NewNode(size, tag) \
({ Node *_result; \
AssertMacro((size) >= sizeof(Node)); /* need the tag, at least */ \
_result = (Node *) Palloc0Fast(size); \
_result->type = (tag); \
_result; \
})
#else
/*
* There is no way to dereference the palloc'ed pointer to assign the
* tag, and also return the pointer itself, so we need a holder variable.
* Fortunately, this macro isn't recursive so we just define
* a global variable for this purpose.
*/
extern PGDLLIMPORT Node *newNodeMacroHolder;
#define NewNode(size, tag) \
( \
AssertMacro((size) >= sizeof(Node)), /* need the tag, at least */ \
newNodeMacroHolder = (Node *) Palloc0Fast(size), \
newNodeMacroHolder->type = (tag), \
newNodeMacroHolder \
)
#endif // __GNUC__
#define MakeNode(_type_) ((_type_ *) NewNode(sizeof(_type_),T_##_type_))
#define PStrDup(str) gpdb::SzMemoryContextStrdup(CurrentMemoryContext, (str))
#endif // !GPDB_gpdbwrappers_H
// EOF