Skip to content

[DO NOT MERGE, ONLY FOR REVIEW] Feature/first value implementation#2

Draft
rileydes-improving wants to merge 3 commits intofeature/vector-reducer-functionsfrom
feature/first-value-implementation
Draft

[DO NOT MERGE, ONLY FOR REVIEW] Feature/first value implementation#2
rileydes-improving wants to merge 3 commits intofeature/vector-reducer-functionsfrom
feature/first-value-implementation

Conversation

@rileydes-improving
Copy link
Copy Markdown

An implementation of the First Value Reducer towards adding full FT.Aggregate support

@AlexFilipImproving AlexFilipImproving marked this pull request as draft March 2, 2026 16:27
@AlexFilipImproving
Copy link
Copy Markdown

I think writing compatibility tests will be most helpful to get the desired behaviour. Write them in generate.py and to run them make sure you have docker installed along with the valkey and pytest packages in python. Run pytest generate.py in the integration/compatibility directory, then you can run ./build.sh --run-integration-tests=compatibility at the top level.
generate.py will create an answers file, which you should push as well.

@rileydes-improving
Copy link
Copy Markdown
Author

I think writing compatibility tests will be most helpful to get the desired behaviour. Write them in generate.py and to run them make sure you have docker installed along with the valkey and pytest packages in python. Run pytest generate.py in the integration/compatibility directory, then you can run ./build.sh --run-integration-tests=compatibility at the top level. generate.py will create an answers file, which you should push as well.

Sounds good, I'll do that

AlexFilipImproving pushed a commit that referenced this pull request Mar 3, 2026
Resolves: valkey-io#703 

Encountered the following series of crashes during engine startup. 
1. SIGSEGV in `string2ll_resolver` — IFUNC resolver called before TSAN
runtime initializes
```
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6de0fb0 in ?? ()
#0  0x00007ffff6de0fb0 in ?? ()
#1  0x00000000004b89a7 in string2ll_resolver.lto_priv ()
#2  0x00007ffff7de4d94 in _dl_relocate_object () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7ddceaa in dl_main () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7df0b5f in _dl_sysdep_start () from /lib64/ld-linux-x86-64.so.2
#5  0x00007ffff7ddad2e in _dl_start () from /lib64/ld-linux-x86-64.so.2
#6  0x00007ffff7dd9ef8 in _start () from /lib64/ld-linux-x86-64.so.2
valkey-io#7  0x0000000000000003 in ?? ()
valkey-io#8  0x00007fffffffe04c in ?? ()
valkey-io#9  0x00007fffffffe0b6 in ?? ()
valkey-io#10 0x00007fffffffe0bd in ?? ()
valkey-io#11 0x0000000000000000 in ?? ()
```
2. TSAN abort on `RTLD_DEEPBIND` — module loader uses `RTLD_DEEPBIND`
which is incompatible with TSAN
```
cat /workplace/baswanth/tsan/valkey-search/testing/integration/.build-release-tsan/output/6379_stdout.txt 2>/dev/null | tail -20
45443:M 25 Feb 2026 01:57:58.222 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see jemalloc/jemalloc#1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
45443:M 25 Feb 2026 01:57:58.222 * oO0OoO0OoO0Oo Valkey is starting oO0OoO0OoO0Oo
45443:M 25 Feb 2026 01:57:58.222 * Valkey version=9.0.1, bits=64, commit=ab3c953b, modified=1, pid=45443, just started
45443:M 25 Feb 2026 01:57:58.222 * Configuration loaded
45443:M 25 Feb 2026 01:57:58.224 * monotonic clock: POSIX clock_gettime
45443:M 25 Feb 2026 01:57:58.226 * Running mode=cluster, port=6379.
45443:M 25 Feb 2026 01:57:58.226 * No cluster configuration found, I'm a13c403e8a798f9ad051c654ff540ce1b3833b9d
==45443==You are trying to dlopen a /workplace/baswanth/tsan/valkey-search/.build-release-tsan/valkey-json/build/src/libjson.so shared library with RTLD_DEEPBIND flag which is incompatible with sanitizer runtime (see google/sanitizers#611 for details). If you want to run /workplace/baswanth/tsan/valkey-search/.build-release-tsan/valkey-json/build/src/libjson.so library under sanitizers please remove RTLD_DEEPBIND from dlopen flags.
```
3. `CHECK failed: sanitizer_deadlock_detector.h:67` — TSAN deadlock
detector overflows during module load
```
7826:M 25 Feb 2026 02:39:45.284 * Valkey version=9.0.1, bits=64, commit=ab3c953b, modified=1, pid=17826, just started
17826:M 25 Feb 2026 02:39:45.284 * Configuration loaded
17826:M 25 Feb 2026 02:39:45.286 * monotonic clock: POSIX clock_gettime
17826:M 25 Feb 2026 02:39:45.288 * Running mode=cluster, port=6379.
17826:M 25 Feb 2026 02:39:45.289 * No cluster configuration found, I'm 134edf06efe1a2e084ce9c94a43dab67e8376dfc
17826:M 25 Feb 2026 02:39:45.298 . <module> Setting shards to 524287
ThreadSanitizer: CHECK failed: sanitizer_deadlock_detector.h:67 "((n_all_locks_)) < (((sizeof(all_locks_with_contexts_)/sizeof((all_locks_with_contexts_)[0]))))" (0x40, 0x40) (tid=17826)
```

core changes that needs to be added.
```
cd /workplace/baswanth/tsan/valkey-search/.build-release-tsan/valkey-server && git diff src/util.c src/module.c src/config.h
diff --git a/src/config.h b/src/config.h
index 0c6b111a9..f80fa8cbc 100644
--- a/src/config.h
+++ b/src/config.h
@@ -172,6 +172,10 @@
 #define VALKEY_NO_SANITIZE(sanitizer)
 #endif
 
+#if defined(__SANITIZE_THREAD__)
+#define VALKEY_THREAD_SANITIZER 1
+#endif
+
 #if defined(__SANITIZE_ADDRESS__)
 /* GCC */
 #define VALKEY_ADDRESS_SANITIZER 1
diff --git a/src/module.c b/src/module.c
index 8d1bad4fe..0435499a8 100644
--- a/src/module.c
+++ b/src/module.c
@@ -12545,7 +12545,7 @@ int moduleLoad(const char *path, void **module_argv, int module_argc, int is_loa
     }
 
     int dlopen_flags = RTLD_NOW | RTLD_LOCAL;
-#if (defined(__GLIBC__) || defined(__FreeBSD__)) && !defined(VALKEY_ADDRESS_SANITIZER) && __has_include(<dlfcn.h>)
+#if (defined(__GLIBC__) || defined(__FreeBSD__)) && !defined(VALKEY_ADDRESS_SANITIZER) && !defined(VALKEY_THREAD_SANITIZER) && __has_include(<dlfcn.h>)
     /* RTLD_DEEPBIND, which is required for loading modules that contains the
      * same symbols, does not work with ASAN. Therefore, we exclude
      * RTLD_DEEPBIND when doing test builds with ASAN.
diff --git a/src/util.c b/src/util.c
index 0631736c8..cf5a073b1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -622,7 +622,7 @@ static int string2llScalar(const char *s, size_t slen, long long *value) {
 }
 
 #if HAVE_IFUNC && HAVE_X86_SIMD
-__attribute__((no_sanitize_address, used)) static int (*string2ll_resolver(void))(const char *, size_t, long long *) {
+__attribute__((no_sanitize_address, no_sanitize("thread"), used)) static int (*string2ll_resolver(void))(const char *, size_t, long long *) {
     /* Ifunc resolvers run before ASan initialization and before CPU detection
      * is initialized, so disable ASan and init CPU detection here. */
     __builtin_cpu_init();
 ```

---------

Signed-off-by: Baswanth Vegunta <baswanth@amazon.com>
Co-authored-by: Baswanth Vegunta <baswanth@amazon.com>
rileydes-improving pushed a commit that referenced this pull request Mar 3, 2026
Resolves: valkey-io#703 

Encountered the following series of crashes during engine startup. 
1. SIGSEGV in `string2ll_resolver` — IFUNC resolver called before TSAN
runtime initializes
```
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6de0fb0 in ?? ()
#0  0x00007ffff6de0fb0 in ?? ()
#1  0x00000000004b89a7 in string2ll_resolver.lto_priv ()
#2  0x00007ffff7de4d94 in _dl_relocate_object () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7ddceaa in dl_main () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7df0b5f in _dl_sysdep_start () from /lib64/ld-linux-x86-64.so.2
#5  0x00007ffff7ddad2e in _dl_start () from /lib64/ld-linux-x86-64.so.2
#6  0x00007ffff7dd9ef8 in _start () from /lib64/ld-linux-x86-64.so.2
valkey-io#7  0x0000000000000003 in ?? ()
valkey-io#8  0x00007fffffffe04c in ?? ()
valkey-io#9  0x00007fffffffe0b6 in ?? ()
valkey-io#10 0x00007fffffffe0bd in ?? ()
valkey-io#11 0x0000000000000000 in ?? ()
```
2. TSAN abort on `RTLD_DEEPBIND` — module loader uses `RTLD_DEEPBIND`
which is incompatible with TSAN
```
cat /workplace/baswanth/tsan/valkey-search/testing/integration/.build-release-tsan/output/6379_stdout.txt 2>/dev/null | tail -20
45443:M 25 Feb 2026 01:57:58.222 # WARNING Memory overcommit must be enabled! Without it, a background save or replication may fail under low memory condition. Being disabled, it can also cause failures without low memory condition, see jemalloc/jemalloc#1328. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
45443:M 25 Feb 2026 01:57:58.222 * oO0OoO0OoO0Oo Valkey is starting oO0OoO0OoO0Oo
45443:M 25 Feb 2026 01:57:58.222 * Valkey version=9.0.1, bits=64, commit=ab3c953b, modified=1, pid=45443, just started
45443:M 25 Feb 2026 01:57:58.222 * Configuration loaded
45443:M 25 Feb 2026 01:57:58.224 * monotonic clock: POSIX clock_gettime
45443:M 25 Feb 2026 01:57:58.226 * Running mode=cluster, port=6379.
45443:M 25 Feb 2026 01:57:58.226 * No cluster configuration found, I'm a13c403e8a798f9ad051c654ff540ce1b3833b9d
==45443==You are trying to dlopen a /workplace/baswanth/tsan/valkey-search/.build-release-tsan/valkey-json/build/src/libjson.so shared library with RTLD_DEEPBIND flag which is incompatible with sanitizer runtime (see google/sanitizers#611 for details). If you want to run /workplace/baswanth/tsan/valkey-search/.build-release-tsan/valkey-json/build/src/libjson.so library under sanitizers please remove RTLD_DEEPBIND from dlopen flags.
```
3. `CHECK failed: sanitizer_deadlock_detector.h:67` — TSAN deadlock
detector overflows during module load
```
7826:M 25 Feb 2026 02:39:45.284 * Valkey version=9.0.1, bits=64, commit=ab3c953b, modified=1, pid=17826, just started
17826:M 25 Feb 2026 02:39:45.284 * Configuration loaded
17826:M 25 Feb 2026 02:39:45.286 * monotonic clock: POSIX clock_gettime
17826:M 25 Feb 2026 02:39:45.288 * Running mode=cluster, port=6379.
17826:M 25 Feb 2026 02:39:45.289 * No cluster configuration found, I'm 134edf06efe1a2e084ce9c94a43dab67e8376dfc
17826:M 25 Feb 2026 02:39:45.298 . <module> Setting shards to 524287
ThreadSanitizer: CHECK failed: sanitizer_deadlock_detector.h:67 "((n_all_locks_)) < (((sizeof(all_locks_with_contexts_)/sizeof((all_locks_with_contexts_)[0]))))" (0x40, 0x40) (tid=17826)
```

core changes that needs to be added.
```
cd /workplace/baswanth/tsan/valkey-search/.build-release-tsan/valkey-server && git diff src/util.c src/module.c src/config.h
diff --git a/src/config.h b/src/config.h
index 0c6b111a9..f80fa8cbc 100644
--- a/src/config.h
+++ b/src/config.h
@@ -172,6 +172,10 @@
 #define VALKEY_NO_SANITIZE(sanitizer)
 #endif
 
+#if defined(__SANITIZE_THREAD__)
+#define VALKEY_THREAD_SANITIZER 1
+#endif
+
 #if defined(__SANITIZE_ADDRESS__)
 /* GCC */
 #define VALKEY_ADDRESS_SANITIZER 1
diff --git a/src/module.c b/src/module.c
index 8d1bad4fe..0435499a8 100644
--- a/src/module.c
+++ b/src/module.c
@@ -12545,7 +12545,7 @@ int moduleLoad(const char *path, void **module_argv, int module_argc, int is_loa
     }
 
     int dlopen_flags = RTLD_NOW | RTLD_LOCAL;
-#if (defined(__GLIBC__) || defined(__FreeBSD__)) && !defined(VALKEY_ADDRESS_SANITIZER) && __has_include(<dlfcn.h>)
+#if (defined(__GLIBC__) || defined(__FreeBSD__)) && !defined(VALKEY_ADDRESS_SANITIZER) && !defined(VALKEY_THREAD_SANITIZER) && __has_include(<dlfcn.h>)
     /* RTLD_DEEPBIND, which is required for loading modules that contains the
      * same symbols, does not work with ASAN. Therefore, we exclude
      * RTLD_DEEPBIND when doing test builds with ASAN.
diff --git a/src/util.c b/src/util.c
index 0631736c8..cf5a073b1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -622,7 +622,7 @@ static int string2llScalar(const char *s, size_t slen, long long *value) {
 }
 
 #if HAVE_IFUNC && HAVE_X86_SIMD
-__attribute__((no_sanitize_address, used)) static int (*string2ll_resolver(void))(const char *, size_t, long long *) {
+__attribute__((no_sanitize_address, no_sanitize("thread"), used)) static int (*string2ll_resolver(void))(const char *, size_t, long long *) {
     /* Ifunc resolvers run before ASan initialization and before CPU detection
      * is initialized, so disable ASan and init CPU detection here. */
     __builtin_cpu_init();
 ```

---------

Signed-off-by: Baswanth Vegunta <baswanth@amazon.com>
Co-authored-by: Baswanth Vegunta <baswanth@amazon.com>
@rileydes-improving rileydes-improving force-pushed the feature/first-value-implementation branch from 74eb443 to ed98d17 Compare March 4, 2026 16:56
@AlexFilipImproving AlexFilipImproving force-pushed the feature/vector-reducer-functions branch 2 times, most recently from 2819935 to 0117d89 Compare March 11, 2026 19:02
@rileydes-improving rileydes-improving force-pushed the feature/first-value-implementation branch from 4eb8fd4 to 10bc54f Compare March 16, 2026 13:14
- Add FIRST_VALUE reducer with three argument variants: simple mode (1 arg), BY clause with default ASC order (3 args), and BY clause with explicit ASC/DESC direction (4 args)
- Implement parser logic in ft_aggregate_parser.cc to handle reducer special parsing requirements
- Add parser header definitions for FIRST_VALUE token and parsing functions
- Adding FIRST_VALUE reducer in ft_aggregate_exec.cc
- Update ft.aggregate.json command schema with FIRST_VALUE reducer documentation
- Add compatibility tests
- Update user-facing documentation with FIRST_VALUE syntax and behavior descriptions

Signed-off-by: Riley Des <riley.desserre@improving.com>
Signed-off-by: Riley Des <riley.desserre@improving.com>
Signed-off-by: Riley Des <riley.desserre@improving.com>
@rileydes-improving rileydes-improving force-pushed the feature/first-value-implementation branch from e0d4683 to c8b5223 Compare April 1, 2026 15:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants