Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
095a182
Prepare statements to RecordLayerSchemaTemplate and RecordMetaData
sergei-pustovykh May 12, 2026
385da83
Prepare statements parse as DDL
sergei-pustovykh May 13, 2026
8f3a5db
Prepare statements at first record store open
sergei-pustovykh May 14, 2026
b2e5410
fix test validateMetaDataCoverage
sergei-pustovykh May 14, 2026
0d301b6
fix style
sergei-pustovykh May 14, 2026
93f8706
schema-template-prepare yamsql test
sergei-pustovykh May 15, 2026
4d2f9ca
logger fix
sergei-pustovykh May 15, 2026
a4d0ad4
test jdbc prepare
sergei-pustovykh May 15, 2026
a7778c3
Scheme-template-prepare test based on build version
sergei-pustovykh May 15, 2026
dee2c66
revert-standard-tests.tamsql
sergei-pustovykh May 15, 2026
c1278e0
team-scale test gap cover for NoOpSchemaTemplate.getPrepareStatements()
sergei-pustovykh May 15, 2026
18d346f
supported_version for whole file in schema-template-prepare.yamsql
sergei-pustovykh May 15, 2026
c0e1b7e
Generate plans for all prepare statements form all schema templates i…
sergei-pustovykh Jun 10, 2026
47f5049
Add logging to OfflinePrepareStatementsProcessor
sergei-pustovykh Jun 10, 2026
e40c8c3
unused import
sergei-pustovykh Jun 10, 2026
2f0c45c
OfflineMetricCollector reports to MetricRegistry
sergei-pustovykh Jun 11, 2026
f6ee755
Rename Prepare Statement to Stored Query
sergei-pustovykh Jun 15, 2026
81781bf
CREATE QUERY syntax
sergei-pustovykh Jun 15, 2026
939c65c
Logger guarded
sergei-pustovykh Jun 15, 2026
09f2577
empty catch fix
sergei-pustovykh Jun 15, 2026
4b4d7d2
Tests fixes
sergei-pustovykh Jun 15, 2026
0336a1d
Merge branch 'main' into prepare-statements-metadata
sergei-pustovykh Jun 15, 2026
ab7dde2
Test select on unknown column
sergei-pustovykh Jun 16, 2026
60836a9
Merge branch 'main' into prepare-statements-metadata
sergei-pustovykh Jun 16, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@
private final Map<String, UserDefinedFunction> userDefinedFunctionMap;
@Nonnull
private final Map<String, View> viewMap;
@Nonnull

Check notice on line 89 in fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/RecordMetaData.java

View workflow job for this annotation

GitHub Actions / coverage

File coverage: 94.4% (268/284 lines) | Changed lines: 100.0% (4/4 lines)
private final Map<String, String> storedQueries;
@Nonnull
private final Map<String, Index> indexes;
@Nonnull
private final Map<String, Index> universalIndexes;
Expand Down Expand Up @@ -118,6 +120,7 @@
Collections.unmodifiableList(orig.formerIndexes),
Collections.unmodifiableMap(orig.userDefinedFunctionMap),
Collections.unmodifiableMap(orig.viewMap),
Collections.unmodifiableMap(orig.storedQueries),
orig.splitLongRecords,
orig.storeRecordVersions,
orig.version,
Expand All @@ -139,6 +142,7 @@
@Nonnull List<FormerIndex> formerIndexes,
@Nonnull Map<String, UserDefinedFunction> userDefinedFunctionMap,
@Nonnull Map<String, View> viewMap,
@Nonnull Map<String, String> storedQueries,
boolean splitLongRecords,
boolean storeRecordVersions,
int version,
Expand All @@ -157,6 +161,7 @@
this.formerIndexes = formerIndexes;
this.userDefinedFunctionMap = userDefinedFunctionMap;
this.viewMap = viewMap;
this.storedQueries = storedQueries;

Check warning on line 164 in fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/RecordMetaData.java

View check run for this annotation

fdb.teamscale.io / Teamscale | Findings

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/RecordMetaData.java#L164

Store a copy of `storedQueries` https://fdb.teamscale.io/findings/details/foundationdb-fdb-record-layer?id=E42EE690B13412A46242A8CE45EA6F48&t=FORK_MR%2F4157%2Fsergei-pustovykh%2Fprepare-statements-metadata%3AHEAD
this.splitLongRecords = splitLongRecords;
this.storeRecordVersions = storeRecordVersions;
this.version = version;
Expand Down Expand Up @@ -704,6 +709,7 @@

builder.addAllUserDefinedFunctions(userDefinedFunctionMap.values().stream().map(UserDefinedFunction::toProto).collect(Collectors.toList()));
builder.addAllViews(viewMap.values().stream().map(View::toProto).collect(Collectors.toList()));
builder.putAllStoredQueries(storedQueries);
builder.setSplitLongRecords(splitLongRecords);
builder.setStoreRecordVersions(storeRecordVersions);
builder.setVersion(version);
Expand All @@ -728,6 +734,11 @@
return viewMap;
}

@Nonnull
public Map<String, String> getStoredQueries() {
return storedQueries;

Check warning on line 739 in fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/RecordMetaData.java

View check run for this annotation

fdb.teamscale.io / Teamscale | Findings

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/RecordMetaData.java#L739

Return a copy of `storedQueries` https://fdb.teamscale.io/findings/details/foundationdb-fdb-record-layer?id=27357B0C7D76641A51A15B2AB41199BA&t=FORK_MR%2F4157%2Fsergei-pustovykh%2Fprepare-statements-metadata%3AHEAD
}

@Nonnull
public Type.Record getPlannerType(@Nonnull String recordTypeName) {
final RecordType recordType = getRecordType(recordTypeName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@
private final Map<String, UserDefinedFunction> userDefinedFunctionMap;
@Nonnull
private final Map<String, View> viewMap;
@Nonnull

Check notice on line 118 in fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/RecordMetaDataBuilder.java

View workflow job for this annotation

GitHub Actions / coverage

File coverage: 88.3% (549/622 lines) | Changed lines: 80.0% (4/5 lines)
private final Map<String, String> storedQueries;
@Nonnull
private final Map<String, Index> indexes;
@Nonnull
private final Map<String, Index> universalIndexes;
Expand Down Expand Up @@ -152,6 +154,7 @@
syntheticRecordTypes = new HashMap<>();
userDefinedFunctionMap = new HashMap<>();
viewMap = new HashMap<>();
storedQueries = new HashMap<>();
}

private void processSchemaOptions(boolean processExtensionOptions) {
Expand Down Expand Up @@ -238,6 +241,7 @@
final View view = View.fromProto(viewProto);
viewMap.put(view.getName(), view);
}
storedQueries.putAll(metaDataProto.getStoredQueriesMap());
if (metaDataProto.hasSplitLongRecords()) {
splitLongRecords = metaDataProto.getSplitLongRecords();
}
Expand Down Expand Up @@ -1215,6 +1219,15 @@
viewMap.put(view.getName(), view);
}

@Nonnull
public Map<String, String> getStoredQueries() {
return storedQueries;

Check warning on line 1224 in fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/RecordMetaDataBuilder.java

View check run for this annotation

fdb.teamscale.io / Teamscale | Findings

fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/RecordMetaDataBuilder.java#L1224

Return a copy of `storedQueries` https://fdb.teamscale.io/findings/details/foundationdb-fdb-record-layer?id=0CD80210BACBCE63E235D2A7CAAA6B66&t=FORK_MR%2F4157%2Fsergei-pustovykh%2Fprepare-statements-metadata%3AHEAD
}

public void addStoredQuery(@Nonnull String name, @Nonnull String storedQuery) {
storedQueries.put(name, storedQuery);
}

public boolean isSplitLongRecords() {
return splitLongRecords;
}
Expand Down Expand Up @@ -1456,7 +1469,7 @@
Map<Object, SyntheticRecordType<?>> recordTypeKeyToSyntheticRecordTypeMap = Maps.newHashMapWithExpectedSize(syntheticRecordTypes.size());
RecordMetaData metaData = new RecordMetaData(recordsDescriptor, getUnionDescriptor(), unionFields,
builtRecordTypes, builtSyntheticRecordTypes, recordTypeKeyToSyntheticRecordTypeMap,
indexes, universalIndexes, formerIndexes, userDefinedFunctionMap, viewMap,
indexes, universalIndexes, formerIndexes, userDefinedFunctionMap, viewMap, storedQueries,
splitLongRecords, storeRecordVersions, version, subspaceKeyCounter, usesSubspaceKeyCounter, recordCountKey, localFileDescriptor != null);
for (RecordTypeBuilder recordTypeBuilder : recordTypes.values()) {
KeyExpression primaryKey = recordTypeBuilder.getPrimaryKey();
Expand Down
1 change: 1 addition & 0 deletions fdb-record-layer-core/src/main/proto/record_metadata.proto
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ message MetaData {
repeated UnnestedRecordType unnested_record_types = 13;
repeated PUserDefinedFunction user_defined_functions = 14;
repeated PView views = 15;
map<string, string> stored_queries = 16;
extensions 1000 to 2000;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ void validateMetaDataCoverage() {
assertEquals(Set.of(
"split_long_records", "version", "former_indexes", "record_count_key",
"store_record_versions", "dependencies", "subspace_key_counter", "uses_subspace_key_counter",
"stored_queries",
// the below reference record types
"records", "indexes", "record_types", "joined_record_types", "unnested_record_types",
"user_defined_functions", "views"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@

import javax.annotation.Nonnull;
import java.util.BitSet;
import java.util.Collection;

Check notice on line 29 in fdb-relational-api/src/main/java/com/apple/foundationdb/relational/api/metadata/SchemaTemplate.java

View workflow job for this annotation

GitHub Actions / coverage

File coverage: 0.0% (0/4 lines) | Changed lines: N/A (no executable lines)
import java.util.Map;
import java.util.Optional;
import java.util.Set;

Expand Down Expand Up @@ -130,6 +131,14 @@
@Nonnull
Collection<? extends InvokedRoutine> getTemporaryInvokedRoutines() throws RelationalException;

/**
* Returns the stored queries defined in this schema template.
*
* @return A map of stored query names to their SQL strings.
*/
@Nonnull
Map<String, String> getStoredQueries();

@Nonnull
String getTransactionBoundMetadataAsString() throws RelationalException;

Expand Down
6 changes: 5 additions & 1 deletion fdb-relational-core/src/main/antlr/RelationalParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ utilityStatement

templateClause
:
CREATE ( structDefinition | tableDefinition | enumDefinition | indexDefinition | sqlInvokedFunction | viewDefinition )
CREATE ( structDefinition | tableDefinition | enumDefinition | indexDefinition | sqlInvokedFunction | viewDefinition | queryDefinition )
;

createStatement
Expand Down Expand Up @@ -246,6 +246,10 @@ viewDefinition
: VIEW viewName=fullId AS viewQuery=query
;

queryDefinition
: QUERY queryName=uid AS storedQuery=query
;

tempSqlInvokedFunction
: functionSpecification ON COMMIT DROP FUNCTION routineBody
;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
import com.apple.foundationdb.relational.api.StorageCluster;
import com.apple.foundationdb.relational.api.catalog.StoreCatalog;
import com.apple.foundationdb.relational.api.metrics.NoOpMetricRegistry;
import com.apple.foundationdb.relational.recordlayer.ddl.RecordLayerMetadataOperationsFactory;

Check notice on line 31 in fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/RecordLayerEngine.java

View workflow job for this annotation

GitHub Actions / coverage

File coverage: 100.0% (11/11 lines) | Changed lines: 100.0% (8/8 lines)
import com.apple.foundationdb.relational.recordlayer.query.OfflineStoredQueriesProcessor;
import com.apple.foundationdb.relational.recordlayer.query.cache.RelationalPlanCache;

import com.codahale.metrics.MetricRegistry;
Expand All @@ -52,8 +53,17 @@

MetricRegistry mEngine = convertToRecordLayerEngine(metricsEngine);

List<StorageCluster> clusters = databases.stream().map(db ->
new RecordLayerStorageCluster(new DirectFdbConnection(db, mEngine), baseKeySpace, cfg, schemaCatalog, planCache, ddlFactory)).collect(Collectors.toList());
List<FdbConnection> connections = databases.stream()
.map(db -> new DirectFdbConnection(db, mEngine))
.collect(Collectors.toList());

List<StorageCluster> clusters = connections.stream()
.map(conn -> new RecordLayerStorageCluster(conn, baseKeySpace, cfg, schemaCatalog, planCache, ddlFactory))
.collect(Collectors.toList());

if (planCache != null && !connections.isEmpty()) {
new OfflineStoredQueriesProcessor(planCache, schemaCatalog, connections.get(0), mEngine).run();
}

return new EmbeddedRelationalEngine(clusters, mEngine);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@

import javax.annotation.Nonnull;
import java.util.BitSet;
import java.util.Collection;

Check notice on line 37 in fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/metadata/NoOpSchemaTemplate.java

View workflow job for this annotation

GitHub Actions / coverage

File coverage: 100.0% (22/22 lines) | Changed lines: 100.0% (1/1 lines)
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

Expand Down Expand Up @@ -139,6 +141,12 @@
throw new RelationalException("NoOpSchemaTemplate doesn't have temporary invoked routines!", ErrorCode.INVALID_PARAMETER);
}

@Nonnull
@Override
public Map<String, String> getStoredQueries() {
return Collections.emptyMap();
}

@Nonnull
@Override
public String getTransactionBoundMetadataAsString() throws RelationalException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@

@Nonnull
private final Set<RecordLayerView> views;

Check notice on line 82 in fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/metadata/RecordLayerSchemaTemplate.java

View workflow job for this annotation

GitHub Actions / coverage

File coverage: 91.6% (273/298 lines) | Changed lines: 100.0% (12/12 lines)
@Nonnull
private final Map<String, String> storedQueries;

private final int version;

private final boolean enableLongRows;
Expand Down Expand Up @@ -107,6 +110,7 @@
@Nonnull final Set<RecordLayerTable> tables,
@Nonnull final Set<RecordLayerInvokedRoutine> invokedRoutines,
@Nonnull final Set<RecordLayerView> views,
@Nonnull final Map<String, String> storedQueries,
int version,
boolean enableLongRows,
boolean storeRowVersions,
Expand All @@ -115,6 +119,7 @@
this.tables = ImmutableSet.copyOf(tables);
this.invokedRoutines = ImmutableSet.copyOf(invokedRoutines);
this.views = ImmutableSet.copyOf(views);
this.storedQueries = ImmutableMap.copyOf(storedQueries);
this.version = version;
this.enableLongRows = enableLongRows;
this.storeRowVersions = storeRowVersions;
Expand All @@ -130,6 +135,7 @@
@Nonnull final Set<RecordLayerTable> tables,
@Nonnull final Set<RecordLayerInvokedRoutine> invokedRoutines,
@Nonnull final Set<RecordLayerView> views,
@Nonnull final Map<String, String> storedQueries,
int version,
boolean enableLongRows,
boolean storeRowVersions,
Expand All @@ -140,6 +146,7 @@
this.tables = ImmutableSet.copyOf(tables);
this.invokedRoutines = ImmutableSet.copyOf(invokedRoutines);
this.views = ImmutableSet.copyOf(views);
this.storedQueries = ImmutableMap.copyOf(storedQueries);
this.enableLongRows = enableLongRows;
this.storeRowVersions = storeRowVersions;
this.intermingleTables = intermingleTables;
Expand Down Expand Up @@ -338,6 +345,12 @@
return views;
}

@Nonnull
@Override
public Map<String, String> getStoredQueries() {
return storedQueries;
}

@Nonnull
@Override
public Optional<? extends View> findViewByName(@Nonnull final String viewName) {
Expand Down Expand Up @@ -414,6 +427,9 @@
@Nonnull
private final Map<String, RecordLayerView> views;

@Nonnull
private final Map<String, String> storedQueries;


private RecordMetaData cachedMetadata;

Expand All @@ -422,6 +438,7 @@
auxiliaryTypes = new LinkedHashMap<>();
invokedRoutines = new LinkedHashMap<>();
views = new LinkedHashMap<>();
storedQueries = new LinkedHashMap<>();
// enable long rows is TRUE by default
enableLongRows = true;
}
Expand Down Expand Up @@ -540,6 +557,18 @@
return this;
}

@Nonnull
public Builder addStoredQuery(@Nonnull final String name, @Nonnull final String storedQuery) {
storedQueries.put(name, storedQuery);
return this;
}

@Nonnull
public Builder addStoredQueries(@Nonnull final Map<String, String> storedQueries) {
this.storedQueries.putAll(storedQueries);
return this;
}

/**
* Adds an auxiliary type, an auxiliary type is a type that is merely created, so it can be referenced later on
* in a table definition. Any {@link DataType.Named} data type can be added as an auxiliary type such as {@code enum}s
Expand Down Expand Up @@ -632,10 +661,10 @@

if (cachedMetadata != null) {
return new RecordLayerSchemaTemplate(name, new LinkedHashSet<>(tables.values()),
new LinkedHashSet<>(invokedRoutines.values()), new LinkedHashSet<>(views.values()), version, enableLongRows, storeRowVersions, intermingleTables, cachedMetadata);
new LinkedHashSet<>(invokedRoutines.values()), new LinkedHashSet<>(views.values()), storedQueries, version, enableLongRows, storeRowVersions, intermingleTables, cachedMetadata);
} else {
return new RecordLayerSchemaTemplate(name, new LinkedHashSet<>(tables.values()),
new LinkedHashSet<>(invokedRoutines.values()), new LinkedHashSet<>(views.values()), version, enableLongRows, storeRowVersions, intermingleTables);
new LinkedHashSet<>(invokedRoutines.values()), new LinkedHashSet<>(views.values()), storedQueries, version, enableLongRows, storeRowVersions, intermingleTables);
}
}

Expand Down Expand Up @@ -763,6 +792,7 @@
.setIntermingleTables(intermingleTables)
.addTables(getTables())
.addInvokedRoutines(getInvokedRoutines())
.addViews(getViews());
.addViews(getViews())
.addStoredQueries(getStoredQueries());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@
for (final var view : recordMetaData.getViewMap().entrySet()) {
schemaTemplateBuilder.addView(generateViewBuilder(metadataProvider, view.getKey(), view.getValue().getDefinition()).build());
}
}

Check notice on line 127 in fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/metadata/serde/RecordMetadataDeserializer.java

View workflow job for this annotation

GitHub Actions / coverage

File coverage: 94.2% (65/69 lines) | Changed lines: 100.0% (1/1 lines)
schemaTemplateBuilder.addStoredQueries(recordMetaData.getStoredQueries());
schemaTemplateBuilder.setCachedMetadata(recordMetaData);
return schemaTemplateBuilder;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,14 @@

@Override
public void visit(@Nonnull SchemaTemplate schemaTemplate) {
Assert.thatUnchecked(schemaTemplate instanceof RecordLayerSchemaTemplate);

Check notice on line 109 in fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/metadata/serde/RecordMetadataSerializer.java

View workflow job for this annotation

GitHub Actions / coverage

File coverage: 97.5% (39/40 lines) | Changed lines: 100.0% (4/4 lines)
final var recLayerSchemaTemplate = (RecordLayerSchemaTemplate) schemaTemplate;
getBuilder().setSplitLongRecords(schemaTemplate.isEnableLongRows());
getBuilder().setStoreRecordVersions(schemaTemplate.isStoreRowVersions());
getBuilder().setVersion(schemaTemplate.getVersion());
for (final var entry : recLayerSchemaTemplate.getStoredQueries().entrySet()) {
getBuilder().addStoredQuery(entry.getKey(), entry.getValue());
}
}

@Nonnull
Expand Down
Loading
Loading