* Portions Copyright (c) 2020 Huawei Technologies Co.,Ltd.
* Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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.
* ---------------------------------------------------------------------------------------
*
* extension_dependency.h
* postgis extension head file
*
*
*
* IDENTIFICATION
* contrib/postgis/extension_dependency.h
*
* ---------------------------------------------------------------------------------------
*/
#ifndef EXTENSION_DEPENDENCY
#define EXTENSION_DEPENDENCY
#include "../postgis_config.h"
#include <stdint.h>
#include <signal.h>
#include <ctype.h>
#include "postgres.h"
#include "access/htup.h"
#include <access/heapam.h>
#include <access/skey.h>
#include <access/genam.h>
#include "access/tuptoaster.h"
#include <access/sysattr.h>
#include "catalog/pg_type.h"
#include "catalog/pg_extension.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "commands/extension.h"
#include "fmgr.h"
#include "lib/stringinfo.h"
#include "mb/pg_wchar.h"
#include "nodes/memnodes.h"
#include "nodes/nodes.h"
#include "nodes/pg_list.h"
#include "nodes/parsenodes.h"
#include "utils/array.h"
#include "utils/elog.h"
#include "utils/errcodes.h"
#include "utils/geo_decls.h"
#include "utils/guc.h"
#include "utils/guc_tables.h"
#include "utils/hsearch.h"
#include "utils/palloc.h"
#include "utils/syscache.h"
#include "utils/memutils.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/typcache.h"
#include "utils/fmgroids.h"
#include "knl/knl_variable.h"
typedef int Buffer;
typedef uint16 StrategyNumber;
typedef int16 AttrNumber;
typedef uint16 LocationIndex;
typedef uint32 BlockNumber;
#define RTLeftStrategyNumber 1
#define RTOverLeftStrategyNumber 2
#define RTOverlapStrategyNumber 3
#define RTOverRightStrategyNumber 4
#define RTRightStrategyNumber 5
#define RTSameStrategyNumber 6
#define RTContainsStrategyNumber 7
#define RTContainedByStrategyNumber 8
#define RTOverBelowStrategyNumber 9
#define RTBelowStrategyNumber 10
#define RTAboveStrategyNumber 11
#define RTOverAboveStrategyNumber 12
#define RTOldContainsStrategyNumber 13
#define RTOldContainedByStrategyNumber 14
#define RTKNNSearchStrategyNumber 15
#define WINDOW_SEEK_CURRENT 0
#define WINDOW_SEEK_HEAD 1
#define WINDOW_SEEK_TAIL 2
#define STATISTIC_NUM_SLOTS 5
#define STATISTIC_KIND_TBLSIZE 6
#define STARELKIND_CLASS 'c'
#define STARELKIND_PARTITION 'p'
#define GIST_ROOT_BLKNO 0
#define GistTupleIsInvalid(itup) (ItemPointerGetOffsetNumber(&((itup)->t_tid)) == TUPLE_IS_INVALID)
#define GistTupleSetValid(itup) ItemPointerSetOffsetNumber(&((itup)->t_tid), TUPLE_IS_VALID)
#define TUPLE_IS_VALID 0xffff
#define TUPLE_IS_INVALID 0xfffe
#ifndef SPI_H
#define SPI_OK_CONNECT 1
#define SPI_OK_FINISH 2
#define SPI_OK_FETCH 3
#define SPI_OK_UTILITY 4
#define SPI_OK_SELECT 5
#define SPI_ERROR_NOOUTFUNC (-10)
#define SPI_ERROR_NOATTRIBUTE (-9)
extern THR_LOCAL PGDLLIMPORT uint32 SPI_processed;
extern THR_LOCAL int SPI_result;
typedef uint32 AclMode;
typedef uint16 OffsetNumber;
typedef struct GISTPageOpaqueData GISTPageOpaqueData;
typedef GISTPageOpaqueData* GISTPageOpaque;
typedef struct _SPI_plan* SPIPlanPtr;
typedef struct SPITupleTable {
MemoryContext tuptabcxt;
uint32 alloced;
uint32 free;
TupleDesc tupdesc;
HeapTuple* vals;
} SPITupleTable;
#endif
typedef struct {
NameData proname;
Oid pronamespace;
Oid proowner;
Oid prolang;
float4 procost;
float4 prorows;
Oid provariadic;
regproc protransform;
bool proisagg;
bool proiswindow;
bool prosecdef;
bool proleakproof;
bool proisstrict;
bool proretset;
char provolatile;
int2 pronargs;
int2 pronargdefaults;
Oid prorettype;
oidvector proargtypes;
#ifdef CATALOG_VARLEN
Oid proallargtypes[1];
char proargmodes[1];
text proargnames[1];
pg_node_tree proargdefaults;
text prosrc;
text probin;
text proconfig[1];
aclitem proacl[1];
int2vector prodefaultargpos;
bool fencedmode;
bool proshippable;
bool propackage;
char prokind;
#endif
} FormData_pg_proc;
typedef FormData_pg_proc *Form_pg_proc;
#ifndef FUNCAPI_H
typedef enum TypeFuncClass {
TYPEFUNC_SCALAR,
TYPEFUNC_COMPOSITE,
TYPEFUNC_RECORD,
TYPEFUNC_OTHER
} TypeFuncClass;
#endif
typedef struct ExprContext ExprContext;
typedef struct Tuplestorestate Tuplestorestate;
#ifndef EXECNODES_H
typedef enum {
ExprSingleResult,
ExprMultipleResult,
ExprEndResult
} ExprDoneCond;
typedef enum {
SFRM_ValuePerCall = 0x01,
SFRM_Materialize = 0x02,
SFRM_Materialize_Random = 0x04,
SFRM_Materialize_Preferred = 0x08
} SetFunctionReturnMode;
typedef struct ReturnSetInfo {
NodeTag type;
ExprContext* econtext;
TupleDesc expectedDesc;
int allowedModes;
SetFunctionReturnMode returnMode;
ExprDoneCond isDone;
Tuplestorestate* setResult;
TupleDesc setDesc;
} ReturnSetInfo;
#endif
typedef PageHeaderData* PageHeader;
#ifndef FUNCAPI_H
typedef struct AttInMetadata {
TupleDesc tupdesc;
FmgrInfo* attinfuncs;
Oid* attioparams;
int32* atttypmods;
} AttInMetadata;
typedef struct FuncCallContext {
* Number of times we've been called before
* call_cntr is initialized to 0 for you by SRF_FIRSTCALL_INIT(), and
* incremented for you every time SRF_RETURN_NEXT() is called.
*/
uint32 call_cntr;
* OPTIONAL maximum number of calls
*
* max_calls is here for convenience only and setting it is optional. If
* not set, you must provide alternative means to know when the function
* is done.
*/
uint32 max_calls;
* OPTIONAL pointer to result slot
*
* This is obsolete and only present for backwards compatibility, viz,
* user-defined SRFs that use the deprecated TupleDescGetSlot().
*/
TupleTableSlot* slot;
* OPTIONAL pointer to miscellaneous user-provided context information
*
* user_fctx is for use as a pointer to your own struct to retain
* arbitrary context information between calls of your function.
*/
void* user_fctx;
* OPTIONAL pointer to struct containing attribute type input metadata
*
* attinmeta is for use when returning tuples (i.e. composite data types)
* and is not used when returning base data types. It is only needed if
* you intend to use BuildTupleFromCStrings() to create the return tuple.
*/
AttInMetadata* attinmeta;
* memory context used for structures that must live for multiple calls
*
* multi_call_memory_ctx is set by SRF_FIRSTCALL_INIT() for you, and used
* by SRF_RETURN_DONE() for cleanup. It is the most appropriate memory
* context for any memory that is to be reused across multiple calls of
* the SRF.
*/
MemoryContext multi_call_memory_ctx;
* OPTIONAL pointer to struct containing tuple description
*
* tuple_desc is for use when returning tuples (i.e. composite data types)
* and is only needed if you are going to build the tuples with
* heap_form_tuple() rather than with BuildTupleFromCStrings(). Note that
* the TupleDesc pointer stored here should usually have been run through
* BlessTupleDesc() first.
*/
TupleDesc tuple_desc;
} FuncCallContext;
#endif
typedef struct WindowAggState WindowAggState;
typedef struct WindowObjectData {
NodeTag type;
WindowAggState* winstate;
List* argstates;
void* localmem;
int markptr;
int readptr;
int64 markpos;
int64 seekpos;
} WindowObjectData;
typedef Pointer Page;
typedef struct RelationData* Relation;
typedef struct GISTENTRY {
Datum key;
Relation rel;
Page page;
OffsetNumber offset;
bool leafkey;
} GISTENTRY;
typedef XLogRecPtr GistNSN;
typedef struct GISTPageOpaqueData {
GistNSN nsn;
BlockNumber rightlink;
uint16 flags;
uint16 gist_page_id;
} GISTPageOpaqueData;
typedef struct {
int32 n;
GISTENTRY vector[FLEXIBLE_ARRAY_MEMBER];
} GistEntryVector;
typedef struct GIST_SPLITVEC {
OffsetNumber* spl_left;
int spl_nleft;
Datum spl_ldatum;
bool spl_ldatum_exists;
OffsetNumber* spl_right;
int spl_nright;
Datum spl_rdatum;
bool spl_rdatum_exists;
} GIST_SPLITVEC;
#ifndef RELATION_H
typedef struct ItstDisKey {
List* superset_keys;
List* matching_keys;
} ItstDisKey;
typedef struct PlannerGlobal PlannerGlobal;
typedef struct PlannerInfo {
NodeTag type;
Query* parse;
PlannerGlobal* glob;
Index query_level;
struct PlannerInfo* parent_root;
* simple_rel_array holds pointers to "base rels" and "other rels" (see
* comments for RelOptInfo for more info). It is indexed by rangetable
* index (so entry 0 is always wasted). Entries can be NULL when an RTE
* does not correspond to a base relation, such as a join RTE or an
* unreferenced view RTE; or if the RelOptInfo hasn't been made yet.
*/
struct RelOptInfo** simple_rel_array;
int simple_rel_array_size;
* List of changed var that mutated during cost-based rewrite optimization, the
* element in the list is "struct RewriteVarMapping", for example:
* inlist2join
* pushjoin2union (will implemented)
*
*/
List* var_mappings;
Relids var_mapping_rels;
* simple_rte_array is the same length as simple_rel_array and holds
* pointers to the associated rangetable entries. This lets us avoid
* rt_fetch(), which can be a bit slow once large inheritance sets have
* been expanded.
*/
RangeTblEntry** simple_rte_array;
* all_baserels is a Relids set of all base relids (but not "other"
* relids) in the query; that is, the Relids identifier of the final join
* we need to form.
*/
Relids all_baserels;
* join_rel_list is a list of all join-relation RelOptInfos we have
* considered in this planning run. For small problems we just scan the
* list to do lookups, but when there are many join relations we build a
* hash table for faster lookups. The hash table is present and valid
* when join_rel_hash is not NULL. Note that we still maintain the list
* even when using the hash table for lookups; this simplifies life for
* GEQO
*/
List* join_rel_list;
struct HTAB* join_rel_hash;
* When doing a dynamic-programming-style join search, join_rel_level[k]
* is a list of all join-relation RelOptInfos of level k, and
* join_cur_level is the current level. New join-relation RelOptInfos are
* automatically added to the join_rel_level[join_cur_level] list.
* join_rel_level is NULL if not in use.
*/
List** join_rel_level;
int join_cur_level;
List* init_plans;
List* cte_plan_ids;
List* eq_classes;
List* canon_pathkeys;
* w/nonnullable var on left
*/
List* left_join_clauses;
* w/nonnullable var on right
*/
List* right_join_clauses;
List* full_join_clauses;
List* join_info_list;
List* append_rel_list;
List* rowMarks;
List* placeholder_list;
List* query_pathkeys;
List* group_pathkeys;
List* window_pathkeys;
List* distinct_pathkeys;
List* sort_pathkeys;
List* minmax_aggs;
List* initial_rels;
MemoryContext planner_cxt;
double total_table_pages;
double tuple_fraction;
double limit_tuples;
bool hasInheritedTarget;
bool hasJoinRTEs;
bool hasHavingQual;
bool hasPseudoConstantQuals;
bool hasRecursion;
Index qualSecurityLevel;
#ifdef PGXC
int rs_alias_index;
* In Postgres-XC Coordinators are supposed to skip the handling of
* row marks of type ROW_MARK_EXCLUSIVE & ROW_MARK_SHARE.
* In order to do that we simply remove such type
* of row marks from the list rowMarks. Instead they are saved
* in xc_rowMarks list that is then handeled to add
* FOR UPDATE/SHARE in the remote query
*/
List* xc_rowMarks;
#endif
int wt_param_id;
struct Plan* non_recursive_plan;
Relids curOuterRels;
List* curOuterParams;
Index curIteratorParamIndex;
bool isPartIteratorPlanning;
int curItrs;
List* subqueryRestrictInfo;
void* join_search_private;
List* plan_params;
List* join_null_info;
AttrNumber* grouping_map;
bool is_correlated;
* dataDestRelIndex is index into the range table. This variable
* will take effect on data redistribution state.
* The effective value must be greater than 0.
*/
Index dataDestRelIndex;
ItstDisKey dis_keys;
* indicate if the subquery planning root (PlannerInfo) is under or rooted from
* recursive-cte planning.
*/
bool is_under_recursive_cte;
* indicate if the subquery planning root (PlannerInfo) is under recursive-cte's
* recursive branch
*/
bool is_under_recursive_tree;
bool has_recursive_correlated_rte;
} PlannerInfo;
#endif
typedef struct VacAttrStats VacAttrStats;
typedef struct VacAttrStats* VacAttrStatsP;
typedef Datum (*AnalyzeAttrFetchFunc)(VacAttrStatsP stats, int rownum, bool* isNull, Relation rel);
typedef void (*AnalyzeAttrComputeStatsFunc)(
VacAttrStatsP stats, AnalyzeAttrFetchFunc fetchfunc, int samplerows, double totalrows, Relation rel);
* ATTRIBUTE_FIXED_PART_SIZE is the size of the fixed-layout,
* guaranteed-not-null part of a pg_attribute row. This is in fact as much
* of the row as gets copied into tuple descriptors, so don't expect you
* can access fields beyond attcollation except in a real tuple!
*/
#define ATTRIBUTE_FIXED_PART_SIZE (offsetof(FormData_pg_attribute, attkvtype) + sizeof(Oid))
#define CacheMemoryContext (u_sess->cache_mem_cxt)
#ifndef GAUSSDB
typedef struct VacAttrStats {
* These fields are set up by the main ANALYZE code before invoking the
* type-specific typanalyze function.
*
* Note: do not assume that the data being analyzed has the same datatype
* shown in attr, ie do not trust attr->atttypid, attlen, etc. This is
* because some index opclasses store a different type than the underlying
* column/expression. Instead use attrtypid, attrtypmod, and attrtype for
* information about the datatype being fed to the typanalyze function.
*/
unsigned int num_attrs;
Form_pg_attribute* attrs;
Oid* attrtypid;
int32* attrtypmod;
Form_pg_type* attrtype;
MemoryContext anl_context;
* These fields must be filled in by the typanalyze routine, unless it
* returns FALSE.
*/
AnalyzeAttrComputeStatsFunc compute_stats;
int minrows;
void* extra_data;
* These fields are to be filled in by the compute_stats routine. (They
* are initialized to zero when the struct is created.)
*/
bool stats_valid;
float4 stanullfrac;
int4 stawidth;
float4 stadistinct;
float4 stadndistinct;
int2 stakind[STATISTIC_NUM_SLOTS];
Oid staop[STATISTIC_NUM_SLOTS];
int numnumbers[STATISTIC_NUM_SLOTS];
float4* stanumbers[STATISTIC_NUM_SLOTS];
int numvalues[STATISTIC_NUM_SLOTS];
Datum* stavalues[STATISTIC_NUM_SLOTS];
bool* stanulls[STATISTIC_NUM_SLOTS];
* These fields describe the stavalues[n] element types. They will be
* initialized to match attrtypid, but a custom typanalyze function might
* want to store an array of something other than the analyzed column's
* elements. It should then overwrite these fields.
*/
Oid statypid[STATISTIC_NUM_SLOTS];
int2 statyplen[STATISTIC_NUM_SLOTS];
bool statypbyval[STATISTIC_NUM_SLOTS];
char statypalign[STATISTIC_NUM_SLOTS];
* These fields are private to the main ANALYZE code and should not be
* looked at by type-specific functions.
*/
int tupattnum;
HeapTuple* rows;
#if POSTGIS_GSSQL_VERSION >= 310
#ifndef ENABLE_MULTIPLE_NODES
int numSamplerows;
#endif
#endif
TupleDesc tupDesc;
Datum* exprvals;
bool* exprnulls;
int rowstride;
} VacAttrStats;
#else
#define ereport(elevel, rest) \
(((elevel) > DEBUG1 || (elevel) < DEBUG5 || log_min_messages <= (elevel) || client_min_messages <= (elevel)) ? \
EREPORT_DOMAIN(0, elevel, TEXTDOMAIN, rest) : (void)0)
#define elog(elevel, rest, ...) elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), elog_finish_with_errnum(0, elevel, rest, ##__VA_ARGS__)
typedef Datum (*AnalyzeAttrFetchFuncExt)(VacAttrStatsP stats, int attnum, int rownum, bool* isNull, Relation rel);
typedef void (*AnalyzeAttrComputeStatsFuncExt)(
VacAttrStatsP stats, AnalyzeAttrFetchFuncExt fetchfunc, int samplerows, double totalrows, Relation rel);
typedef struct VacAttrStats {
* These fields are set up by the main ANALYZE code before invoking the
* type-specific typanalyze function.
*
* Note: do not assume that the data being analyzed has the same datatype
* shown in attr, ie do not trust attr->atttypid, attlen, etc. This is
* because some index opclasses store a different type than the underlying
* column/expression. Instead use attrtypid, attrtypmod, and attrtype for
* information about the datatype being fed to the typanalyze function.
*/
unsigned int num_attrs;
Form_pg_attribute* attrs;
Oid* attrtypid;
int32* attrtypmod;
Form_pg_type* attrtype;
MemoryContext anl_context;
* These fields must be filled in by the typanalyze routine, unless it
* returns FALSE.
*/
AnalyzeAttrComputeStatsFunc compute_stats;
AnalyzeAttrComputeStatsFuncExt compute_stats_ext;
int minrows;
void* extra_data;
* These fields are to be filled in by the compute_stats routine. (They
* are initialized to zero when the struct is created.)
*/
bool stats_valid;
float4 stanullfrac;
int4 stawidth;
float4 stadistinct;
float4 stadndistinct;
int2 stakind[STATISTIC_NUM_SLOTS];
Oid staop[STATISTIC_NUM_SLOTS];
int numnumbers[STATISTIC_NUM_SLOTS];
float4* stanumbers[STATISTIC_NUM_SLOTS];
int numvalues[STATISTIC_NUM_SLOTS];
Datum* stavalues[STATISTIC_NUM_SLOTS];
bool* stanulls[STATISTIC_NUM_SLOTS];
* These fields describe the stavalues[n] element types. They will be
* initialized to match attrtypid, but a custom typanalyze function might
* want to store an array of something other than the analyzed column's
* elements. It should then overwrite these fields.
*/
Oid statypid[STATISTIC_NUM_SLOTS];
int2 statyplen[STATISTIC_NUM_SLOTS];
bool statypbyval[STATISTIC_NUM_SLOTS];
char statypalign[STATISTIC_NUM_SLOTS];
* These fields are private to the main ANALYZE code and should not be
* looked at by type-specific functions.
*/
int tupattnum;
HeapTuple* rows;
int numSamplerows;
TupleDesc tupDesc;
Datum* exprvals;
bool* exprnulls;
int rowstride;
* sources of multi-column statistics:
* 'a': automatically created based on indexes
* 'm': manually created
*/
char stasource;
* status of multi-column statistics:
* 'a': active
* 'd': disabled
*/
char stastatus;
} VacAttrStats;
#endif
typedef struct VariableStatData {
Node* var;
RelOptInfo* rel;
HeapTuple statsTuple;
void (*freefunc)(HeapTuple tuple);
Oid vartype;
Oid atttype;
int32 atttypmod;
bool isunique;
bool enablePossion;
bool acl_ok;
PlannerInfo *root;
double numDistinct[2];
bool isEstimated;
PlannerInfo *baseRoot;
Node *baseVar;
RelOptInfo *baseRel;
bool needAdjust;
} VariableStatData;
typedef GISTPageOpaqueData* GISTPageOpaque;
typedef struct WindowObjectData* WindowObject;
extern THR_LOCAL PGDLLIMPORT SPITupleTable* SPI_tuptable;
extern THR_LOCAL PGDLLIMPORT char my_exec_path[];
extern THR_LOCAL PGDLLIMPORT volatile bool InterruptPending;
#define PageIsValid(page) PointerIsValid(page)
#define PointerIsValid(pointer) ((const void*)(pointer) != NULL)
typedef struct PortalData* Portal;
extern bool std_typanalyze(VacAttrStats* stats);
extern bool get_restriction_variable(
PlannerInfo* root, List* args, int varRelid, VariableStatData* vardata, Node** other, bool* varonleft);
#if POSTGIS_GSSQL_VERSION == 210
extern int SPI_exec(const char* src, long tcount);
extern int SPI_connect(CommandDest dest = DestSPI, void (*spiCallbackfn)(void*) = NULL, void* clientData = NULL);
extern int SPI_finish(void);
extern int SPI_execute(const char* src, bool read_only, long tcount, bool isCollectParam = false);
extern char* SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber);
extern int SPI_freeplan(SPIPlanPtr plan);
extern void SPI_freetuptable(SPITupleTable *tuptable);
extern void SPI_cursor_close(Portal portal);
extern int SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls, bool read_only, long tcount);
extern int SPI_execute_with_args(const char* src, int nargs, Oid* argtypes, Datum* Values, const char* Nulls,
bool read_only, long tcount, Cursor_Data* cursor_data);
extern SPIPlanPtr SPI_prepare(const char *src, int nargs, Oid *argtypes);
extern Datum SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool *isnull);
extern Portal SPI_cursor_open_with_args(const char* name, const char* src, int nargs, Oid* argtypes, Datum* Values,
const char* Nulls, bool read_only, int cursorOptions);
extern void SPI_cursor_fetch(Portal portal, bool forward, long count);
extern void* SPI_repalloc(void* pointer, Size size);
#endif
extern char* text_to_cstring(const text* t);
extern text* cstring_to_text(const char* s);
extern HTAB* hash_create(const char* tabname, long nelem, HASHCTL* info, int flags);
extern void hash_destroy(HTAB* hashp);
extern void hash_remove(HTAB* hashp);
extern void hash_stats(const char* where, HTAB* hashp);
extern void* hash_search(HTAB* hashp, const void* keyPtr, HASHACTION action, bool* foundPtr);
extern uint32 get_hash_value(HTAB* hashp, const void* keyPtr);
extern MemoryContext MemoryContextCreate(
NodeTag tag, Size size, MemoryContextMethods* methods, MemoryContext parent, const char* name);
extern void MemoryContextDelete(MemoryContext context);
extern void get_share_path(const char* my_exec_path, char* ret_path);
#define HeapTupleGetDatum(_tuple) PointerGetDatum((_tuple)->t_data)
#define TupleGetDatum(_slot, _tuple) PointerGetDatum((_tuple)->t_data)
extern TypeFuncClass get_func_result_type(Oid functionId, Oid* resultTypeId, TupleDesc* resultTupleDesc);
extern Datum GetAttributeByName(HeapTupleHeader tuple, const char* attname, bool* isNull);
#define CHECK_FOR_INTERRUPTS() \
do { \
if (InterruptPending) \
ProcessInterrupts(); \
} while (0)
extern void ProcessInterrupts(void);
extern int GetNumConfigOptions(void);
typedef void (*pqsigfunc)(int);
extern pqsigfunc pqsignal(int signo, pqsigfunc func);
typedef const Pg_finfo_record* (*PGFInfoFunction)(void);
extern Oid get_fn_expr_argtype(FmgrInfo* flinfo, int argnum);
extern int16 get_typlen(Oid typid);
extern bool get_typbyval(Oid typid);
extern Datum hash_any(register const unsigned char* k, register int keylen);
#define ARR_DIMS(a) ((int*)(((char*)(a)) + sizeof(ArrayType)))
extern int AggCheckCallContext(FunctionCallInfo fcinfo, MemoryContext* aggcontext);
extern Datum datumCopy(Datum value, bool typByVal, int typLen);
extern TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid* resultTypeId, TupleDesc* resultTupleDesc);
extern TupleDesc BlessTupleDesc(TupleDesc tupdesc);
extern HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, Datum* values, bool* isnull);
extern TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid* resultTypeId, TupleDesc* resultTupleDesc);
extern int GetDatabaseEncoding(void);
extern Datum numeric_int4(PG_FUNCTION_ARGS);
extern Datum textout(PG_FUNCTION_ARGS);
extern int16 get_typlen(Oid typid);
extern bool get_typbyval(Oid typid);
extern void get_typlenbyval(Oid typid, int16* typlen, bool* typbyval);
extern void get_typlenbyvalalign(Oid typid, int16* typlen, bool* typbyval, char* typalign);
extern TupleDesc RelationNameGetTupleDesc(const char* relname);
extern AttInMetadata* TupleDescGetAttInMetadata(TupleDesc tupdesc);
extern HeapTuple BuildTupleFromCStrings(AttInMetadata* attinmeta, char** values);
extern void heap_freetuple(HeapTuple htup);
extern ArrayType* construct_array(Datum* elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign);
#define ARR_ELEMTYPE(a) ((a)->elemtype)
#if POSTGIS_GSSQL_VERSION == 210
extern int32 pg_atoi(char *s, int size, int c, bool b = false);
#else
extern int32 pg_atoi(char *s, int size, int c, bool b = false);
#endif
extern void* SPI_palloc(Size size);
typedef bool (*GucStringCheckHook)(char** newval, void** extra, GucSource source);
typedef const char* (*GucShowHook)(void);
extern int SPI_fnumber(TupleDesc tupdesc, const char* fname);
extern ArrayBuildState* accumArrayResult(
ArrayBuildState* astate, Datum dvalue, bool disnull, Oid element_type, MemoryContext rcontext);
extern Datum makeMdArrayResult(
ArrayBuildState* astate, int ndims, int* dims, int* lbs, MemoryContext rcontext, bool release);
extern Datum regclassin(PG_FUNCTION_ARGS);
extern void examine_variable(PlannerInfo* root, Node* node, int varRelid, VariableStatData* vardata);
#define PointerIsValid(pointer) ((const void*)(pointer) != NULL)
#define HeapTupleIsValid(tuple) PointerIsValid(tuple)
#define ReleaseVariableStats(vardata) \
do { \
if (HeapTupleIsValid((vardata).statsTuple)) \
(*(vardata).freefunc)((vardata).statsTuple); \
} while (0)
extern FuncCallContext* init_MultiFuncCall(PG_FUNCTION_ARGS);
extern FuncCallContext* per_MultiFuncCall(PG_FUNCTION_ARGS);
extern void end_MultiFuncCall(PG_FUNCTION_ARGS, FuncCallContext* funcctx);
#define PG_WINDOW_OBJECT() ((WindowObject)fcinfo->context)
#define WindowObjectIsValid(winobj) ((winobj) != NULL && IsA(winobj, WindowObjectData))
extern void* WinGetPartitionLocalMemory(WindowObject winobj, Size sz);
extern int64 WinGetCurrentPosition(WindowObject winobj);
extern int64 WinGetPartitionRowCount(WindowObject winobj);
extern void WinSetMarkPosition(WindowObject winobj, int64 markpos);
extern bool WinRowsArePeers(WindowObject winobj, int64 pos1, int64 pos2);
extern Datum WinGetFuncArgInPartition(
WindowObject winobj, int argno, int relpos, int seektype, bool set_mark, bool* isnull, bool* isout);
extern Datum WinGetFuncArgInFrame(
WindowObject winobj, int argno, int relpos, int seektype, bool set_mark, bool* isnull, bool* isout);
extern Datum WinGetFuncArgCurrent(WindowObject winobj, int argno, bool* isnull);
#define SRF_IS_FIRSTCALL() (fcinfo->flinfo->fn_extra == NULL)
#define SRF_FIRSTCALL_INIT() init_MultiFuncCall(fcinfo)
#define SRF_PERCALL_SETUP() per_MultiFuncCall(fcinfo)
#define SRF_RETURN_NEXT(_funcctx, _result) \
do { \
ReturnSetInfo* rsi; \
(_funcctx)->call_cntr++; \
rsi = (ReturnSetInfo*)fcinfo->resultinfo; \
rsi->isDone = ExprMultipleResult; \
PG_RETURN_DATUM(_result); \
} while (0)
#define SRF_RETURN_DONE(_funcctx) \
do { \
ReturnSetInfo* rsi; \
end_MultiFuncCall(fcinfo, _funcctx); \
rsi = (ReturnSetInfo*)fcinfo->resultinfo; \
rsi->isDone = ExprEndResult; \
PG_RETURN_NULL(); \
} while (0)
#define gistentryinit(e, k, r, pg, o, l) \
do { \
(e).key = (k); \
(e).rel = (r); \
(e).page = (pg); \
(e).offset = (o); \
(e).leafkey = (l); \
} while (0)
#define PageGetSpecialPointer(page) \
(AssertMacro(PageIsValid(page)), (char*)((char*)(page) + ((PageHeader)(page))->pd_special))
#define GistPageGetOpaque(page) ((GISTPageOpaque)PageGetSpecialPointer(page))
#define F_LEAF (1 << 0)
#define GistPageIsLeaf(page) (GistPageGetOpaque(page)->flags & F_LEAF)
#define GIST_LEAF(entry) (GistPageIsLeaf((entry)->page))
#define InvalidOffsetNumber ((OffsetNumber)0)
#define FirstOffsetNumber ((OffsetNumber)1)
#define OffsetNumberNext(offsetNumber) ((OffsetNumber)(1 + (offsetNumber)))
extern bool get_attstatsslot(HeapTuple statstuple, Oid atttype, int32 atttypmod, int reqkind, Oid reqop, Oid* actualop,
Datum** values, int* nvalues, float4** numbers, int* nnumbers);
extern void free_attstatsslot(Oid atttype, Datum* values, int nvalues, float4* numbers, int nnumbers);
extern AttrNumber get_attnum(Oid relid, const char* attname);
#define rt_fetch(rangetable_index, rangetable) ((RangeTblEntry*)list_nth(rangetable, (rangetable_index)-1))
#define getrelid(rangeindex, rangetable) (rt_fetch(rangeindex, rangetable)->relid)
extern void vacuum_delay_point(void);
extern char* get_rel_name(Oid relid);
extern THR_LOCAL PGDLLIMPORT int default_statistics_target;
extern Datum GetAttributeByNum(HeapTupleHeader tuple, AttrNumber attrno, bool* isNull);
extern Datum GetAttributeByName(HeapTupleHeader tuple, const char* attname, bool* isNull);
#define CStringGetTextDatum(s) PointerGetDatum(cstring_to_text(s))
#endif