Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitee7fa66

Browse files
committed
PL/Python: Add result metadata functions
Add result object functions .colnames, .coltypes, .coltypmods toobtain information about the result column names and types, which waspreviously not possible in the PL/Python SPI interface.reviewed by Abhijit Menon-Sen
1 parentc6ea8cc commitee7fa66

File tree

6 files changed

+80
-5
lines changed

6 files changed

+80
-5
lines changed

‎doc/src/sgml/plpython.sgml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,9 +886,12 @@ $$ LANGUAGE plpythonu;
886886
list or dictionary object. The result object can be accessed by
887887
row number and column name. It has these additional methods:
888888
<function>nrows</function> which returns the number of rows
889-
returned by the query, and <function>status</function> which is the
890-
<function>SPI_execute()</function> return value. The result object
891-
can be modified.
889+
returned by the query, <function>status</function> which is the
890+
<function>SPI_execute()</function> return value,
891+
<function>colnames</function> which is the list of column names,
892+
<function>coltypes</function> which is the list of column type OIDs,
893+
and <function>coltypmods</function> which is the list of type-specific type
894+
modifiers for the columns. The result object can be modified.
892895
</para>
893896

894897
<para>

‎src/pl/plpython/expected/plpython_spi.out

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,16 +117,25 @@ SELECT join_sequences(sequences) FROM sequences
117117
--
118118
CREATE FUNCTION result_nrows_test() RETURNS int
119119
AS $$
120-
plan = plpy.prepare("SELECT 1 UNION SELECT 2")
120+
plan = plpy.prepare("SELECT 1AS foo, '11'::text AS barUNION SELECT 2, '22'")
121121
plpy.info(plan.status()) # not really documented or useful
122122
result = plpy.execute(plan)
123123
if result.status() > 0:
124+
plpy.info(result.colnames())
125+
plpy.info(result.coltypes())
126+
plpy.info(result.coltypmods())
124127
return result.nrows()
125128
else:
126129
return None
127130
$$ LANGUAGE plpythonu;
128131
SELECT result_nrows_test();
129132
INFO: True
133+
CONTEXT: PL/Python function "result_nrows_test"
134+
INFO: ['foo', 'bar']
135+
CONTEXT: PL/Python function "result_nrows_test"
136+
INFO: [23, 25]
137+
CONTEXT: PL/Python function "result_nrows_test"
138+
INFO: [-1, -1]
130139
CONTEXT: PL/Python function "result_nrows_test"
131140
result_nrows_test
132141
-------------------

‎src/pl/plpython/plpy_resultobject.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313

1414
staticvoidPLy_result_dealloc(PyObject*arg);
15+
staticPyObject*PLy_result_colnames(PyObject*self,PyObject*unused);
16+
staticPyObject*PLy_result_coltypes(PyObject*self,PyObject*unused);
17+
staticPyObject*PLy_result_coltypmods(PyObject*self,PyObject*unused);
1518
staticPyObject*PLy_result_nrows(PyObject*self,PyObject*args);
1619
staticPyObject*PLy_result_status(PyObject*self,PyObject*args);
1720
staticPy_ssize_tPLy_result_length(PyObject*arg);
@@ -35,6 +38,9 @@ static PySequenceMethods PLy_result_as_sequence = {
3538
};
3639

3740
staticPyMethodDefPLy_result_methods[]= {
41+
{"colnames",PLy_result_colnames,METH_NOARGS,NULL},
42+
{"coltypes",PLy_result_coltypes,METH_NOARGS,NULL},
43+
{"coltypmods",PLy_result_coltypmods,METH_NOARGS,NULL},
3844
{"nrows",PLy_result_nrows,METH_VARARGS,NULL},
3945
{"status",PLy_result_status,METH_VARARGS,NULL},
4046
{NULL,NULL,0,NULL}
@@ -96,6 +102,7 @@ PLy_result_new(void)
96102
ob->status=Py_None;
97103
ob->nrows=PyInt_FromLong(-1);
98104
ob->rows=PyList_New(0);
105+
ob->tupdesc=NULL;
99106

100107
return (PyObject*)ob;
101108
}
@@ -108,10 +115,57 @@ PLy_result_dealloc(PyObject *arg)
108115
Py_XDECREF(ob->nrows);
109116
Py_XDECREF(ob->rows);
110117
Py_XDECREF(ob->status);
118+
if (ob->tupdesc)
119+
{
120+
FreeTupleDesc(ob->tupdesc);
121+
ob->tupdesc=NULL;
122+
}
111123

112124
arg->ob_type->tp_free(arg);
113125
}
114126

127+
staticPyObject*
128+
PLy_result_colnames(PyObject*self,PyObject*unused)
129+
{
130+
PLyResultObject*ob= (PLyResultObject*)self;
131+
PyObject*list;
132+
inti;
133+
134+
list=PyList_New(ob->tupdesc->natts);
135+
for (i=0;i<ob->tupdesc->natts;i++)
136+
PyList_SET_ITEM(list,i,PyString_FromString(NameStr(ob->tupdesc->attrs[i]->attname)));
137+
138+
returnlist;
139+
}
140+
141+
staticPyObject*
142+
PLy_result_coltypes(PyObject*self,PyObject*unused)
143+
{
144+
PLyResultObject*ob= (PLyResultObject*)self;
145+
PyObject*list;
146+
inti;
147+
148+
list=PyList_New(ob->tupdesc->natts);
149+
for (i=0;i<ob->tupdesc->natts;i++)
150+
PyList_SET_ITEM(list,i,PyInt_FromLong(ob->tupdesc->attrs[i]->atttypid));
151+
152+
returnlist;
153+
}
154+
155+
staticPyObject*
156+
PLy_result_coltypmods(PyObject*self,PyObject*unused)
157+
{
158+
PLyResultObject*ob= (PLyResultObject*)self;
159+
PyObject*list;
160+
inti;
161+
162+
list=PyList_New(ob->tupdesc->natts);
163+
for (i=0;i<ob->tupdesc->natts;i++)
164+
PyList_SET_ITEM(list,i,PyInt_FromLong(ob->tupdesc->attrs[i]->atttypmod));
165+
166+
returnlist;
167+
}
168+
115169
staticPyObject*
116170
PLy_result_nrows(PyObject*self,PyObject*args)
117171
{

‎src/pl/plpython/plpy_resultobject.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@
55
#ifndefPLPY_RESULTOBJECT_H
66
#definePLPY_RESULTOBJECT_H
77

8+
#include"access/tupdesc.h"
9+
10+
811
typedefstructPLyResultObject
912
{
1013
PyObject_HEAD
1114
/* HeapTuple *tuples; */
1215
PyObject*nrows;/* number of rows returned by query */
1316
PyObject*rows;/* data rows, or None if no data returned */
1417
PyObject*status;/* query status, SPI_OK_*, or SPI_ERR_* */
18+
TupleDesctupdesc;
1519
}PLyResultObject;
1620

1721
externvoidPLy_result_init_type(void);

‎src/pl/plpython/plpy_spi.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ PLy_spi_execute_fetch_result(SPITupleTable *tuptable, int rows, int status)
398398
oldcontext=CurrentMemoryContext;
399399
PG_TRY();
400400
{
401+
result->tupdesc=CreateTupleDescCopy(tuptable->tupdesc);
402+
401403
if (rows)
402404
{
403405
Py_DECREF(result->rows);

‎src/pl/plpython/sql/plpython_spi.sql

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,13 @@ SELECT join_sequences(sequences) FROM sequences
9595

9696
CREATEFUNCTIONresult_nrows_test() RETURNSint
9797
AS $$
98-
plan=plpy.prepare("SELECT 1 UNION SELECT 2")
98+
plan=plpy.prepare("SELECT 1AS foo, '11'::text AS barUNION SELECT 2, '22'")
9999
plpy.info(plan.status())# not really documented or useful
100100
result=plpy.execute(plan)
101101
ifresult.status()>0:
102+
plpy.info(result.colnames())
103+
plpy.info(result.coltypes())
104+
plpy.info(result.coltypmods())
102105
returnresult.nrows()
103106
else:
104107
return None

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp