Skip to content

Commit 5732c5b

Browse files
Restored sharding support.
1 parent c003b91 commit 5732c5b

File tree

4 files changed

+113
-4
lines changed

4 files changed

+113
-4
lines changed

doc/src/release_notes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Thick Mode Changes
5454
allows for seamless transfer of extended data types.
5555
#) Fixed bug when calling :meth:`SodaDoc.getContent()` for SODA documents
5656
that do not contain JSON.
57+
#) Corrected support for sharding.
5758
#) Errors ``DPY-4011: the database or network closed the connection`` and
5859
``DPY-4024: call timeout of {timeout} ms exceeded`` now retain the original
5960
error message raised by the Oracle Client library.

src/oracledb/connection.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,15 @@ def __init__(
525525

526526
# create thin or thick implementation object
527527
if thin:
528+
if (
529+
params_impl.shardingkey is not None
530+
or params_impl.supershardingkey is not None
531+
):
532+
errors._raise_err(
533+
errors.ERR_FEATURE_NOT_SUPPORTED,
534+
feature="sharding",
535+
driver_type="thick",
536+
)
528537
if pool is not None:
529538
impl = pool_impl.acquire(params_impl)
530539
else:

src/oracledb/impl/thick/connection.pyx

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ cdef class ConnectionParams:
6464
uint32_t private_key_len
6565

6666
uint32_t num_app_context
67-
list app_context_bytes
67+
list bytes_references
6868
dpiAppContext *app_context
6969

7070
uint32_t num_sharding_key_columns
@@ -84,18 +84,72 @@ cdef class ConnectionParams:
8484
uint32_t *length) except -1:
8585
cdef bytes temp
8686
temp = value.encode()
87-
self.app_context_bytes.append(temp)
87+
self.bytes_references.append(temp)
8888
ptr[0] = temp
8989
length[0] = <uint32_t> len(temp)
9090

91+
cdef int _process_sharding_value(self, object value,
92+
dpiShardingKeyColumn *column) except -1:
93+
"""
94+
Process a sharding column value and place it in the format required by
95+
ODPI-C.
96+
"""
97+
cdef:
98+
dpiTimestamp* timestamp
99+
bytes temp
100+
if isinstance(value, str):
101+
temp = value.encode()
102+
self.bytes_references.append(temp)
103+
column.oracleTypeNum = DPI_ORACLE_TYPE_VARCHAR
104+
column.nativeTypeNum = DPI_NATIVE_TYPE_BYTES
105+
column.value.asBytes.ptr = temp
106+
column.value.asBytes.length = <uint32_t> len(temp)
107+
elif isinstance(value, (int, float, PY_TYPE_DECIMAL)):
108+
temp = str(value).encode()
109+
self.bytes_references.append(temp)
110+
column.oracleTypeNum = DPI_ORACLE_TYPE_NUMBER
111+
column.nativeTypeNum = DPI_NATIVE_TYPE_BYTES
112+
column.value.asBytes.ptr = temp
113+
column.value.asBytes.length = <uint32_t> len(temp)
114+
elif isinstance(value, bytes):
115+
self.bytes_references.append(value)
116+
column.oracleTypeNum = DPI_ORACLE_TYPE_RAW
117+
column.nativeTypeNum = DPI_NATIVE_TYPE_BYTES
118+
column.value.asBytes.ptr = <bytes> value
119+
column.value.asBytes.length = <uint32_t> len(value)
120+
elif isinstance(value, PY_TYPE_DATETIME):
121+
column.oracleTypeNum = DPI_ORACLE_TYPE_DATE
122+
column.nativeTypeNum = DPI_NATIVE_TYPE_TIMESTAMP
123+
timestamp = &column.value.asTimestamp
124+
memset(timestamp, 0, sizeof(dpiTimestamp))
125+
timestamp.year = cydatetime.datetime_year(value)
126+
timestamp.month = cydatetime.datetime_month(value)
127+
timestamp.day = cydatetime.datetime_day(value)
128+
timestamp.hour = cydatetime.datetime_hour(value)
129+
timestamp.minute = cydatetime.datetime_minute(value)
130+
timestamp.second = cydatetime.datetime_second(value)
131+
timestamp.fsecond = cydatetime.datetime_microsecond(value) * 1000
132+
elif isinstance(value, PY_TYPE_DATE):
133+
column.oracleTypeNum = DPI_ORACLE_TYPE_DATE
134+
column.nativeTypeNum = DPI_NATIVE_TYPE_TIMESTAMP
135+
timestamp = &column.value.asTimestamp
136+
memset(timestamp, 0, sizeof(dpiTimestamp))
137+
timestamp.year = cydatetime.date_year(value)
138+
timestamp.month = cydatetime.date_month(value)
139+
timestamp.day = cydatetime.date_day(value)
140+
else:
141+
errors._raise_err(errors.ERR_PYTHON_VALUE_NOT_SUPPORTED,
142+
type_name=type(value).__name__)
143+
91144
cdef process_appcontext(self, list entries):
92145
cdef:
93146
object namespace, name, value
94147
dpiAppContext *entry
95148
ssize_t num_bytes
96149
bytes temp
97150
uint32_t i
98-
self.app_context_bytes = []
151+
if self.bytes_references is None:
152+
self.bytes_references = []
99153
self.num_app_context = <uint32_t> len(entries)
100154
num_bytes = self.num_app_context * sizeof(dpiAppContext)
101155
self.app_context = <dpiAppContext*> cpython.PyMem_Malloc(num_bytes)
@@ -109,6 +163,29 @@ cdef class ConnectionParams:
109163
self._process_context_str(name, &entry.name, &entry.nameLength)
110164
self._process_context_str(value, &entry.value, &entry.valueLength)
111165

166+
cdef int process_sharding_key(self, list entries, bint is_super) except -1:
167+
"""
168+
Process the (super) sharding key and place it in the format required by
169+
ODPI-C.
170+
"""
171+
cdef:
172+
dpiShardingKeyColumn *columns
173+
uint32_t num_columns
174+
ssize_t num_bytes, i
175+
if self.bytes_references is None:
176+
self.bytes_references = []
177+
num_columns = <uint32_t> len(entries)
178+
num_bytes = num_columns * sizeof(dpiShardingKeyColumn)
179+
columns = <dpiShardingKeyColumn*> cpython.PyMem_Malloc(num_bytes)
180+
if is_super:
181+
self.super_sharding_key_columns = columns
182+
self.num_super_sharding_key_columns = num_columns
183+
else:
184+
self.sharding_key_columns = columns
185+
self.num_sharding_key_columns = num_columns
186+
for i, entry in enumerate(entries):
187+
self._process_sharding_value(entry, &columns[i])
188+
112189

113190
@cython.freelist(8)
114191
cdef class ThickXid:
@@ -331,6 +408,10 @@ cdef class ThickConnImpl(BaseConnImpl):
331408
params.tag_len = <uint32_t> len(params.tag)
332409
if user_params.appcontext:
333410
params.process_appcontext(user_params.appcontext)
411+
if user_params.shardingkey:
412+
params.process_sharding_key(user_params.shardingkey, False)
413+
if user_params.supershardingkey:
414+
params.process_sharding_key(user_params.supershardingkey, True)
334415
if user_params._token is not None \
335416
or user_params.access_token_callback is not None:
336417
token = user_params._get_token()
@@ -377,6 +458,14 @@ cdef class ThickConnImpl(BaseConnImpl):
377458
if user_params.appcontext:
378459
conn_params.appContext = params.app_context
379460
conn_params.numAppContext = params.num_app_context
461+
if user_params.shardingkey:
462+
conn_params.shardingKeyColumns = params.sharding_key_columns
463+
conn_params.numShardingKeyColumns = params.num_sharding_key_columns
464+
if user_params.supershardingkey:
465+
conn_params.superShardingKeyColumns = \
466+
params.super_sharding_key_columns
467+
conn_params.numSuperShardingKeyColumns = \
468+
params.num_super_sharding_key_columns
380469
if user_params.tag is not None:
381470
conn_params.tag = params.tag_ptr
382471
conn_params.tagLength = params.tag_len
@@ -405,7 +494,8 @@ cdef class ThickConnImpl(BaseConnImpl):
405494
_raise_from_info(&error_info)
406495
elif error_info.isWarning:
407496
self.warning = _create_new_from_info(&error_info)
408-
if conn_params.outNewSession and self.warning is None:
497+
if conn_params.outNewSession and pool_impl is not None \
498+
and self.warning is None:
409499
self.warning = pool_impl.warning
410500
if dpiConn_getServerVersion(self._handle, NULL, NULL,
411501
&version_info) < 0:

utils/templates/connection.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,15 @@ def __init__(
523523

524524
# create thin or thick implementation object
525525
if thin:
526+
if (
527+
params_impl.shardingkey is not None
528+
or params_impl.supershardingkey is not None
529+
):
530+
errors._raise_err(
531+
errors.ERR_FEATURE_NOT_SUPPORTED,
532+
feature="sharding",
533+
driver_type="thick",
534+
)
526535
if pool is not None:
527536
impl = pool_impl.acquire(params_impl)
528537
else:

0 commit comments

Comments
 (0)