|
@@ -581,8 +581,9 @@ class PythonRowBuilder : public CInterfaceOf<IFieldSource>
|
|
{
|
|
{
|
|
public:
|
|
public:
|
|
PythonRowBuilder(PyObject *_row)
|
|
PythonRowBuilder(PyObject *_row)
|
|
- : iter(NULL), elem(NULL), pushback(_row), named(false)
|
|
|
|
|
|
+ : iter(NULL), elem(NULL), named(false)
|
|
{
|
|
{
|
|
|
|
+ pushback.set(_row);
|
|
}
|
|
}
|
|
virtual bool getBooleanResult(const RtlFieldInfo *field)
|
|
virtual bool getBooleanResult(const RtlFieldInfo *field)
|
|
{
|
|
{
|
|
@@ -705,6 +706,7 @@ protected:
|
|
parent.set(elem);
|
|
parent.set(elem);
|
|
iter.setown(PyObject_GetIter(elem));
|
|
iter.setown(PyObject_GetIter(elem));
|
|
named = isNamedTuple(elem);
|
|
named = isNamedTuple(elem);
|
|
|
|
+ elem.clear();
|
|
}
|
|
}
|
|
bool isNamedTuple(PyObject *obj)
|
|
bool isNamedTuple(PyObject *obj)
|
|
{
|
|
{
|
|
@@ -734,6 +736,15 @@ protected:
|
|
BoolArray namedStack;
|
|
BoolArray namedStack;
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static size32_t getRowResult(PyObject *result, ARowBuilder &builder)
|
|
|
|
+{
|
|
|
|
+ PythonRowBuilder pyRowBuilder(result);
|
|
|
|
+ const RtlTypeInfo *typeInfo = builder.queryAllocator()->queryOutputMeta()->queryTypeInfo();
|
|
|
|
+ assertex(typeInfo);
|
|
|
|
+ RtlFieldStrInfo dummyField("<row>", NULL, typeInfo);
|
|
|
|
+ return typeInfo->build(builder, 0, &dummyField, pyRowBuilder);
|
|
|
|
+}
|
|
|
|
+
|
|
// GILBlock ensures the we hold the Python "Global interpreter lock" for the appropriate duration
|
|
// GILBlock ensures the we hold the Python "Global interpreter lock" for the appropriate duration
|
|
|
|
|
|
class GILBlock
|
|
class GILBlock
|
|
@@ -778,11 +789,7 @@ public:
|
|
if (!row)
|
|
if (!row)
|
|
return NULL;
|
|
return NULL;
|
|
RtlDynamicRowBuilder rowBuilder(resultAllocator);
|
|
RtlDynamicRowBuilder rowBuilder(resultAllocator);
|
|
- PythonRowBuilder pyRowBuilder(row);
|
|
|
|
- const RtlTypeInfo *typeInfo = resultAllocator->queryOutputMeta()->queryTypeInfo();
|
|
|
|
- assertex(typeInfo);
|
|
|
|
- RtlFieldStrInfo dummyField("<row>", NULL, typeInfo);
|
|
|
|
- size32_t len = typeInfo->build(rowBuilder, 0, &dummyField, pyRowBuilder);
|
|
|
|
|
|
+ size32_t len = pyembed::getRowResult(row, rowBuilder);
|
|
return rowBuilder.finalizeRowClear(len);
|
|
return rowBuilder.finalizeRowClear(len);
|
|
}
|
|
}
|
|
virtual void stop()
|
|
virtual void stop()
|
|
@@ -864,11 +871,13 @@ public:
|
|
}
|
|
}
|
|
virtual byte * getRowResult(IEngineRowAllocator * _resultAllocator)
|
|
virtual byte * getRowResult(IEngineRowAllocator * _resultAllocator)
|
|
{
|
|
{
|
|
- UNIMPLEMENTED;
|
|
|
|
|
|
+ RtlDynamicRowBuilder rowBuilder(_resultAllocator);
|
|
|
|
+ size32_t len = pyembed::getRowResult(result, rowBuilder);
|
|
|
|
+ return (byte *) rowBuilder.finalizeRowClear(len);
|
|
}
|
|
}
|
|
virtual size32_t getTransformResult(ARowBuilder & builder)
|
|
virtual size32_t getTransformResult(ARowBuilder & builder)
|
|
{
|
|
{
|
|
- UNIMPLEMENTED;
|
|
|
|
|
|
+ return pyembed::getRowResult(result, builder);
|
|
}
|
|
}
|
|
virtual void bindBooleanParam(const char *name, bool val)
|
|
virtual void bindBooleanParam(const char *name, bool val)
|
|
{
|
|
{
|