Skip to content

Commit 2eef2e6

Browse files
committed
Update to version v5.12.0
1 parent 6300fe7 commit 2eef2e6

342 files changed

Lines changed: 10090 additions & 5008 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

bindings/builtinserver/builtinserver.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ type BuiltinServer struct {
4949
}
5050

5151
func (server *BuiltinServer) stopServer(timeout time.Duration) error {
52+
if server.svc == 0 {
53+
return nil
54+
}
5255
if err := err2go(C.stop_reindexer_server(server.svc)); err != nil {
5356
return err
5457
}
@@ -276,6 +279,7 @@ func (server *BuiltinServer) Finalize() error {
276279
return err
277280
}
278281
C.destroy_reindexer_server(server.svc)
282+
server.svc = 0
279283
server.builtin = nil
280284
server.shutdownTimeout = 0
281285
return nil

bindings/consts.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package bindings
22

33
const CInt32Max = int(^uint32(0) >> 1)
44

5-
const ReindexerVersion = "v5.11.1"
5+
const ReindexerVersion = "v5.12.0"
66

77
// public go consts from type_consts.h and reindexer_ctypes.h
88
const (
@@ -40,6 +40,7 @@ const (
4040
CollateCustom = 4
4141

4242
FunctionFlatArrayLen = 0
43+
FunctionNow = 1
4344
)
4445

4546
// private go consts from type_consts.h and reindexer_ctypes.h
@@ -97,6 +98,12 @@ const (
9798
QueryKnnConditionExt = 33
9899
QueryFunction = 34
99100
QueryFunctionSubQueryCondition = 35
101+
QueryExpressions = 36
102+
103+
ExpressionTypeField = 0
104+
ExpressionTypeValues = 1
105+
ExpressionTypeExpression = 2
106+
ExpressionTypeSubQuery = 3
100107

101108
KnnQueryTypeBase = 0
102109
KnnQueryTypeBruteForce = 1

bindings/interface.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,24 @@ type EmbeddingConfig struct {
8787
// Query embedder configuration
8888
QueryEmbedder *EmbedderConfig `json:"query_embedder,omitempty"`
8989
}
90+
type QuantizationConfig struct {
91+
Type string `json:"quantization_type"`
92+
Quantile float32 `json:"quantile,omitempty"`
93+
SampleSize int64 `json:"sample_size,omitempty"`
94+
Threshold int64 `json:"quantization_threshold,omitempty"`
95+
}
9096

9197
type FloatVectorIndexOpts struct {
92-
Metric string `json:"metric"`
93-
Dimension int `json:"dimension"`
94-
M int `json:"m,omitempty"`
95-
EfConstruction int `json:"ef_construction,omitempty"`
96-
StartSize int `json:"start_size,omitempty"`
97-
CentroidsCount int `json:"centroids_count,omitempty"`
98-
MultithreadingMode int `json:"multithreading,omitempty"`
99-
Radius float32 `json:"radius,omitempty"`
100-
EmbeddingConfig *EmbeddingConfig `json:"embedding,omitempty"`
98+
Metric string `json:"metric"`
99+
Dimension int `json:"dimension"`
100+
M int `json:"m,omitempty"`
101+
EfConstruction int `json:"ef_construction,omitempty"`
102+
StartSize int `json:"start_size,omitempty"`
103+
CentroidsCount int `json:"centroids_count,omitempty"`
104+
MultithreadingMode int `json:"multithreading,omitempty"`
105+
Radius float32 `json:"radius,omitempty"`
106+
EmbeddingConfig *EmbeddingConfig `json:"embedding,omitempty"`
107+
QuantizationConfig *QuantizationConfig `json:"quantization_config,omitempty"`
101108
}
102109

103110
type IndexDef struct {

changelog.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,43 @@
1+
# Version 5.12.0 (20.03.2026)
2+
## Core
3+
- [fea] Added [now()-function](readme.md#nowunit) support into `WHERE`-clause. Now it may be used both in `UPDATE SET` and `WHERE` clauses
4+
- [fea] Added [flat_array_len()-function](readme.md#flat_array_lenfield_name) into `UPDATE SET`. Now it may be used both in `UPDATE SET` and `WHERE` clauses
5+
- [fea] Added `checksum` field into `#memstats`-namespaces as better alternative for `datahash`
6+
- [fea] Changed [grouping logic for equal_position](readme.md#search-in-array-fields-with-matching-indexes-using-grouping). New syntax/logic has better match with standard json-paths and also supports nested arrays in explicit way
7+
- [fix] Fixed possible memory leak during `composite`-indexes substitution inside WHERE-clauses (in cases, when `int`->`string` convertion was performed before `composite` substitution)
8+
- [fix] Fixed SQL parsing for queries with combination of `or inner join(...)` and `left join(...)`
9+
- [fix] Fixed storage data migration, when Primary key index was changed
10+
- [fix] Fixed `2D points` convertion on WHERE-clause (perviously it could led to crashes on assertion)
11+
- [fix] Added explicit check for `rtree` Primary keys. [Geo-indexes](readme.md#geometry) can not be PK anymore
12+
- [fix] Fixed [forced sort](readme.md#forced-sort) errors handling for [KNN-queries](float_vector.md), when query has `LIMIT` and `OFFSET`
13+
- [fix] Fixed `UUID`->`string` conversions for nested arrays on `UUID`-index deletion
14+
15+
## Fulltext
16+
- [fea] Added [optional terms boost](fulltext.md#base-config-parameters), that allows to set rank multiplier for specific terms
17+
18+
## Vector indexes
19+
- [fea] Added 8 bit scalar quantization for HNSW-index. [Read more...](float_vector.md#quantization-configuration-for-hnsw-index)
20+
- [fea] Added more effective vectorized implementations for `L2`, `IP` and `cosine` metrics.
21+
22+
## Replication
23+
- [fea] Added `checksum` check instead of `datahash` - `checksum` implementation has lower collisions rate and higher impact from each document's field
24+
- [fix] Fixed some rare case, when `temporary` namespace could remain alive after replication error
25+
26+
## Reindexer server
27+
- [fea] Changed [FilterDef](https://github.com/Restream/reindexer/blob/v5.12.0/cpp_src/server/contrib/server.yml#L4161) in Query DSL: some of the fields were marked as deprecated and `left_expression`/`right_expression` were as more unified alternatives for better [functions](readme.md#functions) support and future filtering expressions development
28+
29+
## Go connector
30+
- [fea] Added unified `WhereExpressions` method for better [functions](readme.md#functions) support and future filtering expressions development
31+
- [fix] Fixed deserialization crash for queries, where `inner join` stays before [equal_position](readme.md#search-in-array-fields-with-matching-indexes) in brackets
32+
33+
## Face
34+
- [fea] Added `Explain` visualization for queries with [MERGE](fulltext.md#merging-queries-results)
35+
- [fea] Added `Boost for specific fulltext terms` into fulltext config tab
36+
- [fix] Fixed up/down buttons for custom field on pagination section
37+
- [fix] Fixed the issue related to the page opening in a new window from left bar
38+
- [fix] Fixed the issue related to the page opening in a new window from `Namespace` tabs
39+
- [fix] Fixed `Explain` table in `Query Builder`
40+
141
# Version 5.11.1 (05.03.2026)
242
## Fulltext
343
- [fix] Fixed possible heap-use-after in composite fulltext indexes, created over non-indexed fields

cjson/creflect.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const (
1717
valueUuid = bindings.ValueUuid
1818
valueFloatVector = bindings.ValueFloatVector
1919
valueFloat = bindings.ValueFloat
20+
valueTuple = bindings.ValueTuple
2021
)
2122

2223
const (

cjson/serializer.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/binary"
55
"fmt"
66
"math"
7+
"reflect"
78
"unsafe"
89

910
"sync"
@@ -117,6 +118,65 @@ func (s *Serializer) PutDouble(v float64) *Serializer {
117118
return s
118119
}
119120

121+
func (s *Serializer) PutValue(v reflect.Value) error {
122+
k := v.Kind()
123+
if k == reflect.Ptr || k == reflect.Interface {
124+
v = v.Elem()
125+
k = v.Kind()
126+
}
127+
switch k {
128+
case reflect.Bool:
129+
s.PutVarCUInt(valueBool)
130+
if v.Bool() {
131+
s.PutVarUInt(1)
132+
} else {
133+
s.PutVarUInt(0)
134+
}
135+
case reflect.Uint:
136+
if unsafe.Sizeof(int(0)) == unsafe.Sizeof(int64(0)) {
137+
s.PutVarCUInt(valueInt64)
138+
} else {
139+
s.PutVarCUInt(valueInt)
140+
}
141+
142+
s.PutVarInt(int64(v.Uint()))
143+
case reflect.Int:
144+
if unsafe.Sizeof(int(0)) == unsafe.Sizeof(int64(0)) {
145+
s.PutVarCUInt(valueInt64)
146+
} else {
147+
s.PutVarCUInt(valueInt)
148+
}
149+
s.PutVarInt(v.Int())
150+
case reflect.Int16, reflect.Int32, reflect.Int8:
151+
s.PutVarCUInt(valueInt)
152+
s.PutVarInt(v.Int())
153+
case reflect.Uint8, reflect.Uint16, reflect.Uint32:
154+
s.PutVarCUInt(valueInt)
155+
s.PutVarInt(int64(v.Uint()))
156+
case reflect.Int64:
157+
s.PutVarCUInt(valueInt64)
158+
s.PutVarInt(v.Int())
159+
case reflect.Uint64:
160+
s.PutVarCUInt(valueInt64)
161+
s.PutVarInt(int64(v.Uint()))
162+
case reflect.String:
163+
s.PutVarCUInt(valueString)
164+
s.PutVString(v.String())
165+
case reflect.Float32, reflect.Float64:
166+
s.PutVarCUInt(valueDouble)
167+
s.PutDouble(v.Float())
168+
case reflect.Slice, reflect.Array:
169+
s.PutVarCUInt(valueTuple)
170+
s.PutVarCUInt(v.Len())
171+
for i := 0; i < v.Len(); i++ {
172+
s.PutValue(v.Index(i))
173+
}
174+
default:
175+
panic(fmt.Errorf("rq: Invalid reflection type %s", v.Kind().String()))
176+
}
177+
return nil
178+
}
179+
120180
func (s *Serializer) writeIntBits(v int64, sz uintptr) {
121181
l := len(s.buf)
122182
s.grow(int(sz))

clang-tidy/.clang-tidy

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ Checks: 'clang-diagnostic-*,
22
clang-analyzer-*,
33
performance-*,
44
bugprone-*,
5+
rx-*,
56
-bugprone-branch-clone,
67
-bugprone-easily-swappable-parameters,
78
-bugprone-macro-parentheses,
@@ -13,6 +14,9 @@ Checks: 'clang-diagnostic-*,
1314
-bugprone-parent-virtual-call,
1415
-bugprone-integer-division,
1516
-bugprone-inc-dec-in-conditions,
17+
-bugprone-std-namespace-modification,
18+
-bugprone-throwing-static-initialization,
19+
-bugprone-derived-method-shadowing-base-method,
1620
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
1721
-performance-no-int-to-ptr,
1822
-performance-enum-size,
@@ -21,6 +25,8 @@ Checks: 'clang-diagnostic-*,
2125
# clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling - too many unnecessary warning in vendored code
2226
# performance-no-int-to-ptr - consider how to fix this
2327
# bugprone-macro-parentheses - consider fixing
28+
# bugprone-std-namespace-modification - we have a lot of std::hash/operator>>. Consider fixing
29+
# bugprone-throwing-static-initialization - seems irrelevant
2430
WarningsAsErrors: '*'
2531
HeaderFilterRegex: '.*/cpp_src/([^v]|v[^e]|ve[^n]|ven[^d]|vend[^o]|vendo[^r]).*$'
2632
FormatStyle: none
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
cmake_minimum_required(VERSION 3.18)
2+
3+
set(CMAKE_CXX_STANDARD 20)
4+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
5+
6+
set(TARGET custom-tidy-checks)
7+
project(${TARGET})
8+
9+
find_package(LLVM REQUIRED CONFIG)
10+
find_package(Clang REQUIRED CONFIG)
11+
12+
message(STATUS "LLVM found: ${LLVM_DIR}")
13+
message(STATUS "Clang found: ${Clang_DIR}")
14+
15+
add_definitions(${LLVM_DEFINITIONS})
16+
include_directories(${LLVM_INCLUDE_DIRS})
17+
include_directories(${CLANG_INCLUDE_DIRS})
18+
include_directories(${PROJECT_SOURCE_DIR}/src)
19+
20+
file (
21+
GLOB_RECURSE
22+
SRCS
23+
${PROJECT_SOURCE_DIR}/src/*
24+
)
25+
26+
add_library(${TARGET} MODULE ${SRCS})
27+
28+
target_link_libraries(${TARGET}
29+
clangTidy
30+
clangTidyMain
31+
clangASTMatchers
32+
clangAST
33+
clangBasic
34+
LLVMSupport
35+
)
36+
37+
set_target_properties(${TARGET} PROPERTIES
38+
PREFIX ""
39+
SUFFIX ".so"
40+
)
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include <clang/AST/ASTContext.h>
2+
#include <clang/AST/DeclCXX.h>
3+
#include <clang/AST/ExprCXX.h>
4+
#include <clang/AST/Type.h>
5+
#include <clang/ASTMatchers/ASTMatchers.h>
6+
#include <clang/Basic/Diagnostic.h>
7+
#include <clang/Basic/SourceLocation.h>
8+
9+
#include "lambda_check.h"
10+
11+
using namespace clang;
12+
using namespace clang::ast_matchers;
13+
14+
namespace clang {
15+
namespace tidy {
16+
namespace reindexer_checks {
17+
18+
void LambdaToStdFunctionAllocationCheck::registerMatchers(MatchFinder* Finder) {
19+
// Match the constructor call of std::function that takes exactly one argument
20+
// whose type (after stripping references) is a lambda closure type.
21+
auto LambdaType = qualType(hasCanonicalType(hasDeclaration(cxxRecordDecl(isLambda()))));
22+
auto StdFunctionCtor =
23+
cxxConstructExpr(hasDeclaration(cxxConstructorDecl(ofClass(classTemplateSpecializationDecl(hasName("::std::function"))))),
24+
argumentCountIs(1), hasArgument(0, hasType(qualType(LambdaType))))
25+
.bind("ctor");
26+
27+
Finder->addMatcher(StdFunctionCtor, this);
28+
}
29+
30+
void LambdaToStdFunctionAllocationCheck::check(const MatchFinder::MatchResult& Result) {
31+
const auto* Ctor = Result.Nodes.getNodeAs<CXXConstructExpr>("ctor");
32+
if (!Ctor) {
33+
return;
34+
}
35+
36+
// Get the type of the lambda argument.
37+
const Expr* Arg = Ctor->getArg(0);
38+
QualType ArgType = Arg->getType();
39+
40+
// Strip references and cv-qualifiers to get the underlying lambda type.
41+
ArgType = ArgType.getCanonicalType().getNonReferenceType().getUnqualifiedType();
42+
43+
const auto* RD = ArgType->getAsCXXRecordDecl();
44+
if (!RD || !RD->isLambda()) {
45+
return;
46+
}
47+
48+
// Compute the size of the lambda closure type in bytes.
49+
ASTContext& Ctx = *Result.Context;
50+
uint64_t Size = Ctx.getTypeSize(ArgType) / 8; // bits → bytes
51+
52+
const unsigned Threshold = 16;
53+
if (Size > Threshold) {
54+
diag(Ctor->getBeginLoc(), "lambda capture size is %0 bytes (>%1), converting to std::function may allocate memory dynamically")
55+
<< Size << Threshold;
56+
}
57+
}
58+
59+
} // namespace reindexer_checks
60+
} // namespace tidy
61+
} // namespace clang
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
#include <clang-tidy/ClangTidy.h>
4+
#include <clang-tidy/ClangTidyCheck.h>
5+
#include <clang/ASTMatchers/ASTMatchFinder.h>
6+
7+
namespace clang {
8+
namespace tidy {
9+
10+
namespace reindexer_checks {
11+
12+
class LambdaToStdFunctionAllocationCheck : public ClangTidyCheck {
13+
public:
14+
LambdaToStdFunctionAllocationCheck(StringRef Name, ClangTidyContext* Context) : ClangTidyCheck(Name, Context) {}
15+
void registerMatchers(::clang::ast_matchers::MatchFinder* Finder) override;
16+
void check(const ::clang::ast_matchers::MatchFinder::MatchResult& Result) override;
17+
};
18+
19+
} // namespace reindexer_checks
20+
} // namespace tidy
21+
} // namespace clang

0 commit comments

Comments
 (0)