Skip to content

Commit 9ae59ef

Browse files
authored
Merge pull request #797 from FgForrest/master-hotfix
Master hotfix
2 parents 40a3448 + 74c6b1f commit 9ae59ef

File tree

4 files changed

+35
-20
lines changed

4 files changed

+35
-20
lines changed

evita_external_api/evita_external_api_grpc/server/src/main/java/io/evitadb/externalApi/grpc/services/EvitaSessionService.java

+8-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import io.evitadb.api.EvitaSessionContract;
3131
import io.evitadb.api.exception.SessionNotFoundException;
3232
import io.evitadb.api.file.FileForFetch;
33+
import io.evitadb.api.query.Constraint;
3334
import io.evitadb.api.query.HeadConstraint;
3435
import io.evitadb.api.query.Query;
3536
import io.evitadb.api.query.head.Head;
@@ -1519,23 +1520,26 @@ public void getTransactionId(Empty request, StreamObserver<GrpcTransactionRespon
15191520
* the first time the apply method is called. Subsequent calls with the same instance will return
15201521
* the original HeadConstraint without modification.
15211522
*/
1523+
@SuppressWarnings("rawtypes")
15221524
@RequiredArgsConstructor
1523-
private static class LabelAppender implements UnaryOperator<HeadConstraint> {
1525+
private static class LabelAppender implements UnaryOperator<Constraint> {
15241526
private final Label[] labels;
15251527
private boolean appended = false;
15261528

15271529
@Override
1528-
public HeadConstraint apply(HeadConstraint constraint) {
1530+
public Constraint apply(Constraint constraint) {
15291531
if (this.appended) {
15301532
return constraint;
1531-
} else {
1533+
} else if (constraint instanceof HeadConstraint headConstraint) {
15321534
this.appended = true;
15331535
final List<HeadConstraint> constraints = new ArrayList<>(labels.length + 1);
1534-
constraints.add(constraint);
1536+
constraints.add(headConstraint);
15351537
Arrays.stream(this.labels).filter(Objects::nonNull).forEach(constraints::add);
15361538

15371539
//noinspection DataFlowIssue
15381540
return head(constraints.toArray(HeadConstraint[]::new));
1541+
} else {
1542+
throw new UnsupportedOperationException("Cannot append labels to a non-head constraint.");
15391543
}
15401544
}
15411545

evita_query/src/main/java/io/evitadb/api/query/Query.java

+17-10
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* | __/\ V /| | || (_| | |_| | |_) |
77
* \___| \_/ |_|\__\__,_|____/|____/
88
*
9-
* Copyright (c) 2023-2024
9+
* Copyright (c) 2023-2025
1010
*
1111
* Licensed under the Business Source License, Version 1.1 (the "License");
1212
* you may not use this file except in compliance with the License.
@@ -197,12 +197,13 @@ public Query normalizeQuery() {
197197
* @deprecated use {@link #normalizeQuery(UnaryOperator, UnaryOperator, UnaryOperator, UnaryOperator)}, this method
198198
* is here only to maintain backward compatibility
199199
*/
200+
@SuppressWarnings("rawtypes")
200201
@Deprecated
201202
@Nonnull
202203
public Query normalizeQuery(
203-
@Nullable UnaryOperator<FilterConstraint> filterConstraintTranslator,
204-
@Nullable UnaryOperator<OrderConstraint> orderConstraintTranslator,
205-
@Nullable UnaryOperator<RequireConstraint> requireConstraintTranslator
204+
@Nullable UnaryOperator<Constraint> filterConstraintTranslator,
205+
@Nullable UnaryOperator<Constraint> orderConstraintTranslator,
206+
@Nullable UnaryOperator<Constraint> requireConstraintTranslator
206207
) {
207208
return normalizeQuery(
208209
null,
@@ -218,19 +219,22 @@ public Query normalizeQuery(
218219
* from the query, all query containers that are {@link ConstraintContainer#isNecessary()} are removed
219220
* and their contents are propagated to their parent.
220221
*/
222+
/* we need to use raw types because constraint of type A might contain constraints of type B */
223+
/* i.e. require constraint might contain filtering constraints etc. */
224+
@SuppressWarnings("rawtypes")
221225
@Nonnull
222226
public Query normalizeQuery(
223-
@Nullable UnaryOperator<HeadConstraint> headConstraintTranslator,
224-
@Nullable UnaryOperator<FilterConstraint> filterConstraintTranslator,
225-
@Nullable UnaryOperator<OrderConstraint> orderConstraintTranslator,
226-
@Nullable UnaryOperator<RequireConstraint> requireConstraintTranslator
227+
@Nullable UnaryOperator<Constraint> headConstraintTranslator,
228+
@Nullable UnaryOperator<Constraint> filterConstraintTranslator,
229+
@Nullable UnaryOperator<Constraint> orderConstraintTranslator,
230+
@Nullable UnaryOperator<Constraint> requireConstraintTranslator
227231
) {
228232
// avoid costly normalization on already normalized query
229233
if (normalized) {
230234
return this;
231235
}
232236

233-
final HeadConstraint normalizedHead = this.head == null ? null : purify(this.head, headConstraintTranslator);
237+
final HeadConstraint normalizedHead = this.head == null ? null : (HeadConstraint) purify(this.head, headConstraintTranslator);
234238
final FilterBy normalizedFilter = this.filterBy == null ? null : (FilterBy) purify(this.filterBy, filterConstraintTranslator);
235239
final OrderBy normalizedOrder = this.orderBy == null ? null : (OrderBy) purify(this.orderBy, orderConstraintTranslator);
236240
final Require normalizedRequire = this.require == null ? null : (Require) purify(this.require, requireConstraintTranslator);
@@ -263,8 +267,11 @@ public StringWithParameters toStringWithParameterExtraction() {
263267
return PrettyPrintingVisitor.toStringWithParameterExtraction(this);
264268
}
265269

270+
/* we need to use raw types because constraint of type A might contain constraints of type B */
271+
/* i.e. require constraint might contain filtering constraints etc. */
266272
@Nullable
267-
private static <T extends Constraint<T>> T purify(@Nonnull T constraint, @Nullable UnaryOperator<T> translator) {
273+
@SuppressWarnings({"unchecked", "rawtypes"})
274+
private static Constraint purify(@Nonnull Constraint constraint, @Nullable UnaryOperator<Constraint> translator) {
268275
return QueryPurifierVisitor.purify(constraint, translator);
269276
}
270277

evita_query/src/main/java/io/evitadb/api/query/parser/visitor/EvitaQLQueryVisitor.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* | __/\ V /| | || (_| | |_| | |_) |
77
* \___| \_/ |_|\__\__,_|____/|____/
88
*
9-
* Copyright (c) 2023
9+
* Copyright (c) 2023-2025
1010
*
1111
* Licensed under the Business Source License, Version 1.1 (the "License");
1212
* you may not use this file except in compliance with the License.
@@ -65,13 +65,13 @@ public Query visitQuery(@Nonnull EvitaQLParser.QueryContext ctx) {
6565
.map(con -> con.accept(constraintVisitor))
6666
.collect(Collectors.toList());
6767

68-
final Collection collectionConstraint = findCollectionConstraint(ctx, constraints);
68+
final HeadConstraint headConstraint = findHeadConstraint(ctx, constraints);
6969
final FilterBy filterByConstraint = findFilterByConstraint(ctx, constraints);
7070
final OrderBy orderByConstraint = findOrderByConstraint(ctx, constraints);
7171
final Require requireConstraint = findRequireConstraint(ctx, constraints);
7272

7373
return Query.query(
74-
collectionConstraint,
74+
headConstraint,
7575
filterByConstraint,
7676
orderByConstraint,
7777
requireConstraint
@@ -88,7 +88,7 @@ public Query visitQuery(@Nonnull EvitaQLParser.QueryContext ctx) {
8888
* @throws EvitaSyntaxException if no appropriated constraint found
8989
*/
9090
@Nullable
91-
protected Collection findCollectionConstraint(@Nonnull ParserRuleContext ctx, @Nonnull List<Constraint<?>> topLevelConstraints) {
91+
protected HeadConstraint findHeadConstraint(@Nonnull ParserRuleContext ctx, @Nonnull List<Constraint<?>> topLevelConstraints) {
9292
final List<Constraint<?>> headConstraints = topLevelConstraints.stream()
9393
.filter(HeadConstraint.class::isInstance)
9494
.toList();
@@ -99,10 +99,10 @@ protected Collection findCollectionConstraint(@Nonnull ParserRuleContext ctx, @N
9999
if ((headConstraints.size() > 1) || !(headConstraints.get(0) instanceof Collection)) {
100100
throw new EvitaSyntaxException(
101101
ctx,
102-
"Query can have only one top level head constraint -> `collection`."
102+
"Query can have only one top level head constraint."
103103
);
104104
}
105-
return (Collection) headConstraints.get(0);
105+
return (HeadConstraint) headConstraints.get(0);
106106
}
107107

108108
/**

evita_store/evita_store_server/src/main/java/io/evitadb/store/traffic/DiskRingBuffer.java

+4
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,10 @@ private void writeDataToFileChannel(@Nonnull ByteBuffer memoryByteBuffer, int to
666666
* used to adjust the position of the ring buffer tail.
667667
*/
668668
private void updateSessionLocations(int totalBytesToWrite) throws IOException {
669+
if (totalBytesToWrite == 0) {
670+
// no bytes to write, nothing to update
671+
return;
672+
}
669673
final long newTail = this.ringBufferTail + totalBytesToWrite;
670674
SessionLocation head = this.sessionLocations.peekFirst();
671675
while (head != null) {

0 commit comments

Comments
 (0)