#include "Python.h" #include "postgres.h" #include "access/relscan.h" #include "catalog/pg_foreign_server.h" #include "catalog/pg_foreign_table.h" #include "catalog/pg_type.h" #include "commands/defrem.h" #include "commands/explain.h" #include "foreign/fdwapi.h" #include "foreign/foreign.h" #include "funcapi.h" #include "lib/stringinfo.h" #include "nodes/bitmapset.h" #include "nodes/makefuncs.h" #include "nodes/pg_list.h" #include "nodes/relation.h" #include "utils/builtins.h" #include "utils/syscache.h" #ifndef PG_MULTICORN_H #define PG_MULTICORN_H /* Data structures */ typedef struct CacheEntry { Oid hashkey; PyObject *value; List *options; List *columns; int xact_depth; /* Keep the "options" and "columns" in a specific context to avoid leaks. */ MemoryContext cacheContext; } CacheEntry; typedef struct ConversionInfo { char *attrname; FmgrInfo *attinfunc; FmgrInfo *attoutfunc; Oid atttypoid; Oid attioparam; int32 atttypmod; int attnum; bool is_array; int attndims; bool need_quote; } ConversionInfo; typedef struct MulticornPlanState { Oid foreigntableid; AttrNumber numattrs; PyObject *fdw_instance; List *target_list; List *qual_list; int startupCost; ConversionInfo **cinfos; List *pathkeys; /* list of MulticornDeparsedSortGroup) */ } MulticornPlanState; typedef struct MulticornExecState { /* instance and iterator */ PyObject *fdw_instance; PyObject *p_iterator; /* Information carried from the plan phase. */ List *target_list; List *qual_list; Datum *values; bool *nulls; ConversionInfo **cinfos; /* Common buffer to avoid repeated allocations */ StringInfo buffer; AttrNumber rowidAttno; char *rowidAttrName; List *pathkeys; /* list of MulticornDeparsedSortGroup) */ } MulticornExecState; typedef struct MulticornModifyState { ConversionInfo **cinfos; ConversionInfo **resultCinfos; PyObject *fdw_instance; StringInfo buffer; AttrNumber rowidAttno; char *rowidAttrName; ConversionInfo *rowidCinfo; } MulticornModifyState; typedef struct MulticornBaseQual { AttrNumber varattno; NodeTag right_type; Oid typeoid; char *opname; bool isArray; bool useOr; } MulticornBaseQual; typedef struct MulticornConstQual { MulticornBaseQual base; Datum value; bool isnull; } MulticornConstQual; typedef struct MulticornVarQual { MulticornBaseQual base; AttrNumber rightvarattno; } MulticornVarQual; typedef struct MulticornParamQual { MulticornBaseQual base; Expr *expr; } MulticornParamQual; typedef struct MulticornDeparsedSortGroup { Name attname; int attnum; bool reversed; bool nulls_first; Name collate; PathKey *key; } MulticornDeparsedSortGroup; /* errors.c */ void errorCheck(void); /* python.c */ PyObject *pgstringToPyUnicode(const char *string); char **pyUnicodeToPgString(PyObject *pyobject); PyObject *getInstance(Oid foreigntableid); PyObject *qualToPyObject(Expr *expr, PlannerInfo *root); PyObject *getClassString(const char *className); PyObject *execute(ForeignScanState *state, ExplainState *es); void pythonResultToTuple(PyObject *p_value, TupleTableSlot *slot, ConversionInfo ** cinfos, StringInfo buffer); PyObject *tupleTableSlotToPyObject(TupleTableSlot *slot, ConversionInfo ** cinfos); char *getRowIdColumn(PyObject *fdw_instance); PyObject *optionsListToPyDict(List *options); const char *getPythonEncodingName(void); void getRelSize(MulticornPlanState * state, PlannerInfo *root, double *rows, int *width); List *pathKeys(MulticornPlanState * state); List *canSort(MulticornPlanState * state, List *deparsed); CacheEntry *getCacheEntry(Oid foreigntableid); UserMapping *multicorn_GetUserMapping(Oid userid, Oid serverid); /* Hash table mapping oid to fdw instances */ extern PGDLLIMPORT HTAB *InstancesHash; /* query.c */ void extractRestrictions(Relids base_relids, Expr *node, List **quals); List *extractColumns(List *reltargetlist, List *restrictinfolist); void initConversioninfo(ConversionInfo ** cinfo, AttInMetadata *attinmeta); Value *colnameFromVar(Var *var, PlannerInfo *root, MulticornPlanState * state); void computeDeparsedSortGroup(List *deparsed, MulticornPlanState *planstate, List **apply_pathkeys, List **deparsed_pathkeys); List *findPaths(PlannerInfo *root, RelOptInfo *baserel, List *possiblePaths, int startupCost, MulticornPlanState *state, List *apply_pathkeys, List *deparsed_pathkeys); List *deparse_sortgroup(PlannerInfo *root, Oid foreigntableid, RelOptInfo *rel); PyObject *datumToPython(Datum node, Oid typeoid, ConversionInfo * cinfo); List *serializeDeparsedSortGroup(List *pathkeys); List *deserializeDeparsedSortGroup(List *items); #endif /* PG_MULTICORN_H */ char *PyUnicode_AsPgString(PyObject *p_unicode); #if PY_MAJOR_VERSION >= 3 PyObject *PyString_FromString(const char *s); PyObject *PyString_FromStringAndSize(const char *s, Py_ssize_t size); char *PyString_AsString(PyObject *unicode); int PyString_AsStringAndSize(PyObject *unicode, char **tempbuffer, Py_ssize_t *length); #endif #if PG_VERSION_NUM < 100000 /* from src/include/access/tupdesc.h, introduced in 2cd708452 */ #define TupleDescAttr(tupdesc, i) ((tupdesc)->attrs[(i)]) #endif