@@ -379,28 +379,81 @@ int cxoVar_bind(cxoVar *var, cxoCursor *cursor, PyObject *name, uint32_t pos)
379379 if (status < 0 )
380380 return cxoError_raiseAndReturnInt ();
381381
382+ // set flag if bound to a DML returning statement and no data set
383+ if (cursor -> stmtInfo .isReturning && !var -> isValueSet )
384+ var -> getReturnedData = 1 ;
385+
382386 return 0 ;
383387}
384388
385389
390+ //-----------------------------------------------------------------------------
391+ // cxoVar_getArrayValue()
392+ // Return the value of the variable as an array.
393+ //-----------------------------------------------------------------------------
394+ static PyObject * cxoVar_getArrayValue (cxoVar * var , uint32_t numElements ,
395+ dpiData * data )
396+ {
397+ PyObject * value , * singleValue ;
398+ uint32_t i ;
399+
400+ // use the first set of returned values if DML returning as array is not
401+ // enabled
402+ if (!(cxoFutureObj && cxoFutureObj -> dmlReturningArray ) &&
403+ var -> getReturnedData && !data ) {
404+ if (dpiVar_getReturnedData (var -> handle , 0 , & numElements , & data ) < 0 )
405+ return cxoError_raiseAndReturnNull ();
406+ }
407+
408+ value = PyList_New (numElements );
409+ if (!value )
410+ return NULL ;
411+
412+ for (i = 0 ; i < numElements ; i ++ ) {
413+ singleValue = cxoVar_getSingleValue (var , data , i );
414+ if (!singleValue ) {
415+ Py_DECREF (value );
416+ return NULL ;
417+ }
418+ PyList_SET_ITEM (value , i , singleValue );
419+ }
420+
421+ return value ;
422+ }
423+
424+
386425//-----------------------------------------------------------------------------
387426// cxoVar_getSingleValue()
388427// Return the value of the variable at the given position.
389428//-----------------------------------------------------------------------------
390- PyObject * cxoVar_getSingleValue (cxoVar * var , uint32_t arrayPos )
429+ PyObject * cxoVar_getSingleValue (cxoVar * var , dpiData * data , uint32_t arrayPos )
391430{
392431 PyObject * value , * result ;
393- dpiData * data ;
394-
395- // ensure we do not exceed the number of allocated elements
396- if (arrayPos >= var -> allocatedElements ) {
397- PyErr_SetString (PyExc_IndexError ,
398- "cxoVar_getSingleValue: array size exceeded" );
399- return NULL ;
432+ uint32_t numReturnedRows ;
433+ dpiData * returnedData ;
434+
435+ // handle DML returning
436+ if (!data && var -> getReturnedData ) {
437+ if (cxoFutureObj && cxoFutureObj -> dmlReturningArray ) {
438+ if (dpiVar_getReturnedData (var -> handle , arrayPos , & numReturnedRows ,
439+ & returnedData ) < 0 )
440+ return cxoError_raiseAndReturnNull ();
441+ return cxoVar_getArrayValue (var , numReturnedRows , returnedData );
442+ }
443+ if (dpiVar_getReturnedData (var -> handle , 0 , & numReturnedRows ,
444+ & data ) < 0 )
445+ return cxoError_raiseAndReturnNull ();
446+ if (arrayPos >= numReturnedRows ) {
447+ PyErr_SetString (PyExc_IndexError ,
448+ "cxoVar_getSingleValue: array size exceeded" );
449+ return NULL ;
450+ }
400451 }
401452
402- // return the value
403- data = & var -> data [arrayPos ];
453+ // in all other cases, just get the value stored at specified position
454+ if (data )
455+ data = & data [arrayPos ];
456+ else data = & var -> data [arrayPos ];
404457 if (data -> isNull )
405458 Py_RETURN_NONE ;
406459 value = cxoTransform_toPython (var -> type -> transformNum , var -> connection ,
@@ -431,33 +484,6 @@ PyObject *cxoVar_getSingleValue(cxoVar *var, uint32_t arrayPos)
431484}
432485
433486
434- //-----------------------------------------------------------------------------
435- // cxoVar_getArrayValue()
436- // Return the value of the variable as an array.
437- //-----------------------------------------------------------------------------
438- static PyObject * cxoVar_getArrayValue (cxoVar * var ,
439- uint32_t numElements )
440- {
441- PyObject * value , * singleValue ;
442- uint32_t i ;
443-
444- value = PyList_New (numElements );
445- if (!value )
446- return NULL ;
447-
448- for (i = 0 ; i < numElements ; i ++ ) {
449- singleValue = cxoVar_getSingleValue (var , i );
450- if (!singleValue ) {
451- Py_DECREF (value );
452- return NULL ;
453- }
454- PyList_SET_ITEM (value , i , singleValue );
455- }
456-
457- return value ;
458- }
459-
460-
461487//-----------------------------------------------------------------------------
462488// cxoVar_getValue()
463489// Return the value of the variable.
@@ -469,10 +495,14 @@ PyObject *cxoVar_getValue(cxoVar *var, uint32_t arrayPos)
469495 if (var -> isArray ) {
470496 if (dpiVar_getNumElementsInArray (var -> handle , & numElements ) < 0 )
471497 return cxoError_raiseAndReturnNull ();
472- return cxoVar_getArrayValue (var , numElements );
498+ return cxoVar_getArrayValue (var , numElements , var -> data );
473499 }
474-
475- return cxoVar_getSingleValue (var , arrayPos );
500+ if (arrayPos >= var -> allocatedElements ) {
501+ PyErr_SetString (PyExc_IndexError ,
502+ "cxoVar_getSingleValue: array size exceeded" );
503+ return NULL ;
504+ }
505+ return cxoVar_getSingleValue (var , NULL , arrayPos );
476506}
477507
478508
@@ -659,6 +689,7 @@ static int cxoVar_setArrayValue(cxoVar *var, PyObject *value)
659689//-----------------------------------------------------------------------------
660690int cxoVar_setValue (cxoVar * var , uint32_t arrayPos , PyObject * value )
661691{
692+ var -> isValueSet = 1 ;
662693 if (var -> isArray ) {
663694 if (arrayPos > 0 ) {
664695 PyErr_SetString (cxoNotSupportedErrorException ,
@@ -737,9 +768,10 @@ static PyObject *cxoVar_externalGetValue(cxoVar *var, PyObject *args,
737768static PyObject * cxoVar_externalGetActualElements (cxoVar * var ,
738769 void * unused )
739770{
740- uint32_t numElements ;
771+ uint32_t numElements = var -> allocatedElements ;
741772
742- if (dpiVar_getNumElementsInArray (var -> handle , & numElements ) < 0 )
773+ if (var -> isArray &&
774+ dpiVar_getNumElementsInArray (var -> handle , & numElements ) < 0 )
743775 return cxoError_raiseAndReturnNull ();
744776 return PyInt_FromLong (numElements );
745777}
@@ -751,11 +783,12 @@ static PyObject *cxoVar_externalGetActualElements(cxoVar *var,
751783//-----------------------------------------------------------------------------
752784static PyObject * cxoVar_externalGetValues (cxoVar * var , void * unused )
753785{
754- uint32_t numElements ;
786+ uint32_t numElements = var -> allocatedElements ;
755787
756- if (dpiVar_getNumElementsInArray (var -> handle , & numElements ) < 0 )
788+ if (var -> isArray &&
789+ dpiVar_getNumElementsInArray (var -> handle , & numElements ) < 0 )
757790 return cxoError_raiseAndReturnNull ();
758- return cxoVar_getArrayValue (var , numElements );
791+ return cxoVar_getArrayValue (var , numElements , NULL );
759792}
760793
761794
@@ -771,10 +804,10 @@ static PyObject *cxoVar_repr(cxoVar *var)
771804 if (var -> isArray ) {
772805 if (dpiVar_getNumElementsInArray (var -> handle , & numElements ) < 0 )
773806 return cxoError_raiseAndReturnNull ();
774- value = cxoVar_getArrayValue (var , numElements );
807+ value = cxoVar_getArrayValue (var , numElements , var -> data );
775808 } else if (var -> allocatedElements == 1 )
776- value = cxoVar_getSingleValue (var , 0 );
777- else value = cxoVar_getArrayValue (var , var -> allocatedElements );
809+ value = cxoVar_getSingleValue (var , NULL , 0 );
810+ else value = cxoVar_getArrayValue (var , var -> allocatedElements , NULL );
778811 if (!value )
779812 return NULL ;
780813 if (cxoUtils_getModuleAndName (Py_TYPE (var ), & module , & name ) < 0 ) {
0 commit comments