@@ -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 )
114191cdef 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 :
0 commit comments