/* * Transform a tuple into a Python dict object. */ static PyObject * PLyDict_FromTuple(PLyDatumToOb *arg, HeapTuple tuple, TupleDesc desc) { PyObject *volatile dict; /* Simple sanity check that desc matches */ Assert(desc->natts == arg->u.tuple.natts); dict = PyDict_New(); if (dict == NULL) return NULL; PG_TRY(); { int i; for (i = 0; i < arg->u.tuple.natts; i++) { PLyDatumToOb *att = &arg->u.tuple.atts[i]; Form_pg_attribute attr = TupleDescAttr(desc, i); char *key; Datum vattr; bool is_null; PyObject *value; if (attr->attisdropped) continue; key = NameStr(attr->attname); vattr = heap_getattr(tuple, (i + 1), desc, &is_null); if (is_null) PyDict_SetItemString(dict, key, Py_None); else { value = att->func(att, vattr); PyDict_SetItemString(dict, key, value); Py_DECREF(value); } } } PG_CATCH(); { Py_DECREF(dict); PG_RE_THROW(); } PG_END_TRY(); return dict; }
static PyObject * PLyList_FromArray(PLyDatumToOb *arg, Datum d) { ArrayType *array = DatumGetArrayTypeP(d); PLyDatumToOb *elm = arg->elm; PyObject *list; int length; int lbound; int i; if (ARR_NDIM(array) == 0) return PyList_New(0); if (ARR_NDIM(array) != 1) ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("cannot convert multidimensional array to Python list"), errdetail("PL/Python only supports one-dimensional arrays."))); length = ARR_DIMS(array)[0]; lbound = ARR_LBOUND(array)[0]; list = PyList_New(length); if (list == NULL) PLy_elog(ERROR, "could not create new Python list"); for (i = 0; i < length; i++) { Datum elem; bool isnull; int offset; offset = lbound + i; elem = array_ref(array, 1, &offset, arg->typlen, elm->typlen, elm->typbyval, elm->typalign, &isnull); if (isnull) { Py_INCREF(Py_None); PyList_SET_ITEM(list, i, Py_None); } else PyList_SET_ITEM(list, i, elm->func(elm, elem)); } return list; }