diff --git a/aerospike-client-c b/aerospike-client-c index 9f3621e9f2..8025c2a0fc 160000 --- a/aerospike-client-c +++ b/aerospike-client-c @@ -1 +1 @@ -Subproject commit 9f3621e9f23bed3fcfe89cc986aced58f6d8903a +Subproject commit 8025c2a0fc28b2cab2f126821c2f3fbe429e9600 diff --git a/doc/query.rst b/doc/query.rst index 4a79bbc152..dffa5922d1 100755 --- a/doc/query.rst +++ b/doc/query.rst @@ -57,6 +57,10 @@ A `stream UDF `_. @@ -496,6 +503,9 @@ Assume this boilerplate code is run before all examples below: If there are selected bins in this Query object via :meth:`~Query.select`, those selected bins will be ignored during the query. + This method cannot be used together with :meth:`~aerospike.Query.apply` on the same :class:`~aerospike.Query` + object — see :meth:`~aerospike.Query.execute_background`. + :param ops: `list` A list of operations generated from :ref:`aerospike_operation_helpers.operations`. .. note:: @@ -506,6 +516,9 @@ Assume this boilerplate code is run before all examples below: Execute a record UDF or write operations on records found by the query in the background. This method returns before the query has completed. A UDF or a list of write operations must have been added to the query with :meth:`Query.apply` or :meth:`Query.add_ops` respectively. + :meth:`Query.apply` and :meth:`Query.add_ops` cannot both be used on the same :class:`~aerospike.Query` object. + Calling this method after both have been set will raise a :exc:`~aerospike.exception.ParamError`. + :param dict policy: optional :ref:`aerospike_write_policies`. :return: a job ID that can be used with :meth:`~aerospike.Client.job_info` to track the status of the :py:data:`aerospike.JOB_QUERY` , as it runs in the background. diff --git a/doc/scan.rst b/doc/scan.rst index 6dce2c9fb6..9973e6a8be 100755 --- a/doc/scan.rst +++ b/doc/scan.rst @@ -71,6 +71,9 @@ Methods If you need to use an unsupported type, (e.g. set or tuple) you must use your own serializer. :return: one of the supported types, :class:`int`, :class:`str`, :class:`float` (double), :class:`list`, :class:`dict` (map), :class:`bytearray` (bytes), :class:`bool`. + This method cannot be used together with :meth:`~aerospike.Scan.add_ops` on the same :class:`~aerospike.Scan` + object — see :meth:`~aerospike.Scan.execute_background`. + .. seealso:: `Developing Record UDFs `_ @@ -84,6 +87,9 @@ Methods For foreground scans, only read operations are allowed. :meth:`Scan.foreach` and :meth:`Scan.results` will raise a :py:exc:`~aerospike.exception.ParamError` if a write operation has been set with :meth:`Scan.add_ops`. + This method cannot be used together with :meth:`~aerospike.Scan.apply` on the same :class:`~aerospike.Scan` + object — see :meth:`~aerospike.Scan.execute_background`. + :param ops: `list` A list of write operations generated by the aerospike_helpers e.g. list_operations, map_operations, etc. .. note:: @@ -297,8 +303,11 @@ Methods .. method:: execute_background([, policy]) - Execute a record UDF on records found by the scan in the background. This method returns before the scan has completed. - A UDF can be added to the scan with :meth:`Scan.apply`. + Execute a record UDF or write operations on records found by the scan in the background. This method returns before the scan has completed. + A UDF or a list of write operations must have been added to the scan with :meth:`Scan.apply` or :meth:`Scan.add_ops` respectively. + + :meth:`Scan.apply` and :meth:`Scan.add_ops` cannot both be used on the same :class:`~aerospike.Scan` object. + Calling this method after both have been set will raise a :exc:`~aerospike.exception.ParamError`. :param dict policy: optional :ref:`aerospike_write_policies`. diff --git a/test/new_tests/test_query_execute_background.py b/test/new_tests/test_query_execute_background.py index 270134adad..28324a343f 100644 --- a/test/new_tests/test_query_execute_background.py +++ b/test/new_tests/test_query_execute_background.py @@ -378,3 +378,21 @@ def test_add_ops_then_select_bins_then_bg_query(self, query): records = query.results() for _, _, bins in records: assert bins[BIN_NAME] == 3 + + def test_add_ops_then_apply(self, query): + query.add_ops(WRITE_OPS) + test_bin = "tz" + query.apply(TEST_UDF_MODULE, TEST_UDF_FUNCTION, [test_bin]) + + with pytest.raises(exception.ParamError) as excinfo: + query.execute_background() + assert excinfo.value.msg == "Cannot combine query operations with aggregation" + + def test_apply_then_add_ops(self, query): + test_bin = "tz" + query.apply(TEST_UDF_MODULE, TEST_UDF_FUNCTION, [test_bin]) + query.add_ops(WRITE_OPS) + + with pytest.raises(exception.ParamError) as excinfo: + query.execute_background() + assert excinfo.value.msg == "Cannot combine query operations with aggregation" diff --git a/test/new_tests/test_scan_execute_background.py b/test/new_tests/test_scan_execute_background.py index 9eb906835b..1a90d90ca4 100644 --- a/test/new_tests/test_scan_execute_background.py +++ b/test/new_tests/test_scan_execute_background.py @@ -379,3 +379,21 @@ def test_add_ops_then_select_bins_then_bg_query(self, scan_obj): records = scan2.results() for _, _, bins in records: assert bins[BIN_NAME] == 3 + + def test_add_ops_then_apply(self, scan_obj): + scan_obj.add_ops(WRITE_OPS) + test_bin = "tz" + scan_obj.apply(TEST_UDF_MODULE, TEST_UDF_FUNCTION, [test_bin]) + + with pytest.raises(exception.ParamError) as excinfo: + scan_obj.execute_background() + assert excinfo.value.msg == "Cannot combine scan operations with a UDF" + + def test_apply_then_add_ops(self, scan_obj): + test_bin = "tz" + scan_obj.apply(TEST_UDF_MODULE, TEST_UDF_FUNCTION, [test_bin]) + scan_obj.add_ops(WRITE_OPS) + + with pytest.raises(exception.ParamError) as excinfo: + scan_obj.execute_background() + assert excinfo.value.msg == "Cannot combine scan operations with a UDF"