Fixed bug with binding boolean values when using Oracle Database 23c
(#263).
This commit is contained in:
parent
86032f96ba
commit
72bb4e4d79
|
@ -69,6 +69,8 @@ Common Changes
|
|||
and scale allow for it -- in the same way that numbers are fetched from the
|
||||
database
|
||||
(`issue 99 <https://github.com/oracle/python-oracledb/issues/99>`__).
|
||||
#) Fixed bug with binding boolean values with Oracle Database 23c
|
||||
(`issue 263 <https://github.com/oracle/python-oracledb/issues/263>`__).
|
||||
#) Fixed bug with getting unknown attributes from DbObject instances.
|
||||
#) Error ``DPY-4029: errors in array DML exceed 65535`` is now raised when the
|
||||
number of batch errors exceeds 65535 when calling
|
||||
|
|
|
@ -243,6 +243,8 @@ cdef class BaseConnImpl:
|
|||
public object outputtypehandler
|
||||
public bint autocommit
|
||||
public bint invoke_session_callback
|
||||
readonly tuple server_version
|
||||
readonly bint supports_bool
|
||||
|
||||
cdef object _check_value(self, DbType dbtype, BaseDbObjectTypeImpl objtype,
|
||||
object value, bint* is_ok)
|
||||
|
|
|
@ -1081,7 +1081,7 @@ class Connection:
|
|||
"""
|
||||
if self._version is None:
|
||||
self._verify_connected()
|
||||
self._version = self._impl.get_version()
|
||||
self._version = ".".join(str(c) for c in self._impl.server_version)
|
||||
return self._version
|
||||
|
||||
def xid(
|
||||
|
|
|
@ -264,10 +264,6 @@ cdef class BaseConnImpl:
|
|||
def get_type(self, object conn, str name):
|
||||
pass
|
||||
|
||||
@utils.CheckImpls("getting the database version")
|
||||
def get_version(self):
|
||||
pass
|
||||
|
||||
@utils.CheckImpls("pinging the database")
|
||||
def ping(self):
|
||||
pass
|
||||
|
|
|
@ -220,7 +220,9 @@ cdef class BaseVarImpl:
|
|||
dbtype = DB_TYPE_VARCHAR
|
||||
size = 1
|
||||
elif isinstance(value, PY_TYPE_BOOL):
|
||||
dbtype = DB_TYPE_BOOLEAN if is_plsql else DB_TYPE_BINARY_INTEGER
|
||||
dbtype = DB_TYPE_BOOLEAN \
|
||||
if self._conn_impl.supports_bool or is_plsql \
|
||||
else DB_TYPE_BINARY_INTEGER
|
||||
elif isinstance(value, str):
|
||||
size = <uint32_t> len(value)
|
||||
dbtype = DB_TYPE_VARCHAR
|
||||
|
|
|
@ -270,6 +270,7 @@ cdef class ThickConnImpl(BaseConnImpl):
|
|||
dpiConnCreateParams conn_params
|
||||
ConnectParamsImpl pool_params
|
||||
dpiAccessToken access_token
|
||||
dpiVersionInfo version_info
|
||||
ConnectionParams params
|
||||
int status
|
||||
|
||||
|
@ -387,8 +388,20 @@ cdef class ThickConnImpl(BaseConnImpl):
|
|||
params.password_len, params.dsn_ptr,
|
||||
params.dsn_len, &common_params,
|
||||
&conn_params, &self._handle)
|
||||
if status == DPI_SUCCESS:
|
||||
status = dpiConn_getServerVersion(self._handle, NULL, NULL,
|
||||
&version_info)
|
||||
if status < 0:
|
||||
_raise_from_odpi()
|
||||
self.server_version = (
|
||||
version_info.versionNum,
|
||||
version_info.releaseNum,
|
||||
version_info.updateNum,
|
||||
version_info.portReleaseNum,
|
||||
version_info.portUpdateNum
|
||||
)
|
||||
self.supports_bool = client_version_info.versionNum >= 23 \
|
||||
and version_info.versionNum >= 23
|
||||
|
||||
# determine if session callback should be invoked; this takes place if
|
||||
# the connection is newly created by the pool or if the requested tag
|
||||
|
@ -581,20 +594,6 @@ cdef class ThickConnImpl(BaseConnImpl):
|
|||
finally:
|
||||
dpiObjectType_release(handle)
|
||||
|
||||
def get_version(self):
|
||||
cdef:
|
||||
dpiVersionInfo version_info
|
||||
int status
|
||||
with nogil:
|
||||
status = dpiConn_getServerVersion(self._handle, NULL, NULL,
|
||||
&version_info)
|
||||
if status < 0:
|
||||
_raise_from_odpi()
|
||||
return "%d.%d.%d.%d.%d" % \
|
||||
(version_info.versionNum, version_info.releaseNum,
|
||||
version_info.updateNum, version_info.portReleaseNum,
|
||||
version_info.portUpdateNum)
|
||||
|
||||
def set_action(self, str value):
|
||||
self._set_text_attr(dpiConn_setAction, value)
|
||||
|
||||
|
|
|
@ -433,21 +433,15 @@ def clientversion():
|
|||
The five values are the major version, minor version, update number, patch
|
||||
number and port update number.
|
||||
"""
|
||||
cdef dpiVersionInfo info
|
||||
global client_version
|
||||
if client_version is None:
|
||||
if driver_context == NULL:
|
||||
errors._raise_err(errors.ERR_INIT_ORACLE_CLIENT_NOT_CALLED)
|
||||
if dpiContext_getClientVersion(driver_context, &info) < 0:
|
||||
_raise_from_odpi()
|
||||
client_version = (
|
||||
info.versionNum,
|
||||
info.releaseNum,
|
||||
info.updateNum,
|
||||
info.portReleaseNum,
|
||||
info.portUpdateNum
|
||||
)
|
||||
return client_version
|
||||
if driver_context == NULL:
|
||||
errors._raise_err(errors.ERR_INIT_ORACLE_CLIENT_NOT_CALLED)
|
||||
return (
|
||||
client_version_info.versionNum,
|
||||
client_version_info.releaseNum,
|
||||
client_version_info.updateNum,
|
||||
client_version_info.portReleaseNum,
|
||||
client_version_info.portUpdateNum
|
||||
)
|
||||
|
||||
|
||||
def init_oracle_client(lib_dir=None, config_dir=None, error_url=None,
|
||||
|
@ -494,6 +488,9 @@ def init_oracle_client(lib_dir=None, config_dir=None, error_url=None,
|
|||
¶ms, &driver_context,
|
||||
&error_info) < 0:
|
||||
_raise_from_info(&error_info)
|
||||
if dpiContext_getClientVersion(driver_context,
|
||||
&client_version_info) < 0:
|
||||
_raise_from_odpi()
|
||||
driver_context_params = params_tuple
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ cdef class ThinConnImpl(BaseConnImpl):
|
|||
uint32_t _statement_cache_size
|
||||
object _statement_cache_lock
|
||||
Protocol _protocol
|
||||
str _server_version
|
||||
uint32_t _session_id
|
||||
uint32_t _serial_num
|
||||
str _action
|
||||
|
@ -353,9 +352,6 @@ cdef class ThinConnImpl(BaseConnImpl):
|
|||
get_dbobject_type_cache(self._dbobject_type_cache_num)
|
||||
return cache.get_type(conn, name)
|
||||
|
||||
def get_version(self):
|
||||
return self._server_version
|
||||
|
||||
def ping(self):
|
||||
cdef Message message
|
||||
message = self._create_message(PingMessage)
|
||||
|
|
|
@ -1538,9 +1538,9 @@ cdef class AuthMessage(Message):
|
|||
self.session_data.get("AUTH_SC_SERVICE_NAME")
|
||||
self.conn_impl._instance_name = \
|
||||
self.session_data.get("AUTH_INSTANCENAME")
|
||||
|
||||
self.conn_impl._server_version = \
|
||||
"%d.%d.%d.%d.%d" % self._get_version_tuple(buf)
|
||||
self.conn_impl.server_version = self._get_version_tuple(buf)
|
||||
self.conn_impl.supports_bool = \
|
||||
buf._caps.ttc_field_version >= TNS_CCAP_FIELD_VERSION_23_1
|
||||
|
||||
cdef int _set_params(self, ConnectParamsImpl params,
|
||||
Description description) except -1:
|
||||
|
|
|
@ -67,9 +67,9 @@ cdef type PY_TYPE_LOB
|
|||
cdef type PY_TYPE_TIMEDELTA = datetime.timedelta
|
||||
|
||||
cdef dpiContext *driver_context = NULL
|
||||
cdef dpiVersionInfo client_version_info
|
||||
|
||||
driver_context_params = None
|
||||
client_version = None
|
||||
|
||||
include "impl/thick/buffer.pyx"
|
||||
include "impl/thick/connection.pyx"
|
||||
|
|
|
@ -106,6 +106,21 @@ class TestCase(test_env.BaseTestCase):
|
|||
)
|
||||
self.assertIsNone(result)
|
||||
|
||||
@unittest.skipUnless(
|
||||
test_env.get_client_version() >= (23, 1), "unsupported client"
|
||||
)
|
||||
@unittest.skipUnless(
|
||||
test_env.get_server_version() >= (23, 1), "unsupported server"
|
||||
)
|
||||
def test_3109_bind_and_fetch_boolean_23c(self):
|
||||
"3109 - test binding and fetching boolean with 23c"
|
||||
for value in (True, False):
|
||||
with self.subTest(value=value):
|
||||
self.cursor.execute("select not :1 from dual", [value])
|
||||
(fetched_value,) = self.cursor.fetchone()
|
||||
self.assertIsInstance(fetched_value, bool)
|
||||
self.assertEqual(fetched_value, not value)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_env.run_test_cases()
|
||||
|
|
|
@ -1079,7 +1079,7 @@ class Connection:
|
|||
"""
|
||||
if self._version is None:
|
||||
self._verify_connected()
|
||||
self._version = self._impl.get_version()
|
||||
self._version = ".".join(str(c) for c in self._impl.server_version)
|
||||
return self._version
|
||||
|
||||
def xid(
|
||||
|
|
Loading…
Reference in New Issue