Commit 41282111 authored by Peter Eisentraut's avatar Peter Eisentraut

Skip dropped attributes when converting Python objects to tuples

Pay attention to the attisdropped field and skip over TupleDesc fields
that have it set.  Not a real problem until we get table returning
functions, but it's the right thing to do anyway.

Jan Urbański
parent 59ea9ef9
...@@ -2304,6 +2304,9 @@ PLyMapping_ToTuple(PLyTypeInfo *info, PyObject *mapping) ...@@ -2304,6 +2304,9 @@ PLyMapping_ToTuple(PLyTypeInfo *info, PyObject *mapping)
PyObject *volatile value; PyObject *volatile value;
PLyObToDatum *att; PLyObToDatum *att;
if (desc->attrs[i]->attisdropped)
continue;
key = NameStr(desc->attrs[i]->attname); key = NameStr(desc->attrs[i]->attname);
value = NULL; value = NULL;
att = &info->out.r.atts[i]; att = &info->out.r.atts[i];
...@@ -2354,6 +2357,7 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence) ...@@ -2354,6 +2357,7 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
HeapTuple tuple; HeapTuple tuple;
Datum *values; Datum *values;
bool *nulls; bool *nulls;
volatile int idx;
volatile int i; volatile int i;
Assert(PySequence_Check(sequence)); Assert(PySequence_Check(sequence));
...@@ -2364,7 +2368,13 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence) ...@@ -2364,7 +2368,13 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
* plpython developer's errors we are strict here * plpython developer's errors we are strict here
*/ */
desc = lookup_rowtype_tupdesc(info->out.d.typoid, -1); desc = lookup_rowtype_tupdesc(info->out.d.typoid, -1);
if (PySequence_Length(sequence) != desc->natts) idx = 0;
for (i = 0; i < desc->natts; i++)
{
if (!desc->attrs[i]->attisdropped)
idx++;
}
if (PySequence_Length(sequence) != idx)
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH), (errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("length of returned sequence did not match number of columns in row"))); errmsg("length of returned sequence did not match number of columns in row")));
...@@ -2376,16 +2386,20 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence) ...@@ -2376,16 +2386,20 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
/* Build tuple */ /* Build tuple */
values = palloc(sizeof(Datum) * desc->natts); values = palloc(sizeof(Datum) * desc->natts);
nulls = palloc(sizeof(bool) * desc->natts); nulls = palloc(sizeof(bool) * desc->natts);
idx = 0;
for (i = 0; i < desc->natts; ++i) for (i = 0; i < desc->natts; ++i)
{ {
PyObject *volatile value; PyObject *volatile value;
PLyObToDatum *att; PLyObToDatum *att;
if (desc->attrs[i]->attisdropped)
continue;
value = NULL; value = NULL;
att = &info->out.r.atts[i]; att = &info->out.r.atts[i];
PG_TRY(); PG_TRY();
{ {
value = PySequence_GetItem(sequence, i); value = PySequence_GetItem(sequence, idx);
Assert(value); Assert(value);
if (value == Py_None) if (value == Py_None)
{ {
...@@ -2407,6 +2421,8 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence) ...@@ -2407,6 +2421,8 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
PG_RE_THROW(); PG_RE_THROW();
} }
PG_END_TRY(); PG_END_TRY();
idx++;
} }
tuple = heap_form_tuple(desc, values, nulls); tuple = heap_form_tuple(desc, values, nulls);
...@@ -2441,6 +2457,9 @@ PLyObject_ToTuple(PLyTypeInfo *info, PyObject *object) ...@@ -2441,6 +2457,9 @@ PLyObject_ToTuple(PLyTypeInfo *info, PyObject *object)
PyObject *volatile value; PyObject *volatile value;
PLyObToDatum *att; PLyObToDatum *att;
if (desc->attrs[i]->attisdropped)
continue;
key = NameStr(desc->attrs[i]->attname); key = NameStr(desc->attrs[i]->attname);
value = NULL; value = NULL;
att = &info->out.r.atts[i]; att = &info->out.r.atts[i];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment