mirror of
https://github.com/postgres/postgres.git
synced 2025-05-15 19:15:29 +03:00
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:
parent
59ea9ef9aa
commit
41282111e6
@ -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)
|
|||||||
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)
|
|||||||
* 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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user