mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Use generic attribute management in PL/Python
Switch the implementation of the plan and result types to generic attribute management, as described at <http://docs.python.org/extending/newtypes.html>. This modernizes and simplifies the code a bit and prepares for Python 3.1, where the old way doesn't work anymore.
This commit is contained in:
		@@ -111,3 +111,24 @@ SELECT join_sequences(sequences) FROM sequences
 | 
				
			|||||||
----------------
 | 
					----------------
 | 
				
			||||||
(0 rows)
 | 
					(0 rows)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- plan and result objects
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					CREATE FUNCTION result_nrows_test() RETURNS int
 | 
				
			||||||
 | 
					AS $$
 | 
				
			||||||
 | 
					plan = plpy.prepare("SELECT 1 UNION SELECT 2")
 | 
				
			||||||
 | 
					plpy.info(plan.status()) # not really documented or useful
 | 
				
			||||||
 | 
					result = plpy.execute(plan)
 | 
				
			||||||
 | 
					if result.status() > 0:
 | 
				
			||||||
 | 
					   return result.nrows()
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					   return None
 | 
				
			||||||
 | 
					$$ LANGUAGE plpythonu;
 | 
				
			||||||
 | 
					SELECT result_nrows_test();
 | 
				
			||||||
 | 
					INFO:  (True,)
 | 
				
			||||||
 | 
					CONTEXT:  PL/Python function "result_nrows_test"
 | 
				
			||||||
 | 
					 result_nrows_test 
 | 
				
			||||||
 | 
					-------------------
 | 
				
			||||||
 | 
					                 2
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
/**********************************************************************
 | 
					/**********************************************************************
 | 
				
			||||||
 * plpython.c - python as a procedural language for PostgreSQL
 | 
					 * plpython.c - python as a procedural language for PostgreSQL
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *	$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.125 2009/08/14 13:12:21 petere Exp $
 | 
					 *	$PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.126 2009/08/25 08:14:42 petere Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *********************************************************************
 | 
					 *********************************************************************
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -2050,12 +2050,10 @@ static PyObject *PLy_fatal(PyObject *, PyObject *);
 | 
				
			|||||||
#define is_PLyPlanObject(x) ((x)->ob_type == &PLy_PlanType)
 | 
					#define is_PLyPlanObject(x) ((x)->ob_type == &PLy_PlanType)
 | 
				
			||||||
static PyObject *PLy_plan_new(void);
 | 
					static PyObject *PLy_plan_new(void);
 | 
				
			||||||
static void PLy_plan_dealloc(PyObject *);
 | 
					static void PLy_plan_dealloc(PyObject *);
 | 
				
			||||||
static PyObject *PLy_plan_getattr(PyObject *, char *);
 | 
					 | 
				
			||||||
static PyObject *PLy_plan_status(PyObject *, PyObject *);
 | 
					static PyObject *PLy_plan_status(PyObject *, PyObject *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *PLy_result_new(void);
 | 
					static PyObject *PLy_result_new(void);
 | 
				
			||||||
static void PLy_result_dealloc(PyObject *);
 | 
					static void PLy_result_dealloc(PyObject *);
 | 
				
			||||||
static PyObject *PLy_result_getattr(PyObject *, char *);
 | 
					 | 
				
			||||||
static PyObject *PLy_result_nrows(PyObject *, PyObject *);
 | 
					static PyObject *PLy_result_nrows(PyObject *, PyObject *);
 | 
				
			||||||
static PyObject *PLy_result_status(PyObject *, PyObject *);
 | 
					static PyObject *PLy_result_status(PyObject *, PyObject *);
 | 
				
			||||||
static Py_ssize_t PLy_result_length(PyObject *);
 | 
					static Py_ssize_t PLy_result_length(PyObject *);
 | 
				
			||||||
@@ -2072,6 +2070,11 @@ static PyObject *PLy_spi_execute_plan(PyObject *, PyObject *, long);
 | 
				
			|||||||
static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *, int, int);
 | 
					static PyObject *PLy_spi_execute_fetch_result(SPITupleTable *, int, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyMethodDef PLy_plan_methods[] = {
 | 
				
			||||||
 | 
						{"status", PLy_plan_status, METH_VARARGS, NULL},
 | 
				
			||||||
 | 
						{NULL, NULL, 0, NULL}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyTypeObject PLy_PlanType = {
 | 
					static PyTypeObject PLy_PlanType = {
 | 
				
			||||||
	PyObject_HEAD_INIT(NULL)
 | 
						PyObject_HEAD_INIT(NULL)
 | 
				
			||||||
	0,							/* ob_size */
 | 
						0,							/* ob_size */
 | 
				
			||||||
@@ -2084,7 +2087,7 @@ static PyTypeObject PLy_PlanType = {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	PLy_plan_dealloc,			/* tp_dealloc */
 | 
						PLy_plan_dealloc,			/* tp_dealloc */
 | 
				
			||||||
	0,							/* tp_print */
 | 
						0,							/* tp_print */
 | 
				
			||||||
	PLy_plan_getattr,			/* tp_getattr */
 | 
						0,							/* tp_getattr */
 | 
				
			||||||
	0,							/* tp_setattr */
 | 
						0,							/* tp_setattr */
 | 
				
			||||||
	0,							/* tp_compare */
 | 
						0,							/* tp_compare */
 | 
				
			||||||
	0,							/* tp_repr */
 | 
						0,							/* tp_repr */
 | 
				
			||||||
@@ -2099,11 +2102,13 @@ static PyTypeObject PLy_PlanType = {
 | 
				
			|||||||
	0,							/* tp_as_buffer */
 | 
						0,							/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
 | 
				
			||||||
	PLy_plan_doc,				/* tp_doc */
 | 
						PLy_plan_doc,				/* tp_doc */
 | 
				
			||||||
};
 | 
						0,							/* tp_traverse */
 | 
				
			||||||
 | 
						0,							/* tp_clear */
 | 
				
			||||||
static PyMethodDef PLy_plan_methods[] = {
 | 
						0,							/* tp_richcompare */
 | 
				
			||||||
	{"status", PLy_plan_status, METH_VARARGS, NULL},
 | 
						0,							/* tp_weaklistoffset */
 | 
				
			||||||
	{NULL, NULL, 0, NULL}
 | 
						0,							/* tp_iter */
 | 
				
			||||||
 | 
						0,							/* tp_iternext */
 | 
				
			||||||
 | 
						PLy_plan_methods,			/* tp_tpmethods */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PySequenceMethods PLy_result_as_sequence = {
 | 
					static PySequenceMethods PLy_result_as_sequence = {
 | 
				
			||||||
@@ -2116,6 +2121,12 @@ static PySequenceMethods PLy_result_as_sequence = {
 | 
				
			|||||||
	PLy_result_ass_slice,		/* sq_ass_slice */
 | 
						PLy_result_ass_slice,		/* sq_ass_slice */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static PyMethodDef PLy_result_methods[] = {
 | 
				
			||||||
 | 
						{"nrows", PLy_result_nrows, METH_VARARGS, NULL},
 | 
				
			||||||
 | 
						{"status", PLy_result_status, METH_VARARGS, NULL},
 | 
				
			||||||
 | 
						{NULL, NULL, 0, NULL}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyTypeObject PLy_ResultType = {
 | 
					static PyTypeObject PLy_ResultType = {
 | 
				
			||||||
	PyObject_HEAD_INIT(NULL)
 | 
						PyObject_HEAD_INIT(NULL)
 | 
				
			||||||
	0,							/* ob_size */
 | 
						0,							/* ob_size */
 | 
				
			||||||
@@ -2128,7 +2139,7 @@ static PyTypeObject PLy_ResultType = {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	PLy_result_dealloc,			/* tp_dealloc */
 | 
						PLy_result_dealloc,			/* tp_dealloc */
 | 
				
			||||||
	0,							/* tp_print */
 | 
						0,							/* tp_print */
 | 
				
			||||||
	PLy_result_getattr,			/* tp_getattr */
 | 
						0,							/* tp_getattr */
 | 
				
			||||||
	0,							/* tp_setattr */
 | 
						0,							/* tp_setattr */
 | 
				
			||||||
	0,							/* tp_compare */
 | 
						0,							/* tp_compare */
 | 
				
			||||||
	0,							/* tp_repr */
 | 
						0,							/* tp_repr */
 | 
				
			||||||
@@ -2143,12 +2154,13 @@ static PyTypeObject PLy_ResultType = {
 | 
				
			|||||||
	0,							/* tp_as_buffer */
 | 
						0,							/* tp_as_buffer */
 | 
				
			||||||
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
 | 
						Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,	/* tp_flags */
 | 
				
			||||||
	PLy_result_doc,				/* tp_doc */
 | 
						PLy_result_doc,				/* tp_doc */
 | 
				
			||||||
};
 | 
						0,							/* tp_traverse */
 | 
				
			||||||
 | 
						0,							/* tp_clear */
 | 
				
			||||||
static PyMethodDef PLy_result_methods[] = {
 | 
						0,							/* tp_richcompare */
 | 
				
			||||||
	{"nrows", PLy_result_nrows, METH_VARARGS, NULL},
 | 
						0,							/* tp_weaklistoffset */
 | 
				
			||||||
	{"status", PLy_result_status, METH_VARARGS, NULL},
 | 
						0,							/* tp_iter */
 | 
				
			||||||
	{NULL, NULL, 0, NULL}
 | 
						0,							/* tp_iternext */
 | 
				
			||||||
 | 
						PLy_result_methods,			/* tp_tpmethods */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyMethodDef PLy_methods[] = {
 | 
					static PyMethodDef PLy_methods[] = {
 | 
				
			||||||
@@ -2217,12 +2229,6 @@ PLy_plan_dealloc(PyObject *arg)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
PLy_plan_getattr(PyObject *self, char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return Py_FindMethod(PLy_plan_methods, self, name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
PLy_plan_status(PyObject *self, PyObject *args)
 | 
					PLy_plan_status(PyObject *self, PyObject *args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -2270,12 +2276,6 @@ PLy_result_dealloc(PyObject *arg)
 | 
				
			|||||||
	arg->ob_type->tp_free(arg);
 | 
						arg->ob_type->tp_free(arg);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static PyObject *
 | 
					 | 
				
			||||||
PLy_result_getattr(PyObject *self, char *name)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return Py_FindMethod(PLy_result_methods, self, name);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PyObject *
 | 
					static PyObject *
 | 
				
			||||||
PLy_result_nrows(PyObject *self, PyObject *args)
 | 
					PLy_result_nrows(PyObject *self, PyObject *args)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -87,3 +87,21 @@ SELECT join_sequences(sequences) FROM sequences
 | 
				
			|||||||
	WHERE join_sequences(sequences) ~* '^A';
 | 
						WHERE join_sequences(sequences) ~* '^A';
 | 
				
			||||||
SELECT join_sequences(sequences) FROM sequences
 | 
					SELECT join_sequences(sequences) FROM sequences
 | 
				
			||||||
	WHERE join_sequences(sequences) ~* '^B';
 | 
						WHERE join_sequences(sequences) ~* '^B';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					-- plan and result objects
 | 
				
			||||||
 | 
					--
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CREATE FUNCTION result_nrows_test() RETURNS int
 | 
				
			||||||
 | 
					AS $$
 | 
				
			||||||
 | 
					plan = plpy.prepare("SELECT 1 UNION SELECT 2")
 | 
				
			||||||
 | 
					plpy.info(plan.status()) # not really documented or useful
 | 
				
			||||||
 | 
					result = plpy.execute(plan)
 | 
				
			||||||
 | 
					if result.status() > 0:
 | 
				
			||||||
 | 
					   return result.nrows()
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					   return None
 | 
				
			||||||
 | 
					$$ LANGUAGE plpythonu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELECT result_nrows_test();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user