diff --git a/Makefile b/Makefile index 013eb39ec..d43e46021 100755 --- a/Makefile +++ b/Makefile @@ -19,7 +19,11 @@ directories.stamp: $(OBJS): directories.stamp -install: python_code +install: python_code + +rpm: setup.py + @echo "About to make RPM" + $(PYTHON) ./setup.py bdist --format=rpm sql/$(EXTENSION)--$(EXTVERSION).sql: sql/$(EXTENSION).sql directories.stamp cp $< $@ diff --git a/multicorn.control b/multicorn.control index 29b1ce4df..689b8a204 100755 --- a/multicorn.control +++ b/multicorn.control @@ -1,4 +1,4 @@ comment = 'Multicorn Python bindings for Postgres 9.2.* Foreign Data Wrapper' default_version = '1.3.2' module_pathname = '$libdir/multicorn' -relocatable = true +relocatable = True diff --git a/setup.py b/setup.py index bcd3aa7e4..c73a3c266 100755 --- a/setup.py +++ b/setup.py @@ -2,6 +2,12 @@ import sys from setuptools import setup, find_packages, Extension + +import os +from sys import platform +from setuptools.command.install import install +from distutils.command.build import build + # hum... borrowed from psycopg2 def get_pg_config(kind, pg_config="pg_config"): p = subprocess.Popen([pg_config, '--%s' % kind], stdout=subprocess.PIPE) @@ -26,12 +32,37 @@ def get_pg_config(kind, pg_config="pg_config"): elif sys.version_info[1] < 6: sys.exit("Sorry, you need at least python 2.6 for Multicorn") +class MulticornBuild(build): + def run(self): + # Original build + build.run(self) + r = subprocess.check_output(['/usr/bin/make', 'multicorn.so']) + r = r.strip().decode('utf8') + if not r: + raise Warning(p[2].readline()) + # After original build + +execfile('multicorn.control') + + setup( - name='multicorn', - version='__VERSION__', - author='Kozea', - license='Postgresql', - package_dir={'': 'python'}, - packages=['multicorn', 'multicorn.fsfdw'], - ext_modules = [multicorn_utils_module] -) + name='multicorn', + # version='__VERSION__', + version=default_version, + author='Kozea', + license='Postgresql', + options={'bdist_rpm': {'post_install': 'rpm/post_install.sh', + 'pre_uninstall': 'rpm/pre_uninstall.sh', + 'requires': 'postgresql95-server', + }}, + package_dir={'': 'python'}, + packages=['multicorn', 'multicorn.fsfdw'], + ext_modules=[multicorn_utils_module], + data_files=[ + ('%s/extension' % get_pg_config('sharedir'), ['multicorn.control', 'sql/multicorn.sql', 'doc/multicorn.md']), + (get_pg_config('libdir'), ['multicorn.so']) + ], + cmdclass={ + 'build': MulticornBuild, + } + ) diff --git a/src/errors.c b/src/errors.c index ae1d877fd..a39fcd08e 100644 --- a/src/errors.c +++ b/src/errors.c @@ -15,11 +15,7 @@ #include "multicorn.h" #include "bytesobject.h" #include "access/xact.h" - -void reportException(PyObject *pErrType, - PyObject *pErrValue, - PyObject *pErrTraceback); - +#include "errors.h" void errorCheck() diff --git a/src/errors.h b/src/errors.h new file mode 100644 index 000000000..f40d7a003 --- /dev/null +++ b/src/errors.h @@ -0,0 +1,12 @@ +#include "multicorn.h" +#include "bytesobject.h" +#include "access/xact.h" + + +#ifndef PG_ERRORS_H +#define PG_ERRORS_H + +void errorCheck(void); +void reportException(PyObject *pErrType, PyObject *pErrValue, PyObject *pErrTraceback); + +#endif diff --git a/src/multicorn.c b/src/multicorn.c index 9cb936b2c..7faf7bbc6 100644 --- a/src/multicorn.c +++ b/src/multicorn.c @@ -25,84 +25,52 @@ #include "utils/rel.h" #include "parser/parsetree.h" +#include "multicorn.h" +#include "errors.h" +#include "query.h" +#include "python.h" PG_MODULE_MAGIC; - -extern Datum multicorn_handler(PG_FUNCTION_ARGS); -extern Datum multicorn_validator(PG_FUNCTION_ARGS); - - -PG_FUNCTION_INFO_V1(multicorn_handler); -PG_FUNCTION_INFO_V1(multicorn_validator); - - -void _PG_init(void); -void _PG_fini(void); - -/* - * FDW functions declarations +/* Static FWD definitions */ +static void multicornGetForeignRelSize(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid); +static void multicornGetForeignPaths(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid); -static void multicornGetForeignRelSize(PlannerInfo *root, - RelOptInfo *baserel, - Oid foreigntableid); -static void multicornGetForeignPaths(PlannerInfo *root, - RelOptInfo *baserel, - Oid foreigntableid); -static ForeignScan *multicornGetForeignPlan(PlannerInfo *root, - RelOptInfo *baserel, - Oid foreigntableid, - ForeignPath *best_path, - List *tlist, - List *scan_clauses #if PG_VERSION_NUM >= 90500 - , Plan *outer_plan +static ForeignScan * multicornGetForeignPlan(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid, ForeignPath *best_path, List *tlist, List *scan_clauses, Plan *outer_plan); +#else +static ForeignScan * multicornGetForeignPlan(PlannerInfo *root, RelOptInfo *baserel, Oid foreigntableid, ForeignPath *best_path, List *tlist, List *scan_clauses); #endif - ); + static void multicornExplainForeignScan(ForeignScanState *node, ExplainState *es); static void multicornBeginForeignScan(ForeignScanState *node, int eflags); -static TupleTableSlot *multicornIterateForeignScan(ForeignScanState *node); +static TupleTableSlot * multicornIterateForeignScan(ForeignScanState *node); static void multicornReScanForeignScan(ForeignScanState *node); static void multicornEndForeignScan(ForeignScanState *node); #if PG_VERSION_NUM >= 90300 -static void multicornAddForeignUpdateTargets(Query *parsetree, - RangeTblEntry *target_rte, - Relation target_relation); - -static List *multicornPlanForeignModify(PlannerInfo *root, - ModifyTable *plan, - Index resultRelation, - int subplan_index); -static void multicornBeginForeignModify(ModifyTableState *mtstate, - ResultRelInfo *resultRelInfo, - List *fdw_private, - int subplan_index, - int eflags); -static TupleTableSlot *multicornExecForeignInsert(EState *estate, ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, - TupleTableSlot *planslot); -static TupleTableSlot *multicornExecForeignDelete(EState *estate, ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, TupleTableSlot *planSlot); -static TupleTableSlot *multicornExecForeignUpdate(EState *estate, ResultRelInfo *resultRelInfo, - TupleTableSlot *slot, TupleTableSlot *planSlot); +static void multicornAddForeignUpdateTargets(Query *parsetree, RangeTblEntry *target_rte, Relation target_relation); +static List * multicornPlanForeignModify(PlannerInfo *root, ModifyTable *plan, Index resultRelation, int subplan_index); +static void multicornBeginForeignModify(ModifyTableState *mtstate, ResultRelInfo *resultRelInfo, List *fdw_private, int subplan_index, int eflags); +static TupleTableSlot * multicornExecForeignInsert(EState *estate, ResultRelInfo *resultRelInfo, TupleTableSlot *slot, TupleTableSlot *planSlot); +static TupleTableSlot * multicornExecForeignDelete(EState *estate, ResultRelInfo *resultRelInfo, TupleTableSlot *slot, TupleTableSlot *planSlot); +static TupleTableSlot * multicornExecForeignUpdate(EState *estate, ResultRelInfo *resultRelInfo, TupleTableSlot *slot, TupleTableSlot *planSlot); static void multicornEndForeignModify(EState *estate, ResultRelInfo *resultRelInfo); - -static void multicorn_subxact_callback(SubXactEvent event, SubTransactionId mySubid, - SubTransactionId parentSubid, void *arg); +static void multicorn_subxact_callback(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg); #endif +static void multicorn_xact_callback(XactEvent event, void *arg); + #if PG_VERSION_NUM >= 90500 -static List *multicornImportForeignSchema(ImportForeignSchemaStmt * stmt, - Oid serverOid); +static List * multicornImportForeignSchema(ImportForeignSchemaStmt * stmt, Oid serverOid); #endif -static void multicorn_xact_callback(XactEvent event, void *arg); -/* Helpers functions */ -void *serializePlanState(MulticornPlanState * planstate); -MulticornExecState *initializeExecState(void *internal_plan_state); + +PG_FUNCTION_INFO_V1(multicorn_handler); +PG_FUNCTION_INFO_V1(multicorn_validator); + /* Hash table mapping oid to fdw instances */ HTAB *InstancesHash; diff --git a/src/multicorn.h b/src/multicorn.h index 45723327c..36465d6b8 100644 --- a/src/multicorn.h +++ b/src/multicorn.h @@ -16,6 +16,9 @@ #include "nodes/relation.h" #include "utils/builtins.h" #include "utils/syscache.h" +#include "utils/timestamp.h" +#include "access/xact.h" + #ifndef PG_MULTICORN_H #define PG_MULTICORN_H @@ -130,78 +133,14 @@ typedef struct MulticornDeparsedSortGroup 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; +extern HTAB *InstancesHash; +void _PG_init(void); +void _PG_fini(void); +Datum multicorn_handler(PG_FUNCTION_ARGS); +Datum multicorn_validator(PG_FUNCTION_ARGS); -/* 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); +void * serializePlanState(MulticornPlanState * state); +MulticornExecState * initializeExecState(void *internalstate); #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 diff --git a/src/python.c b/src/python.c index 3d9c8b6c9..aadf228fa 100644 --- a/src/python.c +++ b/src/python.c @@ -20,81 +20,12 @@ #include "access/xact.h" #include "utils/lsyscache.h" +#include "python.h" +#include "errors.h" +#include "multicorn.h" -List *getOptions(Oid foreigntableid); -bool compareOptions(List *options1, List *options2); - -void getColumnsFromTable(TupleDesc desc, PyObject **p_columns, List **columns); -bool compareColumns(List *columns1, List *columns2); - -PyObject *getClass(PyObject *className); -PyObject *valuesToPySet(List *targetlist); -PyObject *qualDefsToPyList(List *quallist, ConversionInfo ** cinfo); -PyObject *pythonQual(char *operatorname, PyObject *value, - ConversionInfo * cinfo, - bool is_array, - bool use_or, - Oid typeoid); - -PyObject *getSortKey(MulticornDeparsedSortGroup *key); -MulticornDeparsedSortGroup *getDeparsedSortGroup(PyObject *key); - - -Datum pyobjectToDatum(PyObject *object, StringInfo buffer, - ConversionInfo * cinfo); -PyObject *qualdefToPython(MulticornConstQual * qualdef, ConversionInfo ** cinfo); -PyObject *paramDefToPython(List *paramdef, ConversionInfo ** cinfos, - Oid typeoid, - Datum value); - - -PyObject *datumToPython(Datum node, Oid typeoid, ConversionInfo * cinfo); -PyObject *datumStringToPython(Datum node, ConversionInfo * cinfo); -PyObject *datumNumberToPython(Datum node, ConversionInfo * cinfo); -PyObject *datumDateToPython(Datum datum, ConversionInfo * cinfo); -PyObject *datumTimestampToPython(Datum datum, ConversionInfo * cinfo); -PyObject *datumIntToPython(Datum datum, ConversionInfo * cinfo); -PyObject *datumArrayToPython(Datum datum, Oid type, ConversionInfo * cinfo); -PyObject *datumByteaToPython(Datum datum, ConversionInfo * cinfo); -PyObject *datumUnknownToPython(Datum datum, ConversionInfo * cinfo, Oid type); - - -void pythonDictToTuple(PyObject *p_value, - TupleTableSlot *slot, - ConversionInfo ** cinfos, - StringInfo buffer); - -void pythonSequenceToTuple(PyObject *p_value, - TupleTableSlot *slot, - ConversionInfo ** cinfos, - StringInfo buffer); - -/* Python to cstring functions */ -void pyobjectToCString(PyObject *pyobject, StringInfo buffer, - ConversionInfo * cinfo); - -void pynumberToCString(PyObject *pyobject, StringInfo buffer, - ConversionInfo * cinfo); -void pyunicodeToCString(PyObject *pyobject, StringInfo buffer, - ConversionInfo * cinfo); -void pystringToCString(PyObject *pyobject, StringInfo buffer, - ConversionInfo * cinfo); -void pysequenceToCString(PyObject *pyobject, StringInfo buffer, - ConversionInfo * cinfo); -void pymappingToCString(PyObject *pyobject, StringInfo buffer, - ConversionInfo * cinfo); -void pydateToCString(PyObject *pyobject, StringInfo buffer, - ConversionInfo * cinfo); - -void pyunknownToCstring(PyObject *pyobject, StringInfo buffer, - ConversionInfo * cinfo); - -void appendBinaryStringInfoQuote(StringInfo buffer, - char *tempbuffer, - Py_ssize_t strlength, - bool need_quote); - - +/* Static FWD definitions + */ static void begin_remote_xact(CacheEntry * entry); /* diff --git a/src/python.h b/src/python.h new file mode 100644 index 000000000..380747852 --- /dev/null +++ b/src/python.h @@ -0,0 +1,83 @@ +#include +#include "datetime.h" +#include "postgres.h" +#include "multicorn.h" +#include "catalog/pg_user_mapping.h" +#include "access/reloptions.h" +#include "miscadmin.h" +#include "utils/numeric.h" +#include "utils/date.h" +#include "utils/timestamp.h" +#include "utils/array.h" +#include "utils/catcache.h" +#include "utils/memutils.h" +#include "utils/resowner.h" +#include "utils/rel.h" +#include "utils/rel.h" +#include "executor/nodeSubplan.h" +#include "bytesobject.h" +#include "mb/pg_wchar.h" +#include "access/xact.h" +#include "utils/lsyscache.h" + + + +#ifndef PG_PYTHON_H +#define PG_PYTHON_H + +const char * getPythonEncodingName(void); +char * PyUnicode_AsPgString(PyObject *p_unicode); + +#if PY_MAJOR_VERSION >= 3 + PyObject * PyString_FromStringAndSize(const char *s, Py_ssize_t size); + PyObject * PyString_FromString(const char *s); + char * PyString_AsString(PyObject *unicode); + int PyString_AsStringAndSize(PyObject *obj, char **buffer, Py_ssize_t *length); +#endif /* PY_MAJOR_VERSION >= 3 */ + +PyObject * getClass(PyObject *className); +void appendBinaryStringInfoQuote(StringInfo buffer, char *tempbuffer, Py_ssize_t strlength, bool need_quote); +PyObject * valuesToPySet(List *targetlist); +PyObject * qualDefsToPyList(List *qual_list, ConversionInfo ** cinfos); +PyObject * getClassString(const char *className); +List * getOptions(Oid foreigntableid); +UserMapping * multicorn_GetUserMapping(Oid userid, Oid serverid); +PyObject * optionsListToPyDict(List *options); +bool compareOptions(List *options1, List *options2); +void getColumnsFromTable(TupleDesc desc, PyObject **p_columns, List **columns); +bool compareColumns(List *columns1, List *columns2); +CacheEntry * getCacheEntry(Oid foreigntableid); +PyObject * getInstance(Oid foreigntableid); +void getRelSize(MulticornPlanState * state, PlannerInfo *root, double *rows, int *width); +PyObject * qualdefToPython(MulticornConstQual * qualdef, ConversionInfo ** cinfos); +PyObject * pythonQual(char *operatorname, PyObject *value, ConversionInfo * cinfo, bool is_array, bool use_or, Oid typeoid); +PyObject * getSortKey(MulticornDeparsedSortGroup *key); +MulticornDeparsedSortGroup * getDeparsedSortGroup(PyObject *sortKey); +PyObject * execute(ForeignScanState *node, ExplainState *es); +void pynumberToCString(PyObject *pyobject, StringInfo buffer, ConversionInfo * cinfo); +void pyunicodeToCString(PyObject *pyobject, StringInfo buffer, ConversionInfo * cinfo); +void pystringToCString(PyObject *pyobject, StringInfo buffer, ConversionInfo * cinfo); +void pysequenceToCString(PyObject *pyobject, StringInfo buffer, ConversionInfo * cinfo); +void pymappingToCString(PyObject *pyobject, StringInfo buffer, ConversionInfo * cinfo); +void pydateToCString(PyObject *pyobject, StringInfo buffer, ConversionInfo * cinfo); +void pyobjectToCString(PyObject *pyobject, StringInfo buffer, ConversionInfo * cinfo); +void pyunknownToCstring(PyObject *pyobject, StringInfo buffer, ConversionInfo * cinfo); +void pythonDictToTuple(PyObject *p_value, TupleTableSlot *slot, ConversionInfo ** cinfos, StringInfo buffer); +void pythonSequenceToTuple(PyObject *p_value, TupleTableSlot *slot, ConversionInfo ** cinfos, StringInfo buffer); +void pythonResultToTuple(PyObject *p_value, TupleTableSlot *slot, ConversionInfo ** cinfos, StringInfo buffer); +Datum pyobjectToDatum(PyObject *object, StringInfo buffer, ConversionInfo * cinfo); +PyObject * datumStringToPython(Datum datum, ConversionInfo * cinfo); +PyObject * datumUnknownToPython(Datum datum, ConversionInfo * cinfo, Oid type); +PyObject * datumNumberToPython(Datum datum, ConversionInfo * cinfo); +PyObject * datumDateToPython(Datum datum, ConversionInfo * cinfo); +PyObject * datumTimestampToPython(Datum datum, ConversionInfo * cinfo); +PyObject * datumIntToPython(Datum datum, ConversionInfo * cinfo); +PyObject * datumArrayToPython(Datum datum, Oid type, ConversionInfo * cinfo); +PyObject * datumByteaToPython(Datum datum, ConversionInfo * cinfo); +PyObject * datumToPython(Datum datum, Oid type, ConversionInfo * cinfo); +List * pathKeys(MulticornPlanState * state); +List * canSort(MulticornPlanState * state, List *deparsed); +PyObject * tupleTableSlotToPyObject(TupleTableSlot *slot, ConversionInfo ** cinfos); +char * getRowIdColumn(PyObject *fdw_instance); + +#endif diff --git a/src/query.c b/src/query.c index 8e7757a1c..fbd2ba475 100644 --- a/src/query.c +++ b/src/query.c @@ -11,39 +11,8 @@ #include "miscadmin.h" #include "parser/parsetree.h" -void extractClauseFromOpExpr(Relids base_relids, - OpExpr *node, - List **quals); - -void extractClauseFromNullTest(Relids base_relids, - NullTest *node, - List **quals); - -void extractClauseFromScalarArrayOpExpr(Relids base_relids, - ScalarArrayOpExpr *node, - List **quals); - -char *getOperatorString(Oid opoid); - -MulticornBaseQual *makeQual(AttrNumber varattno, char *opname, Expr *value, - bool isarray, - bool useOr); - - -Node *unnestClause(Node *node); -void swapOperandsAsNeeded(Node **left, Node **right, Oid *opoid, - Relids base_relids); -OpExpr *canonicalOpExpr(OpExpr *opExpr, Relids base_relids); -ScalarArrayOpExpr *canonicalScalarArrayOpExpr(ScalarArrayOpExpr *opExpr, - Relids base_relids); - -bool isAttrInRestrictInfo(Index relid, AttrNumber attno, - RestrictInfo *restrictinfo); - -List *clausesInvolvingAttr(Index relid, AttrNumber attnum, - EquivalenceClass *eq_class); - -Expr *multicorn_get_em_expr(EquivalenceClass *ec, RelOptInfo *rel); +#include "query.h" +#include "python.h" /* * The list of needed columns (represented by their respective vars) diff --git a/src/query.h b/src/query.h new file mode 100644 index 000000000..7b7060fde --- /dev/null +++ b/src/query.h @@ -0,0 +1,29 @@ + + + +#ifndef PG_QUERY_H +#define PG_QUERY_H + +List * extractColumns(List *reltargetlist, List *restrictinfolist); +void initConversioninfo(ConversionInfo ** cinfos, AttInMetadata *attinmeta); +char * getOperatorString(Oid opoid); +Node * unnestClause(Node *node); +void swapOperandsAsNeeded(Node **left, Node **right, Oid *opoid, Relids base_relids); +OpExpr * canonicalOpExpr(OpExpr *opExpr, Relids base_relids); +ScalarArrayOpExpr * canonicalScalarArrayOpExpr(ScalarArrayOpExpr *opExpr, Relids base_relids); +void extractRestrictions(Relids base_relids, Expr *node, List **quals); +void extractClauseFromOpExpr(Relids base_relids, OpExpr *op, List **quals); +void extractClauseFromScalarArrayOpExpr(Relids base_relids, ScalarArrayOpExpr *op, List **quals); +void extractClauseFromNullTest(Relids base_relids, NullTest *node, List **quals); +Value * colnameFromVar(Var *var, PlannerInfo *root, MulticornPlanState * planstate); +MulticornBaseQual * makeQual(AttrNumber varattno, char *opname, Expr *value, bool isarray, bool useOr); +bool isAttrInRestrictInfo(Index relid, AttrNumber attno, RestrictInfo *restrictinfo); +List * clausesInvolvingAttr(Index relid, AttrNumber attnum, EquivalenceClass *ec); +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); +Expr * multicorn_get_em_expr(EquivalenceClass *ec, RelOptInfo *rel); +List * serializeDeparsedSortGroup(List *pathkeys); +List * deserializeDeparsedSortGroup(List *items); + +#endif diff --git a/src/utils.c b/src/utils.c index 885dad720..f86ab989a 100644 --- a/src/utils.c +++ b/src/utils.c @@ -16,19 +16,9 @@ #include "postgres.h" #include "multicorn.h" #include "miscadmin.h" - - -struct module_state -{ - PyObject *error; -}; - -#if PY_MAJOR_VERSION >= 3 -#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m)) -#else -#define GETSTATE(m) (&_state) -static struct module_state _state; -#endif +#include "utils.h" +#include "python.h" +#include "errors.h" static PyObject * log_to_postgres(PyObject *self, PyObject *args, PyObject *kwargs) @@ -130,43 +120,48 @@ static PyMethodDef UtilsMethods[] = { {NULL, NULL, 0, NULL} }; + + #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "multicorn._utils", - NULL, - sizeof(struct module_state), - UtilsMethods, - NULL, - NULL, - NULL, - NULL + PyModuleDef_HEAD_INIT, + "multicorn._utils", + NULL, + sizeof(struct module_state), + UtilsMethods, + NULL, + NULL, + NULL, + NULL }; -#define INITERROR return NULL - PyObject * PyInit__utils(void) +{ + PyObject *module = PyModule_Create(&moduledef); + struct module_state *st; + + if (module == NULL) + return NULL; + + st = ((struct module_state*)PyModule_GetState(module)) + + return module; +} #else -#define INITERROR return + +// static struct module_state _state; void init_utils(void) -#endif { -#if PY_MAJOR_VERSION >= 3 - PyObject *module = PyModule_Create(&moduledef); -#else - PyObject *module = Py_InitModule("multicorn._utils", UtilsMethods); -#endif - struct module_state *st; + PyObject *module = Py_InitModule("multicorn._utils", UtilsMethods); + // struct module_state *st; - if (module == NULL) - INITERROR; - st = GETSTATE(module); + if (module == NULL) + return; -#if PY_MAJOR_VERSION >= 3 - return module; -#endif + // st = &_state; } +#endif diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 000000000..4d6585e3d --- /dev/null +++ b/src/utils.h @@ -0,0 +1,24 @@ + + + + +#ifndef PG_UTILS_H +#define PG_UTILS_H + + +struct module_state +{ + PyObject *error; +}; + +static PyObject * log_to_postgres(PyObject *self, PyObject *args, PyObject *kwargs); +static PyObject * py_check_interrupts(PyObject *self, PyObject *args, PyObject *kwargs); + +#if PY_MAJOR_VERSION >= 3 +PyObject * PyInit__utils(void); +#else +void init_utils(void); +#endif + + +#endif