Compare commits

...

5 Commits
main ... v6.3.x

Author SHA1 Message Date
Anthony Tuininga
96b93adf9c Clarify documentation surrounding variable.actualElements. 2018-05-07 21:12:03 -06:00
Anthony Tuininga
55cd513bae Preparing to release cx_Oracle 6.3.1. 2018-05-07 15:21:59 -06:00
Anthony Tuininga
85c4af9d4f Added additional test to verify case when a DML returning statement returns
multiple rows during one execute but in the subsequent execute it returns no
rows.
2018-05-07 15:19:31 -06:00
Anthony Tuininga
a79dcb2ff8 Ensure that behavior in cx_Oracle 6.3 with __future__.dml_ret_array_val not set
or False is the same as the behavior in cx_Oracle 6.2
(https://github.com/oracle/python-cx_Oracle/issues/176).
2018-05-07 15:18:44 -06:00
Anthony Tuininga
2ea4be0be9 cx_Oracle 6.3.x will be based on ODPI-C 2.3.x. 2018-05-07 15:18:01 -06:00
8 changed files with 51 additions and 12 deletions

1
.gitmodules vendored
View File

@ -1,3 +1,4 @@
[submodule "odpi"]
path = odpi
url = https://github.com/oracle/odpi.git
branch = v2.3.x

View File

@ -42,7 +42,7 @@ author = 'Oracle'
# The short X.Y version.
version = '6.3'
# The full version, including alpha/beta/rc tags.
release = '6.3.0'
release = '6.3.1'
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:

View File

@ -8,6 +8,23 @@ cx_Oracle Release Notes
.. _releasenotes60:
Version 6.3.1 (May 2018)
------------------------
#) Update to `ODPI-C 2.3.2
<https://oracle.github.io/odpi/doc/releasenotes.html#
version-2-3-2-may-7-2018>`__.
- Ensure that a call to unregister a subscription only occurs if the
subscription is still registered.
- Ensure that before a statement is executed any buffers used for DML
returning statments are reset.
#) Ensure that behavior with cx_Oracle.__future__.dml_ret_array_val not
set or False is the same as the behavior in cx_Oracle 6.2
(`issue 176 <https://github.com/oracle/python-cx_Oracle/issues/176>`__).
Version 6.3 (April 2018)
------------------------

View File

@ -14,10 +14,8 @@ Variable Objects
This read-only attribute returns the actual number of elements in the
variable. This corresponds to the number of elements in a PL/SQL index-by
table for variables that are created using the method
:func:`Cursor.arrayvar()`. For output variables in a DML returning
statement this value corresponds to the number of rows returned. For all
other variables this value will be identical to the attribute
:attr:`~Variable.numElements`.
:func:`Cursor.arrayvar()`. For all other variables this value will be
identical to the attribute :attr:`~Variable.numElements`.
.. attribute:: Variable.bufferSize

2
odpi

@ -1 +1 @@
Subproject commit 641a979771833098a181195b875fac7d30fabeeb
Subproject commit 4de27730527fe11528ef7cdaf124d18c5c2419dc

View File

@ -20,7 +20,7 @@ except:
from distutils.extension import Extension
# define build constants
BUILD_VERSION = "6.3"
BUILD_VERSION = "6.3.1"
# setup extra link and compile args
extraLinkArgs = []

View File

@ -443,11 +443,14 @@ PyObject *cxoVar_getSingleValue(cxoVar *var, dpiData *data, uint32_t arrayPos)
if (dpiVar_getReturnedData(var->handle, 0, &numReturnedRows,
&data) < 0)
return cxoError_raiseAndReturnNull();
if (arrayPos >= numReturnedRows) {
if (arrayPos >= var->allocatedElements &&
arrayPos >= numReturnedRows) {
PyErr_SetString(PyExc_IndexError,
"cxoVar_getSingleValue: array size exceeded");
return NULL;
}
if (arrayPos >= numReturnedRows)
data = var->data;
}
// in all other cases, just get the value stored at specified position
@ -497,7 +500,7 @@ PyObject *cxoVar_getValue(cxoVar *var, uint32_t arrayPos)
return cxoError_raiseAndReturnNull();
return cxoVar_getArrayValue(var, numElements, var->data);
}
if (arrayPos >= var->allocatedElements) {
if (arrayPos >= var->allocatedElements && !var->getReturnedData) {
PyErr_SetString(PyExc_IndexError,
"cxoVar_getSingleValue: array size exceeded");
return NULL;

View File

@ -112,6 +112,8 @@ class TestDMLReturning(BaseTestCase):
strVar = strVar)
self.assertEqual(intVar.values, [])
self.assertEqual(strVar.values, [])
self.assertEqual(intVar.getvalue(), None)
self.assertEqual(strVar.getvalue(), None)
cx_Oracle.__future__.dml_ret_array_val = True
try:
self.assertEqual(intVar.values, [[]])
@ -141,6 +143,8 @@ class TestDMLReturning(BaseTestCase):
"The final value of string 9",
"The final value of string 10"
])
self.assertEqual(intVar.getvalue(1), 24)
self.assertEqual(strVar.getvalue(2), "The final value of string 10")
cx_Oracle.__future__.dml_ret_array_val = True
try:
self.assertEqual(intVar.values, [[23, 24, 25]])
@ -154,10 +158,11 @@ class TestDMLReturning(BaseTestCase):
def testUpdateMultipleRowsExecuteMany(self):
"test update multiple rows with DML returning (executeMany)"
data = [(i, "The initial value of string %d" % i) \
for i in range(1, 11)]
self.cursor.execute("truncate table TestTempTable")
for i in range(1, 11):
self.cursor.execute("insert into TestTempTable values (:1, :2)",
(i, "The initial value of string %d" % i))
self.cursor.executemany("insert into TestTempTable values (:1, :2)",
data)
intVar = self.cursor.var(cx_Oracle.NUMBER, arraysize = 3)
strVar = self.cursor.var(str, arraysize = 3)
self.cursor.setinputsizes(None, intVar, strVar)
@ -234,3 +239,18 @@ class TestDMLReturning(BaseTestCase):
results.append(intVar.values)
self.assertEqual(results, [ [1, 2, 3, 4], [5, 6, 7], [8, 9] ])
def testDeleteReturningNoRowsAfterManyRows(self):
"test delete returning no rows after initially returning many rows"
data = [(i, "Test String %d" % i) for i in range(1, 11)]
self.cursor.execute("truncate table TestTempTable")
self.cursor.executemany("insert into TestTempTable values (:1, :2)",
data)
intVar = self.cursor.var(int)
self.cursor.execute("""
delete from TestTempTable
where IntCol < :1
returning IntCol into :2""", [5, intVar])
self.assertEqual(intVar.values, [1, 2, 3, 4])
self.cursor.execute(None, [4, intVar])
self.assertEqual(intVar.values, [])