Skip to content

Commit 3a87830

Browse files
committed
Merge remote-tracking branch 'upstream/main' into uuid_support
2 parents 825f4c5 + 05942da commit 3a87830

File tree

130 files changed

+6277
-696
lines changed

Some content is hidden

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

130 files changed

+6277
-696
lines changed

.github/workflows/nightly.yml

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ name: Nightly
33
on:
44
schedule:
55
- cron: "0 7 * * 1-5"
6+
workflow_dispatch:
67

78
jobs:
89
gradle:

build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ subprojects {
279279
sourceSets["test"].resources.srcDirs.stream().flatMap( resourceDir ->
280280
fileTree(dir: resourceDir).matching {
281281
include '**/*.yamsql'
282+
exclude '/initial-version/*'
282283
exclude '/supported-version/*'
283284
}.stream()
284285
).forEach { yamsql ->

docs/sphinx/source/ReleaseNotes.md

+64
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,70 @@ Builds and releases have been moved to a new CI system. This includes the resump
1515

1616
Users performing online updates are encouraged to update from [4.0.559.4](#405594). The continuations of some queries have changed in ways that may break if continued on other 4.0 builds. See: [Issue #3093](https://github.com/FoundationDB/fdb-record-layer/issues/3093), [PR #3092](https://github.com/FoundationDB/fdb-record-layer/pull/3092) fixing the issue, and [PR #3108](https://github.com/FoundationDB/fdb-record-layer/issues/3108) preparing 4.0.559.4 to accept newer continuations.
1717

18+
### 4.1.9.0
19+
20+
<h4> New Features </h4>
21+
22+
* Introduce a new `Option` to set `asyncToSync` timeout. - [PR #3205](https://github.com/FoundationDB/fdb-record-layer/pull/3205)
23+
* `RecordQueryPlanComplexityException` now includes only a shortened plan string as a log message key - [PR #3168](https://github.com/FoundationDB/fdb-record-layer/pull/3168)
24+
<h4> Bug Fixes </h4>
25+
26+
* Fix deserialization of continuations for queries that contain LIKE - [PR #3207](https://github.com/FoundationDB/fdb-record-layer/pull/3207)
27+
* `EXISTS` queries now honor continuation from previous runs to avoid infinite loops - [PR #3221](https://github.com/FoundationDB/fdb-record-layer/pull/3221)
28+
* `RecordQueryExplodePlan` plan adheres to `skip` and `limit` requirements - [PR #3230](https://github.com/FoundationDB/fdb-record-layer/pull/3230)
29+
* Prevent caching `INSERT` statements - [PR #3212](https://github.com/FoundationDB/fdb-record-layer/pull/3212)
30+
* Fix unstable hash for NULL literal - [PR #3222](https://github.com/FoundationDB/fdb-record-layer/pull/3222)
31+
* Fix continuation deserialization errors by deserializing streaming aggregate plans in the correct order - [PR #3215](https://github.com/FoundationDB/fdb-record-layer/pull/3215)
32+
* Serialize missing field `createDefaultIfEmpty` into streaming aggregate plan continuations - [PR #3211](https://github.com/FoundationDB/fdb-record-layer/pull/3211)
33+
* Fix instability in the query planner - [PR #3185](https://github.com/FoundationDB/fdb-record-layer/pull/3185)
34+
* Adjust serialization of `VersionValue` to make continuations compatible with versions older than 4.0.564.0 - [PR #3179](https://github.com/FoundationDB/fdb-record-layer/pull/3179)
35+
* Fixes off-by-one error that could result in streaming aggregate plans returning incorrect results when resumed from a continuation - [PR #3112](https://github.com/FoundationDB/fdb-record-layer/pull/3112)
36+
<h4> Dependency Updates </h4>
37+
38+
* Upgrade protobuf plugin from 0.8.19 to 0.9.4 - [PR #3101](https://github.com/FoundationDB/fdb-record-layer/pull/3101)
39+
40+
<details>
41+
<summary>
42+
43+
<h4> Build/Test/Documentation Improvements (click to expand) </h4>
44+
45+
</summary>
46+
47+
* Enable force continuations mode on all `YamlIntegrationTest`s - [PR #3228](https://github.com/FoundationDB/fdb-record-layer/pull/3228)
48+
* Write PMD output to consoleOutput during build - [PR #3223](https://github.com/FoundationDB/fdb-record-layer/pull/3223)
49+
* Create a yaml test config that runs two servers with the same version - [PR #3217](https://github.com/FoundationDB/fdb-record-layer/pull/3217)
50+
* Test concurrent indexing sessions without sync lock - [PR #3200](https://github.com/FoundationDB/fdb-record-layer/pull/3200)
51+
* Yaml tests: Only allow forced continuations on SELECT queries - [PR #3201](https://github.com/FoundationDB/fdb-record-layer/pull/3201)
52+
* Adds commands to the YAML framework to assert on changing query behavior - [PR #3188](https://github.com/FoundationDB/fdb-record-layer/pull/3188)
53+
* Run nightly variations of yaml-tests in nightly workflow - [PR #3202](https://github.com/FoundationDB/fdb-record-layer/pull/3202)
54+
* Run the PR label check whenever the HEAD commit changes to ensure it is applied to the final commit of each PR - [PR #3195](https://github.com/FoundationDB/fdb-record-layer/pull/3195)
55+
* Change netty logs to INFO when running tests - [PR #3196](https://github.com/FoundationDB/fdb-record-layer/pull/3196)
56+
* Make prepared.yamsql run against 4.0.559.6 as the earliest - [PR #3187](https://github.com/FoundationDB/fdb-record-layer/pull/3187)
57+
* Add protection against test running into an infinite loop - [PR #3186](https://github.com/FoundationDB/fdb-record-layer/pull/3186)
58+
* Add version information to yaml test exceptions - [PR #3189](https://github.com/FoundationDB/fdb-record-layer/pull/3189)
59+
* Generate release notes automatically from pull requests - [PR #3174](https://github.com/FoundationDB/fdb-record-layer/pull/3174)
60+
* Fix link to documentation in README - [PR #3184](https://github.com/FoundationDB/fdb-record-layer/pull/3184)
61+
* Yaml tests: Add protection against infinite continuation loops - [PR #3182](https://github.com/FoundationDB/fdb-record-layer/pull/3182)
62+
* Enable a few tests where the force continuation option does not fail anymore - [PR #3176](https://github.com/FoundationDB/fdb-record-layer/pull/3176)
63+
* Improve multi-server connection testing - [PR #3170](https://github.com/FoundationDB/fdb-record-layer/pull/3170)
64+
* Enforce all PRs are labeled for Release Note generation - [PR #3181](https://github.com/FoundationDB/fdb-record-layer/pull/3181)
65+
* Cache FDB packages during the build and avoid checking them in - [PR #3164](https://github.com/FoundationDB/fdb-record-layer/pull/3164)
66+
* Switch documentation site to sphinx-based solution - [PR #3078](https://github.com/FoundationDB/fdb-record-layer/pull/3078)
67+
68+
</details>
69+
70+
71+
**[Full Changelog (4.1.8.0...4.1.9.0)](https://github.com/FoundationDB/fdb-record-layer/compare/4.1.8.0...4.1.9.0)**
72+
73+
#### Mixed Mode Test Results
74+
75+
Mixed mode testing run against the following previous versions:
76+
77+
`4.0.559.1`, ❌`4.0.559.2`, ❌`4.0.559.3`, ✅`4.0.559.4`, ✅`4.0.559.6`, ❌`4.0.561.0`, ❌`4.0.562.0`, ❌`4.0.564.0`, ❌`4.0.565.0`, ❌`4.0.566.0`, ❌`4.0.567.0`, ❌`4.0.568.0`, ❌`4.0.569.0`, ❌`4.0.570.0`, ❌`4.0.571.0`, ❌`4.0.572.0`, ❌`4.0.573.0`, ❌`4.0.574.0`, ❌`4.0.575.0`, ❌`4.1.4.0`, ✅`4.1.5.0`, ✅`4.1.6.0`, ✅`4.1.8.0`
78+
79+
[See full test run](https://github.com/FoundationDB/fdb-record-layer/actions/runs/13729472581)
80+
81+
1882
### 4.1.8.0
1983

2084
<h4> New Features </h4>

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/RecordCursor.java

+37-3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
import java.util.function.Consumer;
6060
import java.util.function.Function;
6161
import java.util.function.Predicate;
62+
import java.util.function.Supplier;
6263
import java.util.stream.Stream;
6364
import java.util.stream.StreamSupport;
6465

@@ -884,24 +885,57 @@ static <T> RecordCursor<T> fromFuture(@Nonnull CompletableFuture<T> future) {
884885

885886
@Nonnull
886887
static <T> RecordCursor<T> fromFuture(@Nonnull Executor executor, @Nonnull CompletableFuture<T> future) {
887-
return new FutureCursor<>(executor, future);
888+
return fromFuture(executor, future, null);
888889
}
889890

890891
/**
891892
* Get a new cursor that has the contents of the given future as its only record.
892893
* If the continuation is nonnull, return an empty cursor since a {@link FutureCursor} returns only a single record.
894+
* Note that in general, this can lead to futures being started that are not properly waited on,
895+
* so it is generally advised that the user use {@link #fromFuture(Executor, Supplier, byte[])} instead
896+
* of this one. See also the warning on {@link #fromFuture(Executor, Supplier, byte[])} for a word
897+
* about if the work powering the underlying future has more complicated state that should be
898+
* included in the cursor's continuation.
899+
*
893900
* @param executor an executor for executing the future
894901
* @param future a future that completes to the only element of the cursor
895902
* @param continuation a continuation from a future cursor to determine whether the cursor has a single element or no elements
896903
* @param <T> the result type of the future
897904
* @return a new cursor producing the contents of {@code future} if the continuation is nonnull and an empty cursor otherwise
905+
* @see #fromFuture(Executor, Supplier, byte[])
898906
*/
899907
@Nonnull
900908
static <T> RecordCursor<T> fromFuture(@Nonnull Executor executor, @Nonnull CompletableFuture<T> future, @Nullable byte[] continuation) {
909+
return fromFuture(executor, () -> future, continuation);
910+
}
911+
912+
/**
913+
* Get a new cursor that has the contents of the lazily-evaluated future as its only record.
914+
* If the continuation is nonnull, return an empty cursor since a {@link FutureCursor} returns only a single record.
915+
* In that case, the {@code futureSupplier} will not be evaluated to avoid queuing up asynchronous work
916+
* that is not guaranteed to have anyone wait on. For that reason, this should generally be preferred
917+
* to {@link #fromFuture(Executor, CompletableFuture, byte[])}.
918+
*
919+
* <p>
920+
* <em>Warning:</em> Using a {@link FutureCursor} here may lead to incorrect results if the underlying
921+
* future is backed by something that has some kind of state that should be included in the continuation.
922+
* For example, if the future is backed by a cursor that may stop for an out-of-band {@link NoNextReason},
923+
* it may be desirable to include the progress included in the underlying cursor in the final continuation.
924+
* That is not done by this class, so something more bespoke may be required.
925+
* </p>
926+
*
927+
* @param executor an executor for executing the future
928+
* @param futureSupplier a supplier of a future that completes to the only element of the cursor
929+
* @param continuation a continuation from a future cursor to determine whether the cursor has a single element or no elements
930+
* @param <T> the result type of the future
931+
* @return a new cursor producing the contents of {@code future} if the continuation is nonnull and an empty cursor otherwise
932+
*/
933+
@Nonnull
934+
static <T> RecordCursor<T> fromFuture(@Nonnull Executor executor, @Nonnull Supplier<CompletableFuture<T>> futureSupplier, @Nullable byte[] continuation) {
901935
if (continuation == null) {
902-
return new FutureCursor<>(executor, future);
936+
return new FutureCursor<>(executor, futureSupplier.get());
903937
} else {
904-
return RecordCursor.empty();
938+
return RecordCursor.empty(executor);
905939
}
906940
}
907941

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/cursors/FutureCursor.java

+9
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ public class FutureCursor<T> implements RecordCursor<T> {
5050
@Nonnull
5151
private static final RecordCursorContinuation notDoneContinuation = ByteArrayContinuation.fromNullable(new byte[] {0});
5252

53+
/**
54+
* Internal constructor. Users should generally call
55+
* {@link RecordCursor#fromFuture(Executor, java.util.function.Supplier, byte[])}
56+
* in order to ensure that continuations from this cursor are properly handled.
57+
*
58+
* @param executor the executor to associate with this cursor
59+
* @param future a future that when completed will provide the single element returned by this cursor
60+
*/
61+
@API(API.Status.INTERNAL)
5362
public FutureCursor(@Nonnull Executor executor, @Nonnull CompletableFuture<T> future) {
5463
this.executor = executor;
5564
this.future = future;

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/typing/Type.java

+20
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,16 @@ public Null fromProto(@Nonnull final PlanSerializationContext serializationConte
11381138
return Null.fromProto(serializationContext, nullTypeProto);
11391139
}
11401140
}
1141+
1142+
@Override
1143+
public int hashCode() {
1144+
return getTypeCode().name().hashCode();
1145+
}
1146+
1147+
@Override
1148+
public boolean equals(final Object other) {
1149+
return other instanceof Null;
1150+
}
11411151
}
11421152

11431153
/**
@@ -1227,6 +1237,16 @@ public None fromProto(@Nonnull final PlanSerializationContext serializationConte
12271237
return None.fromProto(serializationContext, noneTypeProto);
12281238
}
12291239
}
1240+
1241+
@Override
1242+
public int hashCode() {
1243+
return getTypeCode().name().hashCode();
1244+
}
1245+
1246+
@Override
1247+
public boolean equals(final Object other) {
1248+
return other instanceof None;
1249+
}
12301250
}
12311251

12321252
/**

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/values/PatternForLikeValue.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ public PValue toValueProto(@Nonnull final PlanSerializationContext serialization
188188
public static PatternForLikeValue fromProto(@Nonnull final PlanSerializationContext serializationContext,
189189
@Nonnull final PPatternForLikeValue patternForLikeValueProto) {
190190
return new PatternForLikeValue(Value.fromValueProto(serializationContext, Objects.requireNonNull(patternForLikeValueProto.getPatternChild())),
191-
Value.fromValueProto(serializationContext, Objects.requireNonNull(patternForLikeValueProto.getPatternChild())));
191+
Value.fromValueProto(serializationContext, Objects.requireNonNull(patternForLikeValueProto.getEscapeChild())));
192192
}
193193

194194
@Nonnull

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/plans/RecordQueryExplodePlan.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ public <M extends Message> RecordCursor<QueryResult> executePlan(@Nonnull final
8888
@Nonnull final ExecuteProperties executeProperties) {
8989
final var result = collectionValue.eval(store, context);
9090
return RecordCursor.fromList(result == null ? ImmutableList.of() : (List<?>)result, continuation)
91-
.map(QueryResult::ofComputed);
91+
.map(QueryResult::ofComputed)
92+
.skipThenLimit(executeProperties.getSkip(), executeProperties.getReturnedRowLimit());
9293
}
9394

9495
@Nonnull

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/plans/RecordQueryFirstOrDefaultPlan.java

+12-6
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,10 @@
2828
import com.apple.foundationdb.record.PlanHashable;
2929
import com.apple.foundationdb.record.PlanSerializationContext;
3030
import com.apple.foundationdb.record.RecordCursor;
31-
import com.apple.foundationdb.record.cursors.FutureCursor;
3231
import com.apple.foundationdb.record.planprotos.PRecordQueryFirstOrDefaultPlan;
3332
import com.apple.foundationdb.record.planprotos.PRecordQueryPlan;
3433
import com.apple.foundationdb.record.provider.common.StoreTimer;
3534
import com.apple.foundationdb.record.provider.foundationdb.FDBRecordStoreBase;
36-
import com.apple.foundationdb.record.query.plan.explain.ExplainPlanVisitor;
3735
import com.apple.foundationdb.record.query.plan.cascades.AliasMap;
3836
import com.apple.foundationdb.record.query.plan.cascades.CorrelationIdentifier;
3937
import com.apple.foundationdb.record.query.plan.cascades.Memoizer;
@@ -47,6 +45,7 @@
4745
import com.apple.foundationdb.record.query.plan.cascades.values.DerivedValue;
4846
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
4947
import com.apple.foundationdb.record.query.plan.cascades.values.translation.TranslationMap;
48+
import com.apple.foundationdb.record.query.plan.explain.ExplainPlanVisitor;
5049
import com.google.auto.service.AutoService;
5150
import com.google.common.base.Verify;
5251
import com.google.common.collect.ImmutableList;
@@ -96,10 +95,17 @@ public <M extends Message> RecordCursor<QueryResult> executePlan(@Nonnull final
9695
@Nonnull final EvaluationContext context,
9796
@Nullable final byte[] continuation,
9897
@Nonnull final ExecuteProperties executeProperties) {
99-
return new FutureCursor<>(store.getExecutor(),
100-
getChild().executePlan(store, context, continuation, executeProperties).first()
101-
.thenApply(resultOptional ->
102-
resultOptional.orElseGet(() -> QueryResult.ofComputed(onEmptyResultValue.eval(store, context)))));
98+
// Note that a null child continuation is always handed to the child cursor below.
99+
// This is because the returned FutureCursor only ever returns a single value, and so if
100+
// if that lambda is called, it indicates that the original continuation is null, and we
101+
// are starting the plan from the beginning. That this doesn't handle the inner cursor
102+
// halting with an out-of-band no-next-reasons, which currently is treated the same way
103+
// as the inner cursor being empty.
104+
// See: https://github.com/FoundationDB/fdb-record-layer/issues/3220
105+
return RecordCursor.fromFuture(store.getExecutor(),
106+
() -> getChild().executePlan(store, context, null, executeProperties).first()
107+
.thenApply(resultOptional -> resultOptional.orElseGet(() -> QueryResult.ofComputed(onEmptyResultValue.eval(store, context)))),
108+
continuation);
103109
}
104110

105111
@Override

0 commit comments

Comments
 (0)