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
This commit is contained in:
Peter Eisentraut 2011-01-18 23:39:09 +02:00
parent 59ea9ef9aa
commit 41282111e6
1 changed files with 21 additions and 2 deletions

View File

@ -2304,6 +2304,9 @@ PLyMapping_ToTuple(PLyTypeInfo *info, PyObject *mapping)
PyObject *volatile value;
PLyObToDatum *att;
if (desc->attrs[i]->attisdropped)
continue;
key = NameStr(desc->attrs[i]->attname);
value = NULL;
att = &info->out.r.atts[i];
@ -2354,6 +2357,7 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
HeapTuple tuple;
Datum *values;
bool *nulls;
volatile int idx;
volatile int i;
Assert(PySequence_Check(sequence));
@ -2364,7 +2368,13 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
* plpython developer's errors we are strict here
*/
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,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg("length of returned sequence did not match number of columns in row")));
@ -2376,16 +2386,20 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
/* Build tuple */
values = palloc(sizeof(Datum) * desc->natts);
nulls = palloc(sizeof(bool) * desc->natts);
idx = 0;
for (i = 0; i < desc->natts; ++i)
{
PyObject *volatile value;
PLyObToDatum *att;
if (desc->attrs[i]->attisdropped)
continue;
value = NULL;
att = &info->out.r.atts[i];
PG_TRY();
{
value = PySequence_GetItem(sequence, i);
value = PySequence_GetItem(sequence, idx);
Assert(value);
if (value == Py_None)
{
@ -2407,6 +2421,8 @@ PLySequence_ToTuple(PLyTypeInfo *info, PyObject *sequence)
PG_RE_THROW();
}
PG_END_TRY();
idx++;
}
tuple = heap_form_tuple(desc, values, nulls);
@ -2441,6 +2457,9 @@ PLyObject_ToTuple(PLyTypeInfo *info, PyObject *object)
PyObject *volatile value;
PLyObToDatum *att;
if (desc->attrs[i]->attisdropped)
continue;
key = NameStr(desc->attrs[i]->attname);
value = NULL;
att = &info->out.r.atts[i];