Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions fdb-relational-core/src/main/antlr/RelationalParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ selectStatement
;

query
: ctes? queryExpressionBody continuation?
: ctes? queryExpressionBody
;

ctes
Expand Down Expand Up @@ -369,10 +369,6 @@ tableFunctionName
: fullId
;

continuation
: WITH CONTINUATION continuationAtom
;

// done
queryExpressionBody
: queryTerm #queryTermDefault // done
Expand Down Expand Up @@ -402,7 +398,6 @@ updateStatement
SET updatedElement (',' updatedElement)*
(WHERE whereExpr)?
(RETURNING selectElements)?
(WITH CONTINUATION continuationAtom)?
queryOptions?
;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,17 +271,9 @@ public Object visitQuery(@Nonnull RelationalParser.QueryContext ctx) {
visit(ctx.ctes());
}
ctx.queryExpressionBody().accept(this);
if (ctx.continuation() != null) {
ctx.continuation().accept(this);
}
return null;
}

@Override
public Object visitContinuation(@Nonnull RelationalParser.ContinuationContext ctx) {
return ctx.continuationAtom().accept(this);
}

@Override
public RelationalExpression visitQueryOptions(@Nonnull RelationalParser.QueryOptionsContext ctx) {
for (final var opt : ctx.queryOption()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -624,12 +624,6 @@ public Identifier visitTableFunctionName(final RelationalParser.TableFunctionNam
return identifierVisitor.visitTableFunctionName(ctx);
}

@Nonnull
@Override
public Expression visitContinuation(RelationalParser.ContinuationContext ctx) {
return expressionVisitor.visitContinuation(ctx);
}

@Nonnull
@Override
public Expression visitContinuationAtom(@Nonnull RelationalParser.ContinuationAtomContext ctx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -476,12 +476,6 @@ public Identifier visitTableFunctionName(@Nonnull RelationalParser.TableFunction
return getDelegate().visitTableFunctionName(ctx);
}

@Nonnull
@Override
public Expression visitContinuation(@Nonnull RelationalParser.ContinuationContext ctx) {
return getDelegate().visitContinuation(ctx);
}

@Nonnull
@Override
public Expression visitContinuationAtom(@Nonnull RelationalParser.ContinuationAtomContext ctx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,6 @@ public Expression visitNamedFunctionArg(@Nonnull final RelationalParser.NamedFun
return expression.toNamedArgument(name);
}

@Nonnull
@Override
public Expression visitContinuation(@Nonnull RelationalParser.ContinuationContext ctx) {
return visitContinuationAtom(ctx.continuationAtom());
}

@Nonnull
@Override
public Expression visitContinuationAtom(@Nonnull RelationalParser.ContinuationAtomContext ctx) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
import com.apple.foundationdb.record.query.plan.cascades.predicates.CompatibleTypeEvolutionPredicate;
import com.apple.foundationdb.record.query.plan.cascades.typing.Type;
import com.apple.foundationdb.record.query.plan.cascades.values.FieldValue;
import com.apple.foundationdb.record.query.plan.cascades.values.LiteralValue;
import com.apple.foundationdb.record.query.plan.cascades.values.Value;
import com.apple.foundationdb.record.util.pair.NonnullPair;
import com.apple.foundationdb.relational.api.exceptions.ErrorCode;
Expand All @@ -58,7 +57,6 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import com.google.protobuf.ByteString;
import org.antlr.v4.runtime.ParserRuleContext;

import javax.annotation.Nonnull;
Expand Down Expand Up @@ -98,12 +96,6 @@ public QueryPlan.LogicalQueryPlan visitDmlStatement(@Nonnull RelationalParser.Dm
@Nonnull
@Override
public LogicalOperator visitQuery(@Nonnull RelationalParser.QueryContext ctx) {
if (ctx.continuation() != null) {
final var continuationExpression = visitContinuation(ctx.continuation());
final var continuationValue = Assert.castUnchecked(continuationExpression.getUnderlying(), LiteralValue.class);
final var continuationBytes = Assert.castUnchecked(continuationValue.getLiteralValue(), ByteString.class);
getDelegate().getPlanGenerationContext().setContinuation(continuationBytes.toByteArray());
}
if (ctx.ctes() != null) {
final var currentPlanFragment = getDelegate().pushPlanFragment();
visitCtes(ctx.ctes()).forEach(currentPlanFragment::addOperator);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,10 +266,6 @@ public interface TypedVisitor extends RelationalParserVisitor<Object> {
@Override
Identifier visitTableFunctionName(RelationalParser.TableFunctionNameContext ctx);

@Nonnull
@Override
Expression visitContinuation(RelationalParser.ContinuationContext ctx);

@Nonnull
@Override
Expression visitContinuationAtom(@Nonnull RelationalParser.ContinuationAtomContext ctx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public void continuationWithReturnRowLimit() throws SQLException, RelationalExce
} catch (SQLException e) {
throw new RuntimeException(e);
}
try (final var preparedStatement = conn.prepareStatement("select * from RESTAURANT with continuation ?param")) {
try (final var preparedStatement = conn.prepareStatement("EXECUTE CONTINUATION ?param")) {
preparedStatement.setBytes("param", continuation.serialize());
try (final var resultSet = preparedStatement.executeQuery()) {
Assertions.assertThrows(SQLException.class, resultSet::getContinuation);
Expand Down Expand Up @@ -218,7 +218,7 @@ public void continuationWithScanRowLimit() throws SQLException, RelationalExcept
// 2. Further count the rows in other execution without limits and see if total number of rows is 10
try (final var conn = DriverManager.getConnection(database.getConnectionUri().toString()).unwrap(RelationalConnection.class)) {
conn.setSchema(database.getSchemaName());
try (final var preparedStatement = conn.prepareStatement("select * from RESTAURANT with continuation ?param")) {
try (final var preparedStatement = conn.prepareStatement("EXECUTE CONTINUATION ?param")) {
preparedStatement.setBytes("param", continuation.serialize());
try (final var resultSet = preparedStatement.executeQuery()) {
Assertions.assertThrows(SQLException.class, resultSet::getContinuation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,11 @@ public Stream<? extends Arguments> provideArguments(final ExtensionContext conte
Arguments.of(57, "select * from restaurant where (((42 + 3) - 2) + 6 is not null OR ((42 + 3) - 2) + 6 > rest_no) OR (name = 'foo')", null),
Arguments.of(58, "select * from restaurant where rest_no is null", null),
Arguments.of(59, "select * from restaurant where rest_no is not null", null),
Arguments.of(60, "select * from restaurant with continuation b64'abc'", null),
Arguments.of(60, "select * from restaurant with continuation b64'abc'", "syntax error"),
Arguments.of(61, "select * from restaurant USE INDEX (record_name_idx) where rest_no > 10 ", null),
Arguments.of(62, "select * from restaurant USE INDEX (record_name_idx, reviewer_name_idx) where rest_no > 10 ", "Unknown index(es) REVIEWER_NAME_IDX"),
Arguments.of(63, "select * from restaurant USE INDEX (record_name_idx), USE INDEX (reviewer_name_idx) where rest_no > 10 ", "Unknown index(es) REVIEWER_NAME_IDX"),
Arguments.of(64, "select * from restaurant with continuation", "syntax error[[]]select * from restaurant with continuation[[]] ^^"),
Arguments.of(64, "select * from restaurant with continuation", "syntax error"),
Arguments.of(65, "select X.rest_no from (select rest_no from restaurant where 42 >= rest_no OR 42 > rest_no) X", null),
Arguments.of( 66, "select X.UNKNOWN from (select rest_no from restaurant where 42 >= rest_no OR 42 > rest_no) X", "Attempting to query non existing column 'X.UNKNOWN'"),
Arguments.of(67, "select X.rest_no from (select Y.rest_no from (select rest_no from restaurant where 42 >= rest_no OR 42 > rest_no) Y where 42 >= Y.rest_no OR 42 > Y.rest_no) X", null),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@

import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Base64;
import java.util.Collections;
import java.util.List;

Expand Down Expand Up @@ -70,8 +69,9 @@ void useScanContinuationInQueryShouldNotWork() throws Exception {
rrs.next();
continuation1 = rrs.getContinuation();
}
String continuationString = Base64.getEncoder().encodeToString(continuation1.serialize());
org.junit.jupiter.api.Assertions.assertThrows(ContextualSQLException.class, () -> s.executeQuery("SELECT * FROM RESTAURANT_REVIEWER LIMIT 1 WITH CONTINUATION B64'" + continuationString + "'"), "Continuation binding does not match query");
// Try to use scan continuation with EXECUTE CONTINUATION - should fail
String continuationString = java.util.Base64.getEncoder().encodeToString(continuation1.serialize());
org.junit.jupiter.api.Assertions.assertThrows(ContextualSQLException.class, () -> s.executeQuery("EXECUTE CONTINUATION B64'" + continuationString + "'"), "Continuation binding does not match query");
}

// get
Expand All @@ -81,8 +81,9 @@ void useScanContinuationInQueryShouldNotWork() throws Exception {
rrs.next();
continuation1 = rrs.getContinuation();
}
String continuationString = Base64.getEncoder().encodeToString(continuation1.serialize());
org.junit.jupiter.api.Assertions.assertThrows(ContextualSQLException.class, () -> s.executeQuery("SELECT * FROM RESTAURANT_REVIEWER LIMIT 1 WITH CONTINUATION B64'" + continuationString + "'"), "Continuation binding does not match query");
// Try to use get continuation with EXECUTE CONTINUATION - should fail
String continuationString = java.util.Base64.getEncoder().encodeToString(continuation1.serialize());
org.junit.jupiter.api.Assertions.assertThrows(ContextualSQLException.class, () -> s.executeQuery("EXECUTE CONTINUATION B64'" + continuationString + "'"), "Continuation binding does not match query");
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -521,26 +521,6 @@ void stripBase64Literal() throws RelationalException {
Map.of(constantId(1), ByteString.copyFrom(Hex.decodeHex("cafe"))));
}

@Test
void continuationIsStripped() throws Exception {
validate(List.of("select * from t1 with continuation b64'yv4='",
"select * from t1 with continuation x'cafe'",
"select * from t1"),
"select * from \"T1\" ");
}

@Test
void parseContinuation() throws Exception {
final var expectedContinuationStr = "FBUCFA==";
validate(List.of("select * from t1 with continuation b64'" + expectedContinuationStr + "'",
"select * from t1 with continuation b64'" + expectedContinuationStr + "'"),
PreparedParams.empty(),
"select * from \"T1\" ",
List.of(Map.of(), Map.of()),
expectedContinuationStr,
-1);
}

@Test
void parseInPredicateAllConstants() throws Exception {
// although these queries have different number of arguments in their in-predicate
Expand Down Expand Up @@ -886,27 +866,6 @@ void stripBase64LiteralWithPreparedParameters() throws RelationalException {
constantId(5), ByteString.copyFrom(Hex.decodeHex("0B0C"))));
}

@Test
void parseContinuationWithPreparedParameters() throws Exception {
final var expectedContinuationStr = "FBUCFA==";
final var expectedContinuation = Base64.getDecoder().decode(expectedContinuationStr);
validate(List.of("select * from t1 with continuation ?",
"select * from t1 with continuation ? "),
PreparedParams.ofUnnamed(Map.of(1, expectedContinuation)),
"select * from \"T1\" ",
List.of(Map.of(), Map.of()),
expectedContinuationStr,
-1);

validate(List.of("select * from t1 with continuation ?param",
"select * from t1 with continuation ?param "),
PreparedParams.ofNamed(Map.of("param", expectedContinuation)),
"select * from \"T1\" ",
List.of(Map.of(), Map.of()),
expectedContinuationStr,
-1);
}

@Test
void parseInPredicateAllConstantsWithPreparedParameters() throws Exception {
// although these queries have different number of arguments in their in-predicate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,11 @@ void hitLimitEveryRow(Options.Name optionName, Object optionValue, int expectedR
try (var conn = driver.connect(database.getConnectionUri(), Options.builder().withOption(optionName, optionValue).build())) {
conn.setSchema("TEST_SCHEMA");
while (!continuation.atEnd()) {
try (var ps = conn.prepareStatement("SELECT * FROM FOO WITH CONTINUATION ?")) {
ps.setBytes(1, continuation.serialize());
String query = continuation.atBeginning() ? "SELECT * FROM FOO" : "EXECUTE CONTINUATION ?";
try (var ps = conn.prepareStatement(query)) {
if (!continuation.atBeginning()) {
ps.setBytes(1, continuation.serialize());
}
try (final RelationalResultSet rs = ps.executeQuery()) {
for (int currentRowCount = 0; currentRowCount < expectedRowCountPerQuery; currentRowCount++) {
if (nextCorrectResult == 17L) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ void explainWithContinuationSerializedPlanTest() throws Exception {
continuation = consumeResultAndGetContinuation(ps, 2);
}

try (RelationalPreparedStatement ps = connection.prepareStatement("EXPLAIN SELECT * FROM RestaurantComplexRecord WITH CONTINUATION ?cont")) {
try (RelationalPreparedStatement ps = connection.prepareStatement("EXPLAIN EXECUTE CONTINUATION ?cont")) {
ps.setObject("cont", continuation.serialize());
try (final RelationalResultSet resultSet = ps.executeQuery()) {
final var assertResult = ResultSetAssert.assertThat(resultSet);
Expand All @@ -146,38 +146,6 @@ void explainWithContinuationSerializedPlanTest() throws Exception {
}
}

@Test
void explainWithContinuationSerializedPlanWithDifferentQueryTest() throws Exception {
try (var ddl = Ddl.builder().database(URI.create("/TEST/QT")).relationalExtension(relationalExtension).schemaTemplate(schemaTemplate).build()) {
executeInsert(ddl);
Continuation continuation;
try (final var connection = ddl.setSchemaAndGetConnection()) {
try (RelationalPreparedStatement ps = ddl.setSchemaAndGetConnection().prepareStatement("SELECT * FROM RestaurantComplexRecord")) {
ps.setMaxRows(2);
continuation = consumeResultAndGetContinuation(ps, 2);
}

try (RelationalPreparedStatement ps = connection.prepareStatement("EXPLAIN SELECT rest_no FROM RestaurantComplexRecord WITH CONTINUATION ?cont")) {
ps.setObject("cont", continuation.serialize());
try (final RelationalResultSet resultSet = ps.executeQuery()) {
final var assertResult = ResultSetAssert.assertThat(resultSet);
assertResult.hasNextRow()
.hasColumn("PLAN", "COVERING(RECORD_NAME_IDX <,> -> [NAME: KEY[0], REST_NO: KEY[2]]) | MAP (_.REST_NO AS REST_NO)")
.hasColumn("PLAN_HASH", 4759756);
final var continuationInfo = resultSet.getStruct(5);
org.junit.jupiter.api.Assertions.assertNotNull(continuationInfo);
final var assertStruct = RelationalStructAssert.assertThat(continuationInfo);
assertStruct.hasValue("EXECUTION_STATE", new byte[]{10, 5, 0, 21, 1, 21, 11, 17, -84, -51, 115, -104, -35, 66, 0, 94});
assertStruct.hasValue("VERSION", 1);
assertStruct.hasValue("PLAN_HASH_MODE", "VC0");
assertStruct.hasValue("PLAN_HASH", -1635569052);
assertStruct.hasValue("SERIALIZED_PLAN_COMPLEXITY", 1);
}
}
}
}
}

@Test
void explainExecuteStatementTest() throws Exception {
try (var ddl = Ddl.builder().database(URI.create("/TEST/QT")).relationalExtension(relationalExtension).schemaTemplate(schemaTemplate).build()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import org.junit.jupiter.api.extension.RegisterExtension;

import java.net.URI;
import java.util.Base64;

import static com.apple.foundationdb.relational.recordlayer.query.QueryTestUtils.insertT1Record;
import static com.apple.foundationdb.relational.recordlayer.query.QueryTestUtils.insertT1RecordColAIsNull;
Expand Down Expand Up @@ -149,13 +148,15 @@
.hasNoNextRow();
continuation = resultSet.getContinuation();
}
String postfix = " WITH CONTINUATION B64'" + Base64.getEncoder().encodeToString(continuation.serialize()) + "'";
Assertions.assertTrue(statement.execute(query + postfix), "Did not return a result set from a select statement!");
try (final RelationalResultSet resultSet = statement.getResultSet()) {
ResultSetAssert.assertThat(resultSet).hasNextRow()
.isRowExactly(9.5)
.hasNoNextRow();
continuation = resultSet.getContinuation();
try (var ps = conn.prepareStatement("EXECUTE CONTINUATION ?continuation")) {
ps.setBytes("continuation", continuation.serialize());
Assertions.assertTrue(ps.execute(), "Did not return a result set from a select statement!");
try (final RelationalResultSet resultSet = ps.getResultSet()) {
ResultSetAssert.assertThat(resultSet).hasNextRow()
.isRowExactly(9.5)
.hasNoNextRow();
continuation = resultSet.getContinuation();

Check warning on line 158 in fdb-relational-core/src/test/java/com/apple/foundationdb/relational/recordlayer/query/GroupByQueryTests.java

View check run for this annotation

fdb.teamscale.io / Teamscale | Findings

fdb-relational-core/src/test/java/com/apple/foundationdb/relational/recordlayer/query/GroupByQueryTests.java#L155-L158

[New] This method is slightly nested [0]. Consider extracting helper methods or reducing the nesting by using early breaks or returns. [0] https://fdb.teamscale.io/findings/details/foundationdb-fdb-record-layer?t=FORK_MR%2F3765%2Farnaud-lacurie%2Fremove_with_continuation%3AHEAD&id=68F153A8A8CF673C582226D33B53CF26
}
}
}
}
Expand Down
Loading
Loading