Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split out declarations and definitions into .h and .c #153

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 $< $@
Expand Down
2 changes: 1 addition & 1 deletion multicorn.control
Original file line number Diff line number Diff line change
@@ -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
47 changes: 39 additions & 8 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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,
}
)
6 changes: 1 addition & 5 deletions src/errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
12 changes: 12 additions & 0 deletions src/errors.h
Original file line number Diff line number Diff line change
@@ -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
84 changes: 26 additions & 58 deletions src/multicorn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
81 changes: 10 additions & 71 deletions src/multicorn.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
79 changes: 5 additions & 74 deletions src/python.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/*
Expand Down
Loading