summaryrefslogtreecommitdiff
path: root/src/pl/plpython/plpy_util.c
diff options
context:
space:
mode:
authorPeter Eisentraut2011-12-18 19:14:16 +0000
committerPeter Eisentraut2011-12-18 19:24:00 +0000
commit147c2482542868d1f9dcf7d2ecfeac58d845335c (patch)
tree11617370d58bfc7ff6cca2b5b78212dd804a1147 /src/pl/plpython/plpy_util.c
parent59e242a4969d2efa6ce68dc7aab3cbd8cf975b08 (diff)
Split plpython.c into smaller pieces
This moves the code around from one huge file into hopefully logical and more manageable modules. For the most part, the code itself was not touched, except: PLy_function_handler and PLy_trigger_handler were renamed to PLy_exec_function and PLy_exec_trigger, because they were not actually handlers in the PL handler sense, and it makes the naming more similar to the way PL/pgSQL is organized. The initialization of the procedure caches was separated into a new function init_procedure_caches to keep the hash tables private to plpy_procedures.c. Jan UrbaƄski and Peter Eisentraut
Diffstat (limited to 'src/pl/plpython/plpy_util.c')
-rw-r--r--src/pl/plpython/plpy_util.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/src/pl/plpython/plpy_util.c b/src/pl/plpython/plpy_util.c
new file mode 100644
index 00000000000..414b9d5445a
--- /dev/null
+++ b/src/pl/plpython/plpy_util.c
@@ -0,0 +1,125 @@
+/*
+ * utility functions
+ *
+ * src/pl/plpython/plpy_util.c
+ */
+
+#include "postgres.h"
+
+#include "mb/pg_wchar.h"
+#include "utils/memutils.h"
+#include "utils/palloc.h"
+
+#include "plpython.h"
+
+#include "plpy_util.h"
+
+#include "plpy_elog.h"
+
+
+void *
+PLy_malloc(size_t bytes)
+{
+ /* We need our allocations to be long-lived, so use TopMemoryContext */
+ return MemoryContextAlloc(TopMemoryContext, bytes);
+}
+
+void *
+PLy_malloc0(size_t bytes)
+{
+ void *ptr = PLy_malloc(bytes);
+
+ MemSet(ptr, 0, bytes);
+ return ptr;
+}
+
+char *
+PLy_strdup(const char *str)
+{
+ char *result;
+ size_t len;
+
+ len = strlen(str) + 1;
+ result = PLy_malloc(len);
+ memcpy(result, str, len);
+
+ return result;
+}
+
+/* define this away */
+void
+PLy_free(void *ptr)
+{
+ pfree(ptr);
+}
+
+/*
+ * Convert a Python unicode object to a Python string/bytes object in
+ * PostgreSQL server encoding. Reference ownership is passed to the
+ * caller.
+ */
+PyObject *
+PLyUnicode_Bytes(PyObject *unicode)
+{
+ PyObject *rv;
+ const char *serverenc;
+
+ /*
+ * Python understands almost all PostgreSQL encoding names, but it doesn't
+ * know SQL_ASCII.
+ */
+ if (GetDatabaseEncoding() == PG_SQL_ASCII)
+ serverenc = "ascii";
+ else
+ serverenc = GetDatabaseEncodingName();
+ rv = PyUnicode_AsEncodedString(unicode, serverenc, "strict");
+ if (rv == NULL)
+ PLy_elog(ERROR, "could not convert Python Unicode object to PostgreSQL server encoding");
+ return rv;
+}
+
+/*
+ * Convert a Python unicode object to a C string in PostgreSQL server
+ * encoding. No Python object reference is passed out of this
+ * function. The result is palloc'ed.
+ *
+ * Note that this function is disguised as PyString_AsString() when
+ * using Python 3. That function retuns a pointer into the internal
+ * memory of the argument, which isn't exactly the interface of this
+ * function. But in either case you get a rather short-lived
+ * reference that you ought to better leave alone.
+ */
+char *
+PLyUnicode_AsString(PyObject *unicode)
+{
+ PyObject *o = PLyUnicode_Bytes(unicode);
+ char *rv = pstrdup(PyBytes_AsString(o));
+
+ Py_XDECREF(o);
+ return rv;
+}
+
+#if PY_MAJOR_VERSION >= 3
+/*
+ * Convert a C string in the PostgreSQL server encoding to a Python
+ * unicode object. Reference ownership is passed to the caller.
+ */
+PyObject *
+PLyUnicode_FromString(const char *s)
+{
+ char *utf8string;
+ PyObject *o;
+
+ utf8string = (char *) pg_do_encoding_conversion((unsigned char *) s,
+ strlen(s),
+ GetDatabaseEncoding(),
+ PG_UTF8);
+
+ o = PyUnicode_FromString(utf8string);
+
+ if (utf8string != s)
+ pfree(utf8string);
+
+ return o;
+}
+#endif /* PY_MAJOR_VERSION >= 3 */