Skip to content

Commit 72bb4e4

Browse files
Fixed bug with binding boolean values when using Oracle Database 23c
(#263).
1 parent 86032f9 commit 72bb4e4

File tree

12 files changed

+53
-44
lines changed

12 files changed

+53
-44
lines changed

doc/src/release_notes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ Common Changes
6969
and scale allow for it -- in the same way that numbers are fetched from the
7070
database
7171
(`issue 99 <https://github.com/oracle/python-oracledb/issues/99>`__).
72+
#) Fixed bug with binding boolean values with Oracle Database 23c
73+
(`issue 263 <https://github.com/oracle/python-oracledb/issues/263>`__).
7274
#) Fixed bug with getting unknown attributes from DbObject instances.
7375
#) Error ``DPY-4029: errors in array DML exceed 65535`` is now raised when the
7476
number of batch errors exceeds 65535 when calling

src/oracledb/base_impl.pxd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ cdef class BaseConnImpl:
243243
public object outputtypehandler
244244
public bint autocommit
245245
public bint invoke_session_callback
246+
readonly tuple server_version
247+
readonly bint supports_bool
246248

247249
cdef object _check_value(self, DbType dbtype, BaseDbObjectTypeImpl objtype,
248250
object value, bint* is_ok)

src/oracledb/connection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,7 @@ def version(self) -> str:
10811081
"""
10821082
if self._version is None:
10831083
self._verify_connected()
1084-
self._version = self._impl.get_version()
1084+
self._version = ".".join(str(c) for c in self._impl.server_version)
10851085
return self._version
10861086

10871087
def xid(

src/oracledb/impl/base/connection.pyx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,6 @@ cdef class BaseConnImpl:
264264
def get_type(self, object conn, str name):
265265
pass
266266

267-
@utils.CheckImpls("getting the database version")
268-
def get_version(self):
269-
pass
270-
271267
@utils.CheckImpls("pinging the database")
272268
def ping(self):
273269
pass

src/oracledb/impl/base/var.pyx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,9 @@ cdef class BaseVarImpl:
220220
dbtype = DB_TYPE_VARCHAR
221221
size = 1
222222
elif isinstance(value, PY_TYPE_BOOL):
223-
dbtype = DB_TYPE_BOOLEAN if is_plsql else DB_TYPE_BINARY_INTEGER
223+
dbtype = DB_TYPE_BOOLEAN \
224+
if self._conn_impl.supports_bool or is_plsql \
225+
else DB_TYPE_BINARY_INTEGER
224226
elif isinstance(value, str):
225227
size = <uint32_t> len(value)
226228
dbtype = DB_TYPE_VARCHAR

src/oracledb/impl/thick/connection.pyx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ cdef class ThickConnImpl(BaseConnImpl):
270270
dpiConnCreateParams conn_params
271271
ConnectParamsImpl pool_params
272272
dpiAccessToken access_token
273+
dpiVersionInfo version_info
273274
ConnectionParams params
274275
int status
275276

@@ -387,8 +388,20 @@ cdef class ThickConnImpl(BaseConnImpl):
387388
params.password_len, params.dsn_ptr,
388389
params.dsn_len, &common_params,
389390
&conn_params, &self._handle)
391+
if status == DPI_SUCCESS:
392+
status = dpiConn_getServerVersion(self._handle, NULL, NULL,
393+
&version_info)
390394
if status < 0:
391395
_raise_from_odpi()
396+
self.server_version = (
397+
version_info.versionNum,
398+
version_info.releaseNum,
399+
version_info.updateNum,
400+
version_info.portReleaseNum,
401+
version_info.portUpdateNum
402+
)
403+
self.supports_bool = client_version_info.versionNum >= 23 \
404+
and version_info.versionNum >= 23
392405

393406
# determine if session callback should be invoked; this takes place if
394407
# the connection is newly created by the pool or if the requested tag
@@ -581,20 +594,6 @@ cdef class ThickConnImpl(BaseConnImpl):
581594
finally:
582595
dpiObjectType_release(handle)
583596

584-
def get_version(self):
585-
cdef:
586-
dpiVersionInfo version_info
587-
int status
588-
with nogil:
589-
status = dpiConn_getServerVersion(self._handle, NULL, NULL,
590-
&version_info)
591-
if status < 0:
592-
_raise_from_odpi()
593-
return "%d.%d.%d.%d.%d" % \
594-
(version_info.versionNum, version_info.releaseNum,
595-
version_info.updateNum, version_info.portReleaseNum,
596-
version_info.portUpdateNum)
597-
598597
def set_action(self, str value):
599598
self._set_text_attr(dpiConn_setAction, value)
600599

src/oracledb/impl/thick/utils.pyx

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -433,21 +433,15 @@ def clientversion():
433433
The five values are the major version, minor version, update number, patch
434434
number and port update number.
435435
"""
436-
cdef dpiVersionInfo info
437-
global client_version
438-
if client_version is None:
439-
if driver_context == NULL:
440-
errors._raise_err(errors.ERR_INIT_ORACLE_CLIENT_NOT_CALLED)
441-
if dpiContext_getClientVersion(driver_context, &info) < 0:
442-
_raise_from_odpi()
443-
client_version = (
444-
info.versionNum,
445-
info.releaseNum,
446-
info.updateNum,
447-
info.portReleaseNum,
448-
info.portUpdateNum
449-
)
450-
return client_version
436+
if driver_context == NULL:
437+
errors._raise_err(errors.ERR_INIT_ORACLE_CLIENT_NOT_CALLED)
438+
return (
439+
client_version_info.versionNum,
440+
client_version_info.releaseNum,
441+
client_version_info.updateNum,
442+
client_version_info.portReleaseNum,
443+
client_version_info.portUpdateNum
444+
)
451445

452446

453447
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,
494488
&params, &driver_context,
495489
&error_info) < 0:
496490
_raise_from_info(&error_info)
491+
if dpiContext_getClientVersion(driver_context,
492+
&client_version_info) < 0:
493+
_raise_from_odpi()
497494
driver_context_params = params_tuple
498495

499496

src/oracledb/impl/thin/connection.pyx

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ cdef class ThinConnImpl(BaseConnImpl):
3636
uint32_t _statement_cache_size
3737
object _statement_cache_lock
3838
Protocol _protocol
39-
str _server_version
4039
uint32_t _session_id
4140
uint32_t _serial_num
4241
str _action
@@ -353,9 +352,6 @@ cdef class ThinConnImpl(BaseConnImpl):
353352
get_dbobject_type_cache(self._dbobject_type_cache_num)
354353
return cache.get_type(conn, name)
355354

356-
def get_version(self):
357-
return self._server_version
358-
359355
def ping(self):
360356
cdef Message message
361357
message = self._create_message(PingMessage)

src/oracledb/impl/thin/messages.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,9 +1538,9 @@ cdef class AuthMessage(Message):
15381538
self.session_data.get("AUTH_SC_SERVICE_NAME")
15391539
self.conn_impl._instance_name = \
15401540
self.session_data.get("AUTH_INSTANCENAME")
1541-
1542-
self.conn_impl._server_version = \
1543-
"%d.%d.%d.%d.%d" % self._get_version_tuple(buf)
1541+
self.conn_impl.server_version = self._get_version_tuple(buf)
1542+
self.conn_impl.supports_bool = \
1543+
buf._caps.ttc_field_version >= TNS_CCAP_FIELD_VERSION_23_1
15441544

15451545
cdef int _set_params(self, ConnectParamsImpl params,
15461546
Description description) except -1:

src/oracledb/thick_impl.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ cdef type PY_TYPE_LOB
6767
cdef type PY_TYPE_TIMEDELTA = datetime.timedelta
6868

6969
cdef dpiContext *driver_context = NULL
70+
cdef dpiVersionInfo client_version_info
7071

7172
driver_context_params = None
72-
client_version = None
7373

7474
include "impl/thick/buffer.pyx"
7575
include "impl/thick/connection.pyx"

0 commit comments

Comments
 (0)