* PHP < 8.0 took a `char*` as `php_json_decode` input, whereas newer
versions take a const char * so ifdef around this.
* Fix compilation errors due to `false` not being defined. So as to make
a minimal change we can just use 0 and 1
Unfortunately `VEMB` has a unique `RESP2` reply as far as I can tell,
where it sends the embedding mode (int8, bin, fp32) as a simple string.
This would cause any of PhpRedis' generic reply handlers to turn that
into `true` which isn't useful. For that reason we need a custom reply
handler.
Additionally slightly rework `VINFO` to short circuit and return failure
if we read anything other than a bulk string or an integer reply type.
Otherwise we may get out of sync on the socket.
See #2543
All of these commands have the same form `<cmd> key`. `VINFO` is a bit
of an outlier however that uses simple strings as opposed to bulk
strings for the key names, meaning we had to create a custom handler.
See #2543
Valkey 9.0.0 implemented a new variant of `GEOSEARCH` where you supply
the verticies to an arbitrary polygon.
Since we can't modify the `geosearch` prototype using it is a little
wonky (you need to just pass empty strings for position and unit).
```php
$redis->geosearch('ca:cities', '', [
-121.90, 39.65, -121.77, 39.65, -121.77, 39.80, -121.90, 39.80
], '');
$redis->geosearchstore('ca:cities', 'dst', '', [
-121.90, 39.65, -121.77, 39.65, -121.77, 39.80, -121.90, 39.80
], '');
```
When the slot's->slaves was null, it was dereferencing null, causing
segfault.
This happens in weird scenario when some of the nodes in cluster are
down or having changed IP addresses without knowing about it.
This is likely to never happen but just skipping NULL nodes is better than aborting the reset.
Co-authored-by: Pavlo Yatsukhnenko <yatsukhnenko@users.noreply.github.com>
This wrapper macro implicitly defines an `} else {` block but this is
not clear at the callsite which obsures what is actually going on.
There's no real advantage to the wrapping macro. Instead just call the
underlying macro in an explicit else branch.
Mostly null pointer derefs or use of uninitialized values. Some were
probably false positives since hte analyzer can't fully reason about how
the zend internals use `zval` structs but the fixes don't really have
any downside.
* Rework `HEXPIRE` test inclusion + bump Valkey
* Add a little `haveCommand` helper which uses `COMMAND INFO` to check
if a given server has a specific command. This way when we bump valkey
to an official release that supports the commands we will start
testing.
* Bump Valkey from 7.2.5 to 8.1.3 which is much newer.
* Rework `haveCommand` to explicitly check for the command name
COMMAND INFO will return the command name as one of the first bits of
data so we can check for it that way.
* Fix incorrect logic
* We can make the code simpler by using `zend_empty_array` when no args
are passed as well as the new argument parsing macros and newer internal
redis command appending functions that take zend strings.
* Add a regression test for when we execute `EVAL[SHA]` with arguments
but do not send any keys. This was causing UB in RedisCluster (#2681).
We were previously only picking a random slot if the user didn't pass
any arguments at all whereas we want to pick a random slot if they don't
pass any *keys*.
This change just universally picks a random slot at the beginning and
then if any keys are processed those keys will override the random
selection.
Fixes#2681
This command is similar to `VADD` in that it's pretty simple but allows
for a great many options.
In it's most basic form:
```php
// To get similarity of a different element
$redis->vsim('myvec', 'some-element');
// To get similarity for a vector of scores
```
As seen above the method attempts to infer element or vector from the
argument passed to $member`. However, since we do serialize the member
when doing `ELE` mode, the user can also specify `ELE` explicitly in the
options array to force an `ELE` search sending serialized values.
```php
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
$redis->vsim('myvec', [3.14, 2.71], ['ELE']);
```
See #2543
This is for Redis 8.0's vector sets.
The command itself can be quite complex with all of the various options but
pretty simple using all defaults.
```php
$redis->vadd('myvec', [3.14, 2.17], 'myelement');
```
The implementation takes a default argument `$options` which can be an array in
order to specify the myriad of other knobs users can send. We just do a bit of
validation on inputs (e.g. certain numeric options must be positive) and make
sure the command is constructed in a valid way (e.g. REDUCE <dim> must come
before the floating point values).
By default we deliver `FP32` blobs but allow the user to send `VALUES` in the
options array which will cause PhpRedis to send N individual values. Sending
values is slower but might be nice for debugging (e.g. watching monitor)
See #2543