Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 31 additions & 3 deletions src/include/conversions.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,37 @@ PyObject *create_class_instance_from_module(as_error *error_p,
// We return an unsigned long long because it should be able to fit all fixed-width int types up to uint64_t
// Returns -1 on error. Error indicator can be checked to verify if error occurred
// TODO: replace this with new API calls in Python 3.14
unsigned long long
convert_pyobject_to_fixed_width_integer_type(PyObject *pyobject,
unsigned long long max_bound);
unsigned long long convert_pyobject_to_unsigned_fixed_width_integer_type(
PyObject *pyobject, unsigned long long max_bound);

uint64_t convert_unsigned_long_long_into_uint64_t(as_error *err,
PyObject *pyobject,
const char *component);

int64_t convert_long_long_into_int64_t(as_error *err, PyObject *pyobject,
const char *component);

uint32_t convert_unsigned_long_into_uint32_t(as_error *err, PyObject *pyobject,
const char *component);

int32_t convert_long_into_int32_t(as_error *err, PyObject *pyobject,
const char *component);

int convert_long_into_int(as_error *err, PyObject *pyobject,
const char *component);

unsigned int convert_unsigned_long_into_enum(as_error *err, PyObject *py_long,
unsigned int max_enum_value,
const char *component);

uint16_t convert_unsigned_long_into_uint16_t(as_error *err, PyObject *pyobject,
const char *component);

int16_t convert_long_into_int16_t(as_error *err, PyObject *pyobject,
const char *component);

int64_t convert_pyobject_to_int64_t(PyObject *pyobject);

uint8_t convert_pyobject_to_uint8_t(PyObject *pyobject);

uint16_t convert_pyobject_to_uint16_t(PyObject *pyobject);
Expand Down
2 changes: 0 additions & 2 deletions src/include/query.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,6 @@ PyObject *AerospikeQuery_Get_Partitions_status(AerospikeQuery *self);
*/
PyObject *StoreUnicodePyObject(AerospikeQuery *self, PyObject *obj);

int64_t pyobject_to_int64(PyObject *py_obj);

// We need to share this with src/main/client/query.c because this function is no longer assigned
// to the query type's tp_new slot. We are trying to prevent users from using the query type's constructor directly
// to create a query instance.
Expand Down
18 changes: 5 additions & 13 deletions src/main/client/cdt_operation_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,19 +136,11 @@ as_status get_optional_int64_t(as_error *err, const char *key,
return AEROSPIKE_OK;
}

if (!PyLong_Check(py_val)) {
return as_error_update(err, AEROSPIKE_ERR_PARAM,
"%s must be an integer", key);
}

*i64_valptr = (int64_t)PyLong_AsLongLong(py_val);
if (PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
return as_error_update(err, AEROSPIKE_ERR_PARAM, "%s too large",
key);
}
return as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s",
key);
*i64_valptr = convert_pyobject_to_int64_t(py_val);
if (err->code != AEROSPIKE_OK) {
as_error_update(err, AEROSPIKE_ERR_PARAM,
"Unable to convert Python object to int64_t");
return err->code;
}

*found = true;
Expand Down
16 changes: 8 additions & 8 deletions src/main/client/operate.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,10 @@ as_status add_op(AerospikeClient *self, as_error *err,
goto CLEANUP;
}
if (PyLong_Check(py_index)) {
index = PyLong_AsLong(py_index);
index = convert_long_into_int(err, py_index, "py_index");
if (err->code != AEROSPIKE_OK) {
goto CLEANUP;
}
}
else {
as_error_update(err, AEROSPIKE_ERR_PARAM,
Expand Down Expand Up @@ -680,13 +683,10 @@ as_status add_op(AerospikeClient *self, as_error *err,
break;
case AS_OPERATOR_INCR:
if (PyLong_Check(py_value)) {
offset = PyLong_AsLong(py_value);
if (offset == -1 && PyErr_Occurred() && self->strict_types) {
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
as_error_update(err, AEROSPIKE_ERR_PARAM,
"integer value exceeds sys.maxsize");
goto CLEANUP;
}
offset = convert_unsigned_long_long_into_uint64_t(
err, py_value, "AS_OPERATOR_INCR");
if (err->code != AEROSPIKE_OK) {
goto CLEANUP;
}
as_operations_add_incr(ops, bin, offset);
}
Expand Down
23 changes: 17 additions & 6 deletions src/main/client/query.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,11 @@ static int query_where_add(as_query **query, as_predicate_type predicate,
"Bin must be a string or unicode");
return 1;
}
int64_t val = pyobject_to_int64(py_val1);

int64_t val = convert_long_long_into_int64_t(err, py_val1,
"query numeric index");
if (err->code != AEROSPIKE_OK) {
return 1;
}
as_query_where_init(*query, 1);
if (index_type == 0) {
as_query_where(*query, bin, as_equals(NUMERIC, val));
Expand Down Expand Up @@ -193,7 +196,11 @@ static int query_where_add(as_query **query, as_predicate_type predicate,
return 1;
}
if (PyLong_Check(py_val1)) {
min = pyobject_to_int64(py_val1);
min = convert_unsigned_long_long_into_uint64_t(err, py_val1,
"predicate max");
if (err->code != AEROSPIKE_OK) {
return 1;
}
}
else {
Py_XDECREF(py_ubin);
Expand All @@ -203,7 +210,11 @@ static int query_where_add(as_query **query, as_predicate_type predicate,
}

if (PyLong_Check(py_val2)) {
max = pyobject_to_int64(py_val2);
max = convert_unsigned_long_long_into_uint64_t(err, py_val2,
"predicate max");
if (err->code != AEROSPIKE_OK) {
return 1;
}
}
else {
Py_XDECREF(py_ubin);
Expand Down Expand Up @@ -405,15 +416,15 @@ static PyObject *AerospikeClient_QueryApply_Invoke(
}

long op = PyLong_AsLong(py_op);
if (op == -1 && PyErr_Occurred()) {
if (PyErr_Occurred()) {
as_error_update(&err, AEROSPIKE_ERR_PARAM,
"unknown predicate type");
goto CLEANUP;
}

as_index_datatype op_data =
(as_index_datatype)PyLong_AsLong(py_op_data);
if (op == -1 && PyErr_Occurred()) {
if (PyErr_Occurred()) {
as_error_update(&err, AEROSPIKE_ERR_PARAM,
"unknown index data type");
goto CLEANUP;
Expand Down
13 changes: 3 additions & 10 deletions src/main/client/remove.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,9 @@ PyObject *AerospikeClient_Remove_Invoke(AerospikeClient *self, PyObject *py_key,
if (py_gen) {
if (PyLong_Check(py_gen)) {
remove_policy_p->generation =
(uint16_t)PyLong_AsLong(py_gen);
}
else if (PyLong_Check(py_gen)) {
remove_policy_p->generation =
(uint16_t)PyLong_AsLongLong(py_gen);
if ((uint16_t)-1 == remove_policy_p->generation &&
PyErr_Occurred()) {
as_error_update(
&err, AEROSPIKE_ERR_PARAM,
"integer value for gen exceeds sys.maxsize");
convert_unsigned_long_into_uint16_t(&err, py_gen,
"generation");
if (err.code != AEROSPIKE_OK) {
goto CLEANUP;
}
}
Expand Down
33 changes: 18 additions & 15 deletions src/main/client/sec_index.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@
#include "exceptions.h"
#include "policy.h"

static bool getTypeFromPyObject(PyObject *py_datatype, int *idx_datatype,
as_error *err);
static bool getTypeFromPyObject(PyObject *py_datatype,
unsigned int *idx_datatype,
unsigned int max_enum_value, as_error *err);

static PyObject *createIndexWithCollectionType(
AerospikeClient *self, PyObject *py_policy, PyObject *py_ns,
Expand Down Expand Up @@ -244,11 +245,13 @@ PyObject *AerospikeClient_Index_Cdt_Create(AerospikeClient *self,
return NULL;
}

if (!getTypeFromPyObject(py_indextype, (int *)&index_type, &err)) {
if (!getTypeFromPyObject(py_indextype, (unsigned int *)&index_type,
AS_INDEX_TYPE_MAPVALUES, &err)) {
goto CLEANUP;
}

if (!getTypeFromPyObject(py_datatype, (int *)&data_type, &err)) {
if (!getTypeFromPyObject(py_datatype, (unsigned int *)&data_type,
AS_INDEX_BLOB, &err)) {
goto CLEANUP;
}

Expand Down Expand Up @@ -513,19 +516,18 @@ PyObject *AerospikeClient_Index_2dsphere_Create(AerospikeClient *self,
/*
* Convert a PyObject into an as_index_datatype, return False if the conversion fails for any reason.
*/
static bool getTypeFromPyObject(PyObject *py_datatype, int *idx_datatype,
as_error *err)
static bool getTypeFromPyObject(PyObject *py_datatype,
unsigned int *idx_datatype,
unsigned int max_enum_value, as_error *err)
{

long type = 0;
if (PyLong_Check(py_datatype)) {
type = PyLong_AsLong(py_datatype);
if (type == -1 && PyErr_Occurred()) {
if (PyErr_ExceptionMatches(PyExc_OverflowError)) {
as_error_update(err, AEROSPIKE_ERR_PARAM,
"integer value exceeds sys.maxsize");
goto CLEANUP;
}

*idx_datatype = convert_unsigned_long_into_enum(
err, py_datatype, max_enum_value, "for getTypeFromPyObject");
if (err->code != AEROSPIKE_OK) {
goto CLEANUP;
}
}
else {
Expand All @@ -534,7 +536,7 @@ static bool getTypeFromPyObject(PyObject *py_datatype, int *idx_datatype,
goto CLEANUP;
}

*idx_datatype = type;
*idx_datatype = (unsigned int)type;

CLEANUP:
if (err->code != AEROSPIKE_OK) {
Expand All @@ -558,7 +560,8 @@ static PyObject *createIndexWithCollectionType(
as_error err;
as_error_init(&err);

if (!getTypeFromPyObject(py_datatype, (int *)&data_type, &err)) {
if (!getTypeFromPyObject(py_datatype, (unsigned int *)&data_type,
(unsigned int)AS_INDEX_BLOB, &err)) {
return NULL;
}

Expand Down
19 changes: 3 additions & 16 deletions src/main/client/truncate.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ PyObject *AerospikeClient_Truncate(AerospikeClient *self, PyObject *args,
PyObject *py_nanos = NULL;
PyObject *py_policy = NULL;
PyObject *ret_val = NULL;
long long temp_long;
as_error err;
uint64_t nanos = 1; // If assignment fails, this will cause an error
char *namespace = NULL;
Expand Down Expand Up @@ -126,21 +125,9 @@ PyObject *AerospikeClient_Truncate(AerospikeClient *self, PyObject *args,

// Start conversion of the nanosecond parameter
if (PyLong_Check(py_nanos)) {

temp_long = PyLong_AsLongLong(py_nanos);
// There was a negative number outside of the range of - 2 ^ 63
if (temp_long < 0 && !PyErr_Occurred()) {
as_error_update(&err, AEROSPIKE_ERR_PARAM,
"Nanoseconds must be a positive value");
goto CLEANUP;
}
// Its possible that this is a valid uint64 between 2 ^ 63 and 2^64 -1
PyErr_Clear();
nanos = (uint64_t)PyLong_AsUnsignedLongLong(py_nanos);

if (PyErr_Occurred()) {
as_error_update(&err, AEROSPIKE_ERR_PARAM,
"Nanoseconds value too large");
nanos = convert_unsigned_long_long_into_uint64_t(&err, py_nanos,
"truncate");
if (err.code) {
goto CLEANUP;
}
}
Expand Down
Loading
Loading