Remove code specific to strings being 4000 characters now that Oracle… · dataSyman/python-cx_Oracle@faadbe4 · GitHub
Skip to content

Commit faadbe4

Browse files
Remove code specific to strings being 4000 characters now that Oracle 12c has
the ability to have strings up to 32k characters. This implies that using setinputsizes() is necessary if a long string type is desired as this will not occur automatically when the string exceeds 4000 characters. Tests are tidied up to remove the "p_" prefix from all bind variables.
1 parent fdde7da commit faadbe4

21 files changed

Lines changed: 442 additions & 505 deletions

Callback.c

Lines changed: 7 additions & 5 deletions

Environment.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,12 @@ typedef struct {
1414
int fixedWidth;
1515
char *encoding;
1616
char *nencoding;
17-
ub4 maxStringBytes;
1817
PyObject *cloneEnv;
1918
udt_Buffer numberToStringFormatBuffer;
2019
udt_Buffer numberFromStringFormatBuffer;
2120
udt_Buffer nlsNumericCharactersBuffer;
2221
} udt_Environment;
2322

24-
//-----------------------------------------------------------------------------
25-
// maximum number of characters/bytes applicable to strings/binaries
26-
//-----------------------------------------------------------------------------
27-
#define MAX_STRING_CHARS 4000
28-
#define MAX_BINARY_BYTES 4000
29-
3023
//-----------------------------------------------------------------------------
3124
// forward declarations
3225
//-----------------------------------------------------------------------------
@@ -82,7 +75,6 @@ static udt_Environment *Environment_New(
8275
env->errorHandle = NULL;
8376
env->fixedWidth = 1;
8477
env->maxBytesPerCharacter = 1;
85-
env->maxStringBytes = MAX_STRING_CHARS;
8678
env->cloneEnv = NULL;
8779
cxBuffer_Init(&env->numberToStringFormatBuffer);
8880
cxBuffer_Init(&env->numberFromStringFormatBuffer);
@@ -226,7 +218,6 @@ static udt_Environment *Environment_NewFromScratch(
226218
Py_DECREF(env);
227219
return NULL;
228220
}
229-
env->maxStringBytes = MAX_STRING_CHARS * env->maxBytesPerCharacter;
230221

231222
// acquire whether character set is fixed width
232223
status = OCINlsNumericInfoGet(env->handle, env->errorHandle,
@@ -275,7 +266,6 @@ static udt_Environment *Environment_Clone(
275266
if (!env)
276267
return NULL;
277268
env->maxBytesPerCharacter = cloneEnv->maxBytesPerCharacter;
278-
env->maxStringBytes = cloneEnv->maxStringBytes;
279269
env->fixedWidth = cloneEnv->fixedWidth;
280270
Py_INCREF(cloneEnv);
281271
env->cloneEnv = (PyObject*) cloneEnv;

StringVar.c

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ static udt_VariableType vt_String = {
190190
&g_StringVarType, // Python type
191191
SQLT_CHR, // Oracle type
192192
SQLCS_IMPLICIT, // charset form
193-
MAX_STRING_CHARS, // element length (default)
193+
4000, // element length (default)
194194
1, // is character data
195195
1, // is variable length
196196
1, // can be copied
@@ -211,7 +211,7 @@ static udt_VariableType vt_NationalCharString = {
211211
&g_UnicodeVarType, // Python type
212212
SQLT_CHR, // Oracle type
213213
SQLCS_NCHAR, // charset form
214-
MAX_STRING_CHARS, // element length (default)
214+
4000, // element length (default)
215215
1, // is character data
216216
1, // is variable length
217217
1, // can be copied
@@ -295,7 +295,7 @@ static udt_VariableType vt_Binary = {
295295
&g_BinaryVarType, // Python type
296296
SQLT_BIN, // Oracle type
297297
SQLCS_IMPLICIT, // charset form
298-
MAX_BINARY_BYTES, // element length (default)
298+
4000, // element length (default)
299299
0, // is character data
300300
1, // is variable length
301301
1, // can be copied
@@ -311,12 +311,18 @@ static int StringVar_Initialize(
311311
udt_StringVar *var, // variable to initialize
312312
udt_Cursor *cursor) // cursor to use
313313
{
314-
var->actualLength = (ub2*) PyMem_Malloc(var->allocatedElements *
315-
sizeof(ub2));
314+
ub4 i;
315+
316+
var->actualLength = (ACTUAL_LENGTH_TYPE *)
317+
PyMem_Malloc(var->allocatedElements * sizeof(ACTUAL_LENGTH_TYPE));
316318
if (!var->actualLength) {
317319
PyErr_NoMemory();
318320
return -1;
319321
}
322+
323+
for (i = 0; i < var->allocatedElements; i++)
324+
var->actualLength[i] = 0;
325+
320326
return 0;
321327
}
322328

@@ -335,17 +341,6 @@ static int StringVar_SetValue(
335341
// populate the buffer and confirm the maximum size is not exceeded
336342
if (cxBuffer_FromObject(&buffer, value, var->environment->encoding) < 0)
337343
return -1;
338-
if (var->type->isCharacterData
339-
&& buffer.numCharacters > MAX_STRING_CHARS) {
340-
cxBuffer_Clear(&buffer);
341-
PyErr_SetString(PyExc_ValueError, "string data too large");
342-
return -1;
343-
} else if (!var->type->isCharacterData
344-
&& buffer.size > MAX_BINARY_BYTES) {
345-
cxBuffer_Clear(&buffer);
346-
PyErr_SetString(PyExc_ValueError, "binary data too large");
347-
return -1;
348-
}
349344

350345
// ensure that the buffer is large enough
351346
if (buffer.size > var->bufferSize) {
@@ -356,7 +351,7 @@ static int StringVar_SetValue(
356351
}
357352

358353
// keep a copy of the string
359-
var->actualLength[pos] = (ub2) buffer.size;
354+
var->actualLength[pos] = (ACTUAL_LENGTH_TYPE) buffer.size;
360355
if (buffer.size)
361356
memcpy(var->data + var->bufferSize * pos, buffer.ptr, buffer.size);
362357
cxBuffer_Clear(&buffer);

Variable.c

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@
66
//-----------------------------------------------------------------------------
77
// define structure common to all variables
88
//-----------------------------------------------------------------------------
9+
#if ORACLE_VERSION_HEX >= ORACLE_VERSION(12,1)
10+
#define OCIBINDBYNAME OCIBindByName2
11+
#define OCIBINDBYPOS OCIBindByPos2
12+
#define OCIDEFINEBYPOS OCIDefineByPos2
13+
#define ACTUAL_LENGTH_TYPE ub4
14+
#else
15+
#define OCIBINDBYNAME OCIBindByName
16+
#define OCIBINDBYPOS OCIBindByPos
17+
#define OCIDEFINEBYPOS OCIDefineByPos
18+
#define ACTUAL_LENGTH_TYPE ub2
19+
#endif
20+
921
struct _udt_VariableType;
1022
#define Variable_HEAD \
1123
PyObject_HEAD \
@@ -24,7 +36,7 @@ struct _udt_VariableType;
2436
int isAllocatedInternally; \
2537
sb2 *indicator; \
2638
ub2 *returnCode; \
27-
ub2 *actualLength; \
39+
ACTUAL_LENGTH_TYPE *actualLength; \
2840
ub4 size; \
2941
ub4 bufferSize; \
3042
struct _udt_VariableType *type;
@@ -484,24 +496,18 @@ static udt_VariableType *Variable_TypeByValue(
484496
}
485497
if (cxString_Check(value)) {
486498
*size = cxString_GetSize(value);
487-
if (*size > MAX_STRING_CHARS)
488-
return &vt_LongString;
489499
return &vt_String;
490500
}
491501
#if PY_MAJOR_VERSION < 3
492502
if (PyUnicode_Check(value)) {
493503
*size = PyUnicode_GET_SIZE(value);
494-
if (*size > MAX_STRING_CHARS)
495-
return &vt_LongNationalCharString;
496504
return &vt_NationalCharString;
497505
}
498506
if (PyInt_Check(value))
499507
return &vt_Integer;
500508
#else
501509
if (PyBytes_Check(value)) {
502510
*size = PyBytes_GET_SIZE(value);
503-
if (*size > MAX_BINARY_BYTES)
504-
return &vt_LongBinary;
505511
return &vt_Binary;
506512
}
507513
#endif
@@ -517,8 +523,6 @@ static udt_VariableType *Variable_TypeByValue(
517523
return NULL;
518524
*size = temp.size;
519525
cxBuffer_Clear(&temp);
520-
if (*size > MAX_BINARY_BYTES)
521-
return &vt_LongBinary;
522526
return &vt_Binary;
523527
}
524528
if (PyDateTime_Check(value))
@@ -824,9 +828,7 @@ static udt_Variable *Variable_NewByType(
824828
size = PyInt_AsLong(value);
825829
if (PyErr_Occurred())
826830
return NULL;
827-
if (size > MAX_STRING_CHARS)
828-
varType = &vt_LongString;
829-
else varType = &vt_String;
831+
varType = &vt_String;
830832
return Variable_New(cursor, numElements, varType, size);
831833
}
832834

@@ -993,7 +995,7 @@ static udt_Variable *Variable_DefineHelper(
993995
}
994996

995997
// perform the define
996-
status = OCIDefineByPos(cursor->handle, &var->defineHandle,
998+
status = OCIDEFINEBYPOS(cursor->handle, &var->defineHandle,
997999
var->environment->errorHandle, position, var->data,
9981000
var->bufferSize, var->type->oracleType, var->indicator,
9991001
var->actualLength, var->returnCode, OCI_DEFAULT);
@@ -1058,14 +1060,14 @@ static int Variable_InternalBind(
10581060
var->environment->encoding) < 0)
10591061
return -1;
10601062
if (var->isArray) {
1061-
status = OCIBindByName(var->boundCursorHandle, &var->bindHandle,
1063+
status = OCIBINDBYNAME(var->boundCursorHandle, &var->bindHandle,
10621064
var->environment->errorHandle, (text*) buffer.ptr,
10631065
buffer.size, var->data, var->bufferSize,
10641066
var->type->oracleType, var->indicator, var->actualLength,
10651067
var->returnCode, var->allocatedElements,
10661068
&var->actualElements, OCI_DEFAULT);
10671069
} else {
1068-
status = OCIBindByName(var->boundCursorHandle, &var->bindHandle,
1070+
status = OCIBINDBYNAME(var->boundCursorHandle, &var->bindHandle,
10691071
var->environment->errorHandle, (text*) buffer.ptr,
10701072
buffer.size, var->data, var->bufferSize,
10711073
var->type->oracleType, var->indicator, var->actualLength,
@@ -1074,13 +1076,13 @@ static int Variable_InternalBind(
10741076
cxBuffer_Clear(&buffer);
10751077
} else {
10761078
if (var->isArray) {
1077-
status = OCIBindByPos(var->boundCursorHandle, &var->bindHandle,
1079+
status = OCIBINDBYPOS(var->boundCursorHandle, &var->bindHandle,
10781080
var->environment->errorHandle, var->boundPos, var->data,
10791081
var->bufferSize, var->type->oracleType, var->indicator,
10801082
var->actualLength, var->returnCode, var->allocatedElements,
10811083
&var->actualElements, OCI_DEFAULT);
10821084
} else {
1083-
status = OCIBindByPos(var->boundCursorHandle, &var->bindHandle,
1085+
status = OCIBINDBYPOS(var->boundCursorHandle, &var->bindHandle,
10841086
var->environment->errorHandle, var->boundPos, var->data,
10851087
var->bufferSize, var->type->oracleType, var->indicator,
10861088
var->actualLength, var->returnCode, 0, 0, OCI_DEFAULT);

test/3kNumberVar.py

Lines changed: 29 additions & 29 deletions

0 commit comments

Comments
 (0)