--- /dev/null
+-- test error handling, i forgot to restore Warn_restart in
+-- the trigger handler once. the errors and subsequent core dump were
+-- interesting.
+SELECT invalid_type_uncaught('rick');
+WARNING: plpython: in function invalid_type_uncaught:
+DETAIL: <class 'plpy.SPIError'>: Unknown error in PLy_spi_prepare
+ERROR: type "test" does not exist
+SELECT invalid_type_caught('rick');
+WARNING: plpython: in function invalid_type_caught:
+DETAIL: <class 'plpy.SPIError'>: Unknown error in PLy_spi_prepare
+ERROR: type "test" does not exist
+SELECT invalid_type_reraised('rick');
+WARNING: plpython: in function invalid_type_reraised:
+DETAIL: <class 'plpy.SPIError'>: Unknown error in PLy_spi_prepare
+ERROR: type "test" does not exist
+SELECT valid_type('rick');
+ valid_type
+------------
+
+(1 row)
+
+--
+-- Test Unicode error handling.
+--
+SELECT unicode_return_error();
+ERROR: plpython: function "unicode_return_error" could not create return value
+DETAIL: <type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
+INSERT INTO unicode_test (testvalue) VALUES ('test');
+ERROR: plpython: function "unicode_trigger_error" could not modify tuple
+DETAIL: <type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
+SELECT unicode_plan_error1();
+WARNING: plpython: in function unicode_plan_error1:
+DETAIL: <class 'plpy.Error'>: Unknown error in PLy_spi_execute_plan
+ERROR: plpython: function "unicode_plan_error1" could not execute plan
+DETAIL: <type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
+SELECT unicode_plan_error2();
+ERROR: plpython: function "unicode_plan_error2" could not execute plan
+DETAIL: <type 'exceptions.UnicodeEncodeError'>: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.66.2.5 2007/11/23 01:47:12 alvherre Exp $
+ * $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.66.2.6 2008/07/28 18:45:05 tgl Exp $
*
*********************************************************************
*/
#include <Python.h>
+
+/*
+ * Py_ssize_t compat for Python <= 2.4
+ */
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+#define PY_SSIZE_T_MAX INT_MAX
+#define PY_SSIZE_T_MIN INT_MIN
+#endif
+
#include "postgres.h"
/* system stuff */
static PyObject *PLy_result_getattr(PyObject *, char *);
static PyObject *PLy_result_nrows(PyObject *, PyObject *);
static PyObject *PLy_result_status(PyObject *, PyObject *);
-static int PLy_result_length(PyObject *);
-static PyObject *PLy_result_item(PyObject *, int);
-static PyObject *PLy_result_slice(PyObject *, int, int);
-static int PLy_result_ass_item(PyObject *, int, PyObject *);
-static int PLy_result_ass_slice(PyObject *, int, int, PyObject *);
+static Py_ssize_t PLy_result_length(PyObject *);
+static PyObject *PLy_result_item(PyObject *, Py_ssize_t);
+static PyObject *PLy_result_slice(PyObject *, Py_ssize_t, Py_ssize_t);
+static int PLy_result_ass_item(PyObject *, Py_ssize_t, PyObject *);
+static int PLy_result_ass_slice(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
static PyObject *PLy_spi_prepare(PyObject *, PyObject *);
/*
* methods
*/
- (destructor) PLy_plan_dealloc, /* tp_dealloc */
+ PLy_plan_dealloc, /* tp_dealloc */
0, /* tp_print */
- (getattrfunc) PLy_plan_getattr, /* tp_getattr */
+ PLy_plan_getattr, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- 0, /* tp_xxx4 */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
PLy_plan_doc, /* tp_doc */
};
{NULL, NULL, 0, NULL}
};
-
static PySequenceMethods PLy_result_as_sequence = {
- (inquiry) PLy_result_length, /* sq_length */
- (binaryfunc) 0, /* sq_concat */
- (intargfunc) 0, /* sq_repeat */
- (intargfunc) PLy_result_item, /* sq_item */
- (intintargfunc) PLy_result_slice, /* sq_slice */
- (intobjargproc) PLy_result_ass_item, /* sq_ass_item */
- (intintobjargproc) PLy_result_ass_slice, /* sq_ass_slice */
+ PLy_result_length, /* sq_length */
+ NULL, /* sq_concat */
+ NULL, /* sq_repeat */
+ PLy_result_item, /* sq_item */
+ PLy_result_slice, /* sq_slice */
+ PLy_result_ass_item, /* sq_ass_item */
+ PLy_result_ass_slice, /* sq_ass_slice */
};
static PyTypeObject PLy_ResultType = {
/*
* methods
*/
- (destructor) PLy_result_dealloc, /* tp_dealloc */
+ PLy_result_dealloc, /* tp_dealloc */
0, /* tp_print */
- (getattrfunc) PLy_result_getattr, /* tp_getattr */
+ PLy_result_getattr, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- 0, /* tp_xxx4 */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
PLy_result_doc, /* tp_doc */
};
PLy_free(ob->args);
}
- PyMem_DEL(arg);
+ arg->ob_type->tp_free(arg);
}
Py_XDECREF(ob->rows);
Py_XDECREF(ob->status);
- PyMem_DEL(ob);
+ arg->ob_type->tp_free(arg);
}
static PyObject *
return ob->status;
}
-static int
+static Py_ssize_t
PLy_result_length(PyObject * arg)
{
PLyResultObject *ob = (PLyResultObject *) arg;
}
static PyObject *
-PLy_result_item(PyObject * arg, int idx)
+PLy_result_item(PyObject * arg, Py_ssize_t idx)
{
PyObject *rv;
PLyResultObject *ob = (PLyResultObject *) arg;
}
static int
-PLy_result_ass_item(PyObject * arg, int idx, PyObject * item)
+PLy_result_ass_item(PyObject * arg, Py_ssize_t idx, PyObject * item)
{
int rv;
PLyResultObject *ob = (PLyResultObject *) arg;
}
static PyObject *
-PLy_result_slice(PyObject * arg, int lidx, int hidx)
+PLy_result_slice(PyObject * arg, Py_ssize_t lidx, Py_ssize_t hidx)
{
PyObject *rv;
PLyResultObject *ob = (PLyResultObject *) arg;
}
static int
-PLy_result_ass_slice(PyObject * arg, int lidx, int hidx, PyObject * slice)
+PLy_result_ass_slice(PyObject * arg, Py_ssize_t lidx, Py_ssize_t hidx, PyObject * slice)
{
int rv;
PLyResultObject *ob = (PLyResultObject *) arg;
PG_TRY();
{
char *nulls = palloc(nargs * sizeof(char));
+ volatile int j;
- for (i = 0; i < nargs; i++)
+ for (j = 0; j < nargs; j++)
{
PyObject *elem,
*so;
- elem = PySequence_GetItem(list, i);
+ elem = PySequence_GetItem(list, j);
if (elem != Py_None)
{
so = PyObject_Str(elem);
{
char *sv = PyString_AsString(so);
- plan->values[i] =
- FunctionCall3(&(plan->args[i].out.d.typfunc),
+ plan->values[j] =
+ FunctionCall3(&(plan->args[j].out.d.typfunc),
CStringGetDatum(sv),
- ObjectIdGetDatum(plan->args[i].out.d.typioparam),
+ ObjectIdGetDatum(plan->args[j].out.d.typioparam),
Int32GetDatum(-1));
}
PG_CATCH();
PG_END_TRY();
Py_DECREF(so);
- nulls[i] = ' ';
+ nulls[j] = ' ';
}
else
{
Py_DECREF(elem);
- plan->values[i] = (Datum) 0;
- nulls[i] = 'n';
+ plan->values[j] = (Datum) 0;
+ nulls[j] = 'n';
}
}
}
PG_CATCH();
{
+ int k;
+
MemoryContextSwitchTo(oldcontext);
PLy_error_in_progress = CopyErrorData();
FlushErrorState();
/*
* cleanup plan->values array
*/
- for (i = 0; i < nargs; i++)
+ for (k = 0; k < nargs; k++)
{
- if (!plan->args[i].out.d.typbyval &&
- (plan->values[i] != (Datum) NULL))
+ if (!plan->args[k].out.d.typbyval &&
+ (plan->values[k] != (Datum) NULL))
{
- pfree(DatumGetPointer(plan->values[i]));
- plan->values[i] = (Datum) NULL;
+ pfree(DatumGetPointer(plan->values[k]));
+ plan->values[k] = (Datum) NULL;
}
}
/*
* initialize plpy module
*/
- PLy_PlanType.ob_type = PLy_ResultType.ob_type = &PyType_Type;
+ if (PyType_Ready(&PLy_PlanType) < 0)
+ elog(ERROR, "could not init PLy_PlanType");
+ if (PyType_Ready(&PLy_ResultType) < 0)
+ elog(ERROR, "could not init PLy_ResultType");
+
plpy = Py_InitModule("plpy", PLy_methods);
plpy_dict = PyModule_GetDict(plpy);