Skip to content

Commit

Permalink
Fixed bug when a connect descriptor is used that doesn't define any
Browse files Browse the repository at this point in the history
addresses (#339).
  • Loading branch information
anthony-tuininga committed May 24, 2024
1 parent 4b9bb26 commit 5d0a183
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 14 deletions.
3 changes: 3 additions & 0 deletions doc/src/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ Thin Mode Changes
(`issue 336 <https://github.com/oracle/python-oracledb/issues/336>`__).
#) Fixed bug when fetching LOBs after an exception has been raised
(`issue 338 <https://github.com/oracle/python-oracledb/issues/338>`__).
#) Fixed bug when a connect descriptor is used that doesn't define any
addresses
(`issue 339 <https://github.com/oracle/python-oracledb/issues/339>`__).
#) Fixed bug in statement cache when the maximum number of cursors is unknown
due to the database not being open.
#) Fixed bug in handling redirect data with small SDU sizes.
Expand Down
4 changes: 3 additions & 1 deletion src/oracledb/base_impl.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ cdef class Description(ConnectParamsNode):
cdef class DescriptionList(ConnectParamsNode):

cdef str build_connect_string(self)
cdef list get_addresses(self)


cdef class ConnectParamsImpl:
Expand Down Expand Up @@ -430,7 +431,8 @@ cdef class ConnectParamsImpl:
cdef int _parse_connect_string(self, str connect_string) except -1
cdef int _parse_easy_connect_string(self, str connect_string,
object match) except -1
cdef int _process_connect_descriptor(self, dict args) except -1
cdef int _process_connect_descriptor(self, str connecte_string,
dict args) except -1
cdef int _set_access_token(self, object val, int error_num) except -1
cdef int _set_access_token_param(self, object val) except -1
cdef int _set_new_password(self, str password) except -1
Expand Down
4 changes: 4 additions & 0 deletions src/oracledb/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ def _raise_err(
ERR_CURSOR_HAS_BEEN_CLOSED = 2046
ERR_INVALID_LOB_AMOUNT = 2047
ERR_DML_RETURNING_DUP_BINDS = 2048
ERR_MISSING_ADDRESS = 2049

# error numbers that result in NotSupportedError
ERR_TIME_NOT_SUPPORTED = 3000
Expand Down Expand Up @@ -576,6 +577,9 @@ def _raise_err(
"internal error: unknown protocol message type {message_type} "
"at position {position}"
),
ERR_MISSING_ADDRESS: (
"no addresses are defined in connect descriptor: {connect_string}"
),
ERR_MISSING_BIND_VALUE: (
'a bind variable replacement value for placeholder ":{name}" was '
"not provided"
Expand Down
38 changes: 25 additions & 13 deletions src/oracledb/impl/base/connect_params.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ cdef class ConnectParamsImpl:
# to be a full connect descriptor
if connect_string.startswith("("):
_parse_connect_descriptor(connect_string, args)
return self._process_connect_descriptor(args)
return self._process_connect_descriptor(connect_string, args)

# otherwise, see if the connect string is an EasyConnect string
m = re.search(EASY_CONNECT_PATTERN, connect_string)
Expand All @@ -342,7 +342,7 @@ cdef class ConnectParamsImpl:
self._parse_easy_connect_string(connect_string, m)
else:
_parse_connect_descriptor(connect_string, args)
self._process_connect_descriptor(args)
self._process_connect_descriptor(connect_string, args)

cdef int _parse_easy_connect_string(self, str connect_string,
object match) except -1:
Expand Down Expand Up @@ -382,26 +382,28 @@ cdef class ConnectParamsImpl:
self.description_list = DescriptionList()
self.description_list.children.append(description)

cdef int _process_connect_descriptor(self, dict args) except -1:
cdef int _process_connect_descriptor(self, str connect_string,
dict args) except -1:
"""
Internal method used for processing the parsed connect descriptor into
the set of DescriptionList, Description, AddressList and Address
container objects.
"""
cdef:
DescriptionList description_list
AddressList address_list
Description description
Address address
self.description_list = DescriptionList()
description_list = DescriptionList()
list_args = args.get("description_list")
if list_args is not None:
self.description_list.set_from_args(list_args)
description_list.set_from_args(list_args)
else:
list_args = args
for desc_args in list_args.get("description", [list_args]):
description = self._default_description.copy()
description.set_from_description_args(desc_args)
self.description_list.children.append(description)
description_list.children.append(description)
sub_args = desc_args.get("connect_data")
if sub_args is not None:
description.set_from_connect_data_args(sub_args)
Expand All @@ -416,6 +418,10 @@ cdef class ConnectParamsImpl:
address = self._default_address.copy()
address.set_from_args(addr_args)
address_list.children.append(address)
if not description_list.get_addresses():
errors._raise_err(errors.ERR_MISSING_ADDRESS,
connect_string=connect_string)
self.description_list = description_list

cdef int _set_access_token(self, object val, int error_num) except -1:
"""
Expand Down Expand Up @@ -513,13 +519,7 @@ cdef class ConnectParamsImpl:
"""
Return a list of the stored addresses.
"""
cdef:
AddressList addr_list
Description desc
Address addr
return [addr for desc in self.description_list.children \
for addr_list in desc.children \
for addr in addr_list.children]
return self.description_list.get_addresses()

def get_connect_string(self):
"""
Expand Down Expand Up @@ -980,6 +980,18 @@ cdef class DescriptionList(ConnectParamsNode):
return parts[0]
return f'(DESCIPTION_LIST={"".join(parts)})'

cdef list get_addresses(self):
"""
Return a list of the stored addresses.
"""
cdef:
AddressList addr_list
Description desc
Address addr
return [addr for desc in self.children \
for addr_list in desc.children \
for addr in addr_list.children]

def set_from_args(self, dict args):
"""
Set paramter values from an argument dictionary or a (DESCRIPTION_LIST)
Expand Down
28 changes: 28 additions & 0 deletions tests/test_4500_connect_params.py
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,34 @@ def test_4545(self):
params.set(use_tcp_fast_open=1)
self.assertTrue(params.use_tcp_fast_open)

def test_4546(self):
"4546 - test connect descriptor without addresses defined"
params = oracledb.ConnectParams()
host = "host_4546"
port = 4546
service_name = "service_name_4546"
ok_container_names = ("DESCRIPTION", "ADDRESS")
options = [
("DESRIPTION", "ADDRESS"),
ok_container_names,
("DESCRIPTION", "ADRESS"),
]
for option in options:
desc_name, addr_name = option
connect_string = (
f"({desc_name}=({addr_name}=(PROTOCOL=TCP)(HOST={host})"
f"(PORT={port}))(CONNECT_DATA=(SERVICE_NAME={service_name})))"
)
params = oracledb.ConnectParams()
if option == ok_container_names:
params.parse_connect_string(connect_string)
self.assertEqual(params.host, host)
self.assertEqual(params.port, port)
self.assertEqual(params.service_name, service_name)
else:
with self.assertRaisesFullCode("DPY-2049"):
params.parse_connect_string(connect_string)


if __name__ == "__main__":
test_env.run_test_cases()

0 comments on commit 5d0a183

Please sign in to comment.