# How to run multiple expressions in sequence (AER-6473)

**URL:** <https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738>\
**Category:** General Discussion\
**Tags:** expressions\
**Created:** [August 19, 2021, 6:54am UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738 "2021-08-19T06:54:13Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![avi](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@avi](https://discuss.aerospike.com/u/avi)\
**Post date:** [August 19, 2021, 6:54am UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/1 "2021-08-19T06:54:13Z")

</div>

this is in the context of expression conditions, here’s the pseudo code of what i am trying to do

```auto
expressions.Cond(
  condition,
  (action1, action2),
  expressions.Unknown()
)

```

where each of the actions is some expression, e.g. `action1` is removing an element from a list value of a map and `action2` is checking if the list is empty and removing the corresponding key from the map if so, is there some way to do this?

---

<div class="post-metadata">

**Author:** ![avi](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@avi](https://discuss.aerospike.com/u/avi)\
**Post date:** [August 20, 2021, 2:57am UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/2 "2021-08-20T02:57:29Z")

</div>

a workaround right now, following the example above, is simply to add another expression operation that checks if the list is empty and removes the key if so, so it would reduce to two separate operations something like

```auto
expressions.Cond(
  condition,
  action1,
  expressions.Unknown()
)

```

and

```auto
expressions.Cond(
  condition,
  action2,
  expressions.Unknown()
)

```

which has the disadvantage of checking the `condition` again. is there some better alternative that i am missing? the usefulness of this makes sense right?

---

<div class="post-metadata">

**Author:** ![neelp](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/neelp/32/1369_2.png) [@neelp](https://discuss.aerospike.com/u/neelp)\
**Post date:** [August 20, 2021, 6:27pm UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/3 "2021-08-20T18:27:39Z")

</div>

It seems you will need to use a separate expression operation for the second action. For a condition evaluation that is costly, you may save the condition result in a temp bin and use it multiple times, and delete the bin later. (Also, since the second action also has to perform an additional null list check, its condition would be: condition && null-list-check.)

---

<div class="post-metadata">

**Author:** ![kporter](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/kporter/32/515_2.png) [@kporter](https://discuss.aerospike.com/u/kporter)\
**Post date:** [August 20, 2021, 8:39pm UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/4 "2021-08-20T20:39:15Z")

</div>

Does action1 and action2 apply to the same bin?

---

<div class="post-metadata">

**Author:** ![avi](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@avi](https://discuss.aerospike.com/u/avi)\
**Post date:** [August 20, 2021, 8:39pm UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/5 "2021-08-20T20:39:57Z")

</div>

@kporter yes

---

<div class="post-metadata">

**Author:** ![avi](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@avi](https://discuss.aerospike.com/u/avi)\
**Post date:** [August 20, 2021, 8:42pm UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/6 "2021-08-20T20:42:24Z")

</div>

thanks @neelp i’ll probably double up on the expression operations since the condition is cheap, but taking a list of expressions would still be a cool feature for the future 🙂

---

<div class="post-metadata">

**Author:** ![kporter](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/kporter/32/515_2.png) [@kporter](https://discuss.aerospike.com/u/kporter)\
**Post date:** [August 20, 2021, 8:53pm UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/7 "2021-08-20T20:53:36Z")

</div>

In that case, you should be able to chain the actions - similar to what you describe in your first example.

Would look something like:

```auto
expressions.Cond(
  condition,
  action2(action1),
  expressions.Unknown()
)

```

I could provide a better demonstration if you could provide a more concrete example.

---

<div class="post-metadata">

**Author:** ![kporter](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/kporter/32/515_2.png) [@kporter](https://discuss.aerospike.com/u/kporter)\
**Post date:** [August 20, 2021, 9:38pm UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/8 "2021-08-20T21:38:45Z")

</div>

[Here is an example of what I’m describing](https://github.com/aerospike/aerospike-client-java/blob/744d2c82f8ae989c3714c35250927e6272684e14/test/src/com/aerospike/test/sync/basic/TestListExp.java#L97-L98). It’s written in the context of a filter-exp but the same principle would apply to an operate-exp.

---

<div class="post-metadata">

**Author:** ![avi](https://avatars.discourse-cdn.com/v4/letter/a/b9bd4f/32.png) [@avi](https://discuss.aerospike.com/u/avi)\
**Post date:** [August 24, 2021, 1:05am UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/9 "2021-08-24T01:05:54Z")

</div>

so this may be a separate issue or i maybe be misunderstanding expressions, but i’m getting some weird behavior when doing the post-expression, “chained” bin passing, at least with `expressions.Let`

here’s a full repro with

```auto
python: 3.8.10
python aerospike client: 6.0.0
aerospike image: aerospike:ce-5.6.0.9

```

```python
import aerospike
from aerospike_helpers import cdt_ctx, expressions
from aerospike_helpers.operations import expression_operations

ac = aerospike.client({'hosts': [('localhost', 3000)]})
ac.connect()
key = ('test', None, 0)

ac.put(
    key,
    {
        'bin': {
            'level1': {
                'level2_1': ['010101', '010102'],
                'level2_2': ['010102', '010103'],
            }
        }
    }
)
print(ac.get(key))
ac.operate(
    key,
    [
        expression_operations.expression_write(
            'bin',
            expressions.Let(
                expressions.Def(
                    'with_removed',
                    expressions.MapRemoveByKey(
                        ctx=[cdt_ctx.cdt_ctx_map_key('level1')],
                        key='level2_1',
                        bin='bin'
                    )
                ),
                expressions.Cond(
                    expressions.Eq(
                        expressions.MapSize(
                            ctx=[cdt_ctx.cdt_ctx_map_key('level1')],
                            bin=expressions.Var('with_removed')
                        ),
                        0
                    ),
                    expressions.MapRemoveByKey(
                        ctx=None,
                        key='level1',
                        bin=expressions.Var('with_removed')
                    ),
                    expressions.Var('with_removed')
                    # expressions.MapRemoveByKey(
                    # ctx=[cdt_ctx.cdt_ctx_map_key('level1')],
                    # key='level2_1',
                    # bin='bin'
                    # )
                )
            ).compile()
        )
    ]
)
print(ac.get(key))

```

and i’m gettting this output

```auto
(('test', None, None, bytearray(b'\xb3F\x13{\xa9\x18\x95y\xdaR\x01b\xdf\xdc\xd6\x1a\x10\xfe7\xd6')), {'ttl': 2592000, 'gen': 21}, {'bin': {'level1': {'level2_1': ['010101', '010102'], 'level2_2': ['010102', '010103']}}})
(('test', None, None, bytearray(b'\xb3F\x13{\xa9\x18\x95y\xdaR\x01b\xdf\xdc\xd6\x1a\x10\xfe7\xd6')), {'ttl': 2592000, 'gen': 22}, {'bin': 6.9493343797729e-310})

```

i observed a few things:

1. using the commented out `expressions.MapRemoveByKey` (repeating the `expressions.Def`) works as expected with output

```auto
(('test', None, None, bytearray(b'\xb3F\x13{\xa9\x18\x95y\xdaR\x01b\xdf\xdc\xd6\x1a\x10\xfe7\xd6')), {'ttl': 2592000, 'gen': 27}, {'bin': {'level1': {'level2_1': ['010101', '010102'], 'level2_2': ['010102', '010103']}}})
(('test', None, None, bytearray(b'\xb3F\x13{\xa9\x18\x95y\xdaR\x01b\xdf\xdc\xd6\x1a\x10\xfe7\xd6')), {'ttl': 2592000, 'gen': 28}, {'bin': {'level1': {'level2_2': ['010102', '010103']}}})

```

1. only the non-“level1 removal path” is a problem, commenting out a level2 (to go down the level1 removal path) works as expected with output

```auto
(('test', None, None, bytearray(b'\xb3F\x13{\xa9\x18\x95y\xdaR\x01b\xdf\xdc\xd6\x1a\x10\xfe7\xd6')), {'ttl': 2592000, 'gen': 29}, {'bin': {'level1': {'level2_1': ['010101', '010102']}}})
(('test', None, None, bytearray(b'\xb3F\x13{\xa9\x18\x95y\xdaR\x01b\xdf\xdc\xd6\x1a\x10\xfe7\xd6')), {'ttl': 2592000, 'gen': 30}, {'bin': {}})

```

1. not using a `expressions.Let` and just repeating everything within the `expressions.Cond` works as expected.

is the first output a bug?

---

<div class="post-metadata">

**Author:** ![neelp](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/neelp/32/1369_2.png) [@neelp](https://discuss.aerospike.com/u/neelp)\
**Post date:** [August 27, 2021, 10:46pm UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/10 "2021-08-27T22:46:22Z")

</div>

Thanks for pinpointing the issue. There definitely is a bug (which we will file) - but it seems not in the “default” path, but likely in the way an unchanged var value is returned and gets assigned. If for example you return the var from a condition branch, it still does not work. A modified var (say, with MapPut or MapClear) however would work.

---

<div class="post-metadata">

**Author:** ![kporter](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/kporter/32/515_2.png) [@kporter](https://discuss.aerospike.com/u/kporter)\
**Post date:** [August 30, 2021, 11:48pm UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/11 "2021-08-30T23:48:55Z")

</div>

Thanks for reporting - this is a bug that affects namespaces that are `data-in-memory` or `storage-engine memory`. A fix has been committed internally and should be part of subsequent major and hotfix releases.

---

<div class="post-metadata">

**Author:** ![system](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.aerospike.com/system/32/2274_2.png) [@system](https://discuss.aerospike.com/u/system)\
**Post date:** [November 22, 2021, 11:49pm UTC](https://discuss.aerospike.com/t/how-to-run-multiple-expressions-in-sequence-aer-6473/8738/12 "2021-11-22T23:49:32Z")

</div>

This topic was automatically closed 84 days after the last reply. New replies are no longer allowed.
