2015-04-26 16:33:14 +02:00
|
|
|
#include "postgres.h"
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
|
2015-04-26 16:33:14 +02:00
|
|
|
#include "fmgr.h"
|
2018-09-16 19:46:45 +02:00
|
|
|
#include "hstore/hstore.h"
|
2019-10-23 05:56:22 +02:00
|
|
|
#include "plpy_typeio.h"
|
|
|
|
#include "plpython.h"
|
2015-04-26 16:33:14 +02:00
|
|
|
|
|
|
|
PG_MODULE_MAGIC;
|
|
|
|
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
extern void _PG_init(void);
|
|
|
|
|
|
|
|
/* Linkage to functions in plpython module */
|
|
|
|
typedef char *(*PLyObject_AsString_t) (PyObject *plrv);
|
|
|
|
static PLyObject_AsString_t PLyObject_AsString_p;
|
2016-10-04 15:38:43 +02:00
|
|
|
typedef PyObject *(*PLyUnicode_FromStringAndSize_t) (const char *s, Py_ssize_t size);
|
|
|
|
static PLyUnicode_FromStringAndSize_t PLyUnicode_FromStringAndSize_p;
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
|
|
|
|
/* Linkage to functions in hstore module */
|
|
|
|
typedef HStore *(*hstoreUpgrade_t) (Datum orig);
|
|
|
|
static hstoreUpgrade_t hstoreUpgrade_p;
|
2016-10-04 15:38:43 +02:00
|
|
|
typedef int (*hstoreUniquePairs_t) (Pairs *a, int32 l, int32 *buflen);
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
static hstoreUniquePairs_t hstoreUniquePairs_p;
|
2016-10-04 15:38:43 +02:00
|
|
|
typedef HStore *(*hstorePairs_t) (Pairs *pairs, int32 pcount, int32 buflen);
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
static hstorePairs_t hstorePairs_p;
|
2016-10-04 15:38:43 +02:00
|
|
|
typedef size_t (*hstoreCheckKeyLen_t) (size_t len);
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
static hstoreCheckKeyLen_t hstoreCheckKeyLen_p;
|
2016-10-04 15:38:43 +02:00
|
|
|
typedef size_t (*hstoreCheckValLen_t) (size_t len);
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
static hstoreCheckValLen_t hstoreCheckValLen_p;
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Module initialize function: fetch function pointers for cross-module calls.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
_PG_init(void)
|
|
|
|
{
|
2016-10-04 15:38:43 +02:00
|
|
|
/* Asserts verify that typedefs above match original declarations */
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
AssertVariableIsOfType(&PLyObject_AsString, PLyObject_AsString_t);
|
|
|
|
PLyObject_AsString_p = (PLyObject_AsString_t)
|
|
|
|
load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyObject_AsString",
|
|
|
|
true, NULL);
|
2016-10-04 15:38:43 +02:00
|
|
|
AssertVariableIsOfType(&PLyUnicode_FromStringAndSize, PLyUnicode_FromStringAndSize_t);
|
|
|
|
PLyUnicode_FromStringAndSize_p = (PLyUnicode_FromStringAndSize_t)
|
|
|
|
load_external_function("$libdir/" PLPYTHON_LIBNAME, "PLyUnicode_FromStringAndSize",
|
|
|
|
true, NULL);
|
|
|
|
AssertVariableIsOfType(&hstoreUpgrade, hstoreUpgrade_t);
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
hstoreUpgrade_p = (hstoreUpgrade_t)
|
|
|
|
load_external_function("$libdir/hstore", "hstoreUpgrade",
|
|
|
|
true, NULL);
|
2016-10-04 15:38:43 +02:00
|
|
|
AssertVariableIsOfType(&hstoreUniquePairs, hstoreUniquePairs_t);
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
hstoreUniquePairs_p = (hstoreUniquePairs_t)
|
|
|
|
load_external_function("$libdir/hstore", "hstoreUniquePairs",
|
|
|
|
true, NULL);
|
2016-10-04 15:38:43 +02:00
|
|
|
AssertVariableIsOfType(&hstorePairs, hstorePairs_t);
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
hstorePairs_p = (hstorePairs_t)
|
|
|
|
load_external_function("$libdir/hstore", "hstorePairs",
|
|
|
|
true, NULL);
|
2016-10-04 15:38:43 +02:00
|
|
|
AssertVariableIsOfType(&hstoreCheckKeyLen, hstoreCheckKeyLen_t);
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
hstoreCheckKeyLen_p = (hstoreCheckKeyLen_t)
|
|
|
|
load_external_function("$libdir/hstore", "hstoreCheckKeyLen",
|
|
|
|
true, NULL);
|
2016-10-04 15:38:43 +02:00
|
|
|
AssertVariableIsOfType(&hstoreCheckValLen, hstoreCheckValLen_t);
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
hstoreCheckValLen_p = (hstoreCheckValLen_t)
|
|
|
|
load_external_function("$libdir/hstore", "hstoreCheckValLen",
|
|
|
|
true, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* These defines must be after the module init function */
|
|
|
|
#define PLyObject_AsString PLyObject_AsString_p
|
2016-10-04 15:38:43 +02:00
|
|
|
#define PLyUnicode_FromStringAndSize PLyUnicode_FromStringAndSize_p
|
Convert contrib/hstore_plpython to not use direct linking to other modules.
Previously, on most platforms, we allowed hstore_plpython's references
to hstore and plpython to be unresolved symbols at link time, trusting
the dynamic linker to resolve them when the module is loaded. This
has a number of problems, the worst being that the dynamic linker
does not know where the references come from and can do nothing but
fail if those other modules haven't been loaded. We've more or less
gotten away with that for the limited use-case of datatype transform
modules, but even there, it requires some awkward hacks, most recently
commit 83c249200.
Instead, let's not treat these references as linker-resolvable at all,
but use function pointers that are manually filled in by the module's
_PG_init function. There are few enough contact points that this
doesn't seem unmaintainable, at least for these use-cases. (Note that
the same technique wouldn't work at all for decoupling from libpython
itself, but fortunately that's just a standard shared library and can
be linked to normally.)
This is an initial patch that just converts hstore_plpython. If the
buildfarm doesn't find any fatal problems, I'll work on the other
transform modules soon.
Tom Lane, per an idea of Andres Freund's.
Discussion: <2652.1475512158@sss.pgh.pa.us>
2016-10-04 04:27:11 +02:00
|
|
|
#define hstoreUpgrade hstoreUpgrade_p
|
|
|
|
#define hstoreUniquePairs hstoreUniquePairs_p
|
|
|
|
#define hstorePairs hstorePairs_p
|
|
|
|
#define hstoreCheckKeyLen hstoreCheckKeyLen_p
|
|
|
|
#define hstoreCheckValLen hstoreCheckValLen_p
|
|
|
|
|
2015-04-26 16:33:14 +02:00
|
|
|
|
|
|
|
PG_FUNCTION_INFO_V1(hstore_to_plpython);
|
|
|
|
|
|
|
|
Datum
|
|
|
|
hstore_to_plpython(PG_FUNCTION_ARGS)
|
|
|
|
{
|
2017-09-18 21:21:23 +02:00
|
|
|
HStore *in = PG_GETARG_HSTORE_P(0);
|
2015-04-26 16:33:14 +02:00
|
|
|
int i;
|
|
|
|
int count = HS_COUNT(in);
|
|
|
|
char *base = STRPTR(in);
|
|
|
|
HEntry *entries = ARRPTR(in);
|
|
|
|
PyObject *dict;
|
|
|
|
|
|
|
|
dict = PyDict_New();
|
2017-10-31 15:49:36 +01:00
|
|
|
if (!dict)
|
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_OUT_OF_MEMORY),
|
|
|
|
errmsg("out of memory")));
|
2015-04-26 16:33:14 +02:00
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
PyObject *key;
|
|
|
|
|
2022-03-08 03:30:28 +01:00
|
|
|
key = PLyUnicode_FromStringAndSize(HSTORE_KEY(entries, base, i),
|
2022-05-12 21:17:30 +02:00
|
|
|
HSTORE_KEYLEN(entries, i));
|
2015-11-19 20:54:05 +01:00
|
|
|
if (HSTORE_VALISNULL(entries, i))
|
2015-04-26 16:33:14 +02:00
|
|
|
PyDict_SetItem(dict, key, Py_None);
|
|
|
|
else
|
|
|
|
{
|
2015-05-24 03:35:49 +02:00
|
|
|
PyObject *value;
|
2015-04-26 16:33:14 +02:00
|
|
|
|
2022-03-08 03:30:28 +01:00
|
|
|
value = PLyUnicode_FromStringAndSize(HSTORE_VAL(entries, base, i),
|
2022-05-12 21:17:30 +02:00
|
|
|
HSTORE_VALLEN(entries, i));
|
2015-04-26 16:33:14 +02:00
|
|
|
PyDict_SetItem(dict, key, value);
|
|
|
|
Py_XDECREF(value);
|
|
|
|
}
|
|
|
|
Py_XDECREF(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
return PointerGetDatum(dict);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PG_FUNCTION_INFO_V1(plpython_to_hstore);
|
|
|
|
|
|
|
|
Datum
|
|
|
|
plpython_to_hstore(PG_FUNCTION_ARGS)
|
|
|
|
{
|
|
|
|
PyObject *dict;
|
2019-04-06 23:54:29 +02:00
|
|
|
PyObject *volatile items;
|
|
|
|
Py_ssize_t pcount;
|
|
|
|
HStore *volatile out;
|
2015-04-26 16:33:14 +02:00
|
|
|
|
|
|
|
dict = (PyObject *) PG_GETARG_POINTER(0);
|
2023-04-27 17:55:06 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* As of Python 3, PyMapping_Check() is unreliable unless one first checks
|
|
|
|
* that the object isn't a sequence. (Cleaner solutions exist, but not
|
|
|
|
* before Python 3.10, which we're not prepared to require yet.)
|
|
|
|
*/
|
|
|
|
if (PySequence_Check(dict) || !PyMapping_Check(dict))
|
2015-04-26 16:33:14 +02:00
|
|
|
ereport(ERROR,
|
|
|
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
|
|
|
errmsg("not a Python mapping")));
|
|
|
|
|
|
|
|
pcount = PyMapping_Size(dict);
|
2019-03-14 08:25:25 +01:00
|
|
|
items = PyMapping_Items(dict);
|
2015-04-26 16:33:14 +02:00
|
|
|
|
|
|
|
PG_TRY();
|
|
|
|
{
|
|
|
|
int32 buflen;
|
2019-04-06 23:54:29 +02:00
|
|
|
Py_ssize_t i;
|
2015-04-26 16:33:14 +02:00
|
|
|
Pairs *pairs;
|
|
|
|
|
|
|
|
pairs = palloc(pcount * sizeof(*pairs));
|
|
|
|
|
|
|
|
for (i = 0; i < pcount; i++)
|
|
|
|
{
|
2015-05-24 03:35:49 +02:00
|
|
|
PyObject *tuple;
|
|
|
|
PyObject *key;
|
|
|
|
PyObject *value;
|
2015-04-26 16:33:14 +02:00
|
|
|
|
|
|
|
tuple = PyList_GetItem(items, i);
|
|
|
|
key = PyTuple_GetItem(tuple, 0);
|
|
|
|
value = PyTuple_GetItem(tuple, 1);
|
|
|
|
|
|
|
|
pairs[i].key = PLyObject_AsString(key);
|
|
|
|
pairs[i].keylen = hstoreCheckKeyLen(strlen(pairs[i].key));
|
|
|
|
pairs[i].needfree = true;
|
|
|
|
|
|
|
|
if (value == Py_None)
|
|
|
|
{
|
|
|
|
pairs[i].val = NULL;
|
|
|
|
pairs[i].vallen = 0;
|
|
|
|
pairs[i].isnull = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pairs[i].val = PLyObject_AsString(value);
|
|
|
|
pairs[i].vallen = hstoreCheckValLen(strlen(pairs[i].val));
|
|
|
|
pairs[i].isnull = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pcount = hstoreUniquePairs(pairs, pcount, &buflen);
|
|
|
|
out = hstorePairs(pairs, pcount, buflen);
|
|
|
|
}
|
2019-11-01 11:09:52 +01:00
|
|
|
PG_FINALLY();
|
2015-04-26 16:33:14 +02:00
|
|
|
{
|
2019-03-14 08:25:25 +01:00
|
|
|
Py_DECREF(items);
|
2015-04-26 16:33:14 +02:00
|
|
|
}
|
|
|
|
PG_END_TRY();
|
|
|
|
|
|
|
|
PG_RETURN_POINTER(out);
|
|
|
|
}
|