Added support for binding native integers which has a slight performance

advantage.
This commit is contained in:
Anthony Tuininga 2016-02-03 19:20:12 -07:00
parent 573da4fc21
commit a3947fb244
4 changed files with 108 additions and 2 deletions

View File

@ -18,6 +18,12 @@ typedef struct {
} udt_NativeFloatVar;
typedef struct {
Variable_HEAD
long *data;
} udt_NativeIntVar;
//-----------------------------------------------------------------------------
// Declaration of number variable functions.
//-----------------------------------------------------------------------------
@ -26,6 +32,8 @@ static int NumberVar_SetValue(udt_NumberVar*, unsigned, PyObject*);
static PyObject *NumberVar_GetValue(udt_NumberVar*, unsigned);
static int NativeFloatVar_SetValue(udt_NativeFloatVar*, unsigned, PyObject*);
static PyObject *NativeFloatVar_GetValue(udt_NativeFloatVar*, unsigned);
static int NativeIntVar_SetValue(udt_NativeIntVar*, unsigned, PyObject*);
static PyObject *NativeIntVar_GetValue(udt_NativeIntVar*, unsigned);
//-----------------------------------------------------------------------------
@ -81,6 +89,31 @@ static PyTypeObject g_NativeFloatVarType = {
};
static PyTypeObject g_NativeIntVarType = {
PyVarObject_HEAD_INIT(NULL, 0)
"cx_Oracle.NATIVE_INT", // tp_name
sizeof(udt_NativeIntVar), // tp_basicsize
0, // tp_itemsize
0, // tp_dealloc
0, // tp_print
0, // tp_getattr
0, // tp_setattr
0, // tp_compare
0, // tp_repr
0, // tp_as_number
0, // tp_as_sequence
0, // tp_as_mapping
0, // tp_hash
0, // tp_call
0, // tp_str
0, // tp_getattro
0, // tp_setattro
0, // tp_as_buffer
Py_TPFLAGS_DEFAULT, // tp_flags
0 // tp_doc
};
//-----------------------------------------------------------------------------
// variable type declarations
//-----------------------------------------------------------------------------
@ -126,6 +159,27 @@ static udt_VariableType vt_NativeFloat = {
};
static udt_VariableType vt_NativeInteger = {
(InitializeProc) NULL,
(FinalizeProc) NULL,
(PreDefineProc) NULL,
(PostDefineProc) NULL,
(PreFetchProc) NULL,
(IsNullProc) NULL,
(SetValueProc) NativeIntVar_SetValue,
(GetValueProc) NativeIntVar_GetValue,
(GetBufferSizeProc) NULL,
&g_NativeIntVarType, // Python type
SQLT_INT, // Oracle type
SQLCS_IMPLICIT, // charset form
sizeof(long), // element length
0, // is character data
0, // is variable length
1, // can be copied
1 // can be in array
};
static udt_VariableType vt_Integer = {
(InitializeProc) NULL,
(FinalizeProc) NULL,
@ -594,3 +648,37 @@ static int NativeFloatVar_SetValue(
return 0;
}
//-----------------------------------------------------------------------------
// NativeIntVar_GetValue()
// Returns the value stored at the given array position as an integer.
//-----------------------------------------------------------------------------
static PyObject *NativeIntVar_GetValue(
udt_NativeIntVar *var, // variable to determine value for
unsigned pos) // array position
{
//printf("Getting native integer (value %ld)\n", var->data[pos]);
return PyInt_FromLong(var->data[pos]);
}
//-----------------------------------------------------------------------------
// NativeIntVar_SetValue()
// Set the value of the variable which should be a native integer.
//-----------------------------------------------------------------------------
static int NativeIntVar_SetValue(
udt_NativeIntVar *var, // variable to set value for
unsigned pos, // array position to set
PyObject *value) // value to set
{
if (!PyInt_Check(value)) {
PyErr_SetString(PyExc_TypeError, "expecting integer");
return -1;
}
var->data[pos] = PyInt_AsLong(value);
//printf("Setting native integer to value %ld:\n", var->data[pos]);
if (PyErr_Occurred())
return -1;
return 0;
}

View File

@ -388,7 +388,8 @@ static int Variable_Check(
#if ORACLE_VERSION_HEX >= ORACLE_VERSION(12,1)
Py_TYPE(object) == &g_BooleanVarType ||
#endif
Py_TYPE(object) == &g_NativeFloatVarType);
Py_TYPE(object) == &g_NativeFloatVarType ||
Py_TYPE(object) == &g_NativeIntVarType);
}
@ -470,6 +471,8 @@ static udt_VariableType *Variable_TypeByPythonType(
return &vt_Cursor;
if (type == (PyObject*) &g_NativeFloatVarType)
return &vt_NativeFloat;
if (type == (PyObject*) &g_NativeIntVarType)
return &vt_NativeInteger;
if (type == (PyObject*) &g_ObjectVarType)
return &vt_Object;
@ -606,6 +609,8 @@ static udt_VariableType *Variable_TypeByOracleDataType (
case SQLT_BDOUBLE:
case SQLT_IBDOUBLE:
return &vt_NativeFloat;
case SQLT_INT:
return &vt_NativeInteger;
case SQLT_NUM:
case SQLT_VNU:
return &vt_Float;

View File

@ -414,6 +414,7 @@ static PyObject *Module_Initialize(void)
MAKE_VARIABLE_TYPE_READY(&g_LongNCharVarType);
MAKE_VARIABLE_TYPE_READY(&g_NCLOBVarType);
MAKE_VARIABLE_TYPE_READY(&g_NativeFloatVarType);
MAKE_VARIABLE_TYPE_READY(&g_NativeIntVarType);
MAKE_VARIABLE_TYPE_READY(&g_IntervalVarType);
#if ORACLE_VERSION_HEX >= ORACLE_VERSION(12, 1)
MAKE_VARIABLE_TYPE_READY(&g_BooleanVarType);
@ -496,6 +497,7 @@ static PyObject *Module_Initialize(void)
ADD_TYPE_OBJECT("ROWID", &g_RowidVarType)
ADD_TYPE_OBJECT("STRING", &g_StringVarType)
ADD_TYPE_OBJECT("TIMESTAMP", &g_TimestampVarType)
ADD_TYPE_OBJECT("NATIVE_INT", &g_NativeIntVarType)
ADD_TYPE_OBJECT("NATIVE_FLOAT", &g_NativeFloatVarType)
#if ORACLE_VERSION_HEX >= ORACLE_VERSION(12, 1)
ADD_TYPE_OBJECT("BOOLEAN", &g_BooleanVarType)

View File

@ -766,7 +766,18 @@ Types
.. data:: NATIVE_FLOAT
This type object is used to describe columns in a database that are of type
binary_double or binary_float and is only available in Oracle 10g.
binary_double or binary_float.
.. note::
This type is an extension to the DB API definition.
.. data:: NATIVE_INT
This type object is used to bind integers using Oracle's native integer
support, rather than the standard number support, which improves
performance.
.. note::