]> granicus.if.org Git - postgresql/commitdiff
Skip dropped attributes when converting Python objects to tuples
authorPeter Eisentraut <peter_e@gmx.net>
Tue, 18 Jan 2011 21:39:09 +0000 (23:39 +0200)
committerPeter Eisentraut <peter_e@gmx.net>
Tue, 18 Jan 2011 21:39:09 +0000 (23:39 +0200)
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

src/pl/plpython/plpython.c

index f2702ff4e99bfa9f6158a4090d780290992f0456..39a4bb585b7f89a752b5ba1d3d8cffcd1cccb62f 100644 (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];