From 0fa3ed2c5d5986937131f94d1b123398cd8a37e8 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 9 Jan 2026 15:32:04 -0800 Subject: [PATCH 01/99] First pass at refactoring. Many memory leaks present --- src/main/client/cdt_list_operate.c | 2072 ++++------------------------ 1 file changed, 277 insertions(+), 1795 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index ca83b51c52..fa8fb6a0c3 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -30,211 +30,6 @@ #include "cdt_list_operations.h" #include "cdt_operation_utils.h" -static as_status add_op_list_create(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_append(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_append_items(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_insert(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_insert_items(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_increment(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_size(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_pop(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_pop_range(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_remove(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_remove_range(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_clear(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_get(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_get_range(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_trim(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_set(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -/* NEW CDT LIST OPERATIONS Post 3.16.0.1*/ -/* GET BY*/ -static as_status add_op_list_get_by_index(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_vector *unicodeStrVector, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status -add_op_list_get_by_index_range(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_get_by_rank(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_vector *unicodeStrVector, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status -add_op_list_get_by_rank_range(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_get_by_value(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -static as_status -add_op_list_get_by_value_list(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type); - -static as_status -add_op_list_get_by_value_range(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type); - -/* remove by*/ - -static as_status -add_op_list_remove_by_index(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_remove_by_index_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_vector *unicodeStrVector, as_operations *ops, - as_static_pool *static_pool, int serializer_type); - -static as_status -add_op_list_remove_by_rank(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_remove_by_rank_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_vector *unicodeStrVector, as_operations *ops, - as_static_pool *static_pool, int serializer_type); - -static as_status -add_op_list_remove_by_value(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type); - -static as_status add_op_list_remove_by_value_list( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_vector *unicodeStrVector, as_operations *ops, - as_static_pool *static_pool, int serializer_type); - -static as_status add_op_list_remove_by_value_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type); - -/* Set Order*/ -static as_status add_op_list_set_order(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -/* List sort*/ -static as_status add_op_list_sort(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type); - -/* Server 4.3.0 relative operations*/ - -static as_status add_add_op_list_remove_by_value_rel_rank_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type); - -static as_status add_add_op_list_get_by_value_rel_rank_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type); -/* End forwards*/ as_status add_new_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, as_vector *unicodeStrVector, as_static_pool *static_pool, as_operations *ops, @@ -248,1671 +43,358 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, return err->code; } + as_list_policy list_policy; + bool policy_in_use = false; + switch (operation_code) { case OP_LIST_APPEND: - return add_op_list_append(self, err, bin, op_dict, ops, static_pool, - serializer_type); + case OP_LIST_APPEND_ITEMS: + case OP_LIST_INSERT: + case OP_LIST_INSERT_ITEMS: + case OP_LIST_INCREMENT: + case OP_LIST_SET: + if (get_list_policy(err, op_dict, &list_policy, &policy_in_use, + self->validate_keys) != AEROSPIKE_OK) { + return err->code; + } + break; + } + as_val *val = NULL; + switch (operation_code) { + case OP_LIST_GET_BY_VALUE: + case OP_LIST_GET_BY_VALUE_LIST: + case OP_LIST_REMOVE_BY_VALUE: case OP_LIST_APPEND_ITEMS: - return add_op_list_append_items(self, err, bin, op_dict, ops, - static_pool, serializer_type); + case OP_LIST_INSERT: + case OP_LIST_INCREMENT: + case OP_LIST_SET: + case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: + if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, + serializer_type, true) != AEROSPIKE_OK) { + return err->code; + } + break; + } - case OP_LIST_SIZE: - return add_op_list_size(self, err, bin, op_dict, ops, static_pool, - serializer_type); + int64_t count; + bool range_specified = false; + switch (operation_code) { + case OP_LIST_POP_RANGE: + if (get_int64_t(err, AS_PY_VAL_KEY, op_dict, &count) != AEROSPIKE_OK) { + return err->code; + } + break; + case OP_LIST_GET_BY_INDEX_RANGE: + if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, + &range_specified) != AEROSPIKE_OK) { + return err->code; + } + break; + } - case OP_LIST_INSERT: - return add_op_list_insert(self, err, bin, op_dict, ops, static_pool, - serializer_type); + int return_type = AS_LIST_RETURN_VALUE; + if (OP_LIST_GET_BY_INDEX <= operation_code <= + OP_LIST_REMOVE_BY_VALUE_RANGE) { + if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { + return err->code; + } + } - case OP_LIST_INSERT_ITEMS: - return add_op_list_insert_items(self, err, bin, op_dict, ops, - static_pool, serializer_type); + int64_t index; + if (operation_code == OP_LIST_POP) { + if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != + AEROSPIKE_OK) { + return err->code; + } + } - case OP_LIST_INCREMENT: - return add_op_list_increment(self, err, bin, op_dict, ops, static_pool, - serializer_type); + bool ctx_in_use = false; + as_cdt_ctx ctx; + // TODO: not all operations may take in ctx param + if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, + serializer_type) != AEROSPIKE_OK) { + return err->code; + } - case OP_LIST_POP: - return add_op_list_pop(self, err, bin, op_dict, ops, static_pool, - serializer_type); + int64_t rank; + switch (operation_code) { + case OP_LIST_GET_BY_RANK: + if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { + return err->code; + } + } - case OP_LIST_POP_RANGE: - return add_op_list_pop_range(self, err, bin, op_dict, ops, static_pool, - serializer_type); + as_list *value_list = NULL; + switch (operation_code) { + case OP_LIST_REMOVE_BY_VALUE_LIST: + if (get_val_list(self, err, AS_PY_VALUES_KEY, op_dict, &value_list, + static_pool, serializer_type) != AEROSPIKE_OK) { + return err->code; + } + break; + } - case OP_LIST_REMOVE: - return add_op_list_remove(self, err, bin, op_dict, ops, static_pool, - serializer_type); + as_val *val_begin = NULL; + as_val *val_end = NULL; + if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val_begin, + static_pool, serializer_type, false) != AEROSPIKE_OK) { + return err->code; + } - case OP_LIST_REMOVE_RANGE: - return add_op_list_remove_range(self, err, bin, op_dict, ops, - static_pool, serializer_type); + if (get_asval(self, err, AS_PY_VAL_END_KEY, op_dict, &val_end, static_pool, + serializer_type, false) != AEROSPIKE_OK) { + return err->code; + } - case OP_LIST_CLEAR: - return add_op_list_clear(self, err, bin, op_dict, ops, static_pool, - serializer_type); + int64_t order_type_int; + if (operation_code == OP_LIST_CREATE || operation_code == OP_LIST_SORT) { + if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != + AEROSPIKE_OK) { + return err->code; + } + } + bool success = false; + switch (operation_code) { + case OP_LIST_SIZE: + success = as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL)); + break; + case OP_LIST_POP: + success = + as_operations_list_pop(ops, bin, (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_POP_RANGE: + success = as_operations_list_pop_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_REMOVE: + success = as_operations_list_remove(ops, bin, + (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_REMOVE_RANGE: + success = as_operations_list_remove_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_CLEAR: + success = + as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL)); + break; case OP_LIST_SET: - return add_op_list_set(self, err, bin, op_dict, ops, static_pool, - serializer_type); - + success = as_operations_list_set(ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), + index, val); + break; case OP_LIST_GET: - return add_op_list_get(self, err, bin, op_dict, ops, static_pool, - serializer_type); - + success = + as_operations_list_get(ops, bin, (ctx_in_use ? &ctx : NULL), index); + break; case OP_LIST_GET_RANGE: - return add_op_list_get_range(self, err, bin, op_dict, ops, static_pool, - serializer_type); - + success = as_operations_list_get_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; case OP_LIST_TRIM: - return add_op_list_trim(self, err, bin, op_dict, ops, static_pool, - serializer_type); - /***** New List ops****/ - + success = as_operations_list_trim(ops, bin, (ctx_in_use ? &ctx : NULL), + index, (uint64_t)count); case OP_LIST_GET_BY_INDEX: { - return add_op_list_get_by_index(self, err, bin, op_dict, - unicodeStrVector, ops, static_pool, - serializer_type); + success = as_operations_list_get_by_index( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); } case OP_LIST_GET_BY_INDEX_RANGE: { - return add_op_list_get_by_index_range(self, err, bin, op_dict, - unicodeStrVector, ops, - static_pool, serializer_type); - } + if (range_specified) { + success = as_operations_list_get_by_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_get_by_index_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + } case OP_LIST_GET_BY_RANK: { - return add_op_list_get_by_rank(self, err, bin, op_dict, - unicodeStrVector, ops, static_pool, - serializer_type); + success = as_operations_list_get_by_rank( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); } case OP_LIST_GET_BY_RANK_RANGE: { - return add_op_list_get_by_rank_range(self, err, bin, op_dict, - unicodeStrVector, ops, static_pool, - serializer_type); + if (range_specified) { + success = as_operations_list_get_by_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_get_by_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + } } case OP_LIST_GET_BY_VALUE: { - return add_op_list_get_by_value(self, err, bin, op_dict, ops, - static_pool, serializer_type); + success = as_operations_list_get_by_value( + ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); } - case OP_LIST_GET_BY_VALUE_LIST: { - return add_op_list_get_by_value_list(self, err, bin, op_dict, - unicodeStrVector, ops, static_pool, - serializer_type); + success = as_operations_list_get_by_value_list( + ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); } case OP_LIST_GET_BY_VALUE_RANGE: { - return add_op_list_get_by_value_range(self, err, bin, op_dict, - unicodeStrVector, ops, - static_pool, serializer_type); + success = as_operations_list_get_by_value_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, + return_type); } case OP_LIST_REMOVE_BY_INDEX: { - return add_op_list_remove_by_index(self, err, bin, op_dict, - unicodeStrVector, ops, static_pool, - serializer_type); + success = as_operations_list_remove_by_index( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + break; } case OP_LIST_REMOVE_BY_INDEX_RANGE: { - return add_op_list_remove_by_index_range(self, err, bin, op_dict, - unicodeStrVector, ops, - static_pool, serializer_type); + if (range_specified) { + success = as_operations_list_remove_by_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_remove_by_index_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + } } case OP_LIST_REMOVE_BY_RANK: { - return add_op_list_remove_by_rank(self, err, bin, op_dict, - unicodeStrVector, ops, static_pool, - serializer_type); + success = as_operations_list_remove_by_rank( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + break; } case OP_LIST_REMOVE_BY_RANK_RANGE: { - return add_op_list_remove_by_rank_range(self, err, bin, op_dict, - unicodeStrVector, ops, - static_pool, serializer_type); + if (range_specified) { + success = as_operations_list_remove_by_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_remove_by_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + } } case OP_LIST_REMOVE_BY_VALUE: { - return add_op_list_remove_by_value(self, err, bin, op_dict, - unicodeStrVector, ops, static_pool, - serializer_type); + success = as_operations_list_remove_by_value( + ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + break; } case OP_LIST_REMOVE_BY_VALUE_LIST: { - return add_op_list_remove_by_value_list(self, err, bin, op_dict, - unicodeStrVector, ops, - static_pool, serializer_type); - } + success = as_operations_list_remove_by_value_list( + ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + } break; case OP_LIST_REMOVE_BY_VALUE_RANGE: { - return add_op_list_remove_by_value_range(self, err, bin, op_dict, ops, - static_pool, serializer_type); + success = as_operations_list_remove_by_value_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, + return_type); } case OP_LIST_SET_ORDER: { - return add_op_list_set_order(self, err, bin, op_dict, ops, static_pool, - serializer_type); + success = + as_operations_list_set_order(ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_order)order_type_int); + break; } case OP_LIST_SORT: { - return add_op_list_sort(self, err, bin, op_dict, ops, static_pool, - serializer_type); - } + int64_t sort_flags; - case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: { - return add_add_op_list_remove_by_value_rel_rank_range( - self, err, bin, op_dict, ops, static_pool, serializer_type); + if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != + AEROSPIKE_OK) { + return err->code; + } + success = as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_sort_flags)sort_flags); + break; } case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { - return add_add_op_list_get_by_value_rel_rank_range( - self, err, bin, op_dict, ops, static_pool, serializer_type); } case OP_LIST_CREATE: { - return add_op_list_create(self, err, bin, op_dict, ops, static_pool, - serializer_type); - } - - default: - // This should never be possible since we only get here if we know that the operation is valid. - return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); - } - - return err->code; -} - -static as_status add_op_list_get_by_index(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_vector *unicodeStrVector, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t index; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_get_by_index(ops, bin, (ctx_in_use ? &ctx : NULL), - index, return_type)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add get_by_list_index operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status -add_op_list_get_by_index_range(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type) -{ - int64_t index; - int64_t count; - bool range_specified = false; - bool success = false; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - /* Get the count of items, and store whether it was found in range_specified*/ - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &range_specified) != AEROSPIKE_OK) { - return err->code; - } - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (range_specified) { - success = as_operations_list_get_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_get_by_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } - - if (!success) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add get_by_list_index_range operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_get_by_rank(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_vector *unicodeStrVector, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t rank; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } + bool pad, persist_index; + if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != + AEROSPIKE_OK) { + return err->code; + } - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } + if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, + &persist_index) != AEROSPIKE_OK) { + return err->code; + } - if (!as_operations_list_get_by_rank(ops, bin, (ctx_in_use ? &ctx : NULL), - rank, return_type)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add get_by_list_index operation"); + success = as_operations_list_create_all( + ops, bin, (ctx_in_use ? &ctx : NULL), (as_list_order)order_type_int, + pad, persist_index); + break; } + case OP_LIST_APPEND: + success = as_operations_list_append( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), val); + break; + case OP_LIST_APPEND_ITEMS: + success = as_operations_list_append_items( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), value_list); + break; + case OP_LIST_INSERT: + success = as_operations_list_insert( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_INSERT_ITEMS: + success = as_operations_list_insert_items( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, value_list); + case OP_LIST_INCREMENT: + success = as_operations_list_increment( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: + if (range_specified) { + if (!as_operations_list_remove_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + (uint64_t)count, return_type)) { + as_cdt_ctx_destroy(&ctx); + return as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add list remove by value " + "rank relative operation"); + } + } + else { + if (!as_operations_list_remove_by_value_rel_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + return_type)) { + as_cdt_ctx_destroy(&ctx); + return as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add list remove by value " + "rank relative operation"); + } + } + break; - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); + default: { + // This should never be possible since we only get here if we know that the operation is valid. + return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); } - - return err->code; -} - -static as_status -add_op_list_get_by_rank_range(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type) -{ - int64_t rank; - int64_t count; - bool range_specified = false; - bool success = false; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; } - /* Get the count of items, and store whether it was found in range_specified*/ - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &range_specified) != AEROSPIKE_OK) { - return err->code; - } - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } + if (!success) { + // TODO: regression in error message + as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add operation"); + } - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { return err->code; } - - if (range_specified) { - success = as_operations_list_get_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_get_by_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } - - if (!success) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_get_by_rank_range operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_get_by_value(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - as_val *val = NULL; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to convert ctx list"); - } - - if (!as_operations_list_get_by_value(ops, bin, (ctx_in_use ? &ctx : NULL), - val, return_type)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_get_by_value operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status -add_op_list_get_by_value_list(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type) -{ - as_list *value_list = NULL; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_val_list(self, err, AS_PY_VALUES_KEY, op_dict, &value_list, - static_pool, serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - /* Failed to add the operation, we need to destroy the list of values*/ - as_val_destroy(value_list); - return err->code; - } - - if (!as_operations_list_get_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type)) { - /* Failed to add the operation, we need to destroy the list of values*/ - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_get_by_value_list operation"); - as_val_destroy(value_list); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status -add_op_list_get_by_value_range(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type) -{ - as_val *val_begin = NULL; - as_val *val_end = NULL; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - int return_type = AS_LIST_RETURN_VALUE; - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val_begin, - static_pool, serializer_type, false) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_END_KEY, op_dict, &val_end, static_pool, - serializer_type, false) != AEROSPIKE_OK) { - goto error; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - goto error; - } - - if (!as_operations_list_get_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, - return_type)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_get_by_value_range operation"); - goto error; - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; - -error: - /* Free the as_vals if they exists*/ - if (val_begin) { - as_val_destroy(val_begin); - } - - if (val_end) { - as_val_destroy(val_end); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status -add_op_list_remove_by_index(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type) -{ - int64_t index; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_remove_by_index( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add remove_by_list_index operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_remove_by_index_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_vector *unicodeStrVector, as_operations *ops, - as_static_pool *static_pool, int serializer_type) -{ - int64_t index; - int64_t count; - bool range_specified = false; - bool success = false; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - /* Get the count of items, and store whether it was found in range_specified*/ - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &range_specified) != AEROSPIKE_OK) { - return err->code; - } - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (range_specified) { - success = as_operations_list_remove_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_remove_by_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } - - if (!success) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add remove_by_list_index_range operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status -add_op_list_remove_by_rank(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type) -{ - int64_t rank; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_remove_by_rank(ops, bin, (ctx_in_use ? &ctx : NULL), - rank, return_type)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_remove_by_rank operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_remove_by_rank_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_vector *unicodeStrVector, as_operations *ops, - as_static_pool *static_pool, int serializer_type) -{ - int64_t rank; - int64_t count; - bool range_specified = false; - bool success = false; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - /* Get the count of items, and store whether it was found in range_specified*/ - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &range_specified) != AEROSPIKE_OK) { - return err->code; - } - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (range_specified) { - success = as_operations_list_remove_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_remove_by_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } - - if (!success) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_remove_by_rank_range operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status -add_op_list_remove_by_value(AerospikeClient *self, as_error *err, char *bin, - PyObject *op_dict, as_vector *unicodeStrVector, - as_operations *ops, as_static_pool *static_pool, - int serializer_type) -{ - as_val *val = NULL; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - as_val_destroy(val); - return err->code; - } - - if (!as_operations_list_remove_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_remove_by_value operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_remove_by_value_list( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_vector *unicodeStrVector, as_operations *ops, - as_static_pool *static_pool, int serializer_type) -{ - as_list *value_list = NULL; - int return_type = AS_LIST_RETURN_VALUE; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_val_list(self, err, AS_PY_VALUES_KEY, op_dict, &value_list, - static_pool, serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - /* Failed to convert ctx, we need to destroy the list of values*/ - as_val_destroy(value_list); - return err->code; - } - - if (!as_operations_list_remove_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type)) { - /* Failed to add the operation, we need to destroy the list of values*/ - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_get_by_value_list operation"); - as_val_destroy(value_list); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_remove_by_value_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type) -{ - as_val *val_begin = NULL; - as_val *val_end = NULL; - bool ctx_in_use = false; - as_cdt_ctx ctx; - int return_type = AS_LIST_RETURN_VALUE; - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val_begin, - static_pool, serializer_type, false) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_END_KEY, op_dict, &val_end, static_pool, - serializer_type, false) != AEROSPIKE_OK) { - goto error; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - goto error; - } - - if (!as_operations_list_remove_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, - return_type)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_remove_by_value_range operation"); - goto error; - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; - -error: - /* Free the as_vals if they exist */ - if (val_begin) { - as_val_destroy(val_begin); - } - - if (val_end) { - as_val_destroy(val_end); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_set_order(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t order_type_int; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != - AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_set_order(ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_order)order_type_int)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_set_order operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_sort(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t sort_flags; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != - AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_sort_flags)sort_flags)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_sort operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_create(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t order_type_int; - as_cdt_ctx ctx; - bool ctx_in_use = false; - bool pad, persist_index; - - if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != - AEROSPIKE_OK) { - return err->code; - } - - if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != AEROSPIKE_OK) { - return err->code; - } - - if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, - &persist_index) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - bool add_op_successful = as_operations_list_create_all( - ops, bin, (ctx_in_use ? &ctx : NULL), (as_list_order)order_type_int, - pad, persist_index); - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - if (add_op_successful) { - return AEROSPIKE_OK; - } - else { - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_create operation"); - } -} - -static as_status add_op_list_append(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - as_val *val = NULL; - as_list_policy list_policy; - bool policy_in_use = false; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_list_policy(err, op_dict, &list_policy, &policy_in_use, - self->validate_keys) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - as_val_destroy(val); - return err->code; - } - - if (!as_operations_list_append(ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), - val)) { - as_val_destroy(val); - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_append operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_append_items(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - as_list *items_list = NULL; - as_list_policy list_policy; - bool policy_in_use = false; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_list_policy(err, op_dict, &list_policy, &policy_in_use, - self->validate_keys) != AEROSPIKE_OK) { - return err->code; - } - - if (get_val_list(self, err, AS_PY_VAL_KEY, op_dict, &items_list, - static_pool, serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - as_val_destroy(items_list); - return err->code; - } - - if (!as_operations_list_append_items(ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), - items_list)) { - as_val_destroy(items_list); - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_append_items operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_insert(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - as_val *val = NULL; - int64_t index; - as_list_policy list_policy; - bool policy_in_use = false; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - if (get_list_policy(err, op_dict, &list_policy, &policy_in_use, - self->validate_keys) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - as_val_destroy(val); - return err->code; - } - - if (!as_operations_list_insert(ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, - val)) { - as_val_destroy(val); - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_insert operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_insert_items(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - as_list *items_list = NULL; - int64_t index; - as_list_policy list_policy; - bool policy_in_use = false; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - if (get_list_policy(err, op_dict, &list_policy, &policy_in_use, - self->validate_keys) != AEROSPIKE_OK) { - return err->code; - } - - if (get_val_list(self, err, AS_PY_VAL_KEY, op_dict, &items_list, - static_pool, serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - as_val_destroy(items_list); - return err->code; - } - - if (!as_operations_list_insert_items(ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), - index, items_list)) { - as_val_destroy(items_list); - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_insert_items operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_increment(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - as_val *incr = NULL; - int64_t index; - as_list_policy list_policy; - bool policy_in_use = false; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_list_policy(err, op_dict, &list_policy, &policy_in_use, - self->validate_keys) != AEROSPIKE_OK) { - return err->code; - } - - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &incr, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - as_val_destroy(incr); - return err->code; - } - - if (!as_operations_list_increment(ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), - index, incr)) { - as_val_destroy(incr); - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_increment operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_pop(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t index; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_pop(ops, bin, (ctx_in_use ? &ctx : NULL), index)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_pop operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_pop_range(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t index; - int64_t count; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - /* Get the count*/ - if (get_int64_t(err, AS_PY_VAL_KEY, op_dict, &count) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_pop_range(ops, bin, (ctx_in_use ? &ctx : NULL), - index, (uint64_t)count)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to list_pop_range operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_remove(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t index; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - ; - return err->code; - } - - if (!as_operations_list_remove(ops, bin, (ctx_in_use ? &ctx : NULL), - index)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_remove operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_remove_range(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t index; - int64_t count; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - /* Get the count*/ - if (get_int64_t(err, AS_PY_VAL_KEY, op_dict, &count) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_remove_range(ops, bin, (ctx_in_use ? &ctx : NULL), - index, (uint64_t)count)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to list_remove_range operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_clear(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL))) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_clear operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_set(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - as_val *val = NULL; - int64_t index; - as_list_policy list_policy; - bool policy_in_use = false; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_list_policy(err, op_dict, &list_policy, &policy_in_use, - self->validate_keys) != AEROSPIKE_OK) { - return err->code; - } - - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - as_val_destroy(val); - return err->code; - } - - if (!as_operations_list_set(ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, - val)) { - as_val_destroy(val); - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_set operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_get(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t index; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_get(ops, bin, (ctx_in_use ? &ctx : NULL), index)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_get operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_list_get_range(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t index; - int64_t count; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - /* Get the count*/ - if (get_int64_t(err, AS_PY_VAL_KEY, op_dict, &count) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_get_range(ops, bin, (ctx_in_use ? &ctx : NULL), - index, (uint64_t)count)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to list_get_range operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_trim(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - int64_t index; - int64_t count; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - /* Get the index*/ - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; - } - - /* Get the count*/ - if (get_int64_t(err, AS_PY_VAL_KEY, op_dict, &count) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_trim(ops, bin, (ctx_in_use ? &ctx : NULL), index, - (uint64_t)count)) { - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to list_trim operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return err->code; -} - -static as_status add_op_list_size(AerospikeClient *self, as_error *err, - char *bin, PyObject *op_dict, - as_operations *ops, - as_static_pool *static_pool, - int serializer_type) -{ - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (!as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL))) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list_size operation"); - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_add_op_list_remove_by_value_rel_rank_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type) -{ - bool count_present = false; - int64_t count; - int return_type; - int64_t rank; - as_val *value = NULL; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &count_present) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &value, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (count_present) { - if (!as_operations_list_remove_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value rank relative operation"); - } - } - else { - if (!as_operations_list_remove_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value rank relative operation"); - } - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_add_op_list_get_by_value_rel_rank_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type) -{ - - bool count_present = false; - int64_t count; - int return_type; - int64_t rank; - as_val *value = NULL; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &count_present) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &value, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (count_present) { - if (!as_operations_list_get_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value rank relative operation"); - } - } - else { - if (!as_operations_list_get_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value rank relative operation"); - } - } - - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} From b9d6ecd22876236e08fe81843a47a7f0a0b31652 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 9 Jan 2026 15:34:34 -0800 Subject: [PATCH 02/99] fix --- src/main/client/cdt_list_operate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index fa8fb6a0c3..2ba8e9e706 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -95,8 +95,8 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } int return_type = AS_LIST_RETURN_VALUE; - if (OP_LIST_GET_BY_INDEX <= operation_code <= - OP_LIST_REMOVE_BY_VALUE_RANGE) { + if (operation_code >= OP_LIST_GET_BY_INDEX && + operation_code <= OP_LIST_REMOVE_BY_VALUE_RANGE) { if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { return err->code; } From 5dab35281eca8c931bd10d57ff9f2ca7612e237c Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 9 Jan 2026 15:51:10 -0800 Subject: [PATCH 03/99] fix --- src/main/client/cdt_list_operate.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 2ba8e9e706..3514ac11e3 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -212,7 +212,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_get_by_index_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); } - + } case OP_LIST_GET_BY_RANK: { success = as_operations_list_get_by_rank( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); @@ -229,7 +229,6 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); } } - case OP_LIST_GET_BY_VALUE: { success = as_operations_list_get_by_value( ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); @@ -384,17 +383,15 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } break; - default: { + default: // This should never be possible since we only get here if we know that the operation is valid. return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); - } } - if (!success) { - // TODO: regression in error message - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add operation"); - } - - return err->code; + if (!success) { + // TODO: regression in error message + as_error_update(err, AEROSPIKE_ERR_CLIENT, "Failed to add operation"); } + + return err->code; +} From 8b524a3e21c24065b7126e3280e5d6ed2717ce44 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 9 Jan 2026 16:12:35 -0800 Subject: [PATCH 04/99] fix --- src/main/client/cdt_list_operate.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 3514ac11e3..32f940be22 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -317,6 +317,10 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { + success = as_operations_list_get_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, (uint64_t)count, + return_type); + break; } case OP_LIST_CREATE: { From e666b80d79805d7672d3d706d8c4bce53993634f Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 9 Jan 2026 16:14:28 -0800 Subject: [PATCH 05/99] list_sort doesn't take in a list_order arg --- src/main/client/cdt_list_operate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 32f940be22..76b6255a16 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -149,7 +149,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } int64_t order_type_int; - if (operation_code == OP_LIST_CREATE || operation_code == OP_LIST_SORT) { + if (operation_code == OP_LIST_CREATE) { if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != AEROSPIKE_OK) { return err->code; From 2e2b84f84a77c580e425b9850886d16028ef6611 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 9 Jan 2026 16:26:45 -0800 Subject: [PATCH 06/99] fix index param related errors --- src/main/client/cdt_list_operate.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 76b6255a16..f6fd8302a2 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -103,7 +103,21 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } int64_t index; - if (operation_code == OP_LIST_POP) { + switch (operation_code) { + case OP_LIST_POP: + case OP_LIST_POP_RANGE: + case OP_LIST_REMOVE: + case OP_LIST_REMOVE_RANGE: + case OP_LIST_SET: + case OP_LIST_GET_RANGE: + case OP_LIST_TRIM: + case OP_LIST_GET_BY_INDEX: + case OP_LIST_GET_BY_INDEX_RANGE: + case OP_LIST_REMOVE_BY_INDEX: + case OP_LIST_REMOVE_BY_INDEX_RANGE: + case OP_LIST_INSERT: + case OP_LIST_INSERT_ITEMS: + case OP_LIST_INCREMENT: if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { return err->code; From d6d5d016885d96ee489ae5158999bbd164de536d Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 9 Jan 2026 16:40:20 -0800 Subject: [PATCH 07/99] Add missing breaks --- src/main/client/cdt_list_operate.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index f6fd8302a2..f6f5cf4768 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -211,10 +211,11 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_TRIM: success = as_operations_list_trim(ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; case OP_LIST_GET_BY_INDEX: { success = as_operations_list_get_by_index( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } + } break; case OP_LIST_GET_BY_INDEX_RANGE: { if (range_specified) { @@ -226,11 +227,11 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_get_by_index_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); } - } + } break; case OP_LIST_GET_BY_RANK: { success = as_operations_list_get_by_rank( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } + } break; case OP_LIST_GET_BY_RANK_RANGE: { if (range_specified) { @@ -242,21 +243,21 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_get_by_rank_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); } - } + } break; case OP_LIST_GET_BY_VALUE: { success = as_operations_list_get_by_value( ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); - } + } break; case OP_LIST_GET_BY_VALUE_LIST: { success = as_operations_list_get_by_value_list( ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); - } + } break; case OP_LIST_GET_BY_VALUE_RANGE: { success = as_operations_list_get_by_value_range( ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, return_type); - } + } break; case OP_LIST_REMOVE_BY_INDEX: { success = as_operations_list_remove_by_index( @@ -274,7 +275,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_remove_by_index_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); } - } + } break; case OP_LIST_REMOVE_BY_RANK: { success = as_operations_list_remove_by_rank( @@ -292,7 +293,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_remove_by_rank_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); } - } + } break; case OP_LIST_REMOVE_BY_VALUE: { success = as_operations_list_remove_by_value( @@ -309,7 +310,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_remove_by_value_range( ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, return_type); - } + } break; case OP_LIST_SET_ORDER: { success = @@ -373,6 +374,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_insert_items( ops, bin, (ctx_in_use ? &ctx : NULL), (policy_in_use ? &list_policy : NULL), index, value_list); + break; case OP_LIST_INCREMENT: success = as_operations_list_increment( ops, bin, (ctx_in_use ? &ctx : NULL), From 3250d018c4a723d0ac97b1d8d09943e4eb88b983 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 9 Jan 2026 16:48:18 -0800 Subject: [PATCH 08/99] Fix some operations not receiving the return type in python --- src/main/client/cdt_list_operate.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index f6f5cf4768..2bcdbafe2c 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -95,8 +95,10 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } int return_type = AS_LIST_RETURN_VALUE; - if (operation_code >= OP_LIST_GET_BY_INDEX && - operation_code <= OP_LIST_REMOVE_BY_VALUE_RANGE) { + if ((operation_code >= OP_LIST_GET_BY_INDEX && + operation_code <= OP_LIST_REMOVE_BY_VALUE_RANGE) || + (operation_code >= OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL && + operation_code <= OP_LIST_REMOVE_BY_RANK_RANGE_TO_END)) { if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { return err->code; } From c2c56f447142150b1711a0fcce1b27dd6b9f6b3b Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 08:30:19 -0800 Subject: [PATCH 09/99] fix. --- src/main/client/cdt_list_operate.c | 490 +++++++++++++++-------------- 1 file changed, 258 insertions(+), 232 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 2bcdbafe2c..aefa884e53 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -64,9 +64,15 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, switch (operation_code) { case OP_LIST_GET_BY_VALUE: case OP_LIST_GET_BY_VALUE_LIST: + case OP_LIST_GET_RANGE: case OP_LIST_REMOVE_BY_VALUE: + case OP_LIST_TRIM: + case OP_LIST_APPEND: case OP_LIST_APPEND_ITEMS: case OP_LIST_INSERT: + case OP_LIST_INSERT_ITEMS: + case OP_LIST_POP_RANGE: + case OP_LIST_REMOVE_RANGE: case OP_LIST_INCREMENT: case OP_LIST_SET: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: @@ -87,6 +93,11 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } break; case OP_LIST_GET_BY_INDEX_RANGE: + case OP_LIST_REMOVE_BY_INDEX_RANGE: + case OP_LIST_GET_BY_RANK_RANGE: + case OP_LIST_REMOVE_BY_RANK_RANGE: + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: + case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, &range_specified) != AEROSPIKE_OK) { return err->code; @@ -98,7 +109,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, if ((operation_code >= OP_LIST_GET_BY_INDEX && operation_code <= OP_LIST_REMOVE_BY_VALUE_RANGE) || (operation_code >= OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL && - operation_code <= OP_LIST_REMOVE_BY_RANK_RANGE_TO_END)) { + operation_code <= OP_LIST_GET_BY_VALUE_RANK_RANGE_REL)) { if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { return err->code; } @@ -111,6 +122,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_REMOVE: case OP_LIST_REMOVE_RANGE: case OP_LIST_SET: + case OP_LIST_GET: case OP_LIST_GET_RANGE: case OP_LIST_TRIM: case OP_LIST_GET_BY_INDEX: @@ -128,7 +140,6 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, bool ctx_in_use = false; as_cdt_ctx ctx; - // TODO: not all operations may take in ctx param if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, serializer_type) != AEROSPIKE_OK) { return err->code; @@ -137,13 +148,20 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, int64_t rank; switch (operation_code) { case OP_LIST_GET_BY_RANK: + case OP_LIST_GET_BY_RANK_RANGE: + case OP_LIST_REMOVE_BY_RANK: + case OP_LIST_REMOVE_BY_RANK_RANGE: + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: + case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { return err->code; } + break; } as_list *value_list = NULL; switch (operation_code) { + case OP_LIST_GET_BY_VALUE_LIST: case OP_LIST_REMOVE_BY_VALUE_LIST: if (get_val_list(self, err, AS_PY_VALUES_KEY, op_dict, &value_list, static_pool, serializer_type) != AEROSPIKE_OK) { @@ -154,266 +172,274 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_val *val_begin = NULL; as_val *val_end = NULL; - if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val_begin, - static_pool, serializer_type, false) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_END_KEY, op_dict, &val_end, static_pool, - serializer_type, false) != AEROSPIKE_OK) { - return err->code; - } - - int64_t order_type_int; - if (operation_code == OP_LIST_CREATE) { - if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != - AEROSPIKE_OK) { + switch (operation_code) { + case OP_LIST_GET_BY_VALUE_LIST: + case OP_LIST_REMOVE_BY_VALUE_LIST: + if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val_begin, + static_pool, serializer_type, false) != AEROSPIKE_OK) { return err->code; } - } - bool success = false; - switch (operation_code) { - case OP_LIST_SIZE: - success = as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL)); - break; - case OP_LIST_POP: - success = - as_operations_list_pop(ops, bin, (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_POP_RANGE: - success = as_operations_list_pop_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_REMOVE: - success = as_operations_list_remove(ops, bin, - (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_REMOVE_RANGE: - success = as_operations_list_remove_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_CLEAR: - success = - as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL)); - break; - case OP_LIST_SET: - success = as_operations_list_set(ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), - index, val); - break; - case OP_LIST_GET: - success = - as_operations_list_get(ops, bin, (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_GET_RANGE: - success = as_operations_list_get_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_TRIM: - success = as_operations_list_trim(ops, bin, (ctx_in_use ? &ctx : NULL), - index, (uint64_t)count); + if (get_asval(self, err, AS_PY_VAL_END_KEY, op_dict, &val_end, + static_pool, serializer_type, false) != AEROSPIKE_OK) { + return err->code; + } break; - case OP_LIST_GET_BY_INDEX: { - success = as_operations_list_get_by_index( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } break; - - case OP_LIST_GET_BY_INDEX_RANGE: { - if (range_specified) { - success = as_operations_list_get_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, - return_type); + + int64_t order_type_int; + if (operation_code == OP_LIST_CREATE) { + if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != + AEROSPIKE_OK) { + return err->code; + } } - else { - success = as_operations_list_get_by_index_range_to_end( + + bool success = false; + switch (operation_code) { + case OP_LIST_SIZE: + success = + as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL)); + break; + case OP_LIST_POP: + success = as_operations_list_pop(ops, bin, + (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_POP_RANGE: + success = as_operations_list_pop_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_REMOVE: + success = as_operations_list_remove( + ops, bin, (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_REMOVE_RANGE: + success = as_operations_list_remove_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_CLEAR: + success = + as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL)); + break; + case OP_LIST_SET: + success = as_operations_list_set( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_GET: + success = as_operations_list_get(ops, bin, + (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_GET_RANGE: + success = as_operations_list_get_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_TRIM: + success = as_operations_list_trim( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_GET_BY_INDEX: { + success = as_operations_list_get_by_index( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } - } break; - case OP_LIST_GET_BY_RANK: { - success = as_operations_list_get_by_rank( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } break; - - case OP_LIST_GET_BY_RANK_RANGE: { - if (range_specified) { - success = as_operations_list_get_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_get_by_rank_range_to_end( + } break; + + case OP_LIST_GET_BY_INDEX_RANGE: { + if (range_specified) { + success = as_operations_list_get_by_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, + (uint64_t)count, return_type); + } + else { + success = as_operations_list_get_by_index_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + } + } break; + case OP_LIST_GET_BY_RANK: { + success = as_operations_list_get_by_rank( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } - } break; - case OP_LIST_GET_BY_VALUE: { - success = as_operations_list_get_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); - } break; - case OP_LIST_GET_BY_VALUE_LIST: { - success = as_operations_list_get_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); - } break; - - case OP_LIST_GET_BY_VALUE_RANGE: { - success = as_operations_list_get_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, - return_type); - } break; - - case OP_LIST_REMOVE_BY_INDEX: { - success = as_operations_list_remove_by_index( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - break; - } + } break; - case OP_LIST_REMOVE_BY_INDEX_RANGE: { - if (range_specified) { - success = as_operations_list_remove_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, + case OP_LIST_GET_BY_RANK_RANGE: { + if (range_specified) { + success = as_operations_list_get_by_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_get_by_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + } + } break; + case OP_LIST_GET_BY_VALUE: { + success = as_operations_list_get_by_value( + ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + } break; + case OP_LIST_GET_BY_VALUE_LIST: { + success = as_operations_list_get_by_value_list( + ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + } break; + + case OP_LIST_GET_BY_VALUE_RANGE: { + success = as_operations_list_get_by_value_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, return_type); - } - else { - success = as_operations_list_remove_by_index_range_to_end( + } break; + + case OP_LIST_REMOVE_BY_INDEX: { + success = as_operations_list_remove_by_index( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + break; } - } break; - case OP_LIST_REMOVE_BY_RANK: { - success = as_operations_list_remove_by_rank( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - break; - } + case OP_LIST_REMOVE_BY_INDEX_RANGE: { + if (range_specified) { + success = as_operations_list_remove_by_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, + (uint64_t)count, return_type); + } + else { + success = as_operations_list_remove_by_index_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + } + } break; - case OP_LIST_REMOVE_BY_RANK_RANGE: { - if (range_specified) { - success = as_operations_list_remove_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_remove_by_rank_range_to_end( + case OP_LIST_REMOVE_BY_RANK: { + success = as_operations_list_remove_by_rank( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + break; } - } break; - case OP_LIST_REMOVE_BY_VALUE: { - success = as_operations_list_remove_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); - break; - } + case OP_LIST_REMOVE_BY_RANK_RANGE: { + if (range_specified) { + success = as_operations_list_remove_by_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_remove_by_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + } + } break; - case OP_LIST_REMOVE_BY_VALUE_LIST: { - success = as_operations_list_remove_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); - } break; - - case OP_LIST_REMOVE_BY_VALUE_RANGE: { - success = as_operations_list_remove_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, - return_type); - } break; - - case OP_LIST_SET_ORDER: { - success = - as_operations_list_set_order(ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_order)order_type_int); - break; - } + case OP_LIST_REMOVE_BY_VALUE: { + success = as_operations_list_remove_by_value( + ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + break; + } - case OP_LIST_SORT: { - int64_t sort_flags; + case OP_LIST_REMOVE_BY_VALUE_LIST: { + success = as_operations_list_remove_by_value_list( + ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + } break; - if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != - AEROSPIKE_OK) { - return err->code; + case OP_LIST_REMOVE_BY_VALUE_RANGE: { + success = as_operations_list_remove_by_value_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, + return_type); + } break; + + case OP_LIST_SET_ORDER: { + success = as_operations_list_set_order( + ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_order)order_type_int); + break; } - success = as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_sort_flags)sort_flags); - break; - } - case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { - success = as_operations_list_get_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, (uint64_t)count, - return_type); - break; - } + case OP_LIST_SORT: { + int64_t sort_flags; - case OP_LIST_CREATE: { - bool pad, persist_index; - if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != - AEROSPIKE_OK) { - return err->code; + if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != + AEROSPIKE_OK) { + return err->code; + } + success = + as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_sort_flags)sort_flags); + break; } - if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, - &persist_index) != AEROSPIKE_OK) { - return err->code; + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { + success = as_operations_list_get_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + (uint64_t)count, return_type); + break; } - success = as_operations_list_create_all( - ops, bin, (ctx_in_use ? &ctx : NULL), (as_list_order)order_type_int, - pad, persist_index); - break; - } - case OP_LIST_APPEND: - success = as_operations_list_append( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), val); - break; - case OP_LIST_APPEND_ITEMS: - success = as_operations_list_append_items( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), value_list); - break; - case OP_LIST_INSERT: - success = as_operations_list_insert( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); - break; - case OP_LIST_INSERT_ITEMS: - success = as_operations_list_insert_items( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, value_list); - break; - case OP_LIST_INCREMENT: - success = as_operations_list_increment( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); - break; - case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: - if (range_specified) { - if (!as_operations_list_remove_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value " - "rank relative operation"); + case OP_LIST_CREATE: { + bool pad, persist_index; + if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != + AEROSPIKE_OK) { + return err->code; } + + if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, + &persist_index) != AEROSPIKE_OK) { + return err->code; + } + + success = as_operations_list_create_all( + ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_order)order_type_int, pad, persist_index); + break; } - else { - if (!as_operations_list_remove_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value " - "rank relative operation"); + case OP_LIST_APPEND: + success = as_operations_list_append( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), val); + break; + case OP_LIST_APPEND_ITEMS: + success = as_operations_list_append_items( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), value_list); + break; + case OP_LIST_INSERT: + success = as_operations_list_insert( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_INSERT_ITEMS: + success = as_operations_list_insert_items( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, value_list); + break; + case OP_LIST_INCREMENT: + success = as_operations_list_increment( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: + if (range_specified) { + if (!as_operations_list_remove_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + (uint64_t)count, return_type)) { + as_cdt_ctx_destroy(&ctx); + return as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add list remove by value " + "rank relative operation"); + } + } + else { + if (!as_operations_list_remove_by_value_rel_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + return_type)) { + as_cdt_ctx_destroy(&ctx); + return as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add list remove by value " + "rank relative operation"); + } } + break; + + default: + // This should never be possible since we only get here if we know that the operation is valid. + return as_error_update(err, AEROSPIKE_ERR_PARAM, + "Unknown operation"); } - break; - default: - // This should never be possible since we only get here if we know that the operation is valid. - return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); - } + if (!success) { + // TODO: regression in error message + as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add operation"); + } - if (!success) { - // TODO: regression in error message - as_error_update(err, AEROSPIKE_ERR_CLIENT, "Failed to add operation"); + return err->code; } - - return err->code; -} From 8b9fc85be2488794ea6df9bebb5f73c8bb9d453c Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 08:32:21 -0800 Subject: [PATCH 10/99] fix --- src/main/client/cdt_list_operate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index aefa884e53..597ddb4586 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -443,3 +443,4 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, return err->code; } +} From fd97333d59052d9995872972580a4bb3b40ea378 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 08:35:37 -0800 Subject: [PATCH 11/99] Fix --- src/main/client/cdt_list_operate.c | 450 ++++++++++++++--------------- 1 file changed, 223 insertions(+), 227 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 597ddb4586..0b26d5b87e 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -185,262 +185,258 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, return err->code; } break; + } - int64_t order_type_int; - if (operation_code == OP_LIST_CREATE) { - if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != - AEROSPIKE_OK) { - return err->code; - } + int64_t order_type_int; + if (operation_code == OP_LIST_CREATE) { + if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != + AEROSPIKE_OK) { + return err->code; } + } - bool success = false; - switch (operation_code) { - case OP_LIST_SIZE: - success = - as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL)); - break; - case OP_LIST_POP: - success = as_operations_list_pop(ops, bin, - (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_POP_RANGE: - success = as_operations_list_pop_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_REMOVE: - success = as_operations_list_remove( - ops, bin, (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_REMOVE_RANGE: - success = as_operations_list_remove_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_CLEAR: - success = - as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL)); - break; - case OP_LIST_SET: - success = as_operations_list_set( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); - break; - case OP_LIST_GET: - success = as_operations_list_get(ops, bin, - (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_GET_RANGE: - success = as_operations_list_get_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_TRIM: - success = as_operations_list_trim( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_GET_BY_INDEX: { - success = as_operations_list_get_by_index( + bool success = false; + switch (operation_code) { + case OP_LIST_SIZE: + success = as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL)); + break; + case OP_LIST_POP: + success = + as_operations_list_pop(ops, bin, (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_POP_RANGE: + success = as_operations_list_pop_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_REMOVE: + success = as_operations_list_remove(ops, bin, + (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_REMOVE_RANGE: + success = as_operations_list_remove_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_CLEAR: + success = + as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL)); + break; + case OP_LIST_SET: + success = as_operations_list_set(ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), + index, val); + break; + case OP_LIST_GET: + success = + as_operations_list_get(ops, bin, (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_GET_RANGE: + success = as_operations_list_get_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_TRIM: + success = as_operations_list_trim(ops, bin, (ctx_in_use ? &ctx : NULL), + index, (uint64_t)count); + break; + case OP_LIST_GET_BY_INDEX: { + success = as_operations_list_get_by_index( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + } break; + + case OP_LIST_GET_BY_INDEX_RANGE: { + if (range_specified) { + success = as_operations_list_get_by_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_get_by_index_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } break; - - case OP_LIST_GET_BY_INDEX_RANGE: { - if (range_specified) { - success = as_operations_list_get_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, - (uint64_t)count, return_type); - } - else { - success = as_operations_list_get_by_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } - } break; - case OP_LIST_GET_BY_RANK: { - success = as_operations_list_get_by_rank( + } + } break; + case OP_LIST_GET_BY_RANK: { + success = as_operations_list_get_by_rank( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + } break; + + case OP_LIST_GET_BY_RANK_RANGE: { + if (range_specified) { + success = as_operations_list_get_by_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_get_by_rank_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } break; + } + } break; + case OP_LIST_GET_BY_VALUE: { + success = as_operations_list_get_by_value( + ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + } break; + case OP_LIST_GET_BY_VALUE_LIST: { + success = as_operations_list_get_by_value_list( + ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + } break; + + case OP_LIST_GET_BY_VALUE_RANGE: { + success = as_operations_list_get_by_value_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, + return_type); + } break; + + case OP_LIST_REMOVE_BY_INDEX: { + success = as_operations_list_remove_by_index( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + break; + } - case OP_LIST_GET_BY_RANK_RANGE: { - if (range_specified) { - success = as_operations_list_get_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_get_by_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } - } break; - case OP_LIST_GET_BY_VALUE: { - success = as_operations_list_get_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); - } break; - case OP_LIST_GET_BY_VALUE_LIST: { - success = as_operations_list_get_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); - } break; - - case OP_LIST_GET_BY_VALUE_RANGE: { - success = as_operations_list_get_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, + case OP_LIST_REMOVE_BY_INDEX_RANGE: { + if (range_specified) { + success = as_operations_list_remove_by_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, return_type); - } break; - - case OP_LIST_REMOVE_BY_INDEX: { - success = as_operations_list_remove_by_index( + } + else { + success = as_operations_list_remove_by_index_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - break; } + } break; - case OP_LIST_REMOVE_BY_INDEX_RANGE: { - if (range_specified) { - success = as_operations_list_remove_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, - (uint64_t)count, return_type); - } - else { - success = as_operations_list_remove_by_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } - } break; + case OP_LIST_REMOVE_BY_RANK: { + success = as_operations_list_remove_by_rank( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + break; + } - case OP_LIST_REMOVE_BY_RANK: { - success = as_operations_list_remove_by_rank( + case OP_LIST_REMOVE_BY_RANK_RANGE: { + if (range_specified) { + success = as_operations_list_remove_by_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_remove_by_rank_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - break; } + } break; - case OP_LIST_REMOVE_BY_RANK_RANGE: { - if (range_specified) { - success = as_operations_list_remove_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_remove_by_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } - } break; - - case OP_LIST_REMOVE_BY_VALUE: { - success = as_operations_list_remove_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); - break; - } + case OP_LIST_REMOVE_BY_VALUE: { + success = as_operations_list_remove_by_value( + ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + break; + } - case OP_LIST_REMOVE_BY_VALUE_LIST: { - success = as_operations_list_remove_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); - } break; + case OP_LIST_REMOVE_BY_VALUE_LIST: { + success = as_operations_list_remove_by_value_list( + ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + } break; + + case OP_LIST_REMOVE_BY_VALUE_RANGE: { + success = as_operations_list_remove_by_value_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, + return_type); + } break; + + case OP_LIST_SET_ORDER: { + success = + as_operations_list_set_order(ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_order)order_type_int); + break; + } - case OP_LIST_REMOVE_BY_VALUE_RANGE: { - success = as_operations_list_remove_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, - return_type); - } break; + case OP_LIST_SORT: { + int64_t sort_flags; - case OP_LIST_SET_ORDER: { - success = as_operations_list_set_order( - ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_order)order_type_int); - break; + if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != + AEROSPIKE_OK) { + return err->code; } + success = as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_sort_flags)sort_flags); + break; + } - case OP_LIST_SORT: { - int64_t sort_flags; + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { + success = as_operations_list_get_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, (uint64_t)count, + return_type); + break; + } - if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != - AEROSPIKE_OK) { - return err->code; - } - success = - as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_sort_flags)sort_flags); - break; + case OP_LIST_CREATE: { + bool pad, persist_index; + if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != + AEROSPIKE_OK) { + return err->code; } - case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { - success = as_operations_list_get_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - (uint64_t)count, return_type); - break; + if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, + &persist_index) != AEROSPIKE_OK) { + return err->code; } - case OP_LIST_CREATE: { - bool pad, persist_index; - if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != - AEROSPIKE_OK) { - return err->code; - } - - if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, - &persist_index) != AEROSPIKE_OK) { - return err->code; + success = as_operations_list_create_all( + ops, bin, (ctx_in_use ? &ctx : NULL), (as_list_order)order_type_int, + pad, persist_index); + break; + } + case OP_LIST_APPEND: + success = as_operations_list_append( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), val); + break; + case OP_LIST_APPEND_ITEMS: + success = as_operations_list_append_items( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), value_list); + break; + case OP_LIST_INSERT: + success = as_operations_list_insert( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_INSERT_ITEMS: + success = as_operations_list_insert_items( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, value_list); + break; + case OP_LIST_INCREMENT: + success = as_operations_list_increment( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: + if (range_specified) { + if (!as_operations_list_remove_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + (uint64_t)count, return_type)) { + as_cdt_ctx_destroy(&ctx); + return as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add list remove by value " + "rank relative operation"); } - - success = as_operations_list_create_all( - ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_order)order_type_int, pad, persist_index); - break; } - case OP_LIST_APPEND: - success = as_operations_list_append( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), val); - break; - case OP_LIST_APPEND_ITEMS: - success = as_operations_list_append_items( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), value_list); - break; - case OP_LIST_INSERT: - success = as_operations_list_insert( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); - break; - case OP_LIST_INSERT_ITEMS: - success = as_operations_list_insert_items( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, value_list); - break; - case OP_LIST_INCREMENT: - success = as_operations_list_increment( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); - break; - case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: - if (range_specified) { - if (!as_operations_list_remove_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value " - "rank relative operation"); - } + else { + if (!as_operations_list_remove_by_value_rel_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + return_type)) { + as_cdt_ctx_destroy(&ctx); + return as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add list remove by value " + "rank relative operation"); } - else { - if (!as_operations_list_remove_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value " - "rank relative operation"); - } - } - break; - - default: - // This should never be possible since we only get here if we know that the operation is valid. - return as_error_update(err, AEROSPIKE_ERR_PARAM, - "Unknown operation"); } + break; - if (!success) { - // TODO: regression in error message - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add operation"); - } + default: + // This should never be possible since we only get here if we know that the operation is valid. + return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); + } - return err->code; + if (!success) { + // TODO: regression in error message + as_error_update(err, AEROSPIKE_ERR_CLIENT, "Failed to add operation"); } + + return err->code; } From 21554934bdd733f2bb095dc2d5d91d497d452d41 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 08:43:35 -0800 Subject: [PATCH 12/99] Move switch cases in ascending order so there is a greater chance the compiler will optimize these switch statements --- src/main/client/cdt_list_operate.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 0b26d5b87e..7801cfe2c0 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -62,19 +62,19 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_val *val = NULL; switch (operation_code) { - case OP_LIST_GET_BY_VALUE: - case OP_LIST_GET_BY_VALUE_LIST: - case OP_LIST_GET_RANGE: - case OP_LIST_REMOVE_BY_VALUE: - case OP_LIST_TRIM: case OP_LIST_APPEND: case OP_LIST_APPEND_ITEMS: case OP_LIST_INSERT: case OP_LIST_INSERT_ITEMS: case OP_LIST_POP_RANGE: case OP_LIST_REMOVE_RANGE: - case OP_LIST_INCREMENT: case OP_LIST_SET: + case OP_LIST_INCREMENT: + case OP_LIST_GET_BY_VALUE: + case OP_LIST_GET_BY_VALUE_LIST: + case OP_LIST_GET_RANGE: + case OP_LIST_TRIM: + case OP_LIST_REMOVE_BY_VALUE: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, @@ -93,11 +93,11 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } break; case OP_LIST_GET_BY_INDEX_RANGE: - case OP_LIST_REMOVE_BY_INDEX_RANGE: case OP_LIST_GET_BY_RANK_RANGE: + case OP_LIST_REMOVE_BY_INDEX_RANGE: case OP_LIST_REMOVE_BY_RANK_RANGE: - case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, &range_specified) != AEROSPIKE_OK) { return err->code; @@ -117,6 +117,8 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, int64_t index; switch (operation_code) { + case OP_LIST_INSERT: + case OP_LIST_INSERT_ITEMS: case OP_LIST_POP: case OP_LIST_POP_RANGE: case OP_LIST_REMOVE: @@ -125,13 +127,11 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_GET: case OP_LIST_GET_RANGE: case OP_LIST_TRIM: + case OP_LIST_INCREMENT: case OP_LIST_GET_BY_INDEX: case OP_LIST_GET_BY_INDEX_RANGE: case OP_LIST_REMOVE_BY_INDEX: case OP_LIST_REMOVE_BY_INDEX_RANGE: - case OP_LIST_INSERT: - case OP_LIST_INSERT_ITEMS: - case OP_LIST_INCREMENT: if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { return err->code; From 3e6ebb1c020c9def6fb7d5f4b1d6534bc897e156 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 08:53:21 -0800 Subject: [PATCH 13/99] fix... --- src/main/client/cdt_list_operate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 7801cfe2c0..d3c3390e0c 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -173,8 +173,8 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_val *val_begin = NULL; as_val *val_end = NULL; switch (operation_code) { - case OP_LIST_GET_BY_VALUE_LIST: - case OP_LIST_REMOVE_BY_VALUE_LIST: + case OP_LIST_GET_BY_VALUE_RANGE: + case OP_LIST_REMOVE_BY_VALUE_RANGE: if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val_begin, static_pool, serializer_type, false) != AEROSPIKE_OK) { return err->code; From 43e959fb3e4b867ac8cf94315c055926b0b6be9f Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 09:42:25 -0800 Subject: [PATCH 14/99] fix --- src/main/client/cdt_list_operate.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index d3c3390e0c..f64a675efe 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -71,7 +71,6 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_SET: case OP_LIST_INCREMENT: case OP_LIST_GET_BY_VALUE: - case OP_LIST_GET_BY_VALUE_LIST: case OP_LIST_GET_RANGE: case OP_LIST_TRIM: case OP_LIST_REMOVE_BY_VALUE: From 80797cb630523d10243cae82b97766aa9b45bbd4 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 09:56:43 -0800 Subject: [PATCH 15/99] fix --- src/main/client/cdt_list_operate.c | 442 +++++++++++++++-------------- 1 file changed, 224 insertions(+), 218 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index f64a675efe..23954d31ff 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -187,255 +187,261 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } int64_t order_type_int; - if (operation_code == OP_LIST_CREATE) { + switch (operation_code) { + case OP_LIST_SET_ORDER: + case OP_LIST_CREATE: { if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != AEROSPIKE_OK) { return err->code; } } - bool success = false; - switch (operation_code) { - case OP_LIST_SIZE: - success = as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL)); - break; - case OP_LIST_POP: - success = - as_operations_list_pop(ops, bin, (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_POP_RANGE: - success = as_operations_list_pop_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_REMOVE: - success = as_operations_list_remove(ops, bin, - (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_REMOVE_RANGE: - success = as_operations_list_remove_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_CLEAR: - success = - as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL)); - break; - case OP_LIST_SET: - success = as_operations_list_set(ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), - index, val); - break; - case OP_LIST_GET: - success = - as_operations_list_get(ops, bin, (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_GET_RANGE: - success = as_operations_list_get_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_TRIM: - success = as_operations_list_trim(ops, bin, (ctx_in_use ? &ctx : NULL), - index, (uint64_t)count); - break; - case OP_LIST_GET_BY_INDEX: { - success = as_operations_list_get_by_index( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } break; - - case OP_LIST_GET_BY_INDEX_RANGE: { - if (range_specified) { - success = as_operations_list_get_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_get_by_index_range_to_end( + bool success = false; + switch (operation_code) { + case OP_LIST_SIZE: + success = + as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL)); + break; + case OP_LIST_POP: + success = as_operations_list_pop(ops, bin, + (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_POP_RANGE: + success = as_operations_list_pop_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_REMOVE: + success = as_operations_list_remove( + ops, bin, (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_REMOVE_RANGE: + success = as_operations_list_remove_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_CLEAR: + success = + as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL)); + break; + case OP_LIST_SET: + success = as_operations_list_set( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_GET: + success = as_operations_list_get(ops, bin, + (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_GET_RANGE: + success = as_operations_list_get_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_TRIM: + success = as_operations_list_trim( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_GET_BY_INDEX: { + success = as_operations_list_get_by_index( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } - } break; - case OP_LIST_GET_BY_RANK: { - success = as_operations_list_get_by_rank( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } break; - - case OP_LIST_GET_BY_RANK_RANGE: { - if (range_specified) { - success = as_operations_list_get_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_get_by_rank_range_to_end( + } break; + + case OP_LIST_GET_BY_INDEX_RANGE: { + if (range_specified) { + success = as_operations_list_get_by_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, + (uint64_t)count, return_type); + } + else { + success = as_operations_list_get_by_index_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + } + } break; + case OP_LIST_GET_BY_RANK: { + success = as_operations_list_get_by_rank( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } - } break; - case OP_LIST_GET_BY_VALUE: { - success = as_operations_list_get_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); - } break; - case OP_LIST_GET_BY_VALUE_LIST: { - success = as_operations_list_get_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); - } break; - - case OP_LIST_GET_BY_VALUE_RANGE: { - success = as_operations_list_get_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, - return_type); - } break; - - case OP_LIST_REMOVE_BY_INDEX: { - success = as_operations_list_remove_by_index( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - break; - } + } break; - case OP_LIST_REMOVE_BY_INDEX_RANGE: { - if (range_specified) { - success = as_operations_list_remove_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, + case OP_LIST_GET_BY_RANK_RANGE: { + if (range_specified) { + success = as_operations_list_get_by_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_get_by_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + } + } break; + case OP_LIST_GET_BY_VALUE: { + success = as_operations_list_get_by_value( + ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + } break; + case OP_LIST_GET_BY_VALUE_LIST: { + success = as_operations_list_get_by_value_list( + ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + } break; + + case OP_LIST_GET_BY_VALUE_RANGE: { + success = as_operations_list_get_by_value_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, return_type); - } - else { - success = as_operations_list_remove_by_index_range_to_end( + } break; + + case OP_LIST_REMOVE_BY_INDEX: { + success = as_operations_list_remove_by_index( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + break; } - } break; - case OP_LIST_REMOVE_BY_RANK: { - success = as_operations_list_remove_by_rank( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - break; - } + case OP_LIST_REMOVE_BY_INDEX_RANGE: { + if (range_specified) { + success = as_operations_list_remove_by_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, + (uint64_t)count, return_type); + } + else { + success = as_operations_list_remove_by_index_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + } + } break; - case OP_LIST_REMOVE_BY_RANK_RANGE: { - if (range_specified) { - success = as_operations_list_remove_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_remove_by_rank_range_to_end( + case OP_LIST_REMOVE_BY_RANK: { + success = as_operations_list_remove_by_rank( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + break; } - } break; - case OP_LIST_REMOVE_BY_VALUE: { - success = as_operations_list_remove_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); - break; - } + case OP_LIST_REMOVE_BY_RANK_RANGE: { + if (range_specified) { + success = as_operations_list_remove_by_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_remove_by_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + } + } break; - case OP_LIST_REMOVE_BY_VALUE_LIST: { - success = as_operations_list_remove_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); - } break; - - case OP_LIST_REMOVE_BY_VALUE_RANGE: { - success = as_operations_list_remove_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, - return_type); - } break; - - case OP_LIST_SET_ORDER: { - success = - as_operations_list_set_order(ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_order)order_type_int); - break; - } + case OP_LIST_REMOVE_BY_VALUE: { + success = as_operations_list_remove_by_value( + ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + break; + } - case OP_LIST_SORT: { - int64_t sort_flags; + case OP_LIST_REMOVE_BY_VALUE_LIST: { + success = as_operations_list_remove_by_value_list( + ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + } break; - if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != - AEROSPIKE_OK) { - return err->code; + case OP_LIST_REMOVE_BY_VALUE_RANGE: { + success = as_operations_list_remove_by_value_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, + return_type); + } break; + + case OP_LIST_SET_ORDER: { + success = as_operations_list_set_order( + ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_order)order_type_int); + break; } - success = as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_sort_flags)sort_flags); - break; - } - case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { - success = as_operations_list_get_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, (uint64_t)count, - return_type); - break; - } + case OP_LIST_SORT: { + int64_t sort_flags; - case OP_LIST_CREATE: { - bool pad, persist_index; - if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != - AEROSPIKE_OK) { - return err->code; + if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != + AEROSPIKE_OK) { + return err->code; + } + success = + as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_sort_flags)sort_flags); + break; } - if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, - &persist_index) != AEROSPIKE_OK) { - return err->code; + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { + success = as_operations_list_get_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + (uint64_t)count, return_type); + break; } - success = as_operations_list_create_all( - ops, bin, (ctx_in_use ? &ctx : NULL), (as_list_order)order_type_int, - pad, persist_index); - break; - } - case OP_LIST_APPEND: - success = as_operations_list_append( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), val); - break; - case OP_LIST_APPEND_ITEMS: - success = as_operations_list_append_items( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), value_list); - break; - case OP_LIST_INSERT: - success = as_operations_list_insert( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); - break; - case OP_LIST_INSERT_ITEMS: - success = as_operations_list_insert_items( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, value_list); - break; - case OP_LIST_INCREMENT: - success = as_operations_list_increment( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); - break; - case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: - if (range_specified) { - if (!as_operations_list_remove_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value " - "rank relative operation"); + case OP_LIST_CREATE: { + bool pad, persist_index; + if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != + AEROSPIKE_OK) { + return err->code; } + + if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, + &persist_index) != AEROSPIKE_OK) { + return err->code; + } + + success = as_operations_list_create_all( + ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_order)order_type_int, pad, persist_index); + break; } - else { - if (!as_operations_list_remove_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value " - "rank relative operation"); + case OP_LIST_APPEND: + success = as_operations_list_append( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), val); + break; + case OP_LIST_APPEND_ITEMS: + success = as_operations_list_append_items( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), value_list); + break; + case OP_LIST_INSERT: + success = as_operations_list_insert( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_INSERT_ITEMS: + success = as_operations_list_insert_items( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, value_list); + break; + case OP_LIST_INCREMENT: + success = as_operations_list_increment( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: + if (range_specified) { + if (!as_operations_list_remove_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + (uint64_t)count, return_type)) { + as_cdt_ctx_destroy(&ctx); + return as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add list remove by value " + "rank relative operation"); + } } + else { + if (!as_operations_list_remove_by_value_rel_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + return_type)) { + as_cdt_ctx_destroy(&ctx); + return as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add list remove by value " + "rank relative operation"); + } + } + break; + + default: + // This should never be possible since we only get here if we know that the operation is valid. + return as_error_update(err, AEROSPIKE_ERR_PARAM, + "Unknown operation"); } - break; - default: - // This should never be possible since we only get here if we know that the operation is valid. - return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); - } + if (!success) { + // TODO: regression in error message + as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add operation"); + } - if (!success) { - // TODO: regression in error message - as_error_update(err, AEROSPIKE_ERR_CLIENT, "Failed to add operation"); + return err->code; } - - return err->code; -} From d0758961a8b3cb79cbde460d44a7bf55f1f894f7 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 09:56:57 -0800 Subject: [PATCH 16/99] Revert "fix" This reverts commit 80797cb630523d10243cae82b97766aa9b45bbd4. --- src/main/client/cdt_list_operate.c | 442 ++++++++++++++--------------- 1 file changed, 218 insertions(+), 224 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 23954d31ff..f64a675efe 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -187,261 +187,255 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } int64_t order_type_int; - switch (operation_code) { - case OP_LIST_SET_ORDER: - case OP_LIST_CREATE: { + if (operation_code == OP_LIST_CREATE) { if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != AEROSPIKE_OK) { return err->code; } } - bool success = false; - switch (operation_code) { - case OP_LIST_SIZE: - success = - as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL)); - break; - case OP_LIST_POP: - success = as_operations_list_pop(ops, bin, - (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_POP_RANGE: - success = as_operations_list_pop_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_REMOVE: - success = as_operations_list_remove( - ops, bin, (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_REMOVE_RANGE: - success = as_operations_list_remove_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_CLEAR: - success = - as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL)); - break; - case OP_LIST_SET: - success = as_operations_list_set( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); - break; - case OP_LIST_GET: - success = as_operations_list_get(ops, bin, - (ctx_in_use ? &ctx : NULL), index); - break; - case OP_LIST_GET_RANGE: - success = as_operations_list_get_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_TRIM: - success = as_operations_list_trim( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); - break; - case OP_LIST_GET_BY_INDEX: { - success = as_operations_list_get_by_index( + bool success = false; + switch (operation_code) { + case OP_LIST_SIZE: + success = as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL)); + break; + case OP_LIST_POP: + success = + as_operations_list_pop(ops, bin, (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_POP_RANGE: + success = as_operations_list_pop_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_REMOVE: + success = as_operations_list_remove(ops, bin, + (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_REMOVE_RANGE: + success = as_operations_list_remove_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_CLEAR: + success = + as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL)); + break; + case OP_LIST_SET: + success = as_operations_list_set(ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), + index, val); + break; + case OP_LIST_GET: + success = + as_operations_list_get(ops, bin, (ctx_in_use ? &ctx : NULL), index); + break; + case OP_LIST_GET_RANGE: + success = as_operations_list_get_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + break; + case OP_LIST_TRIM: + success = as_operations_list_trim(ops, bin, (ctx_in_use ? &ctx : NULL), + index, (uint64_t)count); + break; + case OP_LIST_GET_BY_INDEX: { + success = as_operations_list_get_by_index( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + } break; + + case OP_LIST_GET_BY_INDEX_RANGE: { + if (range_specified) { + success = as_operations_list_get_by_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_get_by_index_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } break; - - case OP_LIST_GET_BY_INDEX_RANGE: { - if (range_specified) { - success = as_operations_list_get_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, - (uint64_t)count, return_type); - } - else { - success = as_operations_list_get_by_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } - } break; - case OP_LIST_GET_BY_RANK: { - success = as_operations_list_get_by_rank( + } + } break; + case OP_LIST_GET_BY_RANK: { + success = as_operations_list_get_by_rank( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + } break; + + case OP_LIST_GET_BY_RANK_RANGE: { + if (range_specified) { + success = as_operations_list_get_by_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_get_by_rank_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } break; + } + } break; + case OP_LIST_GET_BY_VALUE: { + success = as_operations_list_get_by_value( + ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + } break; + case OP_LIST_GET_BY_VALUE_LIST: { + success = as_operations_list_get_by_value_list( + ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + } break; + + case OP_LIST_GET_BY_VALUE_RANGE: { + success = as_operations_list_get_by_value_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, + return_type); + } break; + + case OP_LIST_REMOVE_BY_INDEX: { + success = as_operations_list_remove_by_index( + ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + break; + } - case OP_LIST_GET_BY_RANK_RANGE: { - if (range_specified) { - success = as_operations_list_get_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_get_by_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } - } break; - case OP_LIST_GET_BY_VALUE: { - success = as_operations_list_get_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); - } break; - case OP_LIST_GET_BY_VALUE_LIST: { - success = as_operations_list_get_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); - } break; - - case OP_LIST_GET_BY_VALUE_RANGE: { - success = as_operations_list_get_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, + case OP_LIST_REMOVE_BY_INDEX_RANGE: { + if (range_specified) { + success = as_operations_list_remove_by_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, return_type); - } break; - - case OP_LIST_REMOVE_BY_INDEX: { - success = as_operations_list_remove_by_index( + } + else { + success = as_operations_list_remove_by_index_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - break; } + } break; - case OP_LIST_REMOVE_BY_INDEX_RANGE: { - if (range_specified) { - success = as_operations_list_remove_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, - (uint64_t)count, return_type); - } - else { - success = as_operations_list_remove_by_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); - } - } break; + case OP_LIST_REMOVE_BY_RANK: { + success = as_operations_list_remove_by_rank( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + break; + } - case OP_LIST_REMOVE_BY_RANK: { - success = as_operations_list_remove_by_rank( + case OP_LIST_REMOVE_BY_RANK_RANGE: { + if (range_specified) { + success = as_operations_list_remove_by_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, + return_type); + } + else { + success = as_operations_list_remove_by_rank_range_to_end( ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - break; } + } break; - case OP_LIST_REMOVE_BY_RANK_RANGE: { - if (range_specified) { - success = as_operations_list_remove_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); - } - else { - success = as_operations_list_remove_by_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); - } - } break; - - case OP_LIST_REMOVE_BY_VALUE: { - success = as_operations_list_remove_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); - break; - } + case OP_LIST_REMOVE_BY_VALUE: { + success = as_operations_list_remove_by_value( + ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + break; + } - case OP_LIST_REMOVE_BY_VALUE_LIST: { - success = as_operations_list_remove_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); - } break; + case OP_LIST_REMOVE_BY_VALUE_LIST: { + success = as_operations_list_remove_by_value_list( + ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + } break; + + case OP_LIST_REMOVE_BY_VALUE_RANGE: { + success = as_operations_list_remove_by_value_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, + return_type); + } break; + + case OP_LIST_SET_ORDER: { + success = + as_operations_list_set_order(ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_order)order_type_int); + break; + } - case OP_LIST_REMOVE_BY_VALUE_RANGE: { - success = as_operations_list_remove_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, - return_type); - } break; + case OP_LIST_SORT: { + int64_t sort_flags; - case OP_LIST_SET_ORDER: { - success = as_operations_list_set_order( - ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_order)order_type_int); - break; + if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != + AEROSPIKE_OK) { + return err->code; } + success = as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), + (as_list_sort_flags)sort_flags); + break; + } - case OP_LIST_SORT: { - int64_t sort_flags; + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { + success = as_operations_list_get_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, (uint64_t)count, + return_type); + break; + } - if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != - AEROSPIKE_OK) { - return err->code; - } - success = - as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_sort_flags)sort_flags); - break; + case OP_LIST_CREATE: { + bool pad, persist_index; + if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != + AEROSPIKE_OK) { + return err->code; } - case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { - success = as_operations_list_get_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - (uint64_t)count, return_type); - break; + if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, + &persist_index) != AEROSPIKE_OK) { + return err->code; } - case OP_LIST_CREATE: { - bool pad, persist_index; - if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != - AEROSPIKE_OK) { - return err->code; - } - - if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, - &persist_index) != AEROSPIKE_OK) { - return err->code; + success = as_operations_list_create_all( + ops, bin, (ctx_in_use ? &ctx : NULL), (as_list_order)order_type_int, + pad, persist_index); + break; + } + case OP_LIST_APPEND: + success = as_operations_list_append( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), val); + break; + case OP_LIST_APPEND_ITEMS: + success = as_operations_list_append_items( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), value_list); + break; + case OP_LIST_INSERT: + success = as_operations_list_insert( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_INSERT_ITEMS: + success = as_operations_list_insert_items( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, value_list); + break; + case OP_LIST_INCREMENT: + success = as_operations_list_increment( + ops, bin, (ctx_in_use ? &ctx : NULL), + (policy_in_use ? &list_policy : NULL), index, val); + break; + case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: + if (range_specified) { + if (!as_operations_list_remove_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + (uint64_t)count, return_type)) { + as_cdt_ctx_destroy(&ctx); + return as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add list remove by value " + "rank relative operation"); } - - success = as_operations_list_create_all( - ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_order)order_type_int, pad, persist_index); - break; } - case OP_LIST_APPEND: - success = as_operations_list_append( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), val); - break; - case OP_LIST_APPEND_ITEMS: - success = as_operations_list_append_items( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), value_list); - break; - case OP_LIST_INSERT: - success = as_operations_list_insert( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); - break; - case OP_LIST_INSERT_ITEMS: - success = as_operations_list_insert_items( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, value_list); - break; - case OP_LIST_INCREMENT: - success = as_operations_list_increment( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); - break; - case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: - if (range_specified) { - if (!as_operations_list_remove_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value " - "rank relative operation"); - } + else { + if (!as_operations_list_remove_by_value_rel_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + return_type)) { + as_cdt_ctx_destroy(&ctx); + return as_error_update(err, AEROSPIKE_ERR_CLIENT, + "Failed to add list remove by value " + "rank relative operation"); } - else { - if (!as_operations_list_remove_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value " - "rank relative operation"); - } - } - break; - - default: - // This should never be possible since we only get here if we know that the operation is valid. - return as_error_update(err, AEROSPIKE_ERR_PARAM, - "Unknown operation"); } + break; - if (!success) { - // TODO: regression in error message - as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add operation"); - } + default: + // This should never be possible since we only get here if we know that the operation is valid. + return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); + } - return err->code; + if (!success) { + // TODO: regression in error message + as_error_update(err, AEROSPIKE_ERR_CLIENT, "Failed to add operation"); } + + return err->code; +} From ca3a4332caf9d427ccd55c164d56e61bb638d333 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 09:57:50 -0800 Subject: [PATCH 17/99] fix --- src/main/client/cdt_list_operate.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index f64a675efe..9e75cdd627 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -187,7 +187,9 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } int64_t order_type_int; - if (operation_code == OP_LIST_CREATE) { + switch (operation_code) { + case OP_LIST_SET_ORDER: + case OP_LIST_CREATE: if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != AEROSPIKE_OK) { return err->code; From 935373b16a10a0bf1bf37d16819588c34869624c Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 10:23:56 -0800 Subject: [PATCH 18/99] Fix --- src/main/client/cdt_list_operate.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 9e75cdd627..e68ccdd122 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -408,27 +408,15 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, break; case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: if (range_specified) { - if (!as_operations_list_remove_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value " - "rank relative operation"); - } + success = as_operations_list_remove_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, + (uint64_t)count, return_type); } else { - if (!as_operations_list_remove_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Failed to add list remove by value " - "rank relative operation"); - } + success = as_operations_list_remove_by_value_rel_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, return_type); } break; - default: // This should never be possible since we only get here if we know that the operation is valid. return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); From 799f8eb8820d39ff4022e30b4c502d1619994e9f Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 10:39:43 -0800 Subject: [PATCH 19/99] fix --- src/main/client/cdt_list_operate.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index e68ccdd122..3538f0a518 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -67,12 +67,9 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_INSERT: case OP_LIST_INSERT_ITEMS: case OP_LIST_POP_RANGE: - case OP_LIST_REMOVE_RANGE: case OP_LIST_SET: case OP_LIST_INCREMENT: case OP_LIST_GET_BY_VALUE: - case OP_LIST_GET_RANGE: - case OP_LIST_TRIM: case OP_LIST_REMOVE_BY_VALUE: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: @@ -87,6 +84,9 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, bool range_specified = false; switch (operation_code) { case OP_LIST_POP_RANGE: + case OP_LIST_REMOVE_RANGE: + case OP_LIST_GET_RANGE: + case OP_LIST_TRIM: if (get_int64_t(err, AS_PY_VAL_KEY, op_dict, &count) != AEROSPIKE_OK) { return err->code; } @@ -389,7 +389,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_APPEND_ITEMS: success = as_operations_list_append_items( ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), value_list); + (policy_in_use ? &list_policy : NULL), val); break; case OP_LIST_INSERT: success = as_operations_list_insert( From efe8f4abc8b4c0ca0295fe1738aa4b815c165914 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 10:44:34 -0800 Subject: [PATCH 20/99] fix --- src/main/client/cdt_list_operate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 3538f0a518..f1ce8d5990 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -63,7 +63,6 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_val *val = NULL; switch (operation_code) { case OP_LIST_APPEND: - case OP_LIST_APPEND_ITEMS: case OP_LIST_INSERT: case OP_LIST_INSERT_ITEMS: case OP_LIST_POP_RANGE: @@ -160,6 +159,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_list *value_list = NULL; switch (operation_code) { + case OP_LIST_APPEND_ITEMS: case OP_LIST_GET_BY_VALUE_LIST: case OP_LIST_REMOVE_BY_VALUE_LIST: if (get_val_list(self, err, AS_PY_VALUES_KEY, op_dict, &value_list, @@ -389,7 +389,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_APPEND_ITEMS: success = as_operations_list_append_items( ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), val); + (policy_in_use ? &list_policy : NULL), value_list); break; case OP_LIST_INSERT: success = as_operations_list_insert( From c61d4a46837b233a07f28507af7110af3bfaae5c Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 10:47:16 -0800 Subject: [PATCH 21/99] Create a variable to get the results of the ternary operation. This makes it easier to refactor in the future --- src/main/client/cdt_list_operate.c | 129 +++++++++++++---------------- 1 file changed, 58 insertions(+), 71 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index f1ce8d5990..7e499051d1 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -142,6 +142,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, serializer_type) != AEROSPIKE_OK) { return err->code; } + as_cdt_ctx *ctx_ref = (ctx_in_use ? &ctx : NULL); int64_t rank; switch (operation_code) { @@ -199,149 +200,138 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, bool success = false; switch (operation_code) { case OP_LIST_SIZE: - success = as_operations_list_size(ops, bin, (ctx_in_use ? &ctx : NULL)); + success = as_operations_list_size(ops, bin, ctx_ref); break; case OP_LIST_POP: - success = - as_operations_list_pop(ops, bin, (ctx_in_use ? &ctx : NULL), index); + success = as_operations_list_pop(ops, bin, ctx_ref, index); break; case OP_LIST_POP_RANGE: - success = as_operations_list_pop_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + success = as_operations_list_pop_range(ops, bin, ctx_ref, index, + (uint64_t)count); break; case OP_LIST_REMOVE: - success = as_operations_list_remove(ops, bin, - (ctx_in_use ? &ctx : NULL), index); + success = as_operations_list_remove(ops, bin, ctx_ref, index); break; case OP_LIST_REMOVE_RANGE: - success = as_operations_list_remove_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + success = as_operations_list_remove_range(ops, bin, ctx_ref, index, + (uint64_t)count); break; case OP_LIST_CLEAR: - success = - as_operations_list_clear(ops, bin, (ctx_in_use ? &ctx : NULL)); + success = as_operations_list_clear(ops, bin, ctx_ref); break; case OP_LIST_SET: - success = as_operations_list_set(ops, bin, (ctx_in_use ? &ctx : NULL), + success = as_operations_list_set(ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), index, val); break; case OP_LIST_GET: - success = - as_operations_list_get(ops, bin, (ctx_in_use ? &ctx : NULL), index); + success = as_operations_list_get(ops, bin, ctx_ref, index); break; case OP_LIST_GET_RANGE: - success = as_operations_list_get_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count); + success = as_operations_list_get_range(ops, bin, ctx_ref, index, + (uint64_t)count); break; case OP_LIST_TRIM: - success = as_operations_list_trim(ops, bin, (ctx_in_use ? &ctx : NULL), - index, (uint64_t)count); + success = + as_operations_list_trim(ops, bin, ctx_ref, index, (uint64_t)count); break; case OP_LIST_GET_BY_INDEX: { - success = as_operations_list_get_by_index( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + success = as_operations_list_get_by_index(ops, bin, ctx_ref, index, + return_type); } break; case OP_LIST_GET_BY_INDEX_RANGE: { if (range_specified) { success = as_operations_list_get_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, - return_type); + ops, bin, ctx_ref, index, (uint64_t)count, return_type); } else { success = as_operations_list_get_by_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + ops, bin, ctx_ref, index, return_type); } } break; case OP_LIST_GET_BY_RANK: { - success = as_operations_list_get_by_rank( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + success = as_operations_list_get_by_rank(ops, bin, ctx_ref, rank, + return_type); } break; case OP_LIST_GET_BY_RANK_RANGE: { if (range_specified) { success = as_operations_list_get_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); + ops, bin, ctx_ref, rank, (uint64_t)count, return_type); } else { success = as_operations_list_get_by_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + ops, bin, ctx_ref, rank, return_type); } } break; case OP_LIST_GET_BY_VALUE: { - success = as_operations_list_get_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + success = as_operations_list_get_by_value(ops, bin, ctx_ref, val, + return_type); } break; case OP_LIST_GET_BY_VALUE_LIST: { - success = as_operations_list_get_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + success = as_operations_list_get_by_value_list(ops, bin, ctx_ref, + value_list, return_type); } break; case OP_LIST_GET_BY_VALUE_RANGE: { success = as_operations_list_get_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, - return_type); + ops, bin, ctx_ref, val_begin, val_end, return_type); } break; case OP_LIST_REMOVE_BY_INDEX: { - success = as_operations_list_remove_by_index( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + success = as_operations_list_remove_by_index(ops, bin, ctx_ref, index, + return_type); break; } case OP_LIST_REMOVE_BY_INDEX_RANGE: { if (range_specified) { success = as_operations_list_remove_by_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), index, (uint64_t)count, - return_type); + ops, bin, ctx_ref, index, (uint64_t)count, return_type); } else { success = as_operations_list_remove_by_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), index, return_type); + ops, bin, ctx_ref, index, return_type); } } break; case OP_LIST_REMOVE_BY_RANK: { - success = as_operations_list_remove_by_rank( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + success = as_operations_list_remove_by_rank(ops, bin, ctx_ref, rank, + return_type); break; } case OP_LIST_REMOVE_BY_RANK_RANGE: { if (range_specified) { success = as_operations_list_remove_by_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, (uint64_t)count, - return_type); + ops, bin, ctx_ref, rank, (uint64_t)count, return_type); } else { success = as_operations_list_remove_by_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), rank, return_type); + ops, bin, ctx_ref, rank, return_type); } } break; case OP_LIST_REMOVE_BY_VALUE: { - success = as_operations_list_remove_by_value( - ops, bin, (ctx_in_use ? &ctx : NULL), val, return_type); + success = as_operations_list_remove_by_value(ops, bin, ctx_ref, val, + return_type); break; } case OP_LIST_REMOVE_BY_VALUE_LIST: { success = as_operations_list_remove_by_value_list( - ops, bin, (ctx_in_use ? &ctx : NULL), value_list, return_type); + ops, bin, ctx_ref, value_list, return_type); } break; case OP_LIST_REMOVE_BY_VALUE_RANGE: { success = as_operations_list_remove_by_value_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val_begin, val_end, - return_type); + ops, bin, ctx_ref, val_begin, val_end, return_type); } break; case OP_LIST_SET_ORDER: { - success = - as_operations_list_set_order(ops, bin, (ctx_in_use ? &ctx : NULL), - (as_list_order)order_type_int); + success = as_operations_list_set_order(ops, bin, ctx_ref, + (as_list_order)order_type_int); break; } @@ -352,15 +342,14 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, AEROSPIKE_OK) { return err->code; } - success = as_operations_list_sort(ops, bin, (ctx_in_use ? &ctx : NULL), + success = as_operations_list_sort(ops, bin, ctx_ref, (as_list_sort_flags)sort_flags); break; } case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { success = as_operations_list_get_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, (uint64_t)count, - return_type); + ops, bin, ctx_ref, val, rank, (uint64_t)count, return_type); break; } @@ -376,45 +365,43 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, return err->code; } - success = as_operations_list_create_all( - ops, bin, (ctx_in_use ? &ctx : NULL), (as_list_order)order_type_int, - pad, persist_index); + success = as_operations_list_create_all(ops, bin, ctx_ref, + (as_list_order)order_type_int, + pad, persist_index); break; } case OP_LIST_APPEND: success = as_operations_list_append( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), val); + ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), val); break; case OP_LIST_APPEND_ITEMS: success = as_operations_list_append_items( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), value_list); + ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), + value_list); break; case OP_LIST_INSERT: success = as_operations_list_insert( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); + ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), index, + val); break; case OP_LIST_INSERT_ITEMS: success = as_operations_list_insert_items( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, value_list); + ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), index, + value_list); break; case OP_LIST_INCREMENT: success = as_operations_list_increment( - ops, bin, (ctx_in_use ? &ctx : NULL), - (policy_in_use ? &list_policy : NULL), index, val); + ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), index, + val); break; case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: if (range_specified) { success = as_operations_list_remove_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, - (uint64_t)count, return_type); + ops, bin, ctx_ref, val, rank, (uint64_t)count, return_type); } else { success = as_operations_list_remove_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), val, rank, return_type); + ops, bin, ctx_ref, val, rank, return_type); } break; default: From 114c568abddc1580511684495b83ac7a71c84271 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:00:53 -0800 Subject: [PATCH 22/99] list_append and list_insert take in a different key for the list of values --- src/main/client/cdt_list_operate.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 7e499051d1..161cc89306 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -72,6 +72,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_REMOVE_BY_VALUE: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: + case OP_LIST_APPEND_ITEMS: if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, serializer_type, true) != AEROSPIKE_OK) { return err->code; @@ -159,11 +160,22 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } as_list *value_list = NULL; + const char *list_values_key = NULL; switch (operation_code) { + case OP_LIST_GET_BY_VALUE_LIST: + case OP_LIST_REMOVE_BY_VALUE_LIST: + list_values_key = AS_PY_VALUES_KEY; + break; case OP_LIST_APPEND_ITEMS: + list_values_key = AS_PY_VAL_KEY; + break; + } + + switch (operation_code) { case OP_LIST_GET_BY_VALUE_LIST: case OP_LIST_REMOVE_BY_VALUE_LIST: - if (get_val_list(self, err, AS_PY_VALUES_KEY, op_dict, &value_list, + case OP_LIST_APPEND_ITEMS: + if (get_val_list(self, err, list_values_key, op_dict, &value_list, static_pool, serializer_type) != AEROSPIKE_OK) { return err->code; } @@ -376,8 +388,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, break; case OP_LIST_APPEND_ITEMS: success = as_operations_list_append_items( - ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), - value_list); + ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), val); break; case OP_LIST_INSERT: success = as_operations_list_insert( From 77531b5ce16590b51c37a4c565b918d86f5a54fd Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:04:54 -0800 Subject: [PATCH 23/99] fix --- src/main/client/cdt_list_operate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 161cc89306..c097af27f7 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -64,7 +64,6 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, switch (operation_code) { case OP_LIST_APPEND: case OP_LIST_INSERT: - case OP_LIST_INSERT_ITEMS: case OP_LIST_POP_RANGE: case OP_LIST_SET: case OP_LIST_INCREMENT: @@ -167,6 +166,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, list_values_key = AS_PY_VALUES_KEY; break; case OP_LIST_APPEND_ITEMS: + case OP_LIST_INSERT_ITEMS: list_values_key = AS_PY_VAL_KEY; break; } @@ -388,7 +388,8 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, break; case OP_LIST_APPEND_ITEMS: success = as_operations_list_append_items( - ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), val); + ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), + value_list); break; case OP_LIST_INSERT: success = as_operations_list_insert( From 713561175603850ed51eb949f058717b7d5785ec Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:06:46 -0800 Subject: [PATCH 24/99] Also refactor list_policy code to reduce number of times ternary operator is called --- src/main/client/cdt_list_operate.c | 31 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index c097af27f7..bf0c453618 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -44,6 +44,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } as_list_policy list_policy; + as_list_policy *list_policy_ref = NULL; bool policy_in_use = false; switch (operation_code) { @@ -57,6 +58,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, self->validate_keys) != AEROSPIKE_OK) { return err->code; } + list_policy_ref = policy_in_use ? &list_policy : NULL; break; } @@ -232,9 +234,8 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_clear(ops, bin, ctx_ref); break; case OP_LIST_SET: - success = as_operations_list_set(ops, bin, ctx_ref, - (policy_in_use ? &list_policy : NULL), - index, val); + success = + as_operations_list_set(ops, bin, ctx_ref, policy_ref, index, val); break; case OP_LIST_GET: success = as_operations_list_get(ops, bin, ctx_ref, index); @@ -383,28 +384,24 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, break; } case OP_LIST_APPEND: - success = as_operations_list_append( - ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), val); + success = + as_operations_list_append(ops, bin, ctx_ref, list_policy_ref, val); break; case OP_LIST_APPEND_ITEMS: - success = as_operations_list_append_items( - ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), - value_list); + success = as_operations_list_append_items(ops, bin, ctx_ref, policy_ref, + value_list); break; case OP_LIST_INSERT: - success = as_operations_list_insert( - ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), index, - val); + success = as_operations_list_insert(ops, bin, ctx_ref, policy_ref, + index, val); break; case OP_LIST_INSERT_ITEMS: - success = as_operations_list_insert_items( - ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), index, - value_list); + success = as_operations_list_insert_items(ops, bin, ctx_ref, policy_ref, + index, value_list); break; case OP_LIST_INCREMENT: - success = as_operations_list_increment( - ops, bin, ctx_ref, (policy_in_use ? &list_policy : NULL), index, - val); + success = as_operations_list_increment(ops, bin, ctx_ref, policy_ref, + index, val); break; case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: if (range_specified) { From 23b48214652f4ff260672bacec08910393563398 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:08:53 -0800 Subject: [PATCH 25/99] fix... --- src/main/client/cdt_list_operate.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index bf0c453618..c2870ef4ce 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -234,8 +234,8 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_clear(ops, bin, ctx_ref); break; case OP_LIST_SET: - success = - as_operations_list_set(ops, bin, ctx_ref, policy_ref, index, val); + success = as_operations_list_set(ops, bin, ctx_ref, list_policy_ref, + index, val); break; case OP_LIST_GET: success = as_operations_list_get(ops, bin, ctx_ref, index); @@ -388,20 +388,20 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_operations_list_append(ops, bin, ctx_ref, list_policy_ref, val); break; case OP_LIST_APPEND_ITEMS: - success = as_operations_list_append_items(ops, bin, ctx_ref, policy_ref, - value_list); + success = as_operations_list_append_items(ops, bin, ctx_ref, + list_policy_ref, value_list); break; case OP_LIST_INSERT: - success = as_operations_list_insert(ops, bin, ctx_ref, policy_ref, + success = as_operations_list_insert(ops, bin, ctx_ref, list_policy_ref, index, val); break; case OP_LIST_INSERT_ITEMS: - success = as_operations_list_insert_items(ops, bin, ctx_ref, policy_ref, - index, value_list); + success = as_operations_list_insert_items( + ops, bin, ctx_ref, list_policy_ref, index, value_list); break; case OP_LIST_INCREMENT: - success = as_operations_list_increment(ops, bin, ctx_ref, policy_ref, - index, val); + success = as_operations_list_increment(ops, bin, ctx_ref, + list_policy_ref, index, val); break; case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: if (range_specified) { From 0cf272f5f49ae11f7886433347df0b873943c223 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:26:41 -0800 Subject: [PATCH 26/99] fix --- src/main/client/cdt_list_operate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index c2870ef4ce..26efb52937 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -177,6 +177,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_GET_BY_VALUE_LIST: case OP_LIST_REMOVE_BY_VALUE_LIST: case OP_LIST_APPEND_ITEMS: + case OP_LIST_INSERT_ITEMS: if (get_val_list(self, err, list_values_key, op_dict, &value_list, static_pool, serializer_type) != AEROSPIKE_OK) { return err->code; From 86a21f586d2ac7d85f15d56cbafdfa5e0856d87b Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:35:52 -0800 Subject: [PATCH 27/99] Fix mem leaks --- src/main/client/cdt_list_operate.c | 58 ++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 26efb52937..fda59c3c4e 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -40,7 +40,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, char *bin = NULL; if (get_bin(err, op_dict, unicodeStrVector, &bin) != AEROSPIKE_OK) { - return err->code; + goto exit; } as_list_policy list_policy; @@ -56,7 +56,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_SET: if (get_list_policy(err, op_dict, &list_policy, &policy_in_use, self->validate_keys) != AEROSPIKE_OK) { - return err->code; + goto exit; } list_policy_ref = policy_in_use ? &list_policy : NULL; break; @@ -76,7 +76,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_APPEND_ITEMS: if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, serializer_type, true) != AEROSPIKE_OK) { - return err->code; + goto exit; } break; } @@ -89,7 +89,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_GET_RANGE: case OP_LIST_TRIM: if (get_int64_t(err, AS_PY_VAL_KEY, op_dict, &count) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR1; } break; case OP_LIST_GET_BY_INDEX_RANGE: @@ -100,7 +100,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, &range_specified) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR1; } break; } @@ -111,7 +111,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, (operation_code >= OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL && operation_code <= OP_LIST_GET_BY_VALUE_RANK_RANGE_REL)) { if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR1; } } @@ -134,7 +134,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_REMOVE_BY_INDEX_RANGE: if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR1; } } @@ -142,7 +142,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_cdt_ctx ctx; if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, serializer_type) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR1; } as_cdt_ctx *ctx_ref = (ctx_in_use ? &ctx : NULL); @@ -155,12 +155,11 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR2; } break; } - as_list *value_list = NULL; const char *list_values_key = NULL; switch (operation_code) { case OP_LIST_GET_BY_VALUE_LIST: @@ -173,6 +172,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, break; } + as_list *value_list = NULL; switch (operation_code) { case OP_LIST_GET_BY_VALUE_LIST: case OP_LIST_REMOVE_BY_VALUE_LIST: @@ -180,7 +180,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_INSERT_ITEMS: if (get_val_list(self, err, list_values_key, op_dict, &value_list, static_pool, serializer_type) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR2; } break; } @@ -192,12 +192,12 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_REMOVE_BY_VALUE_RANGE: if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val_begin, static_pool, serializer_type, false) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR3; } if (get_asval(self, err, AS_PY_VAL_END_KEY, op_dict, &val_end, static_pool, serializer_type, false) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR4; } break; } @@ -208,7 +208,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_CREATE: if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR5; } } @@ -354,7 +354,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR5; } success = as_operations_list_sort(ops, bin, ctx_ref, (as_list_sort_flags)sort_flags); @@ -371,12 +371,12 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, bool pad, persist_index; if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR5; } if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, &persist_index) != AEROSPIKE_OK) { - return err->code; + goto CLEANUP_ON_ERROR5; } success = as_operations_list_create_all(ops, bin, ctx_ref, @@ -416,7 +416,8 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, break; default: // This should never be possible since we only get here if we know that the operation is valid. - return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); + as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); + goto CLEANUP_ON_ERROR5; } if (!success) { @@ -424,5 +425,26 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_error_update(err, AEROSPIKE_ERR_CLIENT, "Failed to add operation"); } +CLEANUP_ON_ERROR5: + if (val_end) { + as_val_destroy(val_end); + } +CLEANUP_ON_ERROR4: + if (val_begin) { + as_val_destroy(val_begin); + } +CLEANUP_ON_ERROR3: + if (value_list) { + as_list_destroy(value_list); + } +CLEANUP_ON_ERROR2: + if (ctx_ref) { + as_cdt_ctx_destroy(ctx_ref); + } +CLEANUP_ON_ERROR1: + if (val) { + as_val_destroy(val); + } +exit: return err->code; } From 982816e8430c3c2744c31122ca28d1c291733e9e Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 13:57:08 -0800 Subject: [PATCH 28/99] Fix --- src/main/client/cdt_list_operate.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index fda59c3c4e..8d7f4863f9 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -66,14 +66,12 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, switch (operation_code) { case OP_LIST_APPEND: case OP_LIST_INSERT: - case OP_LIST_POP_RANGE: case OP_LIST_SET: case OP_LIST_INCREMENT: case OP_LIST_GET_BY_VALUE: case OP_LIST_REMOVE_BY_VALUE: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: - case OP_LIST_APPEND_ITEMS: if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, serializer_type, true) != AEROSPIKE_OK) { goto exit; From ed26bbde385bfd4945175e042092d925639c5da5 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 14:17:28 -0800 Subject: [PATCH 29/99] as_val shouldn't be destroyed since C client already takes ownership of it --- src/main/client/cdt_list_operate.c | 49 +++++++++++------------------- 1 file changed, 17 insertions(+), 32 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 8d7f4863f9..7d800769c9 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -87,7 +87,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_GET_RANGE: case OP_LIST_TRIM: if (get_int64_t(err, AS_PY_VAL_KEY, op_dict, &count) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR1; + goto exit; } break; case OP_LIST_GET_BY_INDEX_RANGE: @@ -98,7 +98,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, &range_specified) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR1; + goto exit; } break; } @@ -109,7 +109,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, (operation_code >= OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL && operation_code <= OP_LIST_GET_BY_VALUE_RANK_RANGE_REL)) { if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR1; + goto exit; } } @@ -132,7 +132,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_REMOVE_BY_INDEX_RANGE: if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR1; + goto exit; } } @@ -140,7 +140,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_cdt_ctx ctx; if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, serializer_type) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR1; + goto exit; } as_cdt_ctx *ctx_ref = (ctx_in_use ? &ctx : NULL); @@ -153,7 +153,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR2; + goto CLEANUP_CTX_ON_ERROR; } break; } @@ -178,7 +178,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_INSERT_ITEMS: if (get_val_list(self, err, list_values_key, op_dict, &value_list, static_pool, serializer_type) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR2; + goto CLEANUP_CTX_ON_ERROR; } break; } @@ -190,12 +190,12 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_REMOVE_BY_VALUE_RANGE: if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val_begin, static_pool, serializer_type, false) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR3; + goto CLEANUP_CTX_ON_ERROR; } if (get_asval(self, err, AS_PY_VAL_END_KEY, op_dict, &val_end, static_pool, serializer_type, false) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR4; + goto CLEANUP_CTX_ON_ERROR; } break; } @@ -206,7 +206,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_CREATE: if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR5; + goto CLEANUP_CTX_ON_ERROR; } } @@ -234,7 +234,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, break; case OP_LIST_SET: success = as_operations_list_set(ops, bin, ctx_ref, list_policy_ref, - index, val); + index, P); break; case OP_LIST_GET: success = as_operations_list_get(ops, bin, ctx_ref, index); @@ -352,7 +352,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR5; + goto CLEANUP_CTX_ON_ERROR; } success = as_operations_list_sort(ops, bin, ctx_ref, (as_list_sort_flags)sort_flags); @@ -369,12 +369,12 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, bool pad, persist_index; if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR5; + goto CLEANUP_CTX_ON_ERROR; } if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, &persist_index) != AEROSPIKE_OK) { - goto CLEANUP_ON_ERROR5; + goto CLEANUP_CTX_ON_ERROR; } success = as_operations_list_create_all(ops, bin, ctx_ref, @@ -415,7 +415,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, default: // This should never be possible since we only get here if we know that the operation is valid. as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); - goto CLEANUP_ON_ERROR5; + goto CLEANUP_CTX_ON_ERROR; } if (!success) { @@ -423,26 +423,11 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_error_update(err, AEROSPIKE_ERR_CLIENT, "Failed to add operation"); } -CLEANUP_ON_ERROR5: - if (val_end) { - as_val_destroy(val_end); - } -CLEANUP_ON_ERROR4: - if (val_begin) { - as_val_destroy(val_begin); - } -CLEANUP_ON_ERROR3: - if (value_list) { - as_list_destroy(value_list); - } -CLEANUP_ON_ERROR2: +CLEANUP_CTX_ON_ERROR: if (ctx_ref) { as_cdt_ctx_destroy(ctx_ref); } -CLEANUP_ON_ERROR1: - if (val) { - as_val_destroy(val); - } + exit: return err->code; } From a1ed9b76305c96785dd4ba4ceae65b8dd4f75452 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 14:19:46 -0800 Subject: [PATCH 30/99] fix --- src/main/client/cdt_list_operate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 7d800769c9..9cb9e043a9 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -234,7 +234,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, break; case OP_LIST_SET: success = as_operations_list_set(ops, bin, ctx_ref, list_policy_ref, - index, P); + index, val); break; case OP_LIST_GET: success = as_operations_list_get(ops, bin, ctx_ref, index); From f372b80a0fa15722033b0220a81651277dc578c2 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 14:40:08 -0800 Subject: [PATCH 31/99] Curly brackets only needed after case if local variable is initialized --- src/main/client/cdt_list_operate.c | 78 ++++++++++++------------------ 1 file changed, 32 insertions(+), 46 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 9cb9e043a9..b1830a41b3 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -45,7 +45,6 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, as_list_policy list_policy; as_list_policy *list_policy_ref = NULL; - bool policy_in_use = false; switch (operation_code) { case OP_LIST_APPEND: @@ -53,7 +52,8 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_INSERT: case OP_LIST_INSERT_ITEMS: case OP_LIST_INCREMENT: - case OP_LIST_SET: + case OP_LIST_SET: { + bool policy_in_use = false; if (get_list_policy(err, op_dict, &list_policy, &policy_in_use, self->validate_keys) != AEROSPIKE_OK) { goto exit; @@ -61,6 +61,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, list_policy_ref = policy_in_use ? &list_policy : NULL; break; } + } as_val *val = NULL; switch (operation_code) { @@ -247,12 +248,12 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_trim(ops, bin, ctx_ref, index, (uint64_t)count); break; - case OP_LIST_GET_BY_INDEX: { + case OP_LIST_GET_BY_INDEX: success = as_operations_list_get_by_index(ops, bin, ctx_ref, index, return_type); - } break; + break; - case OP_LIST_GET_BY_INDEX_RANGE: { + case OP_LIST_GET_BY_INDEX_RANGE: if (range_specified) { success = as_operations_list_get_by_index_range( ops, bin, ctx_ref, index, (uint64_t)count, return_type); @@ -261,13 +262,13 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_get_by_index_range_to_end( ops, bin, ctx_ref, index, return_type); } - } break; - case OP_LIST_GET_BY_RANK: { + break; + case OP_LIST_GET_BY_RANK: success = as_operations_list_get_by_rank(ops, bin, ctx_ref, rank, return_type); - } break; + break; - case OP_LIST_GET_BY_RANK_RANGE: { + case OP_LIST_GET_BY_RANK_RANGE: if (range_specified) { success = as_operations_list_get_by_rank_range( ops, bin, ctx_ref, rank, (uint64_t)count, return_type); @@ -276,28 +277,25 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_get_by_rank_range_to_end( ops, bin, ctx_ref, rank, return_type); } - } break; - case OP_LIST_GET_BY_VALUE: { + break; + case OP_LIST_GET_BY_VALUE: success = as_operations_list_get_by_value(ops, bin, ctx_ref, val, return_type); - } break; - case OP_LIST_GET_BY_VALUE_LIST: { + break; + case OP_LIST_GET_BY_VALUE_LIST: success = as_operations_list_get_by_value_list(ops, bin, ctx_ref, value_list, return_type); - } break; - - case OP_LIST_GET_BY_VALUE_RANGE: { + break; + case OP_LIST_GET_BY_VALUE_RANGE: success = as_operations_list_get_by_value_range( ops, bin, ctx_ref, val_begin, val_end, return_type); - } break; + break; - case OP_LIST_REMOVE_BY_INDEX: { + case OP_LIST_REMOVE_BY_INDEX: success = as_operations_list_remove_by_index(ops, bin, ctx_ref, index, return_type); break; - } - - case OP_LIST_REMOVE_BY_INDEX_RANGE: { + case OP_LIST_REMOVE_BY_INDEX_RANGE: if (range_specified) { success = as_operations_list_remove_by_index_range( ops, bin, ctx_ref, index, (uint64_t)count, return_type); @@ -306,15 +304,14 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_remove_by_index_range_to_end( ops, bin, ctx_ref, index, return_type); } - } break; + break; - case OP_LIST_REMOVE_BY_RANK: { + case OP_LIST_REMOVE_BY_RANK: success = as_operations_list_remove_by_rank(ops, bin, ctx_ref, rank, return_type); break; - } - case OP_LIST_REMOVE_BY_RANK_RANGE: { + case OP_LIST_REMOVE_BY_RANK_RANGE: if (range_specified) { success = as_operations_list_remove_by_rank_range( ops, bin, ctx_ref, rank, (uint64_t)count, return_type); @@ -323,31 +320,25 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_remove_by_rank_range_to_end( ops, bin, ctx_ref, rank, return_type); } - } break; + break; - case OP_LIST_REMOVE_BY_VALUE: { + case OP_LIST_REMOVE_BY_VALUE: success = as_operations_list_remove_by_value(ops, bin, ctx_ref, val, return_type); break; - } - - case OP_LIST_REMOVE_BY_VALUE_LIST: { + case OP_LIST_REMOVE_BY_VALUE_LIST: success = as_operations_list_remove_by_value_list( ops, bin, ctx_ref, value_list, return_type); - } break; - - case OP_LIST_REMOVE_BY_VALUE_RANGE: { + break; + case OP_LIST_REMOVE_BY_VALUE_RANGE: success = as_operations_list_remove_by_value_range( ops, bin, ctx_ref, val_begin, val_end, return_type); - } break; - - case OP_LIST_SET_ORDER: { + break; + case OP_LIST_SET_ORDER: success = as_operations_list_set_order(ops, bin, ctx_ref, (as_list_order)order_type_int); break; - } - - case OP_LIST_SORT: { + case OP_LIST_SORT: int64_t sort_flags; if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != @@ -357,15 +348,11 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_sort(ops, bin, ctx_ref, (as_list_sort_flags)sort_flags); break; - } - - case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: { + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: success = as_operations_list_get_by_value_rel_rank_range( ops, bin, ctx_ref, val, rank, (uint64_t)count, return_type); break; - } - - case OP_LIST_CREATE: { + case OP_LIST_CREATE: bool pad, persist_index; if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != AEROSPIKE_OK) { @@ -381,7 +368,6 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, (as_list_order)order_type_int, pad, persist_index); break; - } case OP_LIST_APPEND: success = as_operations_list_append(ops, bin, ctx_ref, list_policy_ref, val); From a339e897025a669db40e038fdfaedda6f88cb3d7 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 15:40:12 -0800 Subject: [PATCH 32/99] use X-macro to map operation codes to operation names --- src/include/policy.h | 82 ++++++++++++++---------------- src/main/client/cdt_list_operate.c | 4 +- 2 files changed, 41 insertions(+), 45 deletions(-) diff --git a/src/include/policy.h b/src/include/policy.h index 9948676a86..cb02e894ce 100644 --- a/src/include/policy.h +++ b/src/include/policy.h @@ -41,50 +41,46 @@ enum Aerospike_send_bool_as_values { SEND_BOOL_AS_AS_BOOL, /* default for writing Python bools */ }; +#define LIST_OP_NAMES_EXCEPT_LIST_APPEND \ + X(LIST_APPEND_ITEMS), X(LIST_INSERT), X(LIST_INSERT_ITEMS), X(LIST_POP), \ + X(LIST_POP_RANGE), X(LIST_REMOVE), X(LIST_REMOVE_RANGE), \ + X(LIST_CLEAR), X(LIST_SET), X(LIST_GET), X(LIST_GET_RANGE), \ + X(LIST_TRIM), X(LIST_SIZE), X(LIST_INCREMENT), X(LIST_GET_BY_INDEX), \ + X(LIST_GET_BY_INDEX_RANGE), X(LIST_GET_BY_RANK), \ + X(LIST_GET_BY_RANK_RANGE), X(LIST_GET_BY_VALUE), \ + X(LIST_GET_BY_VALUE_LIST), X(LIST_GET_BY_VALUE_RANGE), \ + X(LIST_REMOVE_BY_INDEX), X(LIST_REMOVE_BY_INDEX_RANGE), \ + X(LIST_REMOVE_BY_RANK), X(LIST_REMOVE_BY_RANK_RANGE), \ + X(LIST_REMOVE_BY_VALUE), X(LIST_REMOVE_BY_VALUE_LIST), \ + X(LIST_REMOVE_BY_VALUE_RANGE), X(LIST_SET_ORDER), X(LIST_SORT), \ + X(LIST_REMOVE_BY_VALUE_RANK_RANGE_REL), \ + X(LIST_GET_BY_VALUE_RANK_RANGE_REL), \ + X(LIST_GET_BY_VALUE_RANK_RANGE_REL_TO_END), \ + X(LIST_GET_BY_INDEX_RANGE_TO_END), X(LIST_GET_BY_RANK_RANGE_TO_END), \ + X(LIST_REMOVE_BY_REL_RANK_RANGE_TO_END), \ + X(LIST_REMOVE_BY_REL_RANK_RANGE), \ + X(LIST_REMOVE_BY_INDEX_RANGE_TO_END), \ + X(LIST_REMOVE_BY_RANK_RANGE_TO_END), X(LIST_CREATE) + enum Aerospike_list_operations { - OP_LIST_APPEND = 1001, - OP_LIST_APPEND_ITEMS, - OP_LIST_INSERT, - OP_LIST_INSERT_ITEMS, - OP_LIST_POP, - OP_LIST_POP_RANGE, - OP_LIST_REMOVE, - OP_LIST_REMOVE_RANGE, - OP_LIST_CLEAR, - OP_LIST_SET, - OP_LIST_GET, - OP_LIST_GET_RANGE, - OP_LIST_TRIM, - OP_LIST_SIZE, - OP_LIST_INCREMENT, - OP_LIST_GET_BY_INDEX, - OP_LIST_GET_BY_INDEX_RANGE, - OP_LIST_GET_BY_RANK, - OP_LIST_GET_BY_RANK_RANGE, - OP_LIST_GET_BY_VALUE, - OP_LIST_GET_BY_VALUE_LIST, - OP_LIST_GET_BY_VALUE_RANGE, - OP_LIST_REMOVE_BY_INDEX, - OP_LIST_REMOVE_BY_INDEX_RANGE, - OP_LIST_REMOVE_BY_RANK, - OP_LIST_REMOVE_BY_RANK_RANGE, - OP_LIST_REMOVE_BY_VALUE, - OP_LIST_REMOVE_BY_VALUE_LIST, - OP_LIST_REMOVE_BY_VALUE_RANGE, - OP_LIST_SET_ORDER, - OP_LIST_SORT, - OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL, - OP_LIST_GET_BY_VALUE_RANK_RANGE_REL, - - // for use in expressions - OP_LIST_GET_BY_VALUE_RANK_RANGE_REL_TO_END, - OP_LIST_GET_BY_INDEX_RANGE_TO_END, - OP_LIST_GET_BY_RANK_RANGE_TO_END, - OP_LIST_REMOVE_BY_REL_RANK_RANGE_TO_END, - OP_LIST_REMOVE_BY_REL_RANK_RANGE, - OP_LIST_REMOVE_BY_INDEX_RANGE_TO_END, - OP_LIST_REMOVE_BY_RANK_RANGE_TO_END, - OP_LIST_CREATE +#define X(op_name) OP_##op_name + X(LIST_APPEND) = 1001, + LIST_OP_NAMES_EXCEPT_LIST_APPEND +#undef X +}; + +typedef struct { + int operation_code; + const char *operation_name; +} op_code_to_name; + +op_code_to_name op_code_to_names[] = { +#define X(op_name) \ + { \ + OP_##op_name, #op_name \ + } + X(LIST_APPEND), LIST_OP_NAMES_EXCEPT_LIST_APPEND +#undef X }; enum Aerospike_map_operations { diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index b1830a41b3..55b26723ea 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -405,8 +405,8 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } if (!success) { - // TODO: regression in error message - as_error_update(err, AEROSPIKE_ERR_CLIENT, "Failed to add operation"); + as_error_update(err, AEROSPIKE_ERR_CLIENT, "Failed to add %s operation", + op_code_to_names[operation_code]); } CLEANUP_CTX_ON_ERROR: From 23f5b55ead720ddc3237c04744b483a0e9269796 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 15:44:19 -0800 Subject: [PATCH 33/99] Define global variable in C source file instead of header to avoid duplicate defs? --- src/include/policy.h | 14 -------------- src/main/client/cdt_list_operate.c | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/include/policy.h b/src/include/policy.h index cb02e894ce..cc5309e593 100644 --- a/src/include/policy.h +++ b/src/include/policy.h @@ -69,20 +69,6 @@ enum Aerospike_list_operations { #undef X }; -typedef struct { - int operation_code; - const char *operation_name; -} op_code_to_name; - -op_code_to_name op_code_to_names[] = { -#define X(op_name) \ - { \ - OP_##op_name, #op_name \ - } - X(LIST_APPEND), LIST_OP_NAMES_EXCEPT_LIST_APPEND -#undef X -}; - enum Aerospike_map_operations { OP_MAP_SET_POLICY = 1101, OP_MAP_PUT, diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 55b26723ea..6b6cdeab47 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -30,6 +30,20 @@ #include "cdt_list_operations.h" #include "cdt_operation_utils.h" +typedef struct { + int operation_code; + const char *operation_name; +} op_code_to_name; + +op_code_to_name op_code_to_names[] = { +#define X(op_name) \ + { \ + OP_##op_name, #op_name \ + } + X(LIST_APPEND), LIST_OP_NAMES_EXCEPT_LIST_APPEND +#undef X +}; + as_status add_new_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, as_vector *unicodeStrVector, as_static_pool *static_pool, as_operations *ops, From 6f34f7c1d7ca8d737a1964225f6d1485dc946bc8 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 16:24:45 -0800 Subject: [PATCH 34/99] Fix memory error --- src/main/client/cdt_list_operate.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 6b6cdeab47..feafbb7a04 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -363,8 +363,14 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, (as_list_sort_flags)sort_flags); break; case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: - success = as_operations_list_get_by_value_rel_rank_range( - ops, bin, ctx_ref, val, rank, (uint64_t)count, return_type); + if (range_specified) { + success = as_operations_list_get_by_value_rel_rank_range( + ops, bin, ctx_ref, val, rank, (uint64_t)count, return_type); + } + else { + success = as_operations_list_get_by_value_rel_rank_range_to_end( + ops, bin, ctx_ref, val, rank, return_type); + } break; case OP_LIST_CREATE: bool pad, persist_index; From 940a7047cd4df79b9bf8b16c5bec90ff879866ef Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 16:55:31 -0800 Subject: [PATCH 35/99] move heap allocations further down the function for performance --- src/main/client/cdt_list_operate.c | 107 ++++++++++++++++++----------- 1 file changed, 66 insertions(+), 41 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index feafbb7a04..1f956c8582 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -51,6 +51,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, int serializer_type) { + bool has_as_operations_taken_ownership_of_as_val_objs = false; char *bin = NULL; if (get_bin(err, op_dict, unicodeStrVector, &bin) != AEROSPIKE_OK) { @@ -77,23 +78,6 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } } - as_val *val = NULL; - switch (operation_code) { - case OP_LIST_APPEND: - case OP_LIST_INSERT: - case OP_LIST_SET: - case OP_LIST_INCREMENT: - case OP_LIST_GET_BY_VALUE: - case OP_LIST_REMOVE_BY_VALUE: - case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: - case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - goto exit; - } - break; - } - int64_t count; bool range_specified = false; switch (operation_code) { @@ -151,6 +135,30 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } } + int64_t rank; + switch (operation_code) { + case OP_LIST_GET_BY_RANK: + case OP_LIST_GET_BY_RANK_RANGE: + case OP_LIST_REMOVE_BY_RANK: + case OP_LIST_REMOVE_BY_RANK_RANGE: + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: + case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: + if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { + goto exit; + } + break; + } + + int64_t order_type_int; + switch (operation_code) { + case OP_LIST_SET_ORDER: + case OP_LIST_CREATE: + if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != + AEROSPIKE_OK) { + goto exit; + } + } + bool ctx_in_use = false; as_cdt_ctx ctx; if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, @@ -159,15 +167,18 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, } as_cdt_ctx *ctx_ref = (ctx_in_use ? &ctx : NULL); - int64_t rank; + as_val *val = NULL; switch (operation_code) { - case OP_LIST_GET_BY_RANK: - case OP_LIST_GET_BY_RANK_RANGE: - case OP_LIST_REMOVE_BY_RANK: - case OP_LIST_REMOVE_BY_RANK_RANGE: - case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: + case OP_LIST_APPEND: + case OP_LIST_INSERT: + case OP_LIST_SET: + case OP_LIST_INCREMENT: + case OP_LIST_GET_BY_VALUE: + case OP_LIST_REMOVE_BY_VALUE: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: - if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { + case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: + if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, + serializer_type, true) != AEROSPIKE_OK) { goto CLEANUP_CTX_ON_ERROR; } break; @@ -193,7 +204,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_INSERT_ITEMS: if (get_val_list(self, err, list_values_key, op_dict, &value_list, static_pool, serializer_type) != AEROSPIKE_OK) { - goto CLEANUP_CTX_ON_ERROR; + goto CLEANUP_VAL_ON_ERROR1; } break; } @@ -205,26 +216,16 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, case OP_LIST_REMOVE_BY_VALUE_RANGE: if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val_begin, static_pool, serializer_type, false) != AEROSPIKE_OK) { - goto CLEANUP_CTX_ON_ERROR; + goto CLEANUP_VAL_ON_ERROR2; } if (get_asval(self, err, AS_PY_VAL_END_KEY, op_dict, &val_end, static_pool, serializer_type, false) != AEROSPIKE_OK) { - goto CLEANUP_CTX_ON_ERROR; + goto CLEANUP_VAL_ON_ERROR3; } break; } - int64_t order_type_int; - switch (operation_code) { - case OP_LIST_SET_ORDER: - case OP_LIST_CREATE: - if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != - AEROSPIKE_OK) { - goto CLEANUP_CTX_ON_ERROR; - } - } - bool success = false; switch (operation_code) { case OP_LIST_SIZE: @@ -357,7 +358,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != AEROSPIKE_OK) { - goto CLEANUP_CTX_ON_ERROR; + goto CLEANUP_VAL_ON_ERROR4; } success = as_operations_list_sort(ops, bin, ctx_ref, (as_list_sort_flags)sort_flags); @@ -376,12 +377,12 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, bool pad, persist_index; if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != AEROSPIKE_OK) { - goto CLEANUP_CTX_ON_ERROR; + goto CLEANUP_VAL_ON_ERROR4; } if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, &persist_index) != AEROSPIKE_OK) { - goto CLEANUP_CTX_ON_ERROR; + goto CLEANUP_VAL_ON_ERROR4; } success = as_operations_list_create_all(ops, bin, ctx_ref, @@ -421,14 +422,38 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, default: // This should never be possible since we only get here if we know that the operation is valid. as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); - goto CLEANUP_CTX_ON_ERROR; + goto CLEANUP_VAL_ON_ERROR4; } + has_as_operations_taken_ownership_of_as_val_objs = true; + if (!success) { as_error_update(err, AEROSPIKE_ERR_CLIENT, "Failed to add %s operation", op_code_to_names[operation_code]); } + if (has_as_operations_taken_ownership_of_as_val_objs == false) { + CLEANUP_VAL_ON_ERROR4: + if (val_end) { + as_val_destroy(val_end); + } + + CLEANUP_VAL_ON_ERROR3: + if (val_begin) { + as_val_destroy(val_begin); + } + + CLEANUP_VAL_ON_ERROR2: + if (value_list) { + as_list_destroy(value_list); + } + + CLEANUP_VAL_ON_ERROR1: + if (val) { + as_val_destroy(val); + } + } + CLEANUP_CTX_ON_ERROR: if (ctx_ref) { as_cdt_ctx_destroy(ctx_ref); From 4207bf378f0d3b0079ef4c0e5b069908e1d9ed2f Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Mon, 12 Jan 2026 17:30:04 -0800 Subject: [PATCH 36/99] Fix bug where get_cdt_ctx calls a C client API even though the conversion code from Python to C failed beforehand... --- src/main/conversions.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/conversions.c b/src/main/conversions.c index 23065d51c7..598bec8932 100644 --- a/src/main/conversions.c +++ b/src/main/conversions.c @@ -2505,7 +2505,13 @@ as_status get_cdt_ctx(AerospikeClient *self, as_error *err, as_cdt_ctx *cdt_ctx, int pad = 0; get_int_from_py_dict(err, CDT_CTX_ORDER_KEY, py_extra_args, &list_order); + if (err->code != AEROSPIKE_OK) { + goto CLEANUP1; + } get_int_from_py_dict(err, CDT_CTX_PAD_KEY, py_extra_args, &pad); + if (err->code != AEROSPIKE_OK) { + goto CLEANUP1; + } as_cdt_ctx_add_list_index_create(cdt_ctx, int_val, list_order, pad); break; From 18e9a3e74f675db2cee618f9f7aa081bf845f50e Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 13 Jan 2026 08:43:56 -0800 Subject: [PATCH 37/99] get_cdt_ctx must set status local var or it will be AEROSPIKE_OK --- src/main/conversions.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/conversions.c b/src/main/conversions.c index 598bec8932..82aac7cf8a 100644 --- a/src/main/conversions.c +++ b/src/main/conversions.c @@ -2503,12 +2503,13 @@ as_status get_cdt_ctx(AerospikeClient *self, as_error *err, as_cdt_ctx *cdt_ctx, case CDT_CTX_LIST_INDEX_CREATE:; int list_order = 0; int pad = 0; - get_int_from_py_dict(err, CDT_CTX_ORDER_KEY, py_extra_args, - &list_order); + status = get_int_from_py_dict(err, CDT_CTX_ORDER_KEY, + py_extra_args, &list_order); if (err->code != AEROSPIKE_OK) { goto CLEANUP1; } - get_int_from_py_dict(err, CDT_CTX_PAD_KEY, py_extra_args, &pad); + status = get_int_from_py_dict(err, CDT_CTX_PAD_KEY, + py_extra_args, &pad); if (err->code != AEROSPIKE_OK) { goto CLEANUP1; } From 4f415347537077d058d4ac731237748b0533db92 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:13:20 -0800 Subject: [PATCH 38/99] Clear up why we have this flag instead of using succeed flag --- src/main/client/cdt_list_operate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 1f956c8582..8b5ede8d32 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -51,6 +51,8 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, int serializer_type) { + // as_operations_add_* API methods can take ownership of heap allocated as_val + // objects even if the methods fail and return false. bool has_as_operations_taken_ownership_of_as_val_objs = false; char *bin = NULL; From 5e739477e670baa4f9a99bf40c15fe30802f59f6 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:45:51 -0800 Subject: [PATCH 39/99] Add test case for list_remove_by_index_range receiving count = None --- test/new_tests/test_new_list_operation_helpers.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/new_tests/test_new_list_operation_helpers.py b/test/new_tests/test_new_list_operation_helpers.py index 23d4fc2da4..dc2ee2caeb 100644 --- a/test/new_tests/test_new_list_operation_helpers.py +++ b/test/new_tests/test_new_list_operation_helpers.py @@ -243,17 +243,18 @@ def test_remove_by_index(self): _, _, bins = self.as_connection.get(self.test_key) assert bins[self.test_bin] == self.test_list[:2] + self.test_list[3:] - def test_remove_by_index_range(self): + @pytest.mark.parametrize("count, expected_result", + [(2, [5, 8]), (None, [5, 8, 9, 10])] + ) + def test_remove_by_index_range(self, count, expected_result): """ Remove the 3rd item, a 5 """ - operation = list_operations.list_remove_by_index_range(self.test_bin, 2, aerospike.LIST_RETURN_VALUE, count=2) + operation = list_operations.list_remove_by_index_range(self.test_bin, count, aerospike.LIST_RETURN_VALUE, count=2) result = get_list_result_from_operation(self.as_connection, self.test_key, operation, self.test_bin) - assert result == [5, 8] - _, _, bins = self.as_connection.get(self.test_key) - assert bins[self.test_bin] == self.test_list[:2] + self.test_list[4:] + assert result == expected_result def test_remove_by_index_range_inverted(self): """ From 22094f1775f78626c1d2f2ed891023019de72863 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:50:32 -0800 Subject: [PATCH 40/99] Revert "Add test case for list_remove_by_index_range receiving count = None" This reverts commit 5e739477e670baa4f9a99bf40c15fe30802f59f6. --- test/new_tests/test_new_list_operation_helpers.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/new_tests/test_new_list_operation_helpers.py b/test/new_tests/test_new_list_operation_helpers.py index dc2ee2caeb..23d4fc2da4 100644 --- a/test/new_tests/test_new_list_operation_helpers.py +++ b/test/new_tests/test_new_list_operation_helpers.py @@ -243,18 +243,17 @@ def test_remove_by_index(self): _, _, bins = self.as_connection.get(self.test_key) assert bins[self.test_bin] == self.test_list[:2] + self.test_list[3:] - @pytest.mark.parametrize("count, expected_result", - [(2, [5, 8]), (None, [5, 8, 9, 10])] - ) - def test_remove_by_index_range(self, count, expected_result): + def test_remove_by_index_range(self): """ Remove the 3rd item, a 5 """ - operation = list_operations.list_remove_by_index_range(self.test_bin, count, aerospike.LIST_RETURN_VALUE, count=2) + operation = list_operations.list_remove_by_index_range(self.test_bin, 2, aerospike.LIST_RETURN_VALUE, count=2) result = get_list_result_from_operation(self.as_connection, self.test_key, operation, self.test_bin) - assert result == expected_result + assert result == [5, 8] + _, _, bins = self.as_connection.get(self.test_key) + assert bins[self.test_bin] == self.test_list[:2] + self.test_list[4:] def test_remove_by_index_range_inverted(self): """ From f257041625e92b29b8a3abaee45c165cc38497cc Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 13 Jan 2026 13:22:48 -0800 Subject: [PATCH 41/99] Those stack vars belong to specific cases so they should be in their own scope anyways --- src/main/client/cdt_list_operate.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 8b5ede8d32..c24d1c1197 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -355,7 +355,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_set_order(ops, bin, ctx_ref, (as_list_order)order_type_int); break; - case OP_LIST_SORT: + case OP_LIST_SORT: { int64_t sort_flags; if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != @@ -365,6 +365,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, success = as_operations_list_sort(ops, bin, ctx_ref, (as_list_sort_flags)sort_flags); break; + } case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: if (range_specified) { success = as_operations_list_get_by_value_rel_rank_range( @@ -375,7 +376,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, ops, bin, ctx_ref, val, rank, return_type); } break; - case OP_LIST_CREATE: + case OP_LIST_CREATE: { bool pad, persist_index; if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != AEROSPIKE_OK) { @@ -391,6 +392,7 @@ as_status add_new_list_op(AerospikeClient *self, as_error *err, (as_list_order)order_type_int, pad, persist_index); break; + } case OP_LIST_APPEND: success = as_operations_list_append(ops, bin, ctx_ref, list_policy_ref, val); From 401800c39d56ef2871422d2352be21a7e2c1034f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 25 Feb 2026 00:20:54 +0000 Subject: [PATCH 42/99] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/main/client/cdt_list_operate.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index c24d1c1197..94e26b26e7 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -36,10 +36,7 @@ typedef struct { } op_code_to_name; op_code_to_name op_code_to_names[] = { -#define X(op_name) \ - { \ - OP_##op_name, #op_name \ - } +#define X(op_name) {OP_##op_name, #op_name} X(LIST_APPEND), LIST_OP_NAMES_EXCEPT_LIST_APPEND #undef X }; From c44b6a68f80b37d1fe9c6c8083d40482d8e6bde0 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Wed, 22 Apr 2026 19:36:16 -0700 Subject: [PATCH 43/99] List ops aren't new anymore --- src/include/cdt_list_operations.h | 9 ++++----- src/main/client/cdt_list_operate.c | 9 ++++----- src/main/client/operate.c | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/include/cdt_list_operations.h b/src/include/cdt_list_operations.h index a68a078b54..6fc112d431 100644 --- a/src/include/cdt_list_operations.h +++ b/src/include/cdt_list_operations.h @@ -21,8 +21,7 @@ #include #include "types.h" -as_status add_new_list_op(AerospikeClient *self, as_error *err, - PyObject *op_dict, as_vector *unicodeStrVector, - as_static_pool *static_pool, as_operations *ops, - long operation_code, long *ret_type, - int serializer_type); +as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, + as_vector *unicodeStrVector, as_static_pool *static_pool, + as_operations *ops, long operation_code, long *ret_type, + int serializer_type); diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 94e26b26e7..96ec813721 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -41,11 +41,10 @@ op_code_to_name op_code_to_names[] = { #undef X }; -as_status add_new_list_op(AerospikeClient *self, as_error *err, - PyObject *op_dict, as_vector *unicodeStrVector, - as_static_pool *static_pool, as_operations *ops, - long operation_code, long *ret_type, - int serializer_type) +as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, + as_vector *unicodeStrVector, as_static_pool *static_pool, + as_operations *ops, long operation_code, long *ret_type, + int serializer_type) { // as_operations_add_* API methods can take ownership of heap allocated as_val diff --git a/src/main/client/operate.c b/src/main/client/operate.c index b743252b83..8cf97362e1 100644 --- a/src/main/client/operate.c +++ b/src/main/client/operate.c @@ -355,7 +355,7 @@ as_status add_op(AerospikeClient *self, as_error *err, /* Handle the list operations with a helper in the cdt_list_operate.c file */ if (isListOp(operation)) { - return add_new_list_op( + return add_list_op( self, err, py_operation_dict, unicodeStrVector, static_pool, ops, operation, ret_type, SERIALIZER_PYTHON); //This hardcoding matches current behavior From c1a8785e4c35478a8328043806f3285f782b9241 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Wed, 22 Apr 2026 20:01:07 -0700 Subject: [PATCH 44/99] Simplify code by using only 2 as_val variables instead of four. This simplifies the memory cleanup code. Also add some test coverage for memory cleanup code --- src/main/client/cdt_list_operate.c | 78 +++++++++++--------------- test/new_tests/test_operate_helpers.py | 14 +++++ 2 files changed, 47 insertions(+), 45 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index 96ec813721..e679930d1f 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -165,7 +165,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, } as_cdt_ctx *ctx_ref = (ctx_in_use ? &ctx : NULL); - as_val *val = NULL; + as_val *val1 = NULL; switch (operation_code) { case OP_LIST_APPEND: case OP_LIST_INSERT: @@ -175,7 +175,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, case OP_LIST_REMOVE_BY_VALUE: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val, static_pool, + if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val1, static_pool, serializer_type, true) != AEROSPIKE_OK) { goto CLEANUP_CTX_ON_ERROR; } @@ -194,32 +194,30 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, break; } - as_list *value_list = NULL; switch (operation_code) { case OP_LIST_GET_BY_VALUE_LIST: case OP_LIST_REMOVE_BY_VALUE_LIST: case OP_LIST_APPEND_ITEMS: case OP_LIST_INSERT_ITEMS: - if (get_val_list(self, err, list_values_key, op_dict, &value_list, + if (get_val_list(self, err, list_values_key, op_dict, (as_list **)&val1, static_pool, serializer_type) != AEROSPIKE_OK) { - goto CLEANUP_VAL_ON_ERROR1; + goto CLEANUP_CTX_ON_ERROR; } break; } - as_val *val_begin = NULL; - as_val *val_end = NULL; + as_val *val2 = NULL; switch (operation_code) { case OP_LIST_GET_BY_VALUE_RANGE: case OP_LIST_REMOVE_BY_VALUE_RANGE: - if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val_begin, + if (get_asval(self, err, AS_PY_VAL_BEGIN_KEY, op_dict, &val1, static_pool, serializer_type, false) != AEROSPIKE_OK) { - goto CLEANUP_VAL_ON_ERROR2; + goto CLEANUP_CTX_ON_ERROR; } - if (get_asval(self, err, AS_PY_VAL_END_KEY, op_dict, &val_end, - static_pool, serializer_type, false) != AEROSPIKE_OK) { - goto CLEANUP_VAL_ON_ERROR3; + if (get_asval(self, err, AS_PY_VAL_END_KEY, op_dict, &val2, static_pool, + serializer_type, false) != AEROSPIKE_OK) { + goto CLEANUP_VAL1_ON_ERROR; } break; } @@ -248,7 +246,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, break; case OP_LIST_SET: success = as_operations_list_set(ops, bin, ctx_ref, list_policy_ref, - index, val); + index, val1); break; case OP_LIST_GET: success = as_operations_list_get(ops, bin, ctx_ref, index); @@ -292,7 +290,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, } break; case OP_LIST_GET_BY_VALUE: - success = as_operations_list_get_by_value(ops, bin, ctx_ref, val, + success = as_operations_list_get_by_value(ops, bin, ctx_ref, val1, return_type); break; case OP_LIST_GET_BY_VALUE_LIST: @@ -300,8 +298,8 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, value_list, return_type); break; case OP_LIST_GET_BY_VALUE_RANGE: - success = as_operations_list_get_by_value_range( - ops, bin, ctx_ref, val_begin, val_end, return_type); + success = as_operations_list_get_by_value_range(ops, bin, ctx_ref, val1, + val2, return_type); break; case OP_LIST_REMOVE_BY_INDEX: @@ -336,7 +334,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, break; case OP_LIST_REMOVE_BY_VALUE: - success = as_operations_list_remove_by_value(ops, bin, ctx_ref, val, + success = as_operations_list_remove_by_value(ops, bin, ctx_ref, val1, return_type); break; case OP_LIST_REMOVE_BY_VALUE_LIST: @@ -345,7 +343,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, break; case OP_LIST_REMOVE_BY_VALUE_RANGE: success = as_operations_list_remove_by_value_range( - ops, bin, ctx_ref, val_begin, val_end, return_type); + ops, bin, ctx_ref, val1, val2, return_type); break; case OP_LIST_SET_ORDER: success = as_operations_list_set_order(ops, bin, ctx_ref, @@ -356,7 +354,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != AEROSPIKE_OK) { - goto CLEANUP_VAL_ON_ERROR4; + goto CLEANUP_VAL2_ON_ERROR; } success = as_operations_list_sort(ops, bin, ctx_ref, (as_list_sort_flags)sort_flags); @@ -365,23 +363,23 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: if (range_specified) { success = as_operations_list_get_by_value_rel_rank_range( - ops, bin, ctx_ref, val, rank, (uint64_t)count, return_type); + ops, bin, ctx_ref, val1, rank, (uint64_t)count, return_type); } else { success = as_operations_list_get_by_value_rel_rank_range_to_end( - ops, bin, ctx_ref, val, rank, return_type); + ops, bin, ctx_ref, val1, rank, return_type); } break; case OP_LIST_CREATE: { bool pad, persist_index; if (get_bool_from_pyargs(err, AS_PY_PAD, op_dict, &pad) != AEROSPIKE_OK) { - goto CLEANUP_VAL_ON_ERROR4; + goto CLEANUP_VAL2_ON_ERROR; } if (get_bool_from_pyargs(err, AS_PY_PERSIST_INDEX, op_dict, &persist_index) != AEROSPIKE_OK) { - goto CLEANUP_VAL_ON_ERROR4; + goto CLEANUP_VAL2_ON_ERROR; } success = as_operations_list_create_all(ops, bin, ctx_ref, @@ -391,7 +389,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, } case OP_LIST_APPEND: success = - as_operations_list_append(ops, bin, ctx_ref, list_policy_ref, val); + as_operations_list_append(ops, bin, ctx_ref, list_policy_ref, val1); break; case OP_LIST_APPEND_ITEMS: success = as_operations_list_append_items(ops, bin, ctx_ref, @@ -399,7 +397,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, break; case OP_LIST_INSERT: success = as_operations_list_insert(ops, bin, ctx_ref, list_policy_ref, - index, val); + index, val1); break; case OP_LIST_INSERT_ITEMS: success = as_operations_list_insert_items( @@ -407,22 +405,22 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, break; case OP_LIST_INCREMENT: success = as_operations_list_increment(ops, bin, ctx_ref, - list_policy_ref, index, val); + list_policy_ref, index, val1); break; case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: if (range_specified) { success = as_operations_list_remove_by_value_rel_rank_range( - ops, bin, ctx_ref, val, rank, (uint64_t)count, return_type); + ops, bin, ctx_ref, val1, rank, (uint64_t)count, return_type); } else { success = as_operations_list_remove_by_value_rel_rank_range_to_end( - ops, bin, ctx_ref, val, rank, return_type); + ops, bin, ctx_ref, val1, rank, return_type); } break; default: // This should never be possible since we only get here if we know that the operation is valid. as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); - goto CLEANUP_VAL_ON_ERROR4; + goto CLEANUP_VAL2_ON_ERROR; } has_as_operations_taken_ownership_of_as_val_objs = true; @@ -433,24 +431,14 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, } if (has_as_operations_taken_ownership_of_as_val_objs == false) { - CLEANUP_VAL_ON_ERROR4: - if (val_end) { - as_val_destroy(val_end); - } - - CLEANUP_VAL_ON_ERROR3: - if (val_begin) { - as_val_destroy(val_begin); - } - - CLEANUP_VAL_ON_ERROR2: - if (value_list) { - as_list_destroy(value_list); + CLEANUP_VAL2_ON_ERROR: + if (val2) { + as_val_destroy(val2); } - CLEANUP_VAL_ON_ERROR1: - if (val) { - as_val_destroy(val); + CLEANUP_VAL1_ON_ERROR: + if (val1) { + as_val_destroy(val1); } } diff --git a/test/new_tests/test_operate_helpers.py b/test/new_tests/test_operate_helpers.py index 061c36ddd2..2609ed3e44 100644 --- a/test/new_tests/test_operate_helpers.py +++ b/test/new_tests/test_operate_helpers.py @@ -1059,3 +1059,17 @@ def test_neg_operate_with_incorrect_polic(self): with pytest.raises(e.ParamError): self.as_connection.operate(key, llist, {}, policy) + + @pytest.mark.parametrize( + "op", + [ + list_operations.list_insert_items("a", 0, "nonlist") + ] + ) + def test_list_operations_with_nonlist_parameters(self, op): + key = ("test", "demo", 1) + ops = [ + op + ] + + self.as_connection.operate(key, ops) From 534f1adc83f74f5c41e97ba6b5e1c986806e282a Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Wed, 22 Apr 2026 20:36:53 -0700 Subject: [PATCH 45/99] Fix compiler error --- src/main/client/cdt_list_operate.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index e679930d1f..5d02b865a1 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -294,8 +294,8 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, return_type); break; case OP_LIST_GET_BY_VALUE_LIST: - success = as_operations_list_get_by_value_list(ops, bin, ctx_ref, - value_list, return_type); + success = as_operations_list_get_by_value_list( + ops, bin, ctx_ref, (as_list *)val1, return_type); break; case OP_LIST_GET_BY_VALUE_RANGE: success = as_operations_list_get_by_value_range(ops, bin, ctx_ref, val1, @@ -339,7 +339,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, break; case OP_LIST_REMOVE_BY_VALUE_LIST: success = as_operations_list_remove_by_value_list( - ops, bin, ctx_ref, value_list, return_type); + ops, bin, ctx_ref, (as_list *)val1, return_type); break; case OP_LIST_REMOVE_BY_VALUE_RANGE: success = as_operations_list_remove_by_value_range( @@ -392,8 +392,8 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, as_operations_list_append(ops, bin, ctx_ref, list_policy_ref, val1); break; case OP_LIST_APPEND_ITEMS: - success = as_operations_list_append_items(ops, bin, ctx_ref, - list_policy_ref, value_list); + success = as_operations_list_append_items( + ops, bin, ctx_ref, list_policy_ref, (as_list *)val1); break; case OP_LIST_INSERT: success = as_operations_list_insert(ops, bin, ctx_ref, list_policy_ref, @@ -401,7 +401,7 @@ as_status add_list_op(AerospikeClient *self, as_error *err, PyObject *op_dict, break; case OP_LIST_INSERT_ITEMS: success = as_operations_list_insert_items( - ops, bin, ctx_ref, list_policy_ref, index, value_list); + ops, bin, ctx_ref, list_policy_ref, index, (as_list *)val1); break; case OP_LIST_INCREMENT: success = as_operations_list_increment(ops, bin, ctx_ref, From a6e13fdbdcac6ff82ca23646872fd79dce376b03 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 23 Apr 2026 07:39:48 -0700 Subject: [PATCH 46/99] test is negative. --- test/new_tests/test_operate_helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/new_tests/test_operate_helpers.py b/test/new_tests/test_operate_helpers.py index 2609ed3e44..6898bf99e9 100644 --- a/test/new_tests/test_operate_helpers.py +++ b/test/new_tests/test_operate_helpers.py @@ -1071,5 +1071,5 @@ def test_list_operations_with_nonlist_parameters(self, op): ops = [ op ] - - self.as_connection.operate(key, ops) + with pytest.raises(e.ParamError): + self.as_connection.operate(key, ops) From a8fd0cc3168b9e90ce9d16fc9bdbd427bf678e13 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 23 Apr 2026 08:50:25 -0700 Subject: [PATCH 47/99] add more positive test cases to address missing code coverage --- .../test_new_list_operation_helpers.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/new_tests/test_new_list_operation_helpers.py b/test/new_tests/test_new_list_operation_helpers.py index 23d4fc2da4..5f29dddea6 100644 --- a/test/new_tests/test_new_list_operation_helpers.py +++ b/test/new_tests/test_new_list_operation_helpers.py @@ -255,6 +255,18 @@ def test_remove_by_index_range(self): _, _, bins = self.as_connection.get(self.test_key) assert bins[self.test_bin] == self.test_list[:2] + self.test_list[4:] + def test_remove_by_index_range_with_none_count(self): + """ + Remove all elements starting from index 2 + """ + operation = list_operations.list_remove_by_index_range(self.test_bin, 2, aerospike.LIST_RETURN_VALUE, count=None) + + result = get_list_result_from_operation(self.as_connection, self.test_key, operation, self.test_bin) + + assert result == self.test_list[2:] + _, _, bins = self.as_connection.get(self.test_key) + assert bins[self.test_bin] == self.test_list[:2] + def test_remove_by_index_range_inverted(self): """ Remove the 3rd item, a 5 @@ -294,6 +306,18 @@ def test_remove_by_rank_range(self): _, _, bins = self.as_connection.get(self.test_key) assert bins[self.test_bin] == self.test_list[3:] + def test_remove_by_rank_range_with_none_count(self): + """ + Remove the largest 2 items + """ + operation = list_operations.list_remove_by_rank_range(self.test_bin, 4, aerospike.LIST_RETURN_VALUE, count=None) + + result = get_list_result_from_operation(self.as_connection, self.test_key, operation, self.test_bin) + + assert result == [9, 10] + _, _, bins = self.as_connection.get(self.test_key) + assert bins[self.test_bin] == self.test_list[:-2] + def test_remove_by_rank_range_inverted(self): """ Remove the 3rd smallest item, a 7 at index 0 From fe09cb4975de251a2cadeadfdc1100deec19f100 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 8 May 2026 15:07:07 -0700 Subject: [PATCH 48/99] Rm unused struct from last refactor PR --- src/main/client/cdt_list_operate.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/client/cdt_list_operate.c b/src/main/client/cdt_list_operate.c index c649be0fd3..26c09bf3f8 100644 --- a/src/main/client/cdt_list_operate.c +++ b/src/main/client/cdt_list_operate.c @@ -30,11 +30,6 @@ #include "cdt_list_operations.h" #include "cdt_operation_utils.h" -typedef struct { - int operation_code; - const char *operation_name; -} op_code_to_name; - const char *op_code_to_names[] = { #define X(op_name) [OP_##op_name] = #op_name X(LIST_APPEND), LIST_OP_NAMES_EXCEPT_LIST_APPEND From dc9e00112689dc2f06574b1de99e10c13859a14c Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 8 May 2026 15:23:31 -0700 Subject: [PATCH 49/99] WIP --- src/main/client/cdt_map_operate.c | 86 ++++++++++++------------------- 1 file changed, 33 insertions(+), 53 deletions(-) diff --git a/src/main/client/cdt_map_operate.c b/src/main/client/cdt_map_operate.c index b3f850adde..778db9e696 100644 --- a/src/main/client/cdt_map_operate.c +++ b/src/main/client/cdt_map_operate.c @@ -37,22 +37,6 @@ static as_status get_map_return_type(as_error *err, PyObject *op_dict, int *return_type); -static as_status add_op_map_remove_by_value_rel_rank_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type); - -static as_status add_op_map_get_by_value_rel_rank_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type); - -static as_status add_op_map_remove_by_key_rel_index_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type); - -static as_status add_op_map_get_by_key_rel_index_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type); - as_status add_new_map_op(AerospikeClient *self, as_error *err, PyObject *op_dict, as_vector *unicodeStrVector, as_static_pool *static_pool, as_operations *ops, @@ -66,26 +50,51 @@ as_status add_new_map_op(AerospikeClient *self, as_error *err, return err->code; } + int return_type = AS_MAP_RETURN_VALUE; + if (get_map_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { + return err->code; + } + + bool count_present = false; + int64_t count; + if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, + &count_present) != AEROSPIKE_OK) { + return err->code; + } + + as_cdt_ctx ctx; + if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, + serializer_type) != AEROSPIKE_OK) { + return err->code; + } + + int64_t rank; + as_val *value = NULL; + switch (operation_code) { + case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: + case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: + if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { + return err->code; + } + + if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &value, static_pool, + serializer_type, true) != AEROSPIKE_OK) { + return err->code; + } + } + switch (operation_code) { case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: { - return add_op_map_remove_by_value_rel_rank_range( - self, err, bin, op_dict, ops, static_pool, serializer_type); } case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: { - return add_op_map_get_by_value_rel_rank_range( - self, err, bin, op_dict, ops, static_pool, serializer_type); } case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: { - return add_op_map_remove_by_key_rel_index_range( - self, err, bin, op_dict, ops, static_pool, serializer_type); } case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: { - return add_op_map_get_by_key_rel_index_range( - self, err, bin, op_dict, ops, static_pool, serializer_type); } default: // This should never be possible since we only get here if we know that the operation is valid. @@ -100,35 +109,6 @@ static as_status add_op_map_remove_by_value_rel_rank_range( as_operations *ops, as_static_pool *static_pool, int serializer_type) { bool count_present = false; - int64_t count; - int return_type = AS_MAP_RETURN_VALUE; - int64_t rank; - as_val *value = NULL; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_map_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &count_present) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &value, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } if (count_present) { if (!as_operations_map_remove_by_value_rel_rank_range( From 2f57d8692ce619c27b96fff753403f84a548f5e4 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 8 May 2026 15:47:20 -0700 Subject: [PATCH 50/99] more wip --- src/main/client/cdt_map_operate.c | 281 +++++++----------------------- 1 file changed, 61 insertions(+), 220 deletions(-) diff --git a/src/main/client/cdt_map_operate.c b/src/main/client/cdt_map_operate.c index 778db9e696..ed60d840a2 100644 --- a/src/main/client/cdt_map_operate.c +++ b/src/main/client/cdt_map_operate.c @@ -62,12 +62,6 @@ as_status add_new_map_op(AerospikeClient *self, as_error *err, return err->code; } - as_cdt_ctx ctx; - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - int64_t rank; as_val *value = NULL; switch (operation_code) { @@ -83,246 +77,93 @@ as_status add_new_map_op(AerospikeClient *self, as_error *err, } } + as_val *key = NULL; switch (operation_code) { - - case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: { - } - - case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: { - } - - case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: { - } - - case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: { - } - default: - // This should never be possible since we only get here if we know that the operation is valid. - return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); - } - - return err->code; -} - -static as_status add_op_map_remove_by_value_rel_rank_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type) -{ - bool count_present = false; - - if (count_present) { - if (!as_operations_map_remove_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add map remove by value rank relative operation"); - } - } - else { - if (!as_operations_map_remove_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add map remove by value rank relative operation"); + case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: + case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: + if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &rank) != AEROSPIKE_OK) { + return err->code; } - } - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); + if (get_asval(self, err, AS_PY_MAP_KEY_KEY, op_dict, &key, static_pool, + serializer_type, true) != AEROSPIKE_OK) { + return err->code; + } } - return AEROSPIKE_OK; -} - -static as_status add_op_map_get_by_value_rel_rank_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type) -{ - bool count_present = false; - int64_t count; - int return_type = AS_MAP_RETURN_VALUE; - int64_t rank; - as_val *value = NULL; - bool ctx_in_use = false; as_cdt_ctx ctx; - - if (get_map_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &count_present) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &value, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - + bool ctx_in_use = false; if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, serializer_type) != AEROSPIKE_OK) { return err->code; } - if (count_present) { - if (!as_operations_map_get_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add map get by value rank relative operation"); + switch (operation_code) { + case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: { + if (count_present) { + if (!as_operations_map_remove_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, + (uint64_t)count, return_type)) { + } } - } - else { - if (!as_operations_map_get_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add map get by value rank relative operation"); + else { + if (!as_operations_map_remove_by_value_rel_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, + return_type)) { + } } } - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_map_remove_by_key_rel_index_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type) -{ - bool count_present = false; - int64_t count; - int return_type = AS_MAP_RETURN_VALUE; - int64_t rank; - as_val *key = NULL; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_map_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &count_present) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_MAP_KEY_KEY, op_dict, &key, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - - if (count_present) { - if (!as_operations_map_remove_by_key_rel_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), key, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add map remove by key rank relative operation"); + case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: { + if (count_present) { + if (!as_operations_map_get_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, + (uint64_t)count, return_type)) { + } } - } - else { - if (!as_operations_map_remove_by_key_rel_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), key, rank, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add map remove by key rank relative operation"); + else { + if (!as_operations_map_get_by_value_rel_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, + return_type)) { + } } } - if (ctx_in_use) { - as_cdt_ctx_destroy(&ctx); - } - - return AEROSPIKE_OK; -} - -static as_status add_op_map_get_by_key_rel_index_range( - AerospikeClient *self, as_error *err, char *bin, PyObject *op_dict, - as_operations *ops, as_static_pool *static_pool, int serializer_type) -{ - bool count_present = false; - int64_t count; - int return_type = AS_MAP_RETURN_VALUE; - int64_t rank; - as_val *key = NULL; - bool ctx_in_use = false; - as_cdt_ctx ctx; - - if (get_map_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &count_present) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_MAP_KEY_KEY, op_dict, &key, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; + case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: { + if (count_present) { + if (!as_operations_map_remove_by_value_rel_rank_range( + ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, + (uint64_t)count, return_type)) { + } + else { + if (!as_operations_map_remove_by_value_rel_rank_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, + return_type)) { + } + } + } } - if (count_present) { - if (!as_operations_map_get_by_key_rel_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), key, rank, - (uint64_t)count, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add map get by key rank relative operation"); + case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: { + if (count_present) { + if (!as_operations_map_get_by_key_rel_index_range( + ops, bin, (ctx_in_use ? &ctx : NULL), key, rank, + (uint64_t)count, return_type)) { + } } - } - else { - if (!as_operations_map_get_by_key_rel_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), key, rank, return_type)) { - as_cdt_ctx_destroy(&ctx); - return as_error_update( - err, AEROSPIKE_ERR_CLIENT, - "Failed to add map get by key rank relative operation"); + else { + if (!as_operations_map_get_by_key_rel_index_range_to_end( + ops, bin, (ctx_in_use ? &ctx : NULL), key, rank, + return_type)) { + } } } - - if (ctx_in_use) { //add these spaces - as_cdt_ctx_destroy(&ctx); + default: + // This should never be possible since we only get here if we know that the operation is valid. + return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); } - return AEROSPIKE_OK; + return err->code; } static as_status get_map_return_type(as_error *err, PyObject *op_dict, From b6761590fa5e43c6254797c95f5cf18cec99b2cb Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 7 Jul 2026 08:43:29 -0700 Subject: [PATCH 51/99] Refactor ctx code to be consistent with the other ops --- src/main/client/cdt_map_operate.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/main/client/cdt_map_operate.c b/src/main/client/cdt_map_operate.c index ed60d840a2..1bc347e15a 100644 --- a/src/main/client/cdt_map_operate.c +++ b/src/main/client/cdt_map_operate.c @@ -97,19 +97,19 @@ as_status add_new_map_op(AerospikeClient *self, as_error *err, serializer_type) != AEROSPIKE_OK) { return err->code; } + as_cdt_ctx *ctx_ref = ctx_in_use ? &ctx : NULL; switch (operation_code) { case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: { if (count_present) { if (!as_operations_map_remove_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - (uint64_t)count, return_type)) { + ops, bin, ctx_ref, value, rank, (uint64_t)count, + return_type)) { } } else { if (!as_operations_map_remove_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - return_type)) { + ops, bin, ctx_ref, value, rank, return_type)) { } } } @@ -117,14 +117,13 @@ as_status add_new_map_op(AerospikeClient *self, as_error *err, case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: { if (count_present) { if (!as_operations_map_get_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - (uint64_t)count, return_type)) { + ops, bin, ctx_ref, value, rank, (uint64_t)count, + return_type)) { } } else { if (!as_operations_map_get_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - return_type)) { + ops, bin, ctx_ref, value, rank, return_type)) { } } } @@ -132,13 +131,12 @@ as_status add_new_map_op(AerospikeClient *self, as_error *err, case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: { if (count_present) { if (!as_operations_map_remove_by_value_rel_rank_range( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - (uint64_t)count, return_type)) { + ops, bin, ctx_ref, value, rank, (uint64_t)count, + return_type)) { } else { if (!as_operations_map_remove_by_value_rel_rank_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), value, rank, - return_type)) { + ops, bin, ctx_ref, value, rank, return_type)) { } } } @@ -147,14 +145,13 @@ as_status add_new_map_op(AerospikeClient *self, as_error *err, case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: { if (count_present) { if (!as_operations_map_get_by_key_rel_index_range( - ops, bin, (ctx_in_use ? &ctx : NULL), key, rank, - (uint64_t)count, return_type)) { + ops, bin, ctx_ref, key, rank, (uint64_t)count, + return_type)) { } } else { if (!as_operations_map_get_by_key_rel_index_range_to_end( - ops, bin, (ctx_in_use ? &ctx : NULL), key, rank, - return_type)) { + ops, bin, ctx_ref, key, rank, return_type)) { } } } From 0a94dd3ac0eb08763830f76a21eaae45e3866c61 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:10:44 -0700 Subject: [PATCH 52/99] Rename list_and_string_operate.c to operate_helper.c. Incorporate cdt_map_operate.c into operate_helper.c --- src/include/cdt_list_operations.h | 12 +- src/include/cdt_operation_utils.h | 1 + src/main/client/cdt_map_operate.c | 193 ------------------ src/main/client/operate.c | 29 +-- ..._and_string_operate.c => operate_helper.c} | 107 +++++++++- 5 files changed, 119 insertions(+), 223 deletions(-) delete mode 100644 src/main/client/cdt_map_operate.c rename src/main/client/{list_and_string_operate.c => operate_helper.c} (88%) diff --git a/src/include/cdt_list_operations.h b/src/include/cdt_list_operations.h index 564a9cf042..9f166d0f54 100644 --- a/src/include/cdt_list_operations.h +++ b/src/include/cdt_list_operations.h @@ -21,8 +21,10 @@ #include #include "types.h" -as_status add_list_or_string_op(AerospikeClient *self, as_error *err, - PyObject *op_dict, as_vector *unicodeStrVector, - as_static_pool *static_pool, as_operations *ops, - long operation_code, long *ret_type, - int serializer_type); +as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, + PyObject *op_dict, + as_vector *unicodeStrVector, + as_static_pool *static_pool, + as_operations *ops, + long operation_code, long *ret_type, + int serializer_type); diff --git a/src/include/cdt_operation_utils.h b/src/include/cdt_operation_utils.h index faf61ba483..c06efa004a 100644 --- a/src/include/cdt_operation_utils.h +++ b/src/include/cdt_operation_utils.h @@ -25,6 +25,7 @@ #define AS_PY_BIN_KEY "bin" #define AS_PY_VAL_KEY "val" +#define AS_PY_MAP_KEY_KEY "key" #define AS_PY_VALUES_KEY "value_list" #define AS_PY_VAL_BEGIN_KEY "value_begin" #define AS_PY_VAL_END_KEY "value_end" diff --git a/src/main/client/cdt_map_operate.c b/src/main/client/cdt_map_operate.c deleted file mode 100644 index 1bc347e15a..0000000000 --- a/src/main/client/cdt_map_operate.c +++ /dev/null @@ -1,193 +0,0 @@ -/******************************************************************************* - * Copyright 2013-2019 Aerospike, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ******************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "client.h" -#include "conversions.h" -#include "exceptions.h" -#include "policy.h" -#include "serializer.h" -#include "cdt_map_operations.h" -#include "cdt_operation_utils.h" - -#define AS_PY_MAP_RETURN_KEY "return_type" -#define AS_PY_MAP_KEY_KEY "key" -#define AS_PY_RETURN_INVERTED_KEY "inverted" -#define AS_PY_MAP_INDEX_KEY "index" - -static as_status get_map_return_type(as_error *err, PyObject *op_dict, - int *return_type); - -as_status add_new_map_op(AerospikeClient *self, as_error *err, - PyObject *op_dict, as_vector *unicodeStrVector, - as_static_pool *static_pool, as_operations *ops, - long operation_code, long *ret_type, - int serializer_type) - -{ - char *bin = NULL; - - if (get_bin(err, op_dict, unicodeStrVector, &bin) != AEROSPIKE_OK) { - return err->code; - } - - int return_type = AS_MAP_RETURN_VALUE; - if (get_map_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { - return err->code; - } - - bool count_present = false; - int64_t count; - if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, - &count_present) != AEROSPIKE_OK) { - return err->code; - } - - int64_t rank; - as_val *value = NULL; - switch (operation_code) { - case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: - case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: - if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &value, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - } - - as_val *key = NULL; - switch (operation_code) { - case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: - case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: - if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &rank) != AEROSPIKE_OK) { - return err->code; - } - - if (get_asval(self, err, AS_PY_MAP_KEY_KEY, op_dict, &key, static_pool, - serializer_type, true) != AEROSPIKE_OK) { - return err->code; - } - } - - as_cdt_ctx ctx; - bool ctx_in_use = false; - if (get_cdt_ctx(self, err, &ctx, op_dict, &ctx_in_use, static_pool, - serializer_type) != AEROSPIKE_OK) { - return err->code; - } - as_cdt_ctx *ctx_ref = ctx_in_use ? &ctx : NULL; - - switch (operation_code) { - case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: { - if (count_present) { - if (!as_operations_map_remove_by_value_rel_rank_range( - ops, bin, ctx_ref, value, rank, (uint64_t)count, - return_type)) { - } - } - else { - if (!as_operations_map_remove_by_value_rel_rank_range_to_end( - ops, bin, ctx_ref, value, rank, return_type)) { - } - } - } - - case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: { - if (count_present) { - if (!as_operations_map_get_by_value_rel_rank_range( - ops, bin, ctx_ref, value, rank, (uint64_t)count, - return_type)) { - } - } - else { - if (!as_operations_map_get_by_value_rel_rank_range_to_end( - ops, bin, ctx_ref, value, rank, return_type)) { - } - } - } - - case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: { - if (count_present) { - if (!as_operations_map_remove_by_value_rel_rank_range( - ops, bin, ctx_ref, value, rank, (uint64_t)count, - return_type)) { - } - else { - if (!as_operations_map_remove_by_value_rel_rank_range_to_end( - ops, bin, ctx_ref, value, rank, return_type)) { - } - } - } - } - - case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: { - if (count_present) { - if (!as_operations_map_get_by_key_rel_index_range( - ops, bin, ctx_ref, key, rank, (uint64_t)count, - return_type)) { - } - } - else { - if (!as_operations_map_get_by_key_rel_index_range_to_end( - ops, bin, ctx_ref, key, rank, return_type)) { - } - } - } - default: - // This should never be possible since we only get here if we know that the operation is valid. - return as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); - } - - return err->code; -} - -static as_status get_map_return_type(as_error *err, PyObject *op_dict, - int *return_type) -{ - int64_t int64_return_type; - int py_bool_val = -1; - - if (get_int64_t(err, AS_PY_MAP_RETURN_KEY, op_dict, &int64_return_type) != - AEROSPIKE_OK) { - return err->code; - } - *return_type = int64_return_type; - PyObject *py_inverted = PyDict_GetItemString( - op_dict, AS_PY_RETURN_INVERTED_KEY); //NOT A MAGIC STRING - - if (py_inverted) { - py_bool_val = PyObject_IsTrue(py_inverted); - /* Essentially bool(py_bool_val) failed, so we raise an exception */ - if (py_bool_val == -1) { - return as_error_update(err, AEROSPIKE_ERR_PARAM, - "Invalid inverted option"); - } - if (py_bool_val == 1) { - *return_type |= AS_MAP_RETURN_INVERTED; - } - } - - return AEROSPIKE_OK; -} diff --git a/src/main/client/operate.c b/src/main/client/operate.c index cbcbe4d7a0..b85bd6619e 100644 --- a/src/main/client/operate.c +++ b/src/main/client/operate.c @@ -46,8 +46,6 @@ static as_status get_operation(as_error *err, PyObject *op_dict, long *operation_ptr); -static inline bool is_list_or_string_op(int op); -static inline bool isNewMapOp(int op); static inline bool isBitOp(int op); static inline bool isHllOp(int op); static inline bool isExprOp(int op); @@ -201,7 +199,7 @@ int check_type(AerospikeClient *self, PyObject *py_value, int op, as_error *err) return 0; } -static inline bool is_list_or_string_op(int op) +static inline bool use_operate_conversion_helper(int op) { return ( op == OP_LIST_APPEND || op == OP_LIST_APPEND_ITEMS || @@ -220,15 +218,11 @@ static inline bool is_list_or_string_op(int op) op == OP_LIST_REMOVE_BY_VALUE_RANGE || op == OP_LIST_SET_ORDER || op == OP_LIST_SORT || op == OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL || op == OP_LIST_GET_BY_VALUE_RANK_RANGE_REL || op == OP_LIST_CREATE || - (op >= OP_STRING_STRLEN && op <= OP_STRING_PREPEND)); -} - -static inline bool isNewMapOp(int op) -{ - return (op == OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL || - op == OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL || - op == OP_MAP_GET_BY_VALUE_RANK_RANGE_REL || - op == OP_MAP_GET_BY_KEY_INDEX_RANGE_REL); + (op >= OP_STRING_STRLEN && op <= OP_STRING_PREPEND) || + (op == OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL || + op == OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL || + op == OP_MAP_GET_BY_VALUE_RANK_RANGE_REL || + op == OP_MAP_GET_BY_KEY_INDEX_RANGE_REL)); } static inline bool isBitOp(int op) @@ -361,20 +355,13 @@ as_status add_op(AerospikeClient *self, as_error *err, return err->code; } - /* Handle the list operations with a helper in the cdt_list_operate.c file */ - if (is_list_or_string_op(operation)) { - return add_list_or_string_op( + if (use_operate_conversion_helper(operation)) { + return as_operations_add_from_pyobject( self, err, py_operation_dict, unicodeStrVector, static_pool, ops, operation, ret_type, SERIALIZER_PYTHON); //This hardcoding matches current behavior } - if (isNewMapOp(operation)) { - return add_new_map_op(self, err, py_operation_dict, unicodeStrVector, - static_pool, ops, operation, ret_type, - SERIALIZER_PYTHON); - } - if (isBitOp(operation)) { return add_new_bit_op(self, err, py_operation_dict, unicodeStrVector, static_pool, ops, operation, ret_type, diff --git a/src/main/client/list_and_string_operate.c b/src/main/client/operate_helper.c similarity index 88% rename from src/main/client/list_and_string_operate.c rename to src/main/client/operate_helper.c index d6b36822c0..8cab2da7fd 100644 --- a/src/main/client/list_and_string_operate.c +++ b/src/main/client/operate_helper.c @@ -37,8 +37,14 @@ // Total memory usage is about 0.056 MB per client const char *op_code_to_names[] = { #define X(op_name) [OP_##op_name] = #op_name - X(LIST_APPEND), LIST_OP_NAMES_EXCEPT_LIST_APPEND, - STRING_OP_NAMES X(BIT_RESIZE), BIT_OP_NAMES_EXCEPT_RESIZE + X(LIST_APPEND), + LIST_OP_NAMES_EXCEPT_LIST_APPEND, + STRING_OP_NAMES X(BIT_RESIZE), + BIT_OP_NAMES_EXCEPT_RESIZE, + X(MAP_REMOVE_BY_KEY_INDEX_RANGE_REL), + X(MAP_REMOVE_BY_VALUE_RANK_RANGE_REL), + X(MAP_GET_BY_VALUE_RANK_RANGE_REL), + X(MAP_GET_BY_KEY_INDEX_RANGE_REL), #undef X }; @@ -66,6 +72,18 @@ as_status add_list_or_string_op(AerospikeClient *self, as_error *err, goto exit; } + int return_type = AS_MAP_RETURN_VALUE; + switch (operation_code) { + case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: + case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: + case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: + case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: + if (get_map_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { + return err->code; + } + break; + } + // Specific to list operations as_list_policy list_policy; @@ -106,6 +124,10 @@ as_status add_list_or_string_op(AerospikeClient *self, as_error *err, case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: case OP_STRING_REPEAT: + case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: + case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: + case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: + case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: if (get_optional_int64_t(err, AS_PY_COUNT_KEY, op_dict, &count, &range_specified) != AEROSPIKE_OK) { goto exit; @@ -113,7 +135,7 @@ as_status add_list_or_string_op(AerospikeClient *self, as_error *err, break; } - int return_type = AS_LIST_RETURN_VALUE; + return_type = AS_LIST_RETURN_VALUE; if ((operation_code >= OP_LIST_GET_BY_INDEX && operation_code <= OP_LIST_REMOVE_BY_VALUE_RANGE) || (operation_code >= OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL && @@ -143,6 +165,8 @@ as_status add_list_or_string_op(AerospikeClient *self, as_error *err, case OP_STRING_CHAR_AT: case OP_STRING_INSERT: case OP_STRING_OVERWRITE: + case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: + case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: if (get_int64_t(err, AS_PY_INDEX_KEY, op_dict, &index) != AEROSPIKE_OK) { goto exit; @@ -157,6 +181,8 @@ as_status add_list_or_string_op(AerospikeClient *self, as_error *err, case OP_LIST_REMOVE_BY_RANK_RANGE: case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: + case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: + case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: if (get_int64_t(err, AS_PY_RANK_KEY, op_dict, &rank) != AEROSPIKE_OK) { goto exit; } @@ -191,12 +217,26 @@ as_status add_list_or_string_op(AerospikeClient *self, as_error *err, case OP_LIST_REMOVE_BY_VALUE: case OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL: case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: - if (get_asval(self, err, AS_PY_VAL_KEY, op_dict, &val1, static_pool, + case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: + case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: + case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: + case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: { + const char *val1_key = NULL; + if (operation_code == OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL || + operation_code == OP_MAP_GET_BY_KEY_INDEX_RANGE_REL) { + val1_key = AS_PY_MAP_KEY_KEY; + } + else { + val1_key = AS_PY_VAL_KEY; + } + + if (get_asval(self, err, val1_key, op_dict, &val1, static_pool, serializer_type, true) != AEROSPIKE_OK) { goto CLEANUP_CTX_ON_ERROR; } break; } + } const char *list_values_key = NULL; switch (operation_code) { @@ -724,6 +764,65 @@ as_status add_list_or_string_op(AerospikeClient *self, as_error *err, success = as_operations_string_prepend(ops, bin, ctx_ref, &str_policy, str_attr_value1); break; + case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: { + if (range_specified) { + if (!as_operations_map_remove_by_value_rel_rank_range( + ops, bin, ctx_ref, val1, rank, (uint64_t)count, + return_type)) { + } + } + else { + if (!as_operations_map_remove_by_value_rel_rank_range_to_end( + ops, bin, ctx_ref, val1, rank, return_type)) { + } + } + break; + } + + case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: { + if (range_specified) { + if (!as_operations_map_get_by_value_rel_rank_range( + ops, bin, ctx_ref, val1, rank, (uint64_t)count, + return_type)) { + } + } + else { + if (!as_operations_map_get_by_value_rel_rank_range_to_end( + ops, bin, ctx_ref, val1, rank, return_type)) { + } + } + break; + } + + case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: { + if (range_specified) { + if (!as_operations_map_remove_by_value_rel_rank_range( + ops, bin, ctx_ref, val1, rank, (uint64_t)count, + return_type)) { + } + else { + if (!as_operations_map_remove_by_value_rel_rank_range_to_end( + ops, bin, ctx_ref, val1, rank, return_type)) { + } + } + } + break; + } + + case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: { + if (range_specified) { + if (!as_operations_map_get_by_key_rel_index_range( + ops, bin, ctx_ref, val1, count, (uint64_t)count, + return_type)) { + } + } + else { + if (!as_operations_map_get_by_key_rel_index_range_to_end( + ops, bin, ctx_ref, val1, count, return_type)) { + } + } + break; + } default: // This should never be possible since we only get here if we know that the operation is valid. as_error_update(err, AEROSPIKE_ERR_PARAM, "Unknown operation"); From 57e488b1e4e994b9738e67a8559026e7bd358f50 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:14:00 -0700 Subject: [PATCH 53/99] Address bad implementation that would likely fail.. --- src/main/client/operate_helper.c | 49 +++++++++++++------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index 8cab2da7fd..817b014519 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -764,62 +764,51 @@ as_status add_list_or_string_op(AerospikeClient *self, as_error *err, success = as_operations_string_prepend(ops, bin, ctx_ref, &str_policy, str_attr_value1); break; + case OP_MAP_REMOVE_BY_VALUE_RANK_RANGE_REL: { if (range_specified) { - if (!as_operations_map_remove_by_value_rel_rank_range( - ops, bin, ctx_ref, val1, rank, (uint64_t)count, - return_type)) { - } + success = as_operations_map_remove_by_value_rel_rank_range( + ops, bin, ctx_ref, val1, rank, (uint64_t)count, return_type); } else { - if (!as_operations_map_remove_by_value_rel_rank_range_to_end( - ops, bin, ctx_ref, val1, rank, return_type)) { - } + success = as_operations_map_remove_by_value_rel_rank_range_to_end( + ops, bin, ctx_ref, val1, rank, return_type); } break; } case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: { if (range_specified) { - if (!as_operations_map_get_by_value_rel_rank_range( - ops, bin, ctx_ref, val1, rank, (uint64_t)count, - return_type)) { - } + success = as_operations_map_get_by_value_rel_rank_range( + ops, bin, ctx_ref, val1, rank, (uint64_t)count, return_type); } else { - if (!as_operations_map_get_by_value_rel_rank_range_to_end( - ops, bin, ctx_ref, val1, rank, return_type)) { - } + success = as_operations_map_get_by_value_rel_rank_range_to_end( + ops, bin, ctx_ref, val1, rank, return_type); } break; } case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: { if (range_specified) { - if (!as_operations_map_remove_by_value_rel_rank_range( - ops, bin, ctx_ref, val1, rank, (uint64_t)count, - return_type)) { - } - else { - if (!as_operations_map_remove_by_value_rel_rank_range_to_end( - ops, bin, ctx_ref, val1, rank, return_type)) { - } - } + success = as_operations_map_remove_by_value_rel_rank_range( + ops, bin, ctx_ref, val1, rank, (uint64_t)count, return_type); + } + else { + success = as_operations_map_remove_by_value_rel_rank_range_to_end( + ops, bin, ctx_ref, val1, rank, return_type); } break; } case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: { if (range_specified) { - if (!as_operations_map_get_by_key_rel_index_range( - ops, bin, ctx_ref, val1, count, (uint64_t)count, - return_type)) { - } + success = as_operations_map_get_by_key_rel_index_range( + ops, bin, ctx_ref, val1, count, (uint64_t)count, return_type); } else { - if (!as_operations_map_get_by_key_rel_index_range_to_end( - ops, bin, ctx_ref, val1, count, return_type)) { - } + success = as_operations_map_get_by_key_rel_index_range_to_end( + ops, bin, ctx_ref, val1, count, return_type); } break; } From 5e46ff552a6a370ae6aaf0bb46929d7723157728 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:19:23 -0700 Subject: [PATCH 54/99] Address compiler errors --- src/include/cdt_operation_utils.h | 4 ++++ src/main/client/cdt_operation_utils.c | 29 +++++++++++++++++++++++++++ src/main/client/operate_helper.c | 12 ++++++----- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/include/cdt_operation_utils.h b/src/include/cdt_operation_utils.h index c06efa004a..65b0d27c6a 100644 --- a/src/include/cdt_operation_utils.h +++ b/src/include/cdt_operation_utils.h @@ -24,6 +24,7 @@ #include "types.h" #define AS_PY_BIN_KEY "bin" +#define AS_PY_RETURN_INVERTED_KEY "inverted" #define AS_PY_VAL_KEY "val" #define AS_PY_MAP_KEY_KEY "key" #define AS_PY_VALUES_KEY "value_list" @@ -82,3 +83,6 @@ as_status get_list_return_type(as_error *err, PyObject *op_dict, as_status get_list_policy(as_error *err, PyObject *op_dict, as_list_policy *policy, bool *found, bool validate_keys); + +as_status get_map_return_type(as_error *err, PyObject *op_dict, + int *return_type); diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index 114b76617c..d7ae305fe5 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -262,3 +262,32 @@ as_status get_list_policy(as_error *err, PyObject *op_dict, return AEROSPIKE_OK; } + +static as_status get_map_return_type(as_error *err, PyObject *op_dict, + int *return_type) +{ + int64_t int64_return_type; + int py_bool_val = -1; + + if (get_int64_t(err, AS_PY_MAP_RETURN_KEY, op_dict, &int64_return_type) != + AEROSPIKE_OK) { + return err->code; + } + *return_type = int64_return_type; + PyObject *py_inverted = PyDict_GetItemString( + op_dict, AS_PY_RETURN_INVERTED_KEY); //NOT A MAGIC STRING + + if (py_inverted) { + py_bool_val = PyObject_IsTrue(py_inverted); + /* Essentially bool(py_bool_val) failed, so we raise an exception */ + if (py_bool_val == -1) { + return as_error_update(err, AEROSPIKE_ERR_PARAM, + "Invalid inverted option"); + } + if (py_bool_val == 1) { + *return_type |= AS_MAP_RETURN_INVERTED; + } + } + + return AEROSPIKE_OK; +} diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index 817b014519..f82bef6d5c 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -53,11 +53,13 @@ const char *op_code_to_names[] = { #define STRING_OP_START_KEY "start" #define NEEDLE_OP_START_KEY "needle" -as_status add_list_or_string_op(AerospikeClient *self, as_error *err, - PyObject *op_dict, as_vector *unicodeStrVector, - as_static_pool *static_pool, as_operations *ops, - long operation_code, long *ret_type, - int serializer_type) +as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, + PyObject *op_dict, + as_vector *unicodeStrVector, + as_static_pool *static_pool, + as_operations *ops, + long operation_code, long *ret_type, + int serializer_type) { // as_operations_add_* API methods can take ownership of heap allocated as_val From 3ef114c63c4cc739a56ab2051a3f730e98fdbae7 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:22:15 -0700 Subject: [PATCH 55/99] Address compiler error - get_map_return_type shouldnt be static --- src/main/client/cdt_operation_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index d7ae305fe5..fce6e95892 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -263,8 +263,8 @@ as_status get_list_policy(as_error *err, PyObject *op_dict, return AEROSPIKE_OK; } -static as_status get_map_return_type(as_error *err, PyObject *op_dict, - int *return_type) +as_status get_map_return_type(as_error *err, PyObject *op_dict, + int *return_type) { int64_t int64_return_type; int py_bool_val = -1; From b559236ca2f099d7bdf998b404f7aa2e4309cc13 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 7 Jul 2026 09:24:05 -0700 Subject: [PATCH 56/99] Address compiler error --- src/main/client/operate_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index f82bef6d5c..11cdd8d001 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -223,7 +223,7 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, case OP_MAP_GET_BY_VALUE_RANK_RANGE_REL: case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: { - const char *val1_key = NULL; + char *val1_key = NULL; if (operation_code == OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL || operation_code == OP_MAP_GET_BY_KEY_INDEX_RANGE_REL) { val1_key = AS_PY_MAP_KEY_KEY; From 5729c0c25879a52fb0adca4c1b94ebc2f7fad61b Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 7 Jul 2026 10:02:01 -0700 Subject: [PATCH 57/99] Address test regressions --- src/main/client/operate_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index 11cdd8d001..f2ee046660 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -793,11 +793,11 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: { if (range_specified) { - success = as_operations_map_remove_by_value_rel_rank_range( + success = as_operations_map_remove_by_key_rel_index_range( ops, bin, ctx_ref, val1, rank, (uint64_t)count, return_type); } else { - success = as_operations_map_remove_by_value_rel_rank_range_to_end( + success = as_operations_map_remove_by_key_rel_index_range_to_end( ops, bin, ctx_ref, val1, rank, return_type); } break; From 04dde75d6ecbbca4e015f55a6e90ad14073013b6 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 7 Jul 2026 10:19:56 -0700 Subject: [PATCH 58/99] Address test regressions --- src/main/client/operate_helper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index f2ee046660..7f72c17e57 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -794,11 +794,11 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, case OP_MAP_REMOVE_BY_KEY_INDEX_RANGE_REL: { if (range_specified) { success = as_operations_map_remove_by_key_rel_index_range( - ops, bin, ctx_ref, val1, rank, (uint64_t)count, return_type); + ops, bin, ctx_ref, val1, index, (uint64_t)count, return_type); } else { success = as_operations_map_remove_by_key_rel_index_range_to_end( - ops, bin, ctx_ref, val1, rank, return_type); + ops, bin, ctx_ref, val1, index, return_type); } break; } @@ -806,11 +806,11 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, case OP_MAP_GET_BY_KEY_INDEX_RANGE_REL: { if (range_specified) { success = as_operations_map_get_by_key_rel_index_range( - ops, bin, ctx_ref, val1, count, (uint64_t)count, return_type); + ops, bin, ctx_ref, val1, index, (uint64_t)count, return_type); } else { success = as_operations_map_get_by_key_rel_index_range_to_end( - ops, bin, ctx_ref, val1, count, return_type); + ops, bin, ctx_ref, val1, index, return_type); } break; } From 6338b8e8a47858aea32ddd4f2a1e299ec674d7e8 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 7 Jul 2026 11:15:09 -0700 Subject: [PATCH 59/99] Address test regressions --- src/main/client/operate_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index 7f72c17e57..f641d933e5 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -137,11 +137,11 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, break; } - return_type = AS_LIST_RETURN_VALUE; if ((operation_code >= OP_LIST_GET_BY_INDEX && operation_code <= OP_LIST_REMOVE_BY_VALUE_RANGE) || (operation_code >= OP_LIST_REMOVE_BY_VALUE_RANK_RANGE_REL && operation_code <= OP_LIST_GET_BY_VALUE_RANK_RANGE_REL)) { + return_type = AS_LIST_RETURN_VALUE; if (get_list_return_type(err, op_dict, &return_type) != AEROSPIKE_OK) { goto exit; } From 6dfacacdacef365ad3d5560804c0d88dd80dd3af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jul 2026 18:24:03 +0000 Subject: [PATCH 60/99] Bump aerospike-client-c from `785fa24` to `bce75a6` Bumps [aerospike-client-c](https://github.com/aerospike/aerospike-client-c) from `785fa24` to `bce75a6`. - [Release notes](https://github.com/aerospike/aerospike-client-c/releases) - [Commits](https://github.com/aerospike/aerospike-client-c/compare/785fa240b09bf164ea5f64361ab2346c661046c7...bce75a68adcce897c7e58168113bf928097fb0bd) --- updated-dependencies: - dependency-name: aerospike-client-c dependency-version: bce75a68adcce897c7e58168113bf928097fb0bd dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- aerospike-client-c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aerospike-client-c b/aerospike-client-c index 785fa240b0..bce75a68ad 160000 --- a/aerospike-client-c +++ b/aerospike-client-c @@ -1 +1 @@ -Subproject commit 785fa240b09bf164ea5f64361ab2346c661046c7 +Subproject commit bce75a68adcce897c7e58168113bf928097fb0bd From 256d93e7c8d64a85ba3d6c54b9876fc96a4d6eae Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Tue, 7 Jul 2026 17:15:32 -0700 Subject: [PATCH 61/99] Add new abort status ABORT_COMMIT_FAILED and txn state TXN_STATE_COMMIT_FAILED as module constants for application users to check their txn state. --- aerospike-stubs/aerospike.pyi | 2 ++ doc/aerospike.rst | 10 ++++++++++ src/main/aerospike.c | 4 ++++ 3 files changed, 16 insertions(+) diff --git a/aerospike-stubs/aerospike.pyi b/aerospike-stubs/aerospike.pyi index e406ce8973..518475aae4 100644 --- a/aerospike-stubs/aerospike.pyi +++ b/aerospike-stubs/aerospike.pyi @@ -304,11 +304,13 @@ ABORT_OK: Literal[0] ABORT_ALREADY_ABORTED: Literal[1] ABORT_ROLL_BACK_ABANDONED: Literal[3] ABORT_CLOSE_ABANDONED: Literal[4] +ABORT_COMMIT_FAILED: Literal[5] TXN_STATE_OPEN: Literal[0] TXN_STATE_VERIFIED: Literal[1] TXN_STATE_COMMITTED: Literal[2] TXN_STATE_ABORTED: Literal[3] +TXN_STATE_COMMIT_FAILED: Literal[4] EXP_PATH_SELECT_MATCHING_TREE: Literal[0] EXP_PATH_SELECT_VALUE: Literal[1] diff --git a/doc/aerospike.rst b/doc/aerospike.rst index 6172146d42..dc171d3466 100644 --- a/doc/aerospike.rst +++ b/doc/aerospike.rst @@ -1841,6 +1841,11 @@ Transaction Abort Status Transaction has been rolled back, but client transaction close was abandoned. Server will eventually close the transaction. +.. data:: ABORT_COMMIT_FAILED + + Abort was refused because a commit failed in-doubt and may still advance. + Retry the commit to resolve the transaction safely. + .. _mrt_state: Transaction State @@ -1854,6 +1859,11 @@ Transaction State .. data:: TXN_STATE_ABORTED +.. data:: TXN_STATE_COMMIT_FAILED + + A commit failed in-doubt and may still advance, so abort is not allowed + in this state. Retry the commit to resolve the transaction safely. + .. _exp_path_select_flags: Path Expression Select Flags diff --git a/src/main/aerospike.c b/src/main/aerospike.c index f8988b17c0..c592105045 100644 --- a/src/main/aerospike.c +++ b/src/main/aerospike.c @@ -539,11 +539,15 @@ static struct module_constant_name_to_value module_constants[] = { .value.integer = AS_ABORT_ROLL_BACK_ABANDONED}, {"ABORT_CLOSE_ABANDONED", .value.integer = AS_ABORT_CLOSE_ABANDONED}, + EXPOSE_AS_MACRO_WITHOUT_AS_PREFIX_AS_PUBLIC_FIELD(ABORT_COMMIT_FAILED), + {"TXN_STATE_OPEN", .value.integer = AS_TXN_STATE_OPEN}, {"TXN_STATE_VERIFIED", .value.integer = AS_TXN_STATE_VERIFIED}, {"TXN_STATE_COMMITTED", .value.integer = AS_TXN_STATE_COMMITTED}, {"TXN_STATE_ABORTED", .value.integer = AS_TXN_STATE_ABORTED}, + EXPOSE_AS_MACRO_WITHOUT_AS_PREFIX_AS_PUBLIC_FIELD(TXN_STATE_COMMIT_FAILED), + {"JOB_SCAN", .is_str_value = true, .value.string = "scan"}, {"JOB_QUERY", .is_str_value = true, .value.string = "query"}, From 48a4a54d91f0d2f1552734ff3f8e4cc0b823ea4c Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Wed, 8 Jul 2026 08:53:02 -0700 Subject: [PATCH 62/99] Print deprecation warning if aerospike_helpers.operations receives an out of bounds value for an int64_t parameter. --- src/main/client/cdt_operation_utils.c | 29 +++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index 114b76617c..65f6d7d717 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -140,6 +140,8 @@ as_status get_int64_t(as_error *err, const char *key, PyObject *op_dict, return AEROSPIKE_OK; } +#define OVERFLOW_DEPRECATION_WARNING "Received out of bounds value for int64_t" + as_status get_optional_int64_t(as_error *err, const char *key, PyObject *op_dict, int64_t *i64_valptr, bool *found) @@ -156,17 +158,28 @@ as_status get_optional_int64_t(as_error *err, const char *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); + PyObject *py_err_occurred = PyErr_Occurred(); + int overflow_happened = + py_err_occurred && PyErr_ExceptionMatches(PyExc_OverflowError); + + if (!py_err_occurred || overflow_happened) { + if (overflow_happened) { + PyErr_Clear(); + int retval = + PyErr_WarnEx(PyExc_DeprecationWarning, + OVERFLOW_DEPRECATION_WARNING, STACK_LEVEL); + if (retval == -1) { + return as_error_update(err, AEROSPIKE_ERR_PARAM, + OVERFLOW_DEPRECATION_WARNING); + } } - return as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s", - key); + + *found = true; + return AEROSPIKE_OK; } - *found = true; - return AEROSPIKE_OK; + return as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s", + key); } as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, From d656c5ff0258d3a85b37ad3927f2f97e7f1f0fff Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Wed, 8 Jul 2026 08:54:51 -0700 Subject: [PATCH 63/99] port documentation changes from other CLIENT-4697 branch now that all 64-bit integer parameters are validated. --- .../operations/list_operations.py | 48 ++++++++++--------- .../operations/map_operations.py | 28 ++++++----- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/aerospike_helpers/operations/list_operations.py b/aerospike_helpers/operations/list_operations.py index 238929bd4a..028723db0f 100755 --- a/aerospike_helpers/operations/list_operations.py +++ b/aerospike_helpers/operations/list_operations.py @@ -147,8 +147,8 @@ def list_insert(bin_name: str, index, value, policy: Optional[dict] = None, ctx: Args: bin_name (str): The name of the bin to be operated on. - index (int): The index at which to insert an item. The value may be positive to use - zero based indexing or negative to index from the end of the list. + index (int): The index at which to insert an item. (64-bit signed integer) The value may be + positive to use zero based indexing or negative to index from the end of the list. value: The value to be inserted into the list. policy (dict): An optional dictionary of :ref:`list write options `. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -177,8 +177,8 @@ def list_insert_items(bin_name: str, index, values, policy: Optional[dict] = Non Args: bin_name (str): The name of the bin to be operated on. - index (int): The index at which to insert the items. The value may be positive to use - zero based indexing or negative to index from the end of the list. + index (int): The index at which to insert the items. (64-bit signed integer) The value may be + positive to use zero based indexing or negative to index from the end of the list. values (list): The values to be inserted into the list. policy (dict): An optional dictionary of :ref:`list write options `. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -207,7 +207,7 @@ def list_increment(bin_name: str, index, value, policy: Optional[dict] = None, c Args: bin_name (str): The name of the bin to be operated on. - index (int): The index of the list item to increment. + index (int): The index of the list item to increment. (64-bit signed integer) value (int, float) : The value to be added to the list item. policy (dict): An optional dictionary of :ref:`list write options `. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -236,7 +236,7 @@ def list_pop(bin_name: str, index, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin to be operated on. - index (int): The index of the item to be removed. + index (int): The index of the item to be removed. (64-bit signed integer) ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. Returns: @@ -260,7 +260,7 @@ def list_pop_range(bin_name: str, index, count, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin to be operated on. - index (int): The index of the first item to be removed. + index (int): The index of the first item to be removed. (64-bit signed integer) count (int): A positive number indicating how many items, including the first, to be removed and returned ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. @@ -285,7 +285,7 @@ def list_remove(bin_name: str, index, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin containing the item to be removed. - index (int): The index at which to remove the item. + index (int): The index at which to remove the item. (64-bit signed integer) ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. Returns: @@ -309,7 +309,7 @@ def list_remove_range(bin_name: str, index, count, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin containing the items to be removed. - index (int): The index of the first item to remove. + index (int): The index of the first item to remove. (64-bit signed integer) count (int): A positive number representing the number of items to be removed. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. @@ -355,7 +355,7 @@ def list_set(bin_name: str, index, value, policy: Optional[dict] = None, ctx: Op Args: bin_name (str): The name of the bin containing the list to be operated on. - index (int): The index of the item to be set. + index (int): The index of the item to be set. (64-bit signed integer) value: The value to be assigned to the list item. policy (dict): An optional dictionary of :ref:`list write options `. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -382,7 +382,7 @@ def list_get(bin_name: str, index, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin containing the list to fetch items from. - index (int): The index of the item to be returned. + index (int): The index of the item to be returned. (64-bit signed integer) ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. @@ -405,7 +405,7 @@ def list_get_range(bin_name: str, index, count, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin containing the list to fetch items from. - index (int): The index of the item to be returned. + index (int): The index of the item to be returned. (64-bit signed integer) count (int): A positive number of items to be returned. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. @@ -429,7 +429,7 @@ def list_trim(bin_name: str, index, count, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin containing the list to be trimmed. - index (int): The index of the items to be kept. + index (int): The index of the items to be kept. (64-bit signed integer) count (int): A positive number of items to be kept. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. @@ -479,7 +479,7 @@ def list_get_by_index(bin_name: str, index, return_type, ctx: Optional[list] = N Args: bin_name (str): The name of the bin containing the list to fetch items from. - index (int): The index of the item to be returned. + index (int): The index of the item to be returned. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -510,7 +510,7 @@ def list_get_by_index_range(bin_name: str, index, return_type, count=None, inver Args: bin_name (str): The name of the bin containing the list to fetch items from. - index (int): The index of the first item to be returned. + index (int): The index of the first item to be returned. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values. count (int): The number of list items to be selected. @@ -549,7 +549,7 @@ def list_get_by_rank(bin_name: str, rank, return_type, ctx: Optional[list] = Non Args: bin_name (str): The name of the bin containing the list to fetch a value from. - rank (int): The rank of the item to be fetched. + rank (int): The rank of the item to be fetched. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -575,7 +575,7 @@ def list_get_by_rank_range(bin_name: str, rank, return_type, count=None, inverte Args: bin_name (str): The name of the bin containing the list to fetch items from. - rank (int): The rank of the first items to be returned. + rank (int): The rank of the first items to be returned. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values count (int): A positive number indicating number of items to be returned. @@ -730,7 +730,7 @@ def list_remove_by_index(bin_name: str, index, return_type, ctx: Optional[list] Args: bin_name (str): The name of the bin containing the list to remove an item from. - index (int): The index of the item to be removed. + index (int): The index of the item to be removed. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -768,7 +768,7 @@ def list_remove_by_index_range( Args: bin_name (str): The name of the bin containing the list to remove items from. - index (int): The index of the first item to be removed. + index (int): The index of the first item to be removed. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values. count (int): The number of items to be removed @@ -807,7 +807,7 @@ def list_remove_by_rank(bin_name: str, rank, return_type, ctx: Optional[list] = Args: bin_name (str): The name of the bin containing the list to fetch a value from. - rank (int): The rank of the item to be removed. + rank (int): The rank of the item to be removed. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -838,7 +838,7 @@ def list_remove_by_rank_range(bin_name: str, rank, return_type, count=None, inve Args: bin_name (str): The name of the bin containing the list to fetch items from. - rank (int): The rank of the first item to removed. + rank (int): The rank of the first item to removed. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values count (int): A positive number indicating number of items to be removed. @@ -1040,7 +1040,8 @@ def list_get_by_value_rank_range_relative( Args: bin_name (str): The name of the bin containing the list. value (str): The value of the item in the list for which to search - offset (int): Begin returning items with rank == rank(found_item) + offset + offset (int): Begin returning items with rank == rank(found_item) + offset. + (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values count (int): If specified, the number of items to return. If None, @@ -1118,7 +1119,8 @@ def list_remove_by_value_rank_range_relative( Args: bin_name (str): The name of the bin containing the list. value (str): The value of the item in the list for which to search - offset (int): Begin removing and returning items with rank == rank(found_item) + offset + offset (int): Begin removing and returning items with rank == rank(found_item) + offset. + (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values count (int): If specified, the number of items to remove and return. If None, diff --git a/aerospike_helpers/operations/map_operations.py b/aerospike_helpers/operations/map_operations.py index 32f62df5d5..aac433a35a 100755 --- a/aerospike_helpers/operations/map_operations.py +++ b/aerospike_helpers/operations/map_operations.py @@ -479,7 +479,7 @@ def map_remove_by_index(bin_name: str, index, return_type, ctx: Optional[list] = Args: bin_name (str): The name of the bin containing the map. - index (int): The index of the entry to remove. + index (int): The index of the entry to remove. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -515,7 +515,7 @@ def map_remove_by_index_range( Args: bin_name (str): The name of the bin containing the map. - index_start (int): The index of the first entry to remove. + index_start (int): The index of the first entry to remove. (64-bit signed integer) remove_amt (int): The number of entries to remove from the map. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. @@ -549,7 +549,7 @@ def map_remove_by_rank(bin_name: str, rank, return_type, ctx: Optional[list] = N Args: bin_name (str): The name of the bin containing the map. - rank (int): The rank of the entry to remove. + rank (int): The rank of the entry to remove. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -585,7 +585,7 @@ def map_remove_by_rank_range( Args: bin_name (str): The name of the bin containing the map. - rank_start (int): The rank of the entry to remove. + rank_start (int): The rank of the entry to remove. (64-bit signed integer) remove_amt (int): The number of entries to remove. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. @@ -823,7 +823,7 @@ def map_get_by_index(bin_name: str, index, return_type, ctx: Optional[list] = No Args: bin_name (str): The name of the bin containing the map. - index (int): The index of the entry to return. + index (int): The index of the entry to return. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -854,7 +854,7 @@ def map_get_by_index_range( Args: bin_name (str): The name of the bin containing the map. - index_start (int): The index of the first entry to return. + index_start (int): The index of the first entry to return. (64-bit signed integer) get_amt (int): The number of entries to return from the map. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. @@ -888,7 +888,7 @@ def map_get_by_rank(bin_name: str, rank, return_type, ctx: Optional[list] = None Args: bin_name (str): The name of the bin containing the map. - rank (int): The rank of the entry to return. + rank (int): The rank of the entry to return. (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -912,7 +912,7 @@ def map_get_by_rank_range(bin_name: str, rank_start, get_amt, return_type, inver Args: bin_name (str): The name of the bin containing the map. - rank_start (int): The start of the rank of the entries to return. + rank_start (int): The start of the rank of the entries to return. (64-bit signed integer) get_amt (int): The number of entries to return. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. @@ -951,7 +951,8 @@ def map_remove_by_value_rank_range_relative( Args: bin_name (str): The name of the bin containing the map. value: The value of the entry in the map for which to search - offset (int): Begin removing and returning items with rank == rank(found_item) + offset + offset (int): Begin removing and returning items with rank == rank(found_item) + offset. + (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. count (int): If specified, the number of items to remove and return. If None, @@ -1024,7 +1025,8 @@ def map_get_by_value_rank_range_relative( Args: bin_name (str): The name of the bin containing the map. value (str): The value of the item in the list for which to search - offset (int): Begin removing and returning items with rank == rank(fount_item) + offset + offset (int): Begin removing and returning items with rank == rank(fount_item) + offset. + (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. count (int): If specified, the number of items to remove and return. If None, @@ -1086,7 +1088,8 @@ def map_remove_by_key_index_range_relative( Args: bin_name (str): The name of the bin containing the list. key (str): The key of the item in the list for which to search - offset (int): Begin removing and returning items with rank == rank(fount_item) + offset + offset (int): Begin removing and returning items with rank == rank(fount_item) + offset. + (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. count (int): If specified, the number of items to remove and return. If None, @@ -1157,7 +1160,8 @@ def map_get_by_key_index_range_relative( Args: bin_name (str): The name of the bin containing the list. value (str): The value of the item in the list for which to search - offset (int): Begin removing and returning items with rank == rank(fount_item) + offset + offset (int): Begin removing and returning items with rank == rank(fount_item) + offset. + (64-bit signed integer) return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. count (int): If specified, the number of items to remove and return. If None, From 1db19808647545efc140655bb1c89e9c0c15f64a Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Wed, 8 Jul 2026 10:44:27 -0700 Subject: [PATCH 64/99] Revert "Print deprecation warning if aerospike_helpers.operations receives an out of bounds value for an int64_t parameter." This reverts commit 48a4a54d91f0d2f1552734ff3f8e4cc0b823ea4c. --- src/main/client/cdt_operation_utils.c | 29 ++++++++------------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index c347142354..fce6e95892 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -140,8 +140,6 @@ as_status get_int64_t(as_error *err, const char *key, PyObject *op_dict, return AEROSPIKE_OK; } -#define OVERFLOW_DEPRECATION_WARNING "Received out of bounds value for int64_t" - as_status get_optional_int64_t(as_error *err, const char *key, PyObject *op_dict, int64_t *i64_valptr, bool *found) @@ -158,28 +156,17 @@ as_status get_optional_int64_t(as_error *err, const char *key, } *i64_valptr = (int64_t)PyLong_AsLongLong(py_val); - PyObject *py_err_occurred = PyErr_Occurred(); - int overflow_happened = - py_err_occurred && PyErr_ExceptionMatches(PyExc_OverflowError); - - if (!py_err_occurred || overflow_happened) { - if (overflow_happened) { - PyErr_Clear(); - int retval = - PyErr_WarnEx(PyExc_DeprecationWarning, - OVERFLOW_DEPRECATION_WARNING, STACK_LEVEL); - if (retval == -1) { - return as_error_update(err, AEROSPIKE_ERR_PARAM, - OVERFLOW_DEPRECATION_WARNING); - } + if (PyErr_Occurred()) { + if (PyErr_ExceptionMatches(PyExc_OverflowError)) { + return as_error_update(err, AEROSPIKE_ERR_PARAM, "%s too large", + key); } - - *found = true; - return AEROSPIKE_OK; + return as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s", + key); } - return as_error_update(err, AEROSPIKE_ERR_PARAM, "Failed to convert %s", - key); + *found = true; + return AEROSPIKE_OK; } as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, From 301ee23b463ef252de8a23516994fcc78f4c4c96 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:29:27 -0700 Subject: [PATCH 65/99] Detect if enum values passed to aerospike_helpers.operations are out of bounds and raise a DeprecationWarning in that case. --- src/include/cdt_operation_utils.h | 6 ++ src/main/client/bit_operate.c | 12 ++- src/main/client/cdt_operation_utils.c | 47 ++++++++++-- src/main/client/operate.c | 16 ++-- src/main/client/operate_helper.c | 36 +++++---- src/main/policy.c | 103 ++++++++++---------------- 6 files changed, 124 insertions(+), 96 deletions(-) diff --git a/src/include/cdt_operation_utils.h b/src/include/cdt_operation_utils.h index 65b0d27c6a..a97d73e96b 100644 --- a/src/include/cdt_operation_utils.h +++ b/src/include/cdt_operation_utils.h @@ -74,6 +74,12 @@ as_status get_optional_int64_t(as_error *err, const char *key, as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, uint64_t *ui64_valptr); +as_status get_bounded_int_from_py_dict(as_error *err, const char *key, + PyObject *op_dict, int *int_pointer, + int min_bound, int max_bound, + bool is_optional, + bool warn_if_out_of_bounds); + as_status get_int_from_py_dict(as_error *err, const char *key, PyObject *op_dict, int *int_pointer); diff --git a/src/main/client/bit_operate.c b/src/main/client/bit_operate.c index 5785818419..6c81f29a0f 100644 --- a/src/main/client/bit_operate.c +++ b/src/main/client/bit_operate.c @@ -343,17 +343,15 @@ as_status add_new_bit_op(AerospikeClient *self, as_error *err, static as_status get_bit_resize_flags(as_error *err, PyObject *op_dict, as_bit_resize_flags *resize_flags) { - int64_t flags64; - bool found = false; + int tmp_value; *resize_flags = AS_BIT_RESIZE_DEFAULT; - if (get_optional_int64_t(err, RESIZE_FLAGS_KEY, op_dict, &flags64, - &found) != AEROSPIKE_OK) { + if (get_bounded_int_from_py_dict( + err, RESIZE_FLAGS_KEY, op_dict, &tmp_value, AS_BIT_RESIZE_DEFAULT, + AS_BIT_RESIZE_SHRINK_ONLY, true, true) != AEROSPIKE_OK) { return err->code; } - if (found) { - *resize_flags = (as_bit_resize_flags)flags64; - } + *resize_flags = (as_bit_resize_flags)tmp_value; return AEROSPIKE_OK; } diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index fce6e95892..6f19512550 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -196,24 +196,57 @@ as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, return AEROSPIKE_OK; } -as_status get_int_from_py_dict(as_error *err, const char *key, - PyObject *op_dict, int *int_pointer) +#define OUT_OF_BOUNDS_MESSAGE "%s must be between %d and %d." + +// In C99, enum values can be between INT_MIN and INT_MAX +// So we define our min and max bound parameters as integer types +// https://stackoverflow.com/a/366033 +as_status get_bounded_int_from_py_dict(as_error *err, const char *key, + PyObject *op_dict, int *int_pointer, + int min_bound, int max_bound, + bool is_optional, + bool warn_if_out_of_bounds) { int64_t int64_to_return = -1; - - if (get_int64_t(err, key, op_dict, &int64_to_return) != AEROSPIKE_OK) { + bool found = false; + if (get_optional_int64_t(err, key, op_dict, &int64_to_return, found) != + AEROSPIKE_OK) { return err->code; } - if (int64_to_return > INT_MAX || int64_to_return < INT_MIN) { + if (!found && !is_optional) { return as_error_update(err, AEROSPIKE_ERR_PARAM, - "%s too large for C int.", key); + "Operation missing required entry %s", key); } - *int_pointer = int64_to_return; + if (int64_to_return >= min_bound || int64_to_return <= max_bound) { + goto return_int; + } + + if (warn_if_out_of_bounds) { + int retval = + PyErr_WarnFormat(PyExc_DeprecationWarning, STACK_LEVEL, + OUT_OF_BOUNDS_MESSAGE, key, min_bound, max_bound); + if (retval == 0) { + goto return_int; + } + } + + return as_error_update(err, AEROSPIKE_ERR_PARAM, OUT_OF_BOUNDS_MESSAGE, key, + min_bound, max_bound); + +return_int: + *int_pointer = int64_to_return; return AEROSPIKE_OK; } +as_status get_int_from_py_dict(as_error *err, const char *key, + PyObject *op_dict, int *int_pointer) +{ + return get_bounded_int_from_py_dict(err, key, op_dict, int_pointer, INT_MIN, + INT_MAX, false, false); +} + as_status get_list_return_type(as_error *err, PyObject *op_dict, int *return_type) { diff --git a/src/main/client/operate.c b/src/main/client/operate.c index b85bd6619e..9c72570738 100644 --- a/src/main/client/operate.c +++ b/src/main/client/operate.c @@ -37,6 +37,7 @@ #include "hll_operations.h" #include "pythoncapi_compat.h" #include "expression_operations.h" +#include "cdt_operation_utils.h" #include #include @@ -346,7 +347,6 @@ as_status add_op(AerospikeClient *self, as_error *err, PyObject *py_map_policy = NULL; PyObject *py_return_type = NULL; // For map_create operation - PyObject *py_map_order = NULL; PyObject *py_persist_index = NULL; Py_ssize_t pos = 0; @@ -418,9 +418,6 @@ as_status add_op(AerospikeClient *self, as_error *err, CONVERT_PY_CTX_TO_AS_CTX(); ctx_ref = (ctx_in_use ? &ctx : NULL); } - else if (strcmp(name, "map_order") == 0) { - py_map_order = value; - } else if (strcmp(name, "persist_index") == 0) { py_persist_index = value; } @@ -744,7 +741,16 @@ as_status add_op(AerospikeClient *self, as_error *err, as_operations_map_set_policy(ops, bin, ctx_ref, &map_policy); break; case OP_MAP_CREATE:; - as_map_order order = (as_map_order)PyLong_AsLong(py_map_order); + int tmp_value; + as_map_order order; + if (get_bounded_int_from_py_dict(err, "map_order", py_operation_dict, + &tmp_value, AS_MAP_UNORDERED, + AS_MAP_KEY_VALUE_ORDERED, false, + true) != AEROSPIKE_OK) { + return err->code; + } + order = (as_map_order)tmp_value; + bool persist_index = PyObject_IsTrue(py_persist_index); as_operations_map_create_all(ops, bin, ctx_ref, order, persist_index); break; diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index f641d933e5..33f943f41c 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -191,14 +191,17 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, break; } - int64_t order_type_int; + as_list_order list_order; + int tmp_value; switch (operation_code) { case OP_LIST_SET_ORDER: case OP_LIST_CREATE: - if (get_int64_t(err, AS_PY_LIST_ORDER, op_dict, &order_type_int) != - AEROSPIKE_OK) { + if (get_bounded_int_from_py_dict( + err, AS_PY_LIST_ORDER, op_dict, &tmp_value, AS_LIST_UNORDERED, + AS_LIST_ORDERED, false, true) != AEROSPIKE_OK) { goto exit; } + list_order = (as_list_order)tmp_value; } bool ctx_in_use = false; @@ -330,11 +333,11 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, as_string_numeric_type numeric_type = AS_STRING_NUMERIC_ANY; as_string_regex_flags regex_flags = AS_STRING_REGEX_FLAGS_NONE; - int64_t tmp_value; switch (operation_code) { case OP_STRING_IS_NUMERIC: { - if (get_int64_t(err, "numeric_type", op_dict, &tmp_value) != - AEROSPIKE_OK) { + if (get_bounded_int_from_py_dict( + err, "numeric_type", op_dict, &tmp_value, AS_STRING_NUMERIC_ANY, + AS_STRING_NUMERIC_FLOAT, false, true) != AEROSPIKE_OK) { goto CLEANUP_VAL2_ON_ERROR; } numeric_type = (as_string_numeric_type)tmp_value; @@ -342,8 +345,10 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, } case OP_STRING_REGEX_COMPARE: case OP_STRING_REGEX_REPLACE: { - if (get_int64_t(err, "regex_flags", op_dict, &tmp_value) != - AEROSPIKE_OK) { + if (get_bounded_int_from_py_dict(err, "regex_flags", op_dict, + &tmp_value, AS_STRING_REGEX_FLAGS_NONE, + AS_STRING_REGEX_FLAGS_GLOBAL, false, + true) != AEROSPIKE_OK) { goto CLEANUP_VAL2_ON_ERROR; } regex_flags = (as_string_regex_flags)tmp_value; @@ -557,16 +562,18 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, ops, bin, ctx_ref, val1, val2, return_type); break; case OP_LIST_SET_ORDER: - success = as_operations_list_set_order(ops, bin, ctx_ref, - (as_list_order)order_type_int); + success = as_operations_list_set_order(ops, bin, ctx_ref, list_order); break; case OP_LIST_SORT: { - int64_t sort_flags; + as_list_sort_flags sort_flags; - if (get_int64_t(err, AS_PY_LIST_SORT_FLAGS, op_dict, &sort_flags) != - AEROSPIKE_OK) { + if (get_bounded_int_from_py_dict(err, AS_PY_LIST_SORT_FLAGS, op_dict, + &tmp_value, AS_LIST_SORT_DEFAULT, + AS_LIST_SORT_DROP_DUPLICATES, false, + true) != AEROSPIKE_OK) { goto CLEANUP_VAL2_ON_ERROR; } + sort_flags = (as_list_sort_flags)tmp_value; success = as_operations_list_sort(ops, bin, ctx_ref, (as_list_sort_flags)sort_flags); break; @@ -593,8 +600,7 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, goto CLEANUP_VAL2_ON_ERROR; } - success = as_operations_list_create_all(ops, bin, ctx_ref, - (as_list_order)order_type_int, + success = as_operations_list_create_all(ops, bin, ctx_ref, list_order, pad, persist_index); break; } diff --git a/src/main/policy.c b/src/main/policy.c index 231cca2890..c0bb7768c4 100644 --- a/src/main/policy.c +++ b/src/main/policy.c @@ -35,6 +35,7 @@ #include "policy.h" #include "macros.h" #include "policy_config.h" +#include "cdt_operation_utils.h" #define MAP_WRITE_FLAGS_KEY "map_write_flags" #define BIT_WRITE_FLAGS_KEY "bit_write_flags" @@ -1043,22 +1044,17 @@ as_status pyobject_to_bit_policy(as_error *err, PyObject *py_policy, } } - PyObject *py_bit_flags = - PyDict_GetItemString(py_policy, BIT_WRITE_FLAGS_KEY); - if (py_bit_flags) { - if (PyLong_Check(py_bit_flags)) { - as_bit_write_flags bit_write_flags = - (as_bit_write_flags)PyLong_AsLong(py_bit_flags); - as_bit_policy_set_write_flags(policy, bit_write_flags); - } - } - else if (PyErr_Occurred()) { - /* Fetching a map key failed internally for some reason, raise an error and exit.*/ - PyErr_Clear(); - return as_error_update(err, AEROSPIKE_ERR_CLIENT, - "Unable to get bit_write_flags"); + int tmp_value; + if (get_bounded_int_from_py_dict(err, BIT_WRITE_FLAGS_KEY, py_policy, + &tmp_value, AS_BIT_WRITE_DEFAULT, + AS_BIT_WRITE_PARTIAL, false, + true) != AEROSPIKE_OK) { + return err->code; } + as_bit_write_flags bit_write_flags = (as_bit_write_flags)tmp_value; + as_bit_policy_set_write_flags(policy, bit_write_flags); + return err->code; } as_status pyobject_to_map_policy(as_error *err, PyObject *py_policy, @@ -1081,11 +1077,18 @@ as_status pyobject_to_map_policy(as_error *err, PyObject *py_policy, } // Defaults - long map_order = AS_MAP_UNORDERED; uint32_t map_write_flags = AS_MAP_WRITE_DEFAULT; bool persist_index = false; - MAP_POLICY_SET_FIELD(map_order, PyLong_AsLong); + as_map_order map_order = AS_MAP_UNORDERED; + int tmp_value; + if (get_bounded_int_from_py_dict(err, "map_order", py_policy, &tmp_value, + AS_MAP_UNORDERED, AS_MAP_KEY_VALUE_ORDERED, + false, true) != AEROSPIKE_OK) { + return err->code; + } + map_order = (as_map_order)tmp_value; + MAP_POLICY_SET_FIELD(map_write_flags, PyLong_AsUnsignedLong); PyObject *py_persist_index = @@ -1111,9 +1114,6 @@ as_status pyobject_to_list_policy(as_error *err, PyObject *py_policy, bool validate_keys) { as_list_policy_init(list_policy); - PyObject *py_val = NULL; - long list_order = AS_LIST_UNORDERED; - long flags = AS_LIST_WRITE_DEFAULT; if (!py_policy || py_policy == Py_None) { return AEROSPIKE_OK; @@ -1137,38 +1137,25 @@ as_status pyobject_to_list_policy(as_error *err, PyObject *py_policy, } } - py_val = PyDict_GetItemString(py_policy, "list_order"); - if (py_val && py_val != Py_None) { - if (PyLong_Check(py_val)) { - list_order = PyLong_AsLong(py_val); - if (PyErr_Occurred()) { - return as_error_update(err, AEROSPIKE_ERR_PARAM, - "Failed to convert list_order"); - } - } - else { - return as_error_update(err, AEROSPIKE_ERR_PARAM, - "Invalid List order"); - } + int tmp_value; + as_list_order list_order = AS_LIST_UNORDERED; + + if (get_bounded_int_from_py_dict(err, "list_order", py_policy, &tmp_value, + AS_LIST_UNORDERED, AS_LIST_ORDERED, true, + true) != AEROSPIKE_OK) { + return err->code; } + list_order = (as_list_order)tmp_value; - py_val = PyDict_GetItemString(py_policy, "write_flags"); - if (py_val && py_val != Py_None) { - if (PyLong_Check(py_val)) { - flags = PyLong_AsLong(py_val); - if (PyErr_Occurred()) { - return as_error_update(err, AEROSPIKE_ERR_PARAM, - "Failed to convert write_flags"); - } - } - else { - return as_error_update(err, AEROSPIKE_ERR_PARAM, - "Invalid write_flags"); - } + as_list_write_flags flags = AS_LIST_WRITE_DEFAULT; + if (get_bounded_int_from_py_dict( + err, "write_flags", py_policy, &tmp_value, AS_LIST_WRITE_DEFAULT, + AS_LIST_WRITE_PARTIAL, true, true) != AEROSPIKE_OK) { + return err->code; } + flags = (as_list_write_flags)tmp_value; - as_list_policy_set(list_policy, (as_list_order)list_order, - (as_list_write_flags)flags); + as_list_policy_set(list_policy, list_order, flags); return AEROSPIKE_OK; } @@ -1176,9 +1163,7 @@ as_status pyobject_to_list_policy(as_error *err, PyObject *py_policy, as_status pyobject_to_hll_policy(as_error *err, PyObject *py_policy, as_hll_policy *hll_policy, bool validate_keys) { - int64_t flags = 0; as_hll_policy_init(hll_policy); - PyObject *py_val = NULL; if (!py_policy || py_policy == Py_None) { return AEROSPIKE_OK; @@ -1202,21 +1187,15 @@ as_status pyobject_to_hll_policy(as_error *err, PyObject *py_policy, } } - py_val = PyDict_GetItemString(py_policy, "flags"); - if (py_val && py_val != Py_None) { - if (PyLong_Check(py_val)) { - flags = (int64_t)PyLong_AsLongLong(py_val); - if (PyErr_Occurred()) { - return as_error_update(err, AEROSPIKE_ERR_PARAM, - "Failed to convert flags."); - } - } - else { - return as_error_update(err, AEROSPIKE_ERR_PARAM, - "Invalid hll policy flags."); - } + int tmp_value; + as_hll_write_flags flags; + if (get_bounded_int_from_py_dict( + err, "flags", py_policy, &tmp_value, AS_HLL_WRITE_DEFAULT, + AS_HLL_WRITE_ALLOW_FOLD, true, true) != AEROSPIKE_OK) { + return err->code; } + flags = (as_hll_write_flags)tmp_value; as_hll_policy_set_write_flags(hll_policy, flags); return AEROSPIKE_OK; From 07cf1555618c7c6fbd81ff3d27787cfc58b15296 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:34:39 -0700 Subject: [PATCH 66/99] Address compiler error --- src/main/client/cdt_operation_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index 6f19512550..ede03839c7 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -209,7 +209,7 @@ as_status get_bounded_int_from_py_dict(as_error *err, const char *key, { int64_t int64_to_return = -1; bool found = false; - if (get_optional_int64_t(err, key, op_dict, &int64_to_return, found) != + if (get_optional_int64_t(err, key, op_dict, &int64_to_return, &found) != AEROSPIKE_OK) { return err->code; } From dc690548db04735b4a7f3e193ef2759e5923e54c Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:41:40 -0700 Subject: [PATCH 67/99] Address compiler warning about potential uninitialized read. --- src/main/client/operate_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index 33f943f41c..5d17e8f6bd 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -191,7 +191,7 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, break; } - as_list_order list_order; + as_list_order list_order = AS_LIST_UNORDERED; int tmp_value; switch (operation_code) { case OP_LIST_SET_ORDER: From be21364443dfcd7560e42352c08ffe2dfa35001a Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:47:48 -0700 Subject: [PATCH 68/99] Move comment about get_bounded_int_from_py_dict to the header file --- src/include/cdt_operation_utils.h | 4 ++++ src/main/client/cdt_operation_utils.c | 3 --- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/include/cdt_operation_utils.h b/src/include/cdt_operation_utils.h index a97d73e96b..c0870942bc 100644 --- a/src/include/cdt_operation_utils.h +++ b/src/include/cdt_operation_utils.h @@ -74,6 +74,10 @@ as_status get_optional_int64_t(as_error *err, const char *key, as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, uint64_t *ui64_valptr); +// This is used to validate enum arguments +// In C99, enum values can be between INT_MIN and INT_MAX +// So we define our min and max bound parameters as integer types +// https://stackoverflow.com/a/366033 as_status get_bounded_int_from_py_dict(as_error *err, const char *key, PyObject *op_dict, int *int_pointer, int min_bound, int max_bound, diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index ede03839c7..d188505e9c 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -198,9 +198,6 @@ as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, #define OUT_OF_BOUNDS_MESSAGE "%s must be between %d and %d." -// In C99, enum values can be between INT_MIN and INT_MAX -// So we define our min and max bound parameters as integer types -// https://stackoverflow.com/a/366033 as_status get_bounded_int_from_py_dict(as_error *err, const char *key, PyObject *op_dict, int *int_pointer, int min_bound, int max_bound, From dc9631e874f4b87e843de574439989750bce6891 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:49:44 -0700 Subject: [PATCH 69/99] Revert aerospike_helpers.operations documentation changes to be added in another future ticket --- .../operations/list_operations.py | 48 +++++++++---------- .../operations/map_operations.py | 28 +++++------ 2 files changed, 35 insertions(+), 41 deletions(-) diff --git a/aerospike_helpers/operations/list_operations.py b/aerospike_helpers/operations/list_operations.py index 028723db0f..238929bd4a 100755 --- a/aerospike_helpers/operations/list_operations.py +++ b/aerospike_helpers/operations/list_operations.py @@ -147,8 +147,8 @@ def list_insert(bin_name: str, index, value, policy: Optional[dict] = None, ctx: Args: bin_name (str): The name of the bin to be operated on. - index (int): The index at which to insert an item. (64-bit signed integer) The value may be - positive to use zero based indexing or negative to index from the end of the list. + index (int): The index at which to insert an item. The value may be positive to use + zero based indexing or negative to index from the end of the list. value: The value to be inserted into the list. policy (dict): An optional dictionary of :ref:`list write options `. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -177,8 +177,8 @@ def list_insert_items(bin_name: str, index, values, policy: Optional[dict] = Non Args: bin_name (str): The name of the bin to be operated on. - index (int): The index at which to insert the items. (64-bit signed integer) The value may be - positive to use zero based indexing or negative to index from the end of the list. + index (int): The index at which to insert the items. The value may be positive to use + zero based indexing or negative to index from the end of the list. values (list): The values to be inserted into the list. policy (dict): An optional dictionary of :ref:`list write options `. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -207,7 +207,7 @@ def list_increment(bin_name: str, index, value, policy: Optional[dict] = None, c Args: bin_name (str): The name of the bin to be operated on. - index (int): The index of the list item to increment. (64-bit signed integer) + index (int): The index of the list item to increment. value (int, float) : The value to be added to the list item. policy (dict): An optional dictionary of :ref:`list write options `. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -236,7 +236,7 @@ def list_pop(bin_name: str, index, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin to be operated on. - index (int): The index of the item to be removed. (64-bit signed integer) + index (int): The index of the item to be removed. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. Returns: @@ -260,7 +260,7 @@ def list_pop_range(bin_name: str, index, count, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin to be operated on. - index (int): The index of the first item to be removed. (64-bit signed integer) + index (int): The index of the first item to be removed. count (int): A positive number indicating how many items, including the first, to be removed and returned ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. @@ -285,7 +285,7 @@ def list_remove(bin_name: str, index, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin containing the item to be removed. - index (int): The index at which to remove the item. (64-bit signed integer) + index (int): The index at which to remove the item. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. Returns: @@ -309,7 +309,7 @@ def list_remove_range(bin_name: str, index, count, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin containing the items to be removed. - index (int): The index of the first item to remove. (64-bit signed integer) + index (int): The index of the first item to remove. count (int): A positive number representing the number of items to be removed. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. @@ -355,7 +355,7 @@ def list_set(bin_name: str, index, value, policy: Optional[dict] = None, ctx: Op Args: bin_name (str): The name of the bin containing the list to be operated on. - index (int): The index of the item to be set. (64-bit signed integer) + index (int): The index of the item to be set. value: The value to be assigned to the list item. policy (dict): An optional dictionary of :ref:`list write options `. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -382,7 +382,7 @@ def list_get(bin_name: str, index, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin containing the list to fetch items from. - index (int): The index of the item to be returned. (64-bit signed integer) + index (int): The index of the item to be returned. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. @@ -405,7 +405,7 @@ def list_get_range(bin_name: str, index, count, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin containing the list to fetch items from. - index (int): The index of the item to be returned. (64-bit signed integer) + index (int): The index of the item to be returned. count (int): A positive number of items to be returned. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. @@ -429,7 +429,7 @@ def list_trim(bin_name: str, index, count, ctx: Optional[list] = None): Args: bin_name (str): The name of the bin containing the list to be trimmed. - index (int): The index of the items to be kept. (64-bit signed integer) + index (int): The index of the items to be kept. count (int): A positive number of items to be kept. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation objects. @@ -479,7 +479,7 @@ def list_get_by_index(bin_name: str, index, return_type, ctx: Optional[list] = N Args: bin_name (str): The name of the bin containing the list to fetch items from. - index (int): The index of the item to be returned. (64-bit signed integer) + index (int): The index of the item to be returned. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -510,7 +510,7 @@ def list_get_by_index_range(bin_name: str, index, return_type, count=None, inver Args: bin_name (str): The name of the bin containing the list to fetch items from. - index (int): The index of the first item to be returned. (64-bit signed integer) + index (int): The index of the first item to be returned. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values. count (int): The number of list items to be selected. @@ -549,7 +549,7 @@ def list_get_by_rank(bin_name: str, rank, return_type, ctx: Optional[list] = Non Args: bin_name (str): The name of the bin containing the list to fetch a value from. - rank (int): The rank of the item to be fetched. (64-bit signed integer) + rank (int): The rank of the item to be fetched. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -575,7 +575,7 @@ def list_get_by_rank_range(bin_name: str, rank, return_type, count=None, inverte Args: bin_name (str): The name of the bin containing the list to fetch items from. - rank (int): The rank of the first items to be returned. (64-bit signed integer) + rank (int): The rank of the first items to be returned. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values count (int): A positive number indicating number of items to be returned. @@ -730,7 +730,7 @@ def list_remove_by_index(bin_name: str, index, return_type, ctx: Optional[list] Args: bin_name (str): The name of the bin containing the list to remove an item from. - index (int): The index of the item to be removed. (64-bit signed integer) + index (int): The index of the item to be removed. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -768,7 +768,7 @@ def list_remove_by_index_range( Args: bin_name (str): The name of the bin containing the list to remove items from. - index (int): The index of the first item to be removed. (64-bit signed integer) + index (int): The index of the first item to be removed. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values. count (int): The number of items to be removed @@ -807,7 +807,7 @@ def list_remove_by_rank(bin_name: str, rank, return_type, ctx: Optional[list] = Args: bin_name (str): The name of the bin containing the list to fetch a value from. - rank (int): The rank of the item to be removed. (64-bit signed integer) + rank (int): The rank of the item to be removed. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -838,7 +838,7 @@ def list_remove_by_rank_range(bin_name: str, rank, return_type, count=None, inve Args: bin_name (str): The name of the bin containing the list to fetch items from. - rank (int): The rank of the first item to removed. (64-bit signed integer) + rank (int): The rank of the first item to removed. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values count (int): A positive number indicating number of items to be removed. @@ -1040,8 +1040,7 @@ def list_get_by_value_rank_range_relative( Args: bin_name (str): The name of the bin containing the list. value (str): The value of the item in the list for which to search - offset (int): Begin returning items with rank == rank(found_item) + offset. - (64-bit signed integer) + offset (int): Begin returning items with rank == rank(found_item) + offset return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values count (int): If specified, the number of items to return. If None, @@ -1119,8 +1118,7 @@ def list_remove_by_value_rank_range_relative( Args: bin_name (str): The name of the bin containing the list. value (str): The value of the item in the list for which to search - offset (int): Begin removing and returning items with rank == rank(found_item) + offset. - (64-bit signed integer) + offset (int): Begin removing and returning items with rank == rank(found_item) + offset return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`list_return_types` values count (int): If specified, the number of items to remove and return. If None, diff --git a/aerospike_helpers/operations/map_operations.py b/aerospike_helpers/operations/map_operations.py index aac433a35a..32f62df5d5 100755 --- a/aerospike_helpers/operations/map_operations.py +++ b/aerospike_helpers/operations/map_operations.py @@ -479,7 +479,7 @@ def map_remove_by_index(bin_name: str, index, return_type, ctx: Optional[list] = Args: bin_name (str): The name of the bin containing the map. - index (int): The index of the entry to remove. (64-bit signed integer) + index (int): The index of the entry to remove. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -515,7 +515,7 @@ def map_remove_by_index_range( Args: bin_name (str): The name of the bin containing the map. - index_start (int): The index of the first entry to remove. (64-bit signed integer) + index_start (int): The index of the first entry to remove. remove_amt (int): The number of entries to remove from the map. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. @@ -549,7 +549,7 @@ def map_remove_by_rank(bin_name: str, rank, return_type, ctx: Optional[list] = N Args: bin_name (str): The name of the bin containing the map. - rank (int): The rank of the entry to remove. (64-bit signed integer) + rank (int): The rank of the entry to remove. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -585,7 +585,7 @@ def map_remove_by_rank_range( Args: bin_name (str): The name of the bin containing the map. - rank_start (int): The rank of the entry to remove. (64-bit signed integer) + rank_start (int): The rank of the entry to remove. remove_amt (int): The number of entries to remove. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. @@ -823,7 +823,7 @@ def map_get_by_index(bin_name: str, index, return_type, ctx: Optional[list] = No Args: bin_name (str): The name of the bin containing the map. - index (int): The index of the entry to return. (64-bit signed integer) + index (int): The index of the entry to return. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -854,7 +854,7 @@ def map_get_by_index_range( Args: bin_name (str): The name of the bin containing the map. - index_start (int): The index of the first entry to return. (64-bit signed integer) + index_start (int): The index of the first entry to return. get_amt (int): The number of entries to return from the map. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. @@ -888,7 +888,7 @@ def map_get_by_rank(bin_name: str, rank, return_type, ctx: Optional[list] = None Args: bin_name (str): The name of the bin containing the map. - rank (int): The rank of the entry to return. (64-bit signed integer) + rank (int): The rank of the entry to return. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. ctx (list): An optional list of nested CDT :class:`cdt_ctx ` context operation @@ -912,7 +912,7 @@ def map_get_by_rank_range(bin_name: str, rank_start, get_amt, return_type, inver Args: bin_name (str): The name of the bin containing the map. - rank_start (int): The start of the rank of the entries to return. (64-bit signed integer) + rank_start (int): The start of the rank of the entries to return. get_amt (int): The number of entries to return. return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. @@ -951,8 +951,7 @@ def map_remove_by_value_rank_range_relative( Args: bin_name (str): The name of the bin containing the map. value: The value of the entry in the map for which to search - offset (int): Begin removing and returning items with rank == rank(found_item) + offset. - (64-bit signed integer) + offset (int): Begin removing and returning items with rank == rank(found_item) + offset return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. count (int): If specified, the number of items to remove and return. If None, @@ -1025,8 +1024,7 @@ def map_get_by_value_rank_range_relative( Args: bin_name (str): The name of the bin containing the map. value (str): The value of the item in the list for which to search - offset (int): Begin removing and returning items with rank == rank(fount_item) + offset. - (64-bit signed integer) + offset (int): Begin removing and returning items with rank == rank(fount_item) + offset return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. count (int): If specified, the number of items to remove and return. If None, @@ -1088,8 +1086,7 @@ def map_remove_by_key_index_range_relative( Args: bin_name (str): The name of the bin containing the list. key (str): The key of the item in the list for which to search - offset (int): Begin removing and returning items with rank == rank(fount_item) + offset. - (64-bit signed integer) + offset (int): Begin removing and returning items with rank == rank(fount_item) + offset return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. count (int): If specified, the number of items to remove and return. If None, @@ -1160,8 +1157,7 @@ def map_get_by_key_index_range_relative( Args: bin_name (str): The name of the bin containing the list. value (str): The value of the item in the list for which to search - offset (int): Begin removing and returning items with rank == rank(fount_item) + offset. - (64-bit signed integer) + offset (int): Begin removing and returning items with rank == rank(fount_item) + offset return_type (int): Value specifying what should be returned from the operation. This should be one of the :ref:`map_return_types` values. count (int): If specified, the number of items to remove and return. If None, From fee05c7297576df4f74912313daa4b078cdb4028 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:50:45 -0700 Subject: [PATCH 70/99] improve var naming in helper --- src/main/client/cdt_operation_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index d188505e9c..800d6474c4 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -199,14 +199,14 @@ as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, #define OUT_OF_BOUNDS_MESSAGE "%s must be between %d and %d." as_status get_bounded_int_from_py_dict(as_error *err, const char *key, - PyObject *op_dict, int *int_pointer, + PyObject *py_dict, int *int_pointer, int min_bound, int max_bound, bool is_optional, bool warn_if_out_of_bounds) { int64_t int64_to_return = -1; bool found = false; - if (get_optional_int64_t(err, key, op_dict, &int64_to_return, &found) != + if (get_optional_int64_t(err, key, py_dict, &int64_to_return, &found) != AEROSPIKE_OK) { return err->code; } From 66d04c95bceee5f48ba29ceaa1a81db875aa547b Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:51:26 -0700 Subject: [PATCH 71/99] Somehow updating c def didn't update c decl --- src/include/cdt_operation_utils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/include/cdt_operation_utils.h b/src/include/cdt_operation_utils.h index c0870942bc..a80905ed9a 100644 --- a/src/include/cdt_operation_utils.h +++ b/src/include/cdt_operation_utils.h @@ -79,7 +79,7 @@ as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, // So we define our min and max bound parameters as integer types // https://stackoverflow.com/a/366033 as_status get_bounded_int_from_py_dict(as_error *err, const char *key, - PyObject *op_dict, int *int_pointer, + PyObject *py_dict, int *int_pointer, int min_bound, int max_bound, bool is_optional, bool warn_if_out_of_bounds); From ca7b1939d252bb14ca28778e40082e5ea30a06b8 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 08:57:35 -0700 Subject: [PATCH 72/99] Initialize var right away to prevent undef reads. --- src/main/client/operate.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/client/operate.c b/src/main/client/operate.c index 9c72570738..b3fc9c84f2 100644 --- a/src/main/client/operate.c +++ b/src/main/client/operate.c @@ -742,14 +742,13 @@ as_status add_op(AerospikeClient *self, as_error *err, break; case OP_MAP_CREATE:; int tmp_value; - as_map_order order; if (get_bounded_int_from_py_dict(err, "map_order", py_operation_dict, &tmp_value, AS_MAP_UNORDERED, AS_MAP_KEY_VALUE_ORDERED, false, true) != AEROSPIKE_OK) { return err->code; } - order = (as_map_order)tmp_value; + as_map_order order = (as_map_order)tmp_value; bool persist_index = PyObject_IsTrue(py_persist_index); as_operations_map_create_all(ops, bin, ctx_ref, order, persist_index); From f6f13d64731450bf08d1adec5005485165e8c4b0 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 09:02:27 -0700 Subject: [PATCH 73/99] Rename new helper to get_enum_from_py_dict and reduce number of parameters to improve readability --- src/include/cdt_operation_utils.h | 8 +++---- src/main/client/bit_operate.c | 6 +++--- src/main/client/cdt_operation_utils.c | 21 ++++++++++++------ src/main/client/operate.c | 8 +++---- src/main/client/operate_helper.c | 26 +++++++++++----------- src/main/policy.c | 31 +++++++++++++-------------- 6 files changed, 52 insertions(+), 48 deletions(-) diff --git a/src/include/cdt_operation_utils.h b/src/include/cdt_operation_utils.h index a80905ed9a..1c1db06368 100644 --- a/src/include/cdt_operation_utils.h +++ b/src/include/cdt_operation_utils.h @@ -78,11 +78,9 @@ as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, // In C99, enum values can be between INT_MIN and INT_MAX // So we define our min and max bound parameters as integer types // https://stackoverflow.com/a/366033 -as_status get_bounded_int_from_py_dict(as_error *err, const char *key, - PyObject *py_dict, int *int_pointer, - int min_bound, int max_bound, - bool is_optional, - bool warn_if_out_of_bounds); +as_status get_enum_from_py_dict(as_error *err, const char *key, + PyObject *py_dict, int *int_pointer, + int min_bound, int max_bound, bool is_optional); as_status get_int_from_py_dict(as_error *err, const char *key, PyObject *op_dict, int *int_pointer); diff --git a/src/main/client/bit_operate.c b/src/main/client/bit_operate.c index 6c81f29a0f..838bf8d9f9 100644 --- a/src/main/client/bit_operate.c +++ b/src/main/client/bit_operate.c @@ -346,9 +346,9 @@ static as_status get_bit_resize_flags(as_error *err, PyObject *op_dict, int tmp_value; *resize_flags = AS_BIT_RESIZE_DEFAULT; - if (get_bounded_int_from_py_dict( - err, RESIZE_FLAGS_KEY, op_dict, &tmp_value, AS_BIT_RESIZE_DEFAULT, - AS_BIT_RESIZE_SHRINK_ONLY, true, true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict(err, RESIZE_FLAGS_KEY, op_dict, &tmp_value, + AS_BIT_RESIZE_DEFAULT, AS_BIT_RESIZE_SHRINK_ONLY, + true) != AEROSPIKE_OK) { return err->code; } *resize_flags = (as_bit_resize_flags)tmp_value; diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index 800d6474c4..82777cb9f3 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -198,11 +198,10 @@ as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, #define OUT_OF_BOUNDS_MESSAGE "%s must be between %d and %d." -as_status get_bounded_int_from_py_dict(as_error *err, const char *key, - PyObject *py_dict, int *int_pointer, - int min_bound, int max_bound, - bool is_optional, - bool warn_if_out_of_bounds) +static inline as_status +get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, + int *int_pointer, int min_bound, int max_bound, + bool is_optional, bool warn_if_out_of_bounds) { int64_t int64_to_return = -1; bool found = false; @@ -237,11 +236,19 @@ as_status get_bounded_int_from_py_dict(as_error *err, const char *key, return AEROSPIKE_OK; } +as_status get_enum_from_py_dict(as_error *err, const char *key, + PyObject *py_dict, int *int_pointer, + int min_bound, int max_bound, bool is_optional) +{ + return get_bound_int_from_py_dict(err, key, py_dict, int_pointer, min_bound, + max_bound, is_optional, true); +} + as_status get_int_from_py_dict(as_error *err, const char *key, PyObject *op_dict, int *int_pointer) { - return get_bounded_int_from_py_dict(err, key, op_dict, int_pointer, INT_MIN, - INT_MAX, false, false); + return get_bound_int_from_py_dict(err, key, op_dict, int_pointer, INT_MIN, + INT_MAX, false, false); } as_status get_list_return_type(as_error *err, PyObject *op_dict, diff --git a/src/main/client/operate.c b/src/main/client/operate.c index b3fc9c84f2..6e8a8a309d 100644 --- a/src/main/client/operate.c +++ b/src/main/client/operate.c @@ -742,10 +742,10 @@ as_status add_op(AerospikeClient *self, as_error *err, break; case OP_MAP_CREATE:; int tmp_value; - if (get_bounded_int_from_py_dict(err, "map_order", py_operation_dict, - &tmp_value, AS_MAP_UNORDERED, - AS_MAP_KEY_VALUE_ORDERED, false, - true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict(err, "map_order", py_operation_dict, + &tmp_value, AS_MAP_UNORDERED, + AS_MAP_KEY_VALUE_ORDERED, + false) != AEROSPIKE_OK) { return err->code; } as_map_order order = (as_map_order)tmp_value; diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index 5d17e8f6bd..61f34e983a 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -196,9 +196,9 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, switch (operation_code) { case OP_LIST_SET_ORDER: case OP_LIST_CREATE: - if (get_bounded_int_from_py_dict( - err, AS_PY_LIST_ORDER, op_dict, &tmp_value, AS_LIST_UNORDERED, - AS_LIST_ORDERED, false, true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict(err, AS_PY_LIST_ORDER, op_dict, &tmp_value, + AS_LIST_UNORDERED, AS_LIST_ORDERED, + false) != AEROSPIKE_OK) { goto exit; } list_order = (as_list_order)tmp_value; @@ -335,9 +335,9 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, as_string_regex_flags regex_flags = AS_STRING_REGEX_FLAGS_NONE; switch (operation_code) { case OP_STRING_IS_NUMERIC: { - if (get_bounded_int_from_py_dict( + if (get_enum_from_py_dict( err, "numeric_type", op_dict, &tmp_value, AS_STRING_NUMERIC_ANY, - AS_STRING_NUMERIC_FLOAT, false, true) != AEROSPIKE_OK) { + AS_STRING_NUMERIC_FLOAT, false) != AEROSPIKE_OK) { goto CLEANUP_VAL2_ON_ERROR; } numeric_type = (as_string_numeric_type)tmp_value; @@ -345,10 +345,10 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, } case OP_STRING_REGEX_COMPARE: case OP_STRING_REGEX_REPLACE: { - if (get_bounded_int_from_py_dict(err, "regex_flags", op_dict, - &tmp_value, AS_STRING_REGEX_FLAGS_NONE, - AS_STRING_REGEX_FLAGS_GLOBAL, false, - true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict(err, "regex_flags", op_dict, &tmp_value, + AS_STRING_REGEX_FLAGS_NONE, + AS_STRING_REGEX_FLAGS_GLOBAL, + false) != AEROSPIKE_OK) { goto CLEANUP_VAL2_ON_ERROR; } regex_flags = (as_string_regex_flags)tmp_value; @@ -567,10 +567,10 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, case OP_LIST_SORT: { as_list_sort_flags sort_flags; - if (get_bounded_int_from_py_dict(err, AS_PY_LIST_SORT_FLAGS, op_dict, - &tmp_value, AS_LIST_SORT_DEFAULT, - AS_LIST_SORT_DROP_DUPLICATES, false, - true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict(err, AS_PY_LIST_SORT_FLAGS, op_dict, + &tmp_value, AS_LIST_SORT_DEFAULT, + AS_LIST_SORT_DROP_DUPLICATES, + false) != AEROSPIKE_OK) { goto CLEANUP_VAL2_ON_ERROR; } sort_flags = (as_list_sort_flags)tmp_value; diff --git a/src/main/policy.c b/src/main/policy.c index c0bb7768c4..acd4b0f2a9 100644 --- a/src/main/policy.c +++ b/src/main/policy.c @@ -1045,10 +1045,9 @@ as_status pyobject_to_bit_policy(as_error *err, PyObject *py_policy, } int tmp_value; - if (get_bounded_int_from_py_dict(err, BIT_WRITE_FLAGS_KEY, py_policy, - &tmp_value, AS_BIT_WRITE_DEFAULT, - AS_BIT_WRITE_PARTIAL, false, - true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict(err, BIT_WRITE_FLAGS_KEY, py_policy, &tmp_value, + AS_BIT_WRITE_DEFAULT, AS_BIT_WRITE_PARTIAL, + false) != AEROSPIKE_OK) { return err->code; } @@ -1082,9 +1081,9 @@ as_status pyobject_to_map_policy(as_error *err, PyObject *py_policy, as_map_order map_order = AS_MAP_UNORDERED; int tmp_value; - if (get_bounded_int_from_py_dict(err, "map_order", py_policy, &tmp_value, - AS_MAP_UNORDERED, AS_MAP_KEY_VALUE_ORDERED, - false, true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict(err, "map_order", py_policy, &tmp_value, + AS_MAP_UNORDERED, AS_MAP_KEY_VALUE_ORDERED, + false) != AEROSPIKE_OK) { return err->code; } map_order = (as_map_order)tmp_value; @@ -1140,17 +1139,17 @@ as_status pyobject_to_list_policy(as_error *err, PyObject *py_policy, int tmp_value; as_list_order list_order = AS_LIST_UNORDERED; - if (get_bounded_int_from_py_dict(err, "list_order", py_policy, &tmp_value, - AS_LIST_UNORDERED, AS_LIST_ORDERED, true, - true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict(err, "list_order", py_policy, &tmp_value, + AS_LIST_UNORDERED, AS_LIST_ORDERED, + true) != AEROSPIKE_OK) { return err->code; } list_order = (as_list_order)tmp_value; as_list_write_flags flags = AS_LIST_WRITE_DEFAULT; - if (get_bounded_int_from_py_dict( - err, "write_flags", py_policy, &tmp_value, AS_LIST_WRITE_DEFAULT, - AS_LIST_WRITE_PARTIAL, true, true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict(err, "write_flags", py_policy, &tmp_value, + AS_LIST_WRITE_DEFAULT, AS_LIST_WRITE_PARTIAL, + true) != AEROSPIKE_OK) { return err->code; } flags = (as_list_write_flags)tmp_value; @@ -1189,9 +1188,9 @@ as_status pyobject_to_hll_policy(as_error *err, PyObject *py_policy, int tmp_value; as_hll_write_flags flags; - if (get_bounded_int_from_py_dict( - err, "flags", py_policy, &tmp_value, AS_HLL_WRITE_DEFAULT, - AS_HLL_WRITE_ALLOW_FOLD, true, true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict(err, "flags", py_policy, &tmp_value, + AS_HLL_WRITE_DEFAULT, AS_HLL_WRITE_ALLOW_FOLD, + true) != AEROSPIKE_OK) { return err->code; } From 1be346724533720900ed8d873db2255e94c38236 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 09:05:32 -0700 Subject: [PATCH 74/99] Make var naming less confusing --- src/main/client/cdt_operation_utils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index 82777cb9f3..bdbac3a3a7 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -203,9 +203,9 @@ get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, int *int_pointer, int min_bound, int max_bound, bool is_optional, bool warn_if_out_of_bounds) { - int64_t int64_to_return = -1; + int64_t int64 = -1; bool found = false; - if (get_optional_int64_t(err, key, py_dict, &int64_to_return, &found) != + if (get_optional_int64_t(err, key, py_dict, &int64, &found) != AEROSPIKE_OK) { return err->code; } @@ -215,7 +215,7 @@ get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, "Operation missing required entry %s", key); } - if (int64_to_return >= min_bound || int64_to_return <= max_bound) { + if (int64 >= min_bound || int64 <= max_bound) { goto return_int; } @@ -232,7 +232,7 @@ get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, min_bound, max_bound); return_int: - *int_pointer = int64_to_return; + *int_pointer = int64; return AEROSPIKE_OK; } From 10f6dedbecc9e838afe1501203df796514cabee1 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 09:12:43 -0700 Subject: [PATCH 75/99] Rm unnecessary cast --- src/main/client/operate_helper.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index 61f34e983a..158147c318 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -574,8 +574,7 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, goto CLEANUP_VAL2_ON_ERROR; } sort_flags = (as_list_sort_flags)tmp_value; - success = as_operations_list_sort(ops, bin, ctx_ref, - (as_list_sort_flags)sort_flags); + success = as_operations_list_sort(ops, bin, ctx_ref, sort_flags); break; } case OP_LIST_GET_BY_VALUE_RANK_RANGE_REL: From 0fcd9e47d3842d19b3c21b1382bf4ff9241dec1e Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 09:24:57 -0700 Subject: [PATCH 76/99] Allow ops with map_order attribute that are parsed in operate.c --- src/main/client/operate.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/client/operate.c b/src/main/client/operate.c index 6e8a8a309d..a826e1b6a8 100644 --- a/src/main/client/operate.c +++ b/src/main/client/operate.c @@ -418,6 +418,9 @@ as_status add_op(AerospikeClient *self, as_error *err, CONVERT_PY_CTX_TO_AS_CTX(); ctx_ref = (ctx_in_use ? &ctx : NULL); } + else if (strcmp(name, "map_order") == 0) { + continue; + } else if (strcmp(name, "persist_index") == 0) { py_persist_index = value; } From 835cdd60f19d8618dcc758c592bf91f924a44cda Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 09:50:36 -0700 Subject: [PATCH 77/99] Fix regression where map_order option in map policy is no longer optional --- src/main/policy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/policy.c b/src/main/policy.c index acd4b0f2a9..c573c10c1f 100644 --- a/src/main/policy.c +++ b/src/main/policy.c @@ -1083,7 +1083,7 @@ as_status pyobject_to_map_policy(as_error *err, PyObject *py_policy, int tmp_value; if (get_enum_from_py_dict(err, "map_order", py_policy, &tmp_value, AS_MAP_UNORDERED, AS_MAP_KEY_VALUE_ORDERED, - false) != AEROSPIKE_OK) { + true) != AEROSPIKE_OK) { return err->code; } map_order = (as_map_order)tmp_value; From 1a49f84d33ebac341132be9bb85d84360198980d Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 13:11:27 -0700 Subject: [PATCH 78/99] Fix regression where bit_write_flags is no longer optional --- src/main/policy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/policy.c b/src/main/policy.c index c573c10c1f..da889520a4 100644 --- a/src/main/policy.c +++ b/src/main/policy.c @@ -1047,7 +1047,7 @@ as_status pyobject_to_bit_policy(as_error *err, PyObject *py_policy, int tmp_value; if (get_enum_from_py_dict(err, BIT_WRITE_FLAGS_KEY, py_policy, &tmp_value, AS_BIT_WRITE_DEFAULT, AS_BIT_WRITE_PARTIAL, - false) != AEROSPIKE_OK) { + true) != AEROSPIKE_OK) { return err->code; } From 46f35b19f40c36e9974133c235c15f1c6d25c5df Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:24:38 -0700 Subject: [PATCH 79/99] Add tests to make sure warning is printed for invalid values passed to enum types --- test/new_tests/test_invalid_options.py | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 test/new_tests/test_invalid_options.py diff --git a/test/new_tests/test_invalid_options.py b/test/new_tests/test_invalid_options.py new file mode 100644 index 0000000000..c31f87ba13 --- /dev/null +++ b/test/new_tests/test_invalid_options.py @@ -0,0 +1,43 @@ +from conftest import KEYS +import pytest + +from aerospike_helpers.operations import bitwise_operations, map_operations, list_operations, hll_operations +import aerospike + +@pytest.mark.usefixtures("as_connection") +class TestInvalidOptions: + def setup(self): + self.key = KEYS[0] + self.as_connection.put( + self.key, + bins={ + "bitwise": b'12345', + "map": { + "a": 1 + }, + "list": [] + } + ) + yield + self.as_connection.remove(self.key) + + @pytest.mark.parametrize( + "op", + [ + # Use fixture with correct bins + bitwise_operations.bit_lshift(bin_name="bitwise", bit_offset=0, bit_size=2, shift=1, policy={"bit_write_flags": -1}), + # TODO: aerospike.BIT_WRITE_PARTIAL <= x < aerospike.BIT_WRITE_PARTIAL * 2 may be valid + bitwise_operations.bit_resize(bin_name="bitwise", byte_size=1, resize_flags=aerospike.BIT_RESIZE_SHRINK_ONLY * 2), + # TODO: same issue as above + map_operations.map_set_policy(bin_name="map", policy={"map_write_flags": aerospike.MAP_WRITE_PARTIAL * 2}), + list_operations.list_append(bin_name="list", value=1, policy={"list_order": aerospike.LIST_ORDERED + 1}), + list_operations.list_append(bin_name="list", value=1, policy={"write_flags": aerospike.LIST_WRITE_PARTIAL * 2}), + hll_operations.hll_add(bin_name="hll", policy={"flags": aerospike.HLL_WRITE_ALLOW_FOLD * 2}), + ] + ) + def test_invalid_enum_values_emits_warning(self, op): + ops = [ + op + ] + with pytest.warns(DeprecationWarning): + self.as_connection.operate(self.key, ops) From 3f51c8d621fec71e05988d3b1462744c6d66f2f0 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:28:04 -0700 Subject: [PATCH 80/99] Fix invalid import in test --- test/new_tests/test_invalid_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/new_tests/test_invalid_options.py b/test/new_tests/test_invalid_options.py index c31f87ba13..ce2604523f 100644 --- a/test/new_tests/test_invalid_options.py +++ b/test/new_tests/test_invalid_options.py @@ -1,4 +1,4 @@ -from conftest import KEYS +from .conftest import KEYS import pytest from aerospike_helpers.operations import bitwise_operations, map_operations, list_operations, hll_operations From 961fc323d125f3db568a5837086207735d48dad5 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:29:55 -0700 Subject: [PATCH 81/99] Fix invalid use of hll_add in test. --- test/new_tests/test_invalid_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/new_tests/test_invalid_options.py b/test/new_tests/test_invalid_options.py index ce2604523f..1d919d1b3c 100644 --- a/test/new_tests/test_invalid_options.py +++ b/test/new_tests/test_invalid_options.py @@ -32,7 +32,7 @@ def setup(self): map_operations.map_set_policy(bin_name="map", policy={"map_write_flags": aerospike.MAP_WRITE_PARTIAL * 2}), list_operations.list_append(bin_name="list", value=1, policy={"list_order": aerospike.LIST_ORDERED + 1}), list_operations.list_append(bin_name="list", value=1, policy={"write_flags": aerospike.LIST_WRITE_PARTIAL * 2}), - hll_operations.hll_add(bin_name="hll", policy={"flags": aerospike.HLL_WRITE_ALLOW_FOLD * 2}), + hll_operations.hll_add(bin_name="hll", values=[1], policy={"flags": aerospike.HLL_WRITE_ALLOW_FOLD * 2}), ] ) def test_invalid_enum_values_emits_warning(self, op): From fbd1555800c459eeb49e82346546c9c4482119a5 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:36:46 -0700 Subject: [PATCH 82/99] Address test fixture not running --- test/new_tests/test_invalid_options.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/new_tests/test_invalid_options.py b/test/new_tests/test_invalid_options.py index 1d919d1b3c..eaff0a8b39 100644 --- a/test/new_tests/test_invalid_options.py +++ b/test/new_tests/test_invalid_options.py @@ -6,6 +6,7 @@ @pytest.mark.usefixtures("as_connection") class TestInvalidOptions: + @pytest.fixture(autouse=True) def setup(self): self.key = KEYS[0] self.as_connection.put( From fa07baf7de808ec168868bc3959a13484f63c56e Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:40:50 -0700 Subject: [PATCH 83/99] Fix bug --- src/main/client/cdt_operation_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index bdbac3a3a7..788c6d22b7 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -215,7 +215,7 @@ get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, "Operation missing required entry %s", key); } - if (int64 >= min_bound || int64 <= max_bound) { + if (int64 >= min_bound && int64 <= max_bound) { goto return_int; } From 148909f421e6a77ca18c4c2c85a0be63a59da5c6 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:52:07 -0700 Subject: [PATCH 84/99] If we ignore all ServerError exceptions but only expect DeprecationWarning (from client side invalid input), we don't need to populate the server with data. --- test/new_tests/test_invalid_options.py | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/test/new_tests/test_invalid_options.py b/test/new_tests/test_invalid_options.py index eaff0a8b39..9aed1efb01 100644 --- a/test/new_tests/test_invalid_options.py +++ b/test/new_tests/test_invalid_options.py @@ -3,25 +3,10 @@ from aerospike_helpers.operations import bitwise_operations, map_operations, list_operations, hll_operations import aerospike +from aerospike import exception as e @pytest.mark.usefixtures("as_connection") class TestInvalidOptions: - @pytest.fixture(autouse=True) - def setup(self): - self.key = KEYS[0] - self.as_connection.put( - self.key, - bins={ - "bitwise": b'12345', - "map": { - "a": 1 - }, - "list": [] - } - ) - yield - self.as_connection.remove(self.key) - @pytest.mark.parametrize( "op", [ @@ -40,5 +25,8 @@ def test_invalid_enum_values_emits_warning(self, op): ops = [ op ] - with pytest.warns(DeprecationWarning): - self.as_connection.operate(self.key, ops) + try: + with pytest.warns(DeprecationWarning): + self.as_connection.operate(self.key, ops) + except e.ServerError: + pass From 3a4c4546b5c69ccd3cdabb27f3e200a51c9a2914 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Thu, 9 Jul 2026 18:13:41 -0700 Subject: [PATCH 85/99] Address test syntax error. --- test/new_tests/test_invalid_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/new_tests/test_invalid_options.py b/test/new_tests/test_invalid_options.py index 9aed1efb01..a089999308 100644 --- a/test/new_tests/test_invalid_options.py +++ b/test/new_tests/test_invalid_options.py @@ -27,6 +27,6 @@ def test_invalid_enum_values_emits_warning(self, op): ] try: with pytest.warns(DeprecationWarning): - self.as_connection.operate(self.key, ops) + self.as_connection.operate(KEYS[0], ops) except e.ServerError: pass From bba829508c1c965a2824e3000e93304d391c63ac Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 07:32:24 -0700 Subject: [PATCH 86/99] Only show deprecation warnings for flags if the value is > 2 * (max value of flag) - 1. Flags can be bitwise OR'd together. --- src/main/client/bit_operate.c | 6 +++--- src/main/client/operate_helper.c | 2 +- src/main/policy.c | 15 ++++++++------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/client/bit_operate.c b/src/main/client/bit_operate.c index 838bf8d9f9..1d115592cb 100644 --- a/src/main/client/bit_operate.c +++ b/src/main/client/bit_operate.c @@ -346,9 +346,9 @@ static as_status get_bit_resize_flags(as_error *err, PyObject *op_dict, int tmp_value; *resize_flags = AS_BIT_RESIZE_DEFAULT; - if (get_enum_from_py_dict(err, RESIZE_FLAGS_KEY, op_dict, &tmp_value, - AS_BIT_RESIZE_DEFAULT, AS_BIT_RESIZE_SHRINK_ONLY, - true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict( + err, RESIZE_FLAGS_KEY, op_dict, &tmp_value, AS_BIT_RESIZE_DEFAULT, + AS_BIT_RESIZE_SHRINK_ONLY * 2 - 1, true) != AEROSPIKE_OK) { return err->code; } *resize_flags = (as_bit_resize_flags)tmp_value; diff --git a/src/main/client/operate_helper.c b/src/main/client/operate_helper.c index 158147c318..33ba5e390d 100644 --- a/src/main/client/operate_helper.c +++ b/src/main/client/operate_helper.c @@ -347,7 +347,7 @@ as_status as_operations_add_from_pyobject(AerospikeClient *self, as_error *err, case OP_STRING_REGEX_REPLACE: { if (get_enum_from_py_dict(err, "regex_flags", op_dict, &tmp_value, AS_STRING_REGEX_FLAGS_NONE, - AS_STRING_REGEX_FLAGS_GLOBAL, + AS_STRING_REGEX_FLAGS_GLOBAL * 2 - 1, false) != AEROSPIKE_OK) { goto CLEANUP_VAL2_ON_ERROR; } diff --git a/src/main/policy.c b/src/main/policy.c index da889520a4..910388229b 100644 --- a/src/main/policy.c +++ b/src/main/policy.c @@ -1046,7 +1046,8 @@ as_status pyobject_to_bit_policy(as_error *err, PyObject *py_policy, int tmp_value; if (get_enum_from_py_dict(err, BIT_WRITE_FLAGS_KEY, py_policy, &tmp_value, - AS_BIT_WRITE_DEFAULT, AS_BIT_WRITE_PARTIAL, + AS_BIT_WRITE_DEFAULT, + AS_BIT_WRITE_PARTIAL * 2 - 1, true) != AEROSPIKE_OK) { return err->code; } @@ -1147,9 +1148,9 @@ as_status pyobject_to_list_policy(as_error *err, PyObject *py_policy, list_order = (as_list_order)tmp_value; as_list_write_flags flags = AS_LIST_WRITE_DEFAULT; - if (get_enum_from_py_dict(err, "write_flags", py_policy, &tmp_value, - AS_LIST_WRITE_DEFAULT, AS_LIST_WRITE_PARTIAL, - true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict( + err, "write_flags", py_policy, &tmp_value, AS_LIST_WRITE_DEFAULT, + AS_LIST_WRITE_PARTIAL * 2 - 1, true) != AEROSPIKE_OK) { return err->code; } flags = (as_list_write_flags)tmp_value; @@ -1188,9 +1189,9 @@ as_status pyobject_to_hll_policy(as_error *err, PyObject *py_policy, int tmp_value; as_hll_write_flags flags; - if (get_enum_from_py_dict(err, "flags", py_policy, &tmp_value, - AS_HLL_WRITE_DEFAULT, AS_HLL_WRITE_ALLOW_FOLD, - true) != AEROSPIKE_OK) { + if (get_enum_from_py_dict( + err, "flags", py_policy, &tmp_value, AS_HLL_WRITE_DEFAULT, + AS_HLL_WRITE_ALLOW_FOLD * 2 - 1, true) != AEROSPIKE_OK) { return err->code; } From f79b395b311670afd10e5b892fd94684b039914c Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 08:13:23 -0700 Subject: [PATCH 87/99] Fix bug where if an optional policy field is not set, -1 is passed for that field.. --- src/main/client/cdt_operation_utils.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index 788c6d22b7..689af37fcb 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -207,16 +207,21 @@ get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, bool found = false; if (get_optional_int64_t(err, key, py_dict, &int64, &found) != AEROSPIKE_OK) { - return err->code; + goto return_without_setting; } - if (!found && !is_optional) { - return as_error_update(err, AEROSPIKE_ERR_PARAM, - "Operation missing required entry %s", key); + if (!found) { + if (!is_optional) { + return as_error_update(err, AEROSPIKE_ERR_PARAM, + "Operation missing required entry %s", key); + } + else { + goto return_without_setting; + } } if (int64 >= min_bound && int64 <= max_bound) { - goto return_int; + goto set_int_and_return; } if (warn_if_out_of_bounds) { @@ -224,16 +229,17 @@ get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, PyErr_WarnFormat(PyExc_DeprecationWarning, STACK_LEVEL, OUT_OF_BOUNDS_MESSAGE, key, min_bound, max_bound); if (retval == 0) { - goto return_int; + goto set_int_and_return; } } return as_error_update(err, AEROSPIKE_ERR_PARAM, OUT_OF_BOUNDS_MESSAGE, key, min_bound, max_bound); -return_int: +set_int_and_return: *int_pointer = int64; - return AEROSPIKE_OK; +return_without_setting: + return err->code; } as_status get_enum_from_py_dict(as_error *err, const char *key, From a8778bff0c11824a4f0c32a6e0f707161873aa7d Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 08:18:09 -0700 Subject: [PATCH 88/99] Show the actual invalid argument in the error message to make easier to debug. --- src/main/client/cdt_operation_utils.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index 689af37fcb..dc3e0d9704 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -196,7 +196,8 @@ as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, return AEROSPIKE_OK; } -#define OUT_OF_BOUNDS_MESSAGE "%s must be between %d and %d." +#define OUT_OF_BOUNDS_MESSAGE \ + "%s must be between %d and %d, but received %" PRId64 " instead." static inline as_status get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, @@ -225,16 +226,16 @@ get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, } if (warn_if_out_of_bounds) { - int retval = - PyErr_WarnFormat(PyExc_DeprecationWarning, STACK_LEVEL, - OUT_OF_BOUNDS_MESSAGE, key, min_bound, max_bound); + int retval = PyErr_WarnFormat(PyExc_DeprecationWarning, STACK_LEVEL, + OUT_OF_BOUNDS_MESSAGE, key, min_bound, + max_bound, int64); if (retval == 0) { goto set_int_and_return; } } return as_error_update(err, AEROSPIKE_ERR_PARAM, OUT_OF_BOUNDS_MESSAGE, key, - min_bound, max_bound); + min_bound, max_bound, int64); set_int_and_return: *int_pointer = int64; From 5f74e419209d6e9c8ff5a4ddf2626e56aa4fa7df Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 08:54:06 -0700 Subject: [PATCH 89/99] Change test case to check map_order instead of map_write_flags, since the latter is a uint32 parameter in the C client instead of an enum --- test/new_tests/test_invalid_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/new_tests/test_invalid_options.py b/test/new_tests/test_invalid_options.py index a089999308..a4178f6b86 100644 --- a/test/new_tests/test_invalid_options.py +++ b/test/new_tests/test_invalid_options.py @@ -15,7 +15,7 @@ class TestInvalidOptions: # TODO: aerospike.BIT_WRITE_PARTIAL <= x < aerospike.BIT_WRITE_PARTIAL * 2 may be valid bitwise_operations.bit_resize(bin_name="bitwise", byte_size=1, resize_flags=aerospike.BIT_RESIZE_SHRINK_ONLY * 2), # TODO: same issue as above - map_operations.map_set_policy(bin_name="map", policy={"map_write_flags": aerospike.MAP_WRITE_PARTIAL * 2}), + map_operations.map_put(bin_name="map", key=1, value=1, map_policy={"map_order": aerospike.MAP_KEY_VALUE_ORDERED + 1}), list_operations.list_append(bin_name="list", value=1, policy={"list_order": aerospike.LIST_ORDERED + 1}), list_operations.list_append(bin_name="list", value=1, policy={"write_flags": aerospike.LIST_WRITE_PARTIAL * 2}), hll_operations.hll_add(bin_name="hll", values=[1], policy={"flags": aerospike.HLL_WRITE_ALLOW_FOLD * 2}), From 1d33c05de53614d5e6073e9c7882bfa2c59e93b4 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 09:42:59 -0700 Subject: [PATCH 90/99] Clarify that min and max bounds are inclusive in error message. --- src/main/client/cdt_operation_utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index dc3e0d9704..1d65172faf 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -197,7 +197,8 @@ as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, } #define OUT_OF_BOUNDS_MESSAGE \ - "%s must be between %d and %d, but received %" PRId64 " instead." + "%s must be inclusively between %d and %d, but received %" PRId64 \ + " instead." static inline as_status get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, From 8b05be69487e2d7e79a46a06b057c2a86938ca77 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 09:46:11 -0700 Subject: [PATCH 91/99] TODO's have been addressed. --- test/new_tests/test_invalid_options.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/new_tests/test_invalid_options.py b/test/new_tests/test_invalid_options.py index a4178f6b86..a2499b2640 100644 --- a/test/new_tests/test_invalid_options.py +++ b/test/new_tests/test_invalid_options.py @@ -12,9 +12,7 @@ class TestInvalidOptions: [ # Use fixture with correct bins bitwise_operations.bit_lshift(bin_name="bitwise", bit_offset=0, bit_size=2, shift=1, policy={"bit_write_flags": -1}), - # TODO: aerospike.BIT_WRITE_PARTIAL <= x < aerospike.BIT_WRITE_PARTIAL * 2 may be valid bitwise_operations.bit_resize(bin_name="bitwise", byte_size=1, resize_flags=aerospike.BIT_RESIZE_SHRINK_ONLY * 2), - # TODO: same issue as above map_operations.map_put(bin_name="map", key=1, value=1, map_policy={"map_order": aerospike.MAP_KEY_VALUE_ORDERED + 1}), list_operations.list_append(bin_name="list", value=1, policy={"list_order": aerospike.LIST_ORDERED + 1}), list_operations.list_append(bin_name="list", value=1, policy={"write_flags": aerospike.LIST_WRITE_PARTIAL * 2}), From 918f17db8d08d1079724421068ddd325f064457a Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 12:38:40 -0700 Subject: [PATCH 92/99] Improve C label naming. --- src/main/client/cdt_operation_utils.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index 1d65172faf..7f7c63d473 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -209,7 +209,7 @@ get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, bool found = false; if (get_optional_int64_t(err, key, py_dict, &int64, &found) != AEROSPIKE_OK) { - goto return_without_setting; + goto exit_without_returning_int; } if (!found) { @@ -218,12 +218,12 @@ get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, "Operation missing required entry %s", key); } else { - goto return_without_setting; + goto exit_without_returning_int; } } if (int64 >= min_bound && int64 <= max_bound) { - goto set_int_and_return; + goto return_int; } if (warn_if_out_of_bounds) { @@ -231,16 +231,16 @@ get_bound_int_from_py_dict(as_error *err, const char *key, PyObject *py_dict, OUT_OF_BOUNDS_MESSAGE, key, min_bound, max_bound, int64); if (retval == 0) { - goto set_int_and_return; + goto return_int; } } return as_error_update(err, AEROSPIKE_ERR_PARAM, OUT_OF_BOUNDS_MESSAGE, key, min_bound, max_bound, int64); -set_int_and_return: +return_int: *int_pointer = int64; -return_without_setting: +exit_without_returning_int: return err->code; } From 694f6024662db1f9dc611102063cfbab96ac6c4f Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 12:42:03 -0700 Subject: [PATCH 93/99] Make py_dict var name generic. get_int_from_py_dict is used by as_cdt_ctx_add_from_pyobject and not just for operation dictionaries. --- src/include/cdt_operation_utils.h | 2 +- src/main/client/cdt_operation_utils.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/include/cdt_operation_utils.h b/src/include/cdt_operation_utils.h index 1c1db06368..2d3e755a9e 100644 --- a/src/include/cdt_operation_utils.h +++ b/src/include/cdt_operation_utils.h @@ -83,7 +83,7 @@ as_status get_enum_from_py_dict(as_error *err, const char *key, int min_bound, int max_bound, bool is_optional); as_status get_int_from_py_dict(as_error *err, const char *key, - PyObject *op_dict, int *int_pointer); + PyObject *py_dict, int *int_pointer); as_status get_list_return_type(as_error *err, PyObject *op_dict, int *return_type); diff --git a/src/main/client/cdt_operation_utils.c b/src/main/client/cdt_operation_utils.c index 7f7c63d473..c733961713 100644 --- a/src/main/client/cdt_operation_utils.c +++ b/src/main/client/cdt_operation_utils.c @@ -253,9 +253,9 @@ as_status get_enum_from_py_dict(as_error *err, const char *key, } as_status get_int_from_py_dict(as_error *err, const char *key, - PyObject *op_dict, int *int_pointer) + PyObject *py_dict, int *int_pointer) { - return get_bound_int_from_py_dict(err, key, op_dict, int_pointer, INT_MIN, + return get_bound_int_from_py_dict(err, key, py_dict, int_pointer, INT_MIN, INT_MAX, false, false); } From 2d789b5ab696a64c655ac69fbab6a42ff2b651c3 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 12:44:34 -0700 Subject: [PATCH 94/99] Clear up behavior of get_enum_from_py_dict --- src/include/cdt_operation_utils.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/cdt_operation_utils.h b/src/include/cdt_operation_utils.h index 2d3e755a9e..7d79c5264f 100644 --- a/src/include/cdt_operation_utils.h +++ b/src/include/cdt_operation_utils.h @@ -78,6 +78,7 @@ as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, // In C99, enum values can be between INT_MIN and INT_MAX // So we define our min and max bound parameters as integer types // https://stackoverflow.com/a/366033 +// If is_optional is true, int_pointer does not get dereferenced. as_status get_enum_from_py_dict(as_error *err, const char *key, PyObject *py_dict, int *int_pointer, int min_bound, int max_bound, bool is_optional); From 284afe0f5e3532fd55453c35632317bd9e13b7e7 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 12:45:51 -0700 Subject: [PATCH 95/99] Further clear up how helper should work --- src/include/cdt_operation_utils.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/include/cdt_operation_utils.h b/src/include/cdt_operation_utils.h index 7d79c5264f..fed2c249fe 100644 --- a/src/include/cdt_operation_utils.h +++ b/src/include/cdt_operation_utils.h @@ -79,6 +79,7 @@ as_status get_uint64_t(as_error *err, const char *key, PyObject *op_dict, // So we define our min and max bound parameters as integer types // https://stackoverflow.com/a/366033 // If is_optional is true, int_pointer does not get dereferenced. +// min_bound and max_bound are inclusive as_status get_enum_from_py_dict(as_error *err, const char *key, PyObject *py_dict, int *int_pointer, int min_bound, int max_bound, bool is_optional); From c8c1c87ccf473e315983ca4ea99b5945c2258383 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 12:51:27 -0700 Subject: [PATCH 96/99] Clarify why there is a try-catch statement in the tests --- test/new_tests/test_invalid_options.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/new_tests/test_invalid_options.py b/test/new_tests/test_invalid_options.py index a2499b2640..c0fab1e3ce 100644 --- a/test/new_tests/test_invalid_options.py +++ b/test/new_tests/test_invalid_options.py @@ -10,7 +10,6 @@ class TestInvalidOptions: @pytest.mark.parametrize( "op", [ - # Use fixture with correct bins bitwise_operations.bit_lshift(bin_name="bitwise", bit_offset=0, bit_size=2, shift=1, policy={"bit_write_flags": -1}), bitwise_operations.bit_resize(bin_name="bitwise", byte_size=1, resize_flags=aerospike.BIT_RESIZE_SHRINK_ONLY * 2), map_operations.map_put(bin_name="map", key=1, value=1, map_policy={"map_order": aerospike.MAP_KEY_VALUE_ORDERED + 1}), @@ -26,5 +25,6 @@ def test_invalid_enum_values_emits_warning(self, op): try: with pytest.warns(DeprecationWarning): self.as_connection.operate(KEYS[0], ops) + # We only care about the client printing the DeprecationWarning; this is not an end to end test except e.ServerError: pass From a20e29e9ca84a1da27bf525383692549fe095fed Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 13:47:09 -0700 Subject: [PATCH 97/99] Since map_order is verified for operations, also verify it in the rest of the codebase. --- src/main/conversions.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/conversions.c b/src/main/conversions.c index 6e6e06ca99..488b63cff2 100644 --- a/src/main/conversions.c +++ b/src/main/conversions.c @@ -2640,8 +2640,9 @@ as_status as_cdt_ctx_add_from_pyobject(AerospikeClient *self, as_error *err, break; case CDT_CTX_MAP_KEY_CREATE:; int map_order = 0; - status = get_int_from_py_dict(err, CDT_CTX_ORDER_KEY, py_extra_args, - &map_order); + status = get_enum_from_py_dict(err, CDT_CTX_ORDER_KEY, py_extra_args, + &map_order, AS_MAP_UNORDERED, + AS_MAP_KEY_VALUE_ORDERED, false); if (status != AEROSPIKE_OK) { goto CLEANUP_PY_EXTRA_ARGS; } From a0bab3755af8b01964a12d1064086fd0461f7bfd Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 13:52:09 -0700 Subject: [PATCH 98/99] Verify list_order option throughout codebase --- src/main/conversions.c | 5 +++-- src/main/convert_expressions.c | 11 +++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/conversions.c b/src/main/conversions.c index 488b63cff2..e7dc02fd4f 100644 --- a/src/main/conversions.c +++ b/src/main/conversions.c @@ -2665,8 +2665,9 @@ as_status as_cdt_ctx_add_from_pyobject(AerospikeClient *self, as_error *err, case CDT_CTX_LIST_INDEX_CREATE:; int list_order = 0; int pad = 0; - status = get_int_from_py_dict(err, CDT_CTX_ORDER_KEY, py_extra_args, - &list_order); + status = get_enum_from_py_dict(err, CDT_CTX_ORDER_KEY, py_extra_args, + &list_order, AS_LIST_UNORDERED, + AS_LIST_ORDERED, false); if (status != AEROSPIKE_OK) { goto CLEANUP_PY_EXTRA_ARGS; } diff --git a/src/main/convert_expressions.c b/src/main/convert_expressions.c index 133ef9e84a..3707e0b24f 100644 --- a/src/main/convert_expressions.c +++ b/src/main/convert_expressions.c @@ -1048,15 +1048,18 @@ add_expr_macros(AerospikeClient *self, as_static_pool *static_pool, APPEND_ARRAY(1, as_exp_list_clear(temp_expr->ctx, NIL)); // -1 for bin break; - case OP_LIST_SORT: - if (get_int64_t(err, LIST_ORDER_KEY, temp_expr->pydict, &lval1) != - AEROSPIKE_OK) { + case OP_LIST_SORT: { + int tmp_value; + if (get_enum_from_py_dict(err, LIST_ORDER_KEY, temp_expr->pydict, + &tmp_value, AS_LIST_UNORDERED, + AS_LIST_ORDERED, false) != AEROSPIKE_OK) { return err->code; } - APPEND_ARRAY(1, as_exp_list_sort(temp_expr->ctx, lval1, + APPEND_ARRAY(1, as_exp_list_sort(temp_expr->ctx, tmp_value, NIL)); // -1 for bin break; + } case OP_LIST_REMOVE_BY_VALUE: if (get_int64_t(err, AS_PY_LIST_RETURN_KEY, temp_expr->pydict, &lval1) != AEROSPIKE_OK) { From 297122381f0c9e3c30d7a273e8cb05835fa85fd3 Mon Sep 17 00:00:00 2001 From: Julian Nguyen <109386615+juliannguyen4@users.noreply.github.com> Date: Fri, 10 Jul 2026 13:57:00 -0700 Subject: [PATCH 99/99] Verify bit resize flags everywhere in codebase. --- src/main/convert_expressions.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/convert_expressions.c b/src/main/convert_expressions.c index 3707e0b24f..41874cd763 100644 --- a/src/main/convert_expressions.c +++ b/src/main/convert_expressions.c @@ -1485,14 +1485,18 @@ add_expr_macros(AerospikeClient *self, as_static_pool *static_pool, temp_expr->ctx, lval1, NIL, NIL, NIL)); // - 3 for rank, count, bin break; - case _AS_EXP_BIT_FLAGS: - if (get_int64_t(err, AS_PY_VAL_KEY, temp_expr->pydict, &lval1) != - AEROSPIKE_OK) { + case _AS_EXP_BIT_FLAGS: { + int tmp_value; + if (get_enum_from_py_dict(err, AS_PY_VAL_KEY, temp_expr->pydict, + &tmp_value, AS_BIT_RESIZE_DEFAULT, + AS_BIT_RESIZE_SHRINK_ONLY * 2 - 1, + false) != AEROSPIKE_OK) { return err->code; } - APPEND_ARRAY(0, as_exp_uint((uint64_t)lval1)); + APPEND_ARRAY(0, as_exp_uint(tmp_value)); break; + } case OP_BIT_RESIZE: APPEND_ARRAY(4, as_exp_bit_resize( NULL, NIL, NO_BIT_FLAGS,