From: Peter Eisentraut Date: Tue, 18 Jan 2011 21:39:09 +0000 (+0200) Subject: Skip dropped attributes when converting Python objects to tuples X-Git-Tag: REL9_1_ALPHA4~423 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=41282111e6cc73aca4b63dffe950ba7a63e4bd8a;p=postgresql 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 --- diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c index f2702ff4e9..39a4bb585b 100644 --- a/src/pl/plpython/plpython.c +++ b/src/pl/plpython/plpython.c @@ -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];