diff --git a/fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/typing/Type.java b/fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/typing/Type.java index ec905da4b8..e2f34a8f78 100644 --- a/fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/typing/Type.java +++ b/fdb-record-layer-core/src/main/java/com/apple/foundationdb/record/query/plan/cascades/typing/Type.java @@ -2183,7 +2183,12 @@ public Record withNullability(final boolean newIsNullable) { @Nonnull public Record withName(@Nonnull final String name) { - return new Record(name, ProtoUtils.toProtoBufCompliantName(name), isNullable, fields); + return withNameAndStorageName(name, ProtoUtils.toProtoBufCompliantName(name)); + } + + @Nonnull + public Record withNameAndStorageName(@Nonnull final String name, @Nonnull final String storageName) { + return new Record(name, storageName, isNullable, fields); } @Nullable diff --git a/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/metadata/serde/RecordMetadataDeserializer.java b/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/metadata/serde/RecordMetadataDeserializer.java index f24c446da7..c8100943b3 100644 --- a/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/metadata/serde/RecordMetadataDeserializer.java +++ b/fdb-relational-core/src/main/java/com/apple/foundationdb/relational/recordlayer/metadata/serde/RecordMetadataDeserializer.java @@ -40,6 +40,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Supplier; import com.google.common.base.Suppliers; +import com.google.common.collect.ImmutableList; import com.google.protobuf.Descriptors; import javax.annotation.Nonnull; @@ -47,7 +48,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; @@ -135,14 +135,29 @@ private RecordLayerTable.Builder generateTableBuilder(@Nonnull final String user // todo (yhatem) we rely on the record type for deserialization from ProtoBuf for now, later on // we will avoid this step by having our own deserializers. + var recordLayerType = Type.Record.fromDescriptor(recordType.getDescriptor()).withNameAndStorageName(userName, storageName); // todo (yhatem) this is hacky and must be cleaned up. We need to understand the actually field types so we can take decisions - // on higher level based on these types (wave3). - final var recordLayerType = Type.Record.fromDescriptorPreservingName(recordType.getDescriptor()); + // on higher level based on these types (wave3). + if (recordLayerType.getFields().stream().anyMatch(f -> f.getFieldType().isRecord())) { + ImmutableList.Builder newFields = ImmutableList.builder(); + for (int i = 0; i < recordLayerType.getFields().size(); i++) { + final var protoField = recordType.getDescriptor().getFields().get(i); + final var field = recordLayerType.getField(i); + final Type fieldtype = field.getFieldType(); + if (fieldtype.isRecord()) { + final String fieldProtoType = protoField.getMessageType().getName(); + Type.Record r = ((Type.Record)fieldtype).withNameAndStorageName(ProtoUtils.toProtoBufCompliantName(fieldProtoType), fieldProtoType); + newFields.add(Type.Record.Field.of(r, field.getFieldNameOptional(), field.getFieldIndexOptional())); + } else { + newFields.add(field); + } + } + recordLayerType = Type.Record.fromFields(recordLayerType.isNullable(), newFields.build()).withNameAndStorageName(userName, storageName); + } return RecordLayerTable.Builder .from(recordLayerType) - .setName(userName) .setPrimaryKey(recordType.getPrimaryKey()) - .addIndexes(recordType.getIndexes().stream().map(index -> RecordLayerIndex.from(Objects.requireNonNull(recordLayerType.getName()), Objects.requireNonNull(recordLayerType.getStorageName()), index)).collect(Collectors.toSet())); + .addIndexes(recordType.getIndexes().stream().map(index -> RecordLayerIndex.from(userName, storageName, index)).collect(Collectors.toSet())); } @Nonnull diff --git a/yaml-tests/src/main/java/com/apple/foundationdb/relational/yamltests/command/CommandUtil.java b/yaml-tests/src/main/java/com/apple/foundationdb/relational/yamltests/command/CommandUtil.java index 7e9f27ebf0..f9408226b7 100644 --- a/yaml-tests/src/main/java/com/apple/foundationdb/relational/yamltests/command/CommandUtil.java +++ b/yaml-tests/src/main/java/com/apple/foundationdb/relational/yamltests/command/CommandUtil.java @@ -26,7 +26,6 @@ import com.apple.foundationdb.relational.api.metadata.SchemaTemplate; import com.apple.foundationdb.relational.recordlayer.metadata.RecordLayerSchemaTemplate; import com.apple.foundationdb.relational.yamltests.generated.schemainstance.SchemaInstanceOuterClass; - import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -47,8 +46,11 @@ import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.StringTokenizer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -102,16 +104,39 @@ public static Map fromIndexStateProto(Map deps = new ArrayList<>(); + Set neededDependencies = new LinkedHashSet<>(); + Set includedDependencies = new HashSet<>(); + + // These dependencies are automatically added, so we can treat them like they are bundled with the file dependencies + includedDependencies.add("record_metadata.proto"); + includedDependencies.add("record_metadata_options.proto"); + includedDependencies.add("tuple_fields.proto"); + try { String jsonStr = Files.readString(Paths.get(jsonFileName), StandardCharsets.UTF_8); + + // Load the definition into the meta-data proto JsonFormat.parser().ignoringUnknownFields().merge(jsonStr, builder); + + // Find the list of dependencies of the top-level file JsonObject obj = JsonParser.parseString(jsonStr).getAsJsonObject(); JsonArray dependencyArray = obj.getAsJsonObject("records").getAsJsonArray("dependency"); for (JsonElement element : dependencyArray) { String curDep = element.getAsString(); - if (!"record_metadata.proto".equals(curDep) && !"record_metadata_options.proto".equals(curDep)) { - deps.add(curDep); + neededDependencies.add(curDep); + } + + // Some dependencies may be included in the JSON descriptor itself and do not need to be + // provided from the environment + JsonArray includedDependencyDefinitions = obj.getAsJsonArray("dependencies"); + if (includedDependencyDefinitions != null) { + for (JsonElement element : includedDependencyDefinitions) { + JsonObject definition = element.getAsJsonObject(); + includedDependencies.add(definition.get("name").getAsString()); + if (definition.has("dependency")) { + definition.getAsJsonArray("dependency") + .forEach(dep -> neededDependencies.add(dep.getAsString())); + } } } } catch (IOException e) { @@ -119,7 +144,10 @@ private static RecordMetaData loadRecordMetaDataFromJson(String jsonFileName) { } List fileDescriptors = new ArrayList<>(); - for (String dep: deps) { + for (String dep: neededDependencies) { + if (includedDependencies.contains(dep)) { + continue; + } try { String fullClassName = getFullClassName(dep); Class act = Class.forName(fullClassName); diff --git a/yaml-tests/src/test/java/YamlIntegrationTests.java b/yaml-tests/src/test/java/YamlIntegrationTests.java index fc11024c93..7d281b209b 100644 --- a/yaml-tests/src/test/java/YamlIntegrationTests.java +++ b/yaml-tests/src/test/java/YamlIntegrationTests.java @@ -212,6 +212,11 @@ public void nested(YamlTest.Runner runner) throws Exception { runner.runYamsql("nested-tests.yamsql"); } + @TestTemplate + public void nestedTypeNameClash(YamlTest.Runner runner) throws Exception { + runner.runYamsql("nested-type-name-clash.yamsql"); + } + @TestTemplate public void nestedWithNulls(YamlTest.Runner runner) throws Exception { runner.runYamsql("nested-with-nulls.yamsql"); diff --git a/yaml-tests/src/test/proto/nested_type_name_clash.proto b/yaml-tests/src/test/proto/nested_type_name_clash.proto new file mode 100644 index 0000000000..f1c61655fe --- /dev/null +++ b/yaml-tests/src/test/proto/nested_type_name_clash.proto @@ -0,0 +1,135 @@ +/* + * nested_type_name_clash.proto + * + * This source file is part of the FoundationDB open source project + * + * Copyright 2021-2026 Apple Inc. and the FoundationDB project authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto3"; + +// make sure to use this package naming convention: +// com.apple.foundationdb.relational.yamltests.generated. +// adding "generated" is important to exclude the generated Java file from Jacoco reports. +// suffixing the namespace with your test name is important for segregating similarly-named +// generated-Java-classes (such as RecordTypeUnion) into separate packages, otherwise you +// get an error from `protoc`. +package com.apple.foundationdb.relational.yamltests.generated.nestedtypenameclash; + +option java_outer_classname = "NestedTypeNameClashProto"; + +import "record_metadata_options.proto"; + +message OuterRecord { + optional int64 id = 1 [(com.apple.foundationdb.record.field).primary_key = true]; + optional Middle middle = 2; + optional Inner inner = 3; +} + +message Middle { + enum Type { + // Same name as Inner.Type, but with different values + A = 0; + B = 1; + C = 2; + } + enum Category { + // Same name as Inner.Category + ONE = 0; + TWO = 1; + THREE = 2; + FOUR = 3; + } + enum Grouping { + // Structurally equal to Inner.Sign, but different name + ALFA = 0; + BRAVO = 1; + CHARLIE = 2; + DELTA = 3; + } + + message Blah { + // Same name as Inner.Blah, but different fields + optional int64 blah = 1; + } + message Whatever { + // Identical to Inner.Whatever + optional string whatever = 1; + } + message Anything { + // Structurally equal to Inner.Payload + optional bool datum = 1; + } + + optional string middle_id = 1; + optional Inner inner = 2; + + optional Type middle_type = 3; + optional Category middle_category = 4; + optional Grouping middle_grouping = 5; + optional Blah middle_blah = 6; + optional Whatever middle_whatever = 7; + optional Anything middle_anything = 8; +} + +message Inner { + enum Type { + // Same name as Middle.Type, but with different values + A = 0; + B = 1; + C = 2; + D = 3; + } + enum Category { + // Same name as Middle.Category + ONE = 0; + TWO = 1; + THREE = 2; + FOUR = 3; + } + enum Sign { + // Structurally equal to Middle.Grouping, but different name + ALFA = 0; + BRAVO = 1; + CHARLIE = 2; + DELTA = 3; + } + + message Blah { + // Same name as Middle.Blah, but different fields + optional int64 blah_blah = 1; + } + message Whatever { + // Identical to Outer.Whatever + optional string whatever = 1; + } + message Payload { + // Structurally equal to Middle.Anything + optional bool datum = 1; + } + + optional int64 inner_id = 1; + + optional Type inner_type = 2; + optional Category inner_category = 3; + optional Sign inner_sign = 4; + optional Blah inner_blah = 5; + optional Whatever inner_whatever = 6; + optional Payload inner_payload = 7; +} + +message RecordTypeUnion { + OuterRecord _OuterRecord = 1; +} diff --git a/yaml-tests/src/test/resources/nested-type-name-clash.metrics.binpb b/yaml-tests/src/test/resources/nested-type-name-clash.metrics.binpb new file mode 100644 index 0000000000..86e8ff42d9 --- /dev/null +++ b/yaml-tests/src/test/resources/nested-type-name-clash.metrics.binpb @@ -0,0 +1,169 @@ +% +j +nested-type-name-clashPEXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE middle.middle_id = 'alpha';% +7@ )(08@WSCAN(<,>) | FILTER _.middle.middle_id EQUALS promote(@c12 AS STRING) | MAP (_.id AS id)$digraph G { + fontname=courier; + rankdir=BT; + splines=polyline; + 1 [ label=<
Value Computation
MAP (q23.id AS id)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id)" ]; + 2 [ label=<
Predicate Filter
WHERE q2.middle.middle_id EQUALS promote(@c12 AS STRING)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 4 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 -> 2 [ label=< q2> label="q2" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 4 -> 3 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 2 -> 1 [ label=< q23> label="q23" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; +}% +d +nested-type-name-clashJEXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE "inner".inner_id = 1;$ +; (078@SSCAN(<,>) | FILTER _.inner.inner_id EQUALS promote(@c12 AS LONG) | MAP (_.id AS id)$digraph G { + fontname=courier; + rankdir=BT; + splines=polyline; + 1 [ label=<
Value Computation
MAP (q22.id AS id)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id)" ]; + 2 [ label=<
Predicate Filter
WHERE q2.inner.inner_id EQUALS promote(@c12 AS LONG)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 4 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 -> 2 [ label=< q2> label="q2" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 4 -> 3 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 2 -> 1 [ label=< q22> label="q22" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; +}% +k +nested-type-name-clashQEXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE middle."inner".inner_id = 1;% +; ˶(088@ZSCAN(<,>) | FILTER _.middle.inner.inner_id EQUALS promote(@c14 AS LONG) | MAP (_.id AS id)$digraph G { + fontname=courier; + rankdir=BT; + splines=polyline; + 1 [ label=<
Value Computation
MAP (q22.id AS id)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id)" ]; + 2 [ label=<
Predicate Filter
WHERE q2.middle.inner.inner_id EQUALS promote(@c14 AS LONG)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 4 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 -> 2 [ label=< q2> label="q2" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 4 -> 3 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 2 -> 1 [ label=< q22> label="q22" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; +}& +h +nested-type-name-clashNEXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE middle.middle_type = 'A';% +; (0̠@8@iSCAN(<,>) | FILTER _.middle.middle_type EQUALS promote(@c12 AS ENUM) | MAP (_.id AS id)$digraph G { + fontname=courier; + rankdir=BT; + splines=polyline; + 1 [ label=<
Value Computation
MAP (q22.id AS id)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id)" ]; + 2 [ label=<
Predicate Filter
WHERE q2.middle.middle_type EQUALS promote(@c12 AS ENUM<A(0), B(1), C(2)>)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 4 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 -> 2 [ label=< q2> label="q2" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 4 -> 3 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 2 -> 1 [ label=< q22> label="q22" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; +}& +h +nested-type-name-clashNEXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE "inner".inner_type = 'A';% +; (0D8@mSCAN(<,>) | FILTER _.inner.inner_type EQUALS promote(@c12 AS ENUM) | MAP (_.id AS id)$digraph G { + fontname=courier; + rankdir=BT; + splines=polyline; + 1 [ label=<
Value Computation
MAP (q22.id AS id)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id)" ]; + 2 [ label=<
Predicate Filter
WHERE q2.inner.inner_type EQUALS promote(@c12 AS ENUM<A(0), B(1), C(2), D(3)>)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 4 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 -> 2 [ label=< q2> label="q2" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 4 -> 3 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 2 -> 1 [ label=< q22> label="q22" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; +}& +o +nested-type-name-clashUEXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE middle."inner".inner_type = 'A';% +; (0 8@tSCAN(<,>) | FILTER _.middle.inner.inner_type EQUALS promote(@c14 AS ENUM) | MAP (_.id AS id)$digraph G { + fontname=courier; + rankdir=BT; + splines=polyline; + 1 [ label=<
Value Computation
MAP (q22.id AS id)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id)" ]; + 2 [ label=<
Predicate Filter
WHERE q2.middle.inner.inner_type EQUALS promote(@c14 AS ENUM<A(0), B(1), C(2), D(3)>)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 4 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 -> 2 [ label=< q2> label="q2" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 4 -> 3 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 2 -> 1 [ label=< q22> label="q22" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; +}1 + +nested-type-name-clashEXPLAIN SELECT o.id, o.middle.middle_blah, o.middle.middle_whatever, o.middle.middle_anything, o."inner".inner_blah, o."inner".inner_whatever, o."inner".inner_payload, o.middle."inner".inner_blah AS inner_blah_2, o.middle."inner".inner_whatever AS inner_whatever_2, o."inner".inner_payload AS inner_payload_2 FROM OuterRecord AS o WHERE o."inner".inner_blah.blah_blah > 1000;- +; ɭ(0*8@SCAN(<,>) | FILTER _.inner.inner_blah.blah_blah GREATER_THAN promote(@c82 AS LONG) | MAP (_.id AS id, _.middle.middle_blah AS middle_blah, _.middle.middle_whatever AS middle_whatever, _.middle.middle_anything AS middle_anything, _.inner.inner_blah AS inner_blah, _.inner.inner_whatever AS inner_whatever, _.inner.inner_payload AS inner_payload, _.middle.inner.inner_blah AS inner_blah_2, _.middle.inner.inner_whatever AS inner_whatever_2, _.inner.inner_payload AS inner_payload_2))digraph G { + fontname=courier; + rankdir=BT; + splines=polyline; + 1 [ label=<
Value Computation
MAP (q22.id AS id, q22.middle.middle_blah AS middle_blah, q22.middle.middle_whatever AS middle_whatever, q22.middle.middle_anything AS middle_anything, q22.inner.inner_blah AS inner_blah, q22.inner.inner_whatever AS inner_whatever, q22.inner.inner_payload AS inner_payload, q22.middle.inner.inner_blah AS inner_blah_2, q22.middle.inner.inner_whatever AS inner_whatever_2, q22.inner.inner_payload AS inner_payload_2)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload, LONG AS blah_blah AS inner_blah_2, STRING AS whatever AS inner_whatever_2, BOOLEAN AS datum AS inner_payload_2)" ]; + 2 [ label=<
Predicate Filter
WHERE q2.inner.inner_blah.blah_blah GREATER_THAN promote(@c82 AS LONG)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 4 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 -> 2 [ label=< q2> label="q2" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 4 -> 3 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 2 -> 1 [ label=< q22> label="q22" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; +}= + +nested-type-name-clash{EXPLAIN SELECT A.id, B.id FROM OuterRecord AS A, OuterRecord AS B WHERE A.middle.middle_category = B."inner".inner_category< +X Տ +(0ڎ8@SCAN(<,>) | FLATMAP q0 -> { SCAN(<,>) | FILTER q0.middle.middle_category EQUALS _.inner.inner_category AS q1 RETURN (q0.id AS _0, q1.id AS _1) }:digraph G { + fontname=courier; + rankdir=BT; + splines=polyline; + 1 [ label=<
Nested Loop Join
FLATMAP (q2.id AS _0, q4.id AS _1)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS _0, LONG AS _1)" ]; + 2 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 4 [ label=<
Predicate Filter
WHERE q2.middle.middle_category EQUALS q4.inner.inner_category
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 5 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 6 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 -> 2 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 2 -> 1 [ label=< q2> label="q2" color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 5 -> 4 [ label=< q4> label="q4" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 6 -> 5 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 4 -> 1 [ label=< q4> label="q4" color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + { + rank=same; + rankDir=LR; + 2 -> 4 [ color="red" style="invis" ]; + } +}= + +nested-type-name-clashwEXPLAIN SELECT A.id, B.id FROM OuterRecord AS A, OuterRecord AS B WHERE A.middle.middle_grouping = B."inner".inner_sign< +X (0\8@SCAN(<,>) | FLATMAP q0 -> { SCAN(<,>) | FILTER q0.middle.middle_grouping EQUALS _.inner.inner_sign AS q1 RETURN (q0.id AS _0, q1.id AS _1) }:digraph G { + fontname=courier; + rankdir=BT; + splines=polyline; + 1 [ label=<
Nested Loop Join
FLATMAP (q2.id AS _0, q4.id AS _1)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS _0, LONG AS _1)" ]; + 2 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 4 [ label=<
Predicate Filter
WHERE q2.middle.middle_grouping EQUALS q4.inner.inner_sign
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 5 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 6 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 -> 2 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 2 -> 1 [ label=< q2> label="q2" color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 5 -> 4 [ label=< q4> label="q4" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 6 -> 5 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 4 -> 1 [ label=< q4> label="q4" color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + { + rank=same; + rankDir=LR; + 2 -> 4 [ color="red" style="invis" ]; + } +}= + +nested-type-name-clashEXPLAIN SELECT A.id, B.id FROM OuterRecord AS A, OuterRecord AS B WHERE A.middle.middle_blah.blah = B."inner".inner_blah.blah_blah< +X ў(0v8@SCAN(<,>) | FLATMAP q0 -> { SCAN(<,>) | FILTER q0.middle.middle_blah.blah EQUALS _.inner.inner_blah.blah_blah AS q1 RETURN (q0.id AS _0, q1.id AS _1) }:digraph G { + fontname=courier; + rankdir=BT; + splines=polyline; + 1 [ label=<
Nested Loop Join
FLATMAP (q2.id AS _0, q4.id AS _1)
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS _0, LONG AS _1)" ]; + 2 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 4 [ label=<
Predicate Filter
WHERE q2.middle.middle_blah.blah EQUALS q4.inner.inner_blah.blah_blah
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 5 [ label=<
Scan
range: <-∞, ∞>
> color="black" shape="plain" style="solid" fillcolor="black" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 6 [ label=<
Primary Storage
record types: [OuterRecord]
> color="black" shape="plain" style="filled" fillcolor="lightblue" fontname="courier" fontsize="8" tooltip="RELATION(LONG AS id, STRING AS middle_id, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner, ENUM<A(0), B(1), C(2)> AS middle_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS middle_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS middle_grouping, LONG AS blah AS middle_blah, STRING AS whatever AS middle_whatever, BOOLEAN AS datum AS middle_anything AS middle, LONG AS inner_id, ENUM<A(0), B(1), C(2), D(3)> AS inner_type, ENUM<ONE(0), TWO(1), THREE(2), FOUR(3)> AS inner_category, ENUM<ALFA(0), BRAVO(1), CHARLIE(2), DELTA(3)> AS inner_sign, LONG AS blah_blah AS inner_blah, STRING AS whatever AS inner_whatever, BOOLEAN AS datum AS inner_payload AS inner)" ]; + 3 -> 2 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 2 -> 1 [ label=< q2> label="q2" color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 5 -> 4 [ label=< q4> label="q4" color="gray20" style="bold" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 6 -> 5 [ color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + 4 -> 1 [ label=< q4> label="q4" color="gray20" style="solid" fontname="courier" fontsize="8" arrowhead="normal" arrowtail="none" dir="both" ]; + { + rank=same; + rankDir=LR; + 2 -> 4 [ color="red" style="invis" ]; + } +} \ No newline at end of file diff --git a/yaml-tests/src/test/resources/nested-type-name-clash.metrics.yaml b/yaml-tests/src/test/resources/nested-type-name-clash.metrics.yaml new file mode 100644 index 0000000000..8deb540c7e --- /dev/null +++ b/yaml-tests/src/test/resources/nested-type-name-clash.metrics.yaml @@ -0,0 +1,129 @@ +nested-type-name-clash: +- query: EXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE middle.middle_id = + 'alpha'; + explain: SCAN(<,>) | FILTER _.middle.middle_id EQUALS promote(@c12 AS STRING) + | MAP (_.id AS id) + task_count: 222 + task_total_time_ms: 115 + transform_count: 64 + transform_time_ms: 87 + transform_yield_count: 17 + insert_time_ms: 7 + insert_new_count: 22 + insert_reused_count: 2 +- query: EXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE "inner".inner_id = + 1; + explain: SCAN(<,>) | FILTER _.inner.inner_id EQUALS promote(@c12 AS LONG) | MAP + (_.id AS id) + task_count: 206 + task_total_time_ms: 12 + transform_count: 59 + transform_time_ms: 5 + transform_yield_count: 15 + insert_time_ms: 0 + insert_new_count: 18 + insert_reused_count: 2 +- query: EXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE middle."inner".inner_id + = 1; + explain: SCAN(<,>) | FILTER _.middle.inner.inner_id EQUALS promote(@c14 AS LONG) + | MAP (_.id AS id) + task_count: 206 + task_total_time_ms: 11 + transform_count: 59 + transform_time_ms: 5 + transform_yield_count: 15 + insert_time_ms: 0 + insert_new_count: 18 + insert_reused_count: 2 +- query: EXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE middle.middle_type + = 'A'; + explain: SCAN(<,>) | FILTER _.middle.middle_type EQUALS promote(@c12 AS ENUM) | MAP (_.id AS id) + task_count: 206 + task_total_time_ms: 12 + transform_count: 59 + transform_time_ms: 6 + transform_yield_count: 15 + insert_time_ms: 1 + insert_new_count: 18 + insert_reused_count: 2 +- query: EXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE "inner".inner_type + = 'A'; + explain: SCAN(<,>) | FILTER _.inner.inner_type EQUALS promote(@c12 AS ENUM) | MAP (_.id AS id) + task_count: 206 + task_total_time_ms: 12 + transform_count: 59 + transform_time_ms: 5 + transform_yield_count: 15 + insert_time_ms: 1 + insert_new_count: 18 + insert_reused_count: 2 +- query: EXPLAIN SELECT OuterRecord.id FROM OuterRecord WHERE middle."inner".inner_type + = 'A'; + explain: SCAN(<,>) | FILTER _.middle.inner.inner_type EQUALS promote(@c14 AS ENUM) | MAP (_.id AS id) + task_count: 206 + task_total_time_ms: 7 + transform_count: 59 + transform_time_ms: 3 + transform_yield_count: 15 + insert_time_ms: 0 + insert_new_count: 18 + insert_reused_count: 2 +- query: EXPLAIN SELECT o.id, o.middle.middle_blah, o.middle.middle_whatever, o.middle.middle_anything, + o."inner".inner_blah, o."inner".inner_whatever, o."inner".inner_payload, o.middle."inner".inner_blah + AS inner_blah_2, o.middle."inner".inner_whatever AS inner_whatever_2, o."inner".inner_payload + AS inner_payload_2 FROM OuterRecord AS o WHERE o."inner".inner_blah.blah_blah + > 1000; + explain: SCAN(<,>) | FILTER _.inner.inner_blah.blah_blah GREATER_THAN promote(@c82 + AS LONG) | MAP (_.id AS id, _.middle.middle_blah AS middle_blah, _.middle.middle_whatever + AS middle_whatever, _.middle.middle_anything AS middle_anything, _.inner.inner_blah + AS inner_blah, _.inner.inner_whatever AS inner_whatever, _.inner.inner_payload + AS inner_payload, _.middle.inner.inner_blah AS inner_blah_2, _.middle.inner.inner_whatever + AS inner_whatever_2, _.inner.inner_payload AS inner_payload_2) + task_count: 206 + task_total_time_ms: 10 + transform_count: 59 + transform_time_ms: 5 + transform_yield_count: 15 + insert_time_ms: 0 + insert_new_count: 18 + insert_reused_count: 2 +- query: EXPLAIN SELECT A.id, B.id FROM OuterRecord AS A, OuterRecord AS B WHERE + A.middle.middle_category = B."inner".inner_category + explain: SCAN(<,>) | FLATMAP q0 -> { SCAN(<,>) | FILTER q0.middle.middle_category + EQUALS _.inner.inner_category AS q1 RETURN (q0.id AS _0, q1.id AS _1) } + task_count: 257 + task_total_time_ms: 32 + transform_count: 88 + transform_time_ms: 21 + transform_yield_count: 20 + insert_time_ms: 4 + insert_new_count: 28 + insert_reused_count: 5 +- query: EXPLAIN SELECT A.id, B.id FROM OuterRecord AS A, OuterRecord AS B WHERE + A.middle.middle_grouping = B."inner".inner_sign + explain: SCAN(<,>) | FLATMAP q0 -> { SCAN(<,>) | FILTER q0.middle.middle_grouping + EQUALS _.inner.inner_sign AS q1 RETURN (q0.id AS _0, q1.id AS _1) } + task_count: 257 + task_total_time_ms: 13 + transform_count: 88 + transform_time_ms: 7 + transform_yield_count: 20 + insert_time_ms: 1 + insert_new_count: 28 + insert_reused_count: 5 +- query: EXPLAIN SELECT A.id, B.id FROM OuterRecord AS A, OuterRecord AS B WHERE + A.middle.middle_blah.blah = B."inner".inner_blah.blah_blah + explain: SCAN(<,>) | FLATMAP q0 -> { SCAN(<,>) | FILTER q0.middle.middle_blah.blah + EQUALS _.inner.inner_blah.blah_blah AS q1 RETURN (q0.id AS _0, q1.id AS _1) + } + task_count: 257 + task_total_time_ms: 16 + transform_count: 88 + transform_time_ms: 9 + transform_yield_count: 20 + insert_time_ms: 1 + insert_new_count: 28 + insert_reused_count: 5 diff --git a/yaml-tests/src/test/resources/nested-type-name-clash.yamsql b/yaml-tests/src/test/resources/nested-type-name-clash.yamsql new file mode 100644 index 0000000000..44aff85b93 --- /dev/null +++ b/yaml-tests/src/test/resources/nested-type-name-clash.yamsql @@ -0,0 +1,324 @@ +# +# nested-type-name-clash.yamsql +# +# This source file is part of the FoundationDB open source project +# +# Copyright 2021-2026 Apple Inc. and the FoundationDB project authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +options: + # Requires type repository improvements for queries to avoid type name clashes + supported_version: !current_version + connection_options: + CASE_SENSITIVE_IDENTIFIERS: true +--- +setup: + connect: "jdbc:embed:/__SYS?schema=CATALOG" + steps: + - query: drop schema template if exists NESTED_TYPE_NAME_CLASH_TEMPLATE + - query: drop database if exists /FRL/NESTED_TYPE_NAME_CLASH_YAML + - query: create database /FRL/NESTED_TYPE_NAME_CLASH_YAML + - load schema template: NESTED_TYPE_NAME_CLASH_TEMPLATE from com.apple.foundationdb.relational.yamltests.generated.nestedtypenameclash.NestedTypeNameClashProto + - query: create schema /FRL/NESTED_TYPE_NAME_CLASH_YAML/TEST with template NESTED_TYPE_NAME_CLASH_TEMPLATE +--- +setup: + connect: "jdbc:embed:/FRL/NESTED_TYPE_NAME_CLASH_YAML?schema=TEST" + steps: + - query: INSERT INTO OuterRecord VALUES + (100, ('alpha', (1, 'A', 'ONE', 'ALFA', (10), ('foo'), (false)), 'A', 'ONE', 'ALFA', (100), ('blah_foo'), (false)), (1, 'A', 'ONE', 'ALFA', (1000), ('second_foo'), (true))), + (101, ('alpha', (1, 'A', 'ONE', 'ALFA', (10), ('foo'), (false)), 'A', 'ONE', 'ALFA', (100), ('blah_foo'), (false)), (2, 'B', 'TWO', 'BRAVO', (1000), ('second_foo'), (true))), + (102, ('alpha', (1, 'A', 'ONE', 'ALFA', (10), ('foo'), (false)), 'A', 'ONE', 'ALFA', (100), ('blah_foo'), (false)), (3, 'C', 'THREE', 'CHARLIE', (1000), ('second_foo'), (true))), + (103, ('alpha', (1, 'A', 'ONE', 'ALFA', (10), ('foo'), (false)), 'A', 'ONE', 'ALFA', (100), ('blah_foo'), (false)), (4, 'D', 'FOUR', 'DELTA', (1000), ('second_foo'), (true))), + (104, ('bravo', (2, 'B', 'TWO', 'BRAVO', (11), ('bar'), (true)), 'A', 'ONE', 'ALFA', (100), ('blah_foo'), (false)), (1, 'A', 'ONE', 'ALFA', (1002), ('second_bar'), (false))), + (105, ('charlie', (3, 'C', 'THREE', 'CHARLIE', (12), ('baz'), (false)), 'A', 'ONE', 'ALFA', (100), ('blah_foo'), (false)), (1, 'A', 'ONE', 'ALFA', (1004), ('second_baz'), (false))), + (106, ('delta', (4, 'D', 'FOUR', 'DELTA', (13), ('qux'), (true)), 'A', 'ONE', 'ALFA', (100), ('blah_foo'), (false)), (1, 'A', 'ONE', 'ALFA', (1008), ('second_qux'), (false))), + (107, ('alpha', (1, 'A', 'ONE', 'ALFA', (10), ('foo'), (false)), 'B', 'TWO', 'BRAVO', (103), ('blah_bar'), (true)), (1, 'A', 'ONE', 'ALFA', (1000), ('second_foo'), (true))), + (108, ('alpha', (1, 'A', 'ONE', 'ALFA', (10), ('foo'), (true)), 'C', 'THREE', 'CHARLIE', (105), ('blah_baz'), (true)), (1, 'A', 'ONE', 'ALFA', (1000), ('second_foo'), (true))) +--- +test_block: + connect: "jdbc:embed:/FRL/NESTED_TYPE_NAME_CLASH_YAML?schema=TEST" + name: nested-type-name-clash + tests: + # Select only the id field + - + - query: SELECT OuterRecord.id FROM OuterRecord WHERE middle.middle_id = 'alpha'; + - explain: "SCAN(<,>) | FILTER _.middle.middle_id EQUALS promote(@c12 AS STRING) | MAP (_.id AS id)" + - result: [ + { id: 100 }, + { id: 101 }, + { id: 102 }, + { id: 103 }, + { id: 107 }, + { id: 108 }, + ] + - + - query: SELECT OuterRecord.id FROM OuterRecord WHERE middle.middle_id = 'bravo'; + - result: [ + { id: 104 }, + ] + - + - query: SELECT OuterRecord.id FROM OuterRecord WHERE "inner".inner_id = 1; + - explain: "SCAN(<,>) | FILTER _.inner.inner_id EQUALS promote(@c12 AS LONG) | MAP (_.id AS id)" + - result: [ + { id: 100 }, + { id: 104 }, + { id: 105 }, + { id: 106 }, + { id: 107 }, + { id: 108 }, + ] + - + - query: SELECT OuterRecord.id FROM OuterRecord WHERE "inner".inner_id = 3; + - result: [ + { id: 102 }, + ] + - + - query: SELECT OuterRecord.id FROM OuterRecord WHERE middle."inner".inner_id = 1; + - explain: "SCAN(<,>) | FILTER _.middle.inner.inner_id EQUALS promote(@c14 AS LONG) | MAP (_.id AS id)" + - result: [ + { id: 100 }, + { id: 101 }, + { id: 102 }, + { id: 103 }, + { id: 107 }, + { id: 108 }, + ] + - + - query: SELECT OuterRecord.id FROM OuterRecord WHERE middle."inner".inner_id = 4; + - result: [ + { id: 106 }, + ] + - + - query: SELECT OuterRecord.id FROM OuterRecord WHERE middle.middle_type = 'A'; + - explain: "SCAN(<,>) | FILTER _.middle.middle_type EQUALS promote(@c12 AS ENUM) | MAP (_.id AS id)" + - result: [ + { id: 100 }, + { id: 101 }, + { id: 102 }, + { id: 103 }, + { id: 104 }, + { id: 105 }, + { id: 106 }, + ] + - + - query: SELECT OuterRecord.id FROM OuterRecord WHERE "inner".inner_type = 'A'; + - explain: "SCAN(<,>) | FILTER _.inner.inner_type EQUALS promote(@c12 AS ENUM) | MAP (_.id AS id)" + - result: [ + { id: 100 }, + { id: 104 }, + { id: 105 }, + { id: 106 }, + { id: 107 }, + { id: 108 }, + ] + - + - query: SELECT OuterRecord.id FROM OuterRecord WHERE middle."inner".inner_type = 'A'; + - explain: "SCAN(<,>) | FILTER _.middle.inner.inner_type EQUALS promote(@c14 AS ENUM) | MAP (_.id AS id)" + - result: [ + { id: 100 }, + { id: 101 }, + { id: 102 }, + { id: 103 }, + { id: 107 }, + { id: 108 }, + ] + + # Type clashes in the projected columns + - + - query: SELECT o.id, + o.middle.middle_blah, o.middle.middle_whatever, o.middle.middle_anything, + o."inner".inner_blah, o."inner".inner_whatever, o."inner".inner_payload, + o.middle."inner".inner_blah AS inner_blah_2, o.middle."inner".inner_whatever AS inner_whatever_2, o."inner".inner_payload AS inner_payload_2 + FROM OuterRecord AS o WHERE o."inner".inner_blah.blah_blah > 1000; + - explain: "SCAN(<,>) | FILTER _.inner.inner_blah.blah_blah GREATER_THAN promote(@c82 AS LONG) | MAP (_.id AS id, _.middle.middle_blah AS middle_blah, _.middle.middle_whatever AS middle_whatever, _.middle.middle_anything AS middle_anything, _.inner.inner_blah AS inner_blah, _.inner.inner_whatever AS inner_whatever, _.inner.inner_payload AS inner_payload, _.middle.inner.inner_blah AS inner_blah_2, _.middle.inner.inner_whatever AS inner_whatever_2, _.inner.inner_payload AS inner_payload_2)" + - result: [ + { id: 104, middle_blah: { blah: 100 }, middle_whatever: { whatever: "blah_foo" }, middle_anything: { datum: false }, inner_blah: { blah_blah: 1002 }, inner_whatever: { whatever: "second_bar" }, inner_payload: { datum: false }, inner_blah_2: { blah_blah: 11 }, inner_whatever_2: { whatever: "bar" }, inner_payload_2: { datum: false } }, + { id: 105, middle_blah: { blah: 100 }, middle_whatever: { whatever: "blah_foo" }, middle_anything: { datum: false }, inner_blah: { blah_blah: 1004 }, inner_whatever: { whatever: "second_baz" }, inner_payload: { datum: false }, inner_blah_2: { blah_blah: 12 }, inner_whatever_2: { whatever: "baz" }, inner_payload_2: { datum: false } }, + { id: 106, middle_blah: { blah: 100 }, middle_whatever: { whatever: "blah_foo" }, middle_anything: { datum: false }, inner_blah: { blah_blah: 1008 }, inner_whatever: { whatever: "second_qux" }, inner_payload: { datum: false }, inner_blah_2: { blah_blah: 13 }, inner_whatever_2: { whatever: "qux" }, inner_payload_2: { datum: false } }, + ] + + # Various self-joins, some of which should be possible and some of which should not be + - + - query: + SELECT A.id, B.id + FROM OuterRecord AS A, OuterRecord AS B + WHERE A.middle.middle_type = B."inner".inner_type + # Should fail as enums do not have the same values + - error: XX000 + - + - query: + SELECT A.id, B.id + FROM OuterRecord AS A, OuterRecord AS B + WHERE A.middle.middle_category = B."inner".inner_category + # Should succeed as the two enum types have the same name and values + - explain: "SCAN(<,>) | FLATMAP q0 -> { SCAN(<,>) | FILTER q0.middle.middle_category EQUALS _.inner.inner_category AS q1 RETURN (q0.id AS _0, q1.id AS _1) }" + - result: [ + { '_0': 100, '_1': 100 }, + { '_0': 100, '_1': 104 }, + { '_0': 100, '_1': 105 }, + { '_0': 100, '_1': 106 }, + { '_0': 100, '_1': 107 }, + { '_0': 100, '_1': 108 }, + { '_0': 101, '_1': 100 }, + { '_0': 101, '_1': 104 }, + { '_0': 101, '_1': 105 }, + { '_0': 101, '_1': 106 }, + { '_0': 101, '_1': 107 }, + { '_0': 101, '_1': 108 }, + { '_0': 102, '_1': 100 }, + { '_0': 102, '_1': 104 }, + { '_0': 102, '_1': 105 }, + { '_0': 102, '_1': 106 }, + { '_0': 102, '_1': 107 }, + { '_0': 102, '_1': 108 }, + { '_0': 103, '_1': 100 }, + { '_0': 103, '_1': 104 }, + { '_0': 103, '_1': 105 }, + { '_0': 103, '_1': 106 }, + { '_0': 103, '_1': 107 }, + { '_0': 103, '_1': 108 }, + { '_0': 104, '_1': 100 }, + { '_0': 104, '_1': 104 }, + { '_0': 104, '_1': 105 }, + { '_0': 104, '_1': 106 }, + { '_0': 104, '_1': 107 }, + { '_0': 104, '_1': 108 }, + { '_0': 105, '_1': 100 }, + { '_0': 105, '_1': 104 }, + { '_0': 105, '_1': 105 }, + { '_0': 105, '_1': 106 }, + { '_0': 105, '_1': 107 }, + { '_0': 105, '_1': 108 }, + { '_0': 106, '_1': 100 }, + { '_0': 106, '_1': 104 }, + { '_0': 106, '_1': 105 }, + { '_0': 106, '_1': 106 }, + { '_0': 106, '_1': 107 }, + { '_0': 106, '_1': 108 }, + { '_0': 107, '_1': 101 }, + { '_0': 108, '_1': 102 }, + ] + - + - query: + SELECT A.id, B.id + FROM OuterRecord AS A, OuterRecord AS B + WHERE A.middle.middle_grouping = B."inner".inner_sign + # Should succeed as the two enum types have the same values + - explain: "SCAN(<,>) | FLATMAP q0 -> { SCAN(<,>) | FILTER q0.middle.middle_grouping EQUALS _.inner.inner_sign AS q1 RETURN (q0.id AS _0, q1.id AS _1) }" + - result: [ + { '_0': 100, '_1': 100 }, + { '_0': 100, '_1': 104 }, + { '_0': 100, '_1': 105 }, + { '_0': 100, '_1': 106 }, + { '_0': 100, '_1': 107 }, + { '_0': 100, '_1': 108 }, + { '_0': 101, '_1': 100 }, + { '_0': 101, '_1': 104 }, + { '_0': 101, '_1': 105 }, + { '_0': 101, '_1': 106 }, + { '_0': 101, '_1': 107 }, + { '_0': 101, '_1': 108 }, + { '_0': 102, '_1': 100 }, + { '_0': 102, '_1': 104 }, + { '_0': 102, '_1': 105 }, + { '_0': 102, '_1': 106 }, + { '_0': 102, '_1': 107 }, + { '_0': 102, '_1': 108 }, + { '_0': 103, '_1': 100 }, + { '_0': 103, '_1': 104 }, + { '_0': 103, '_1': 105 }, + { '_0': 103, '_1': 106 }, + { '_0': 103, '_1': 107 }, + { '_0': 103, '_1': 108 }, + { '_0': 104, '_1': 100 }, + { '_0': 104, '_1': 104 }, + { '_0': 104, '_1': 105 }, + { '_0': 104, '_1': 106 }, + { '_0': 104, '_1': 107 }, + { '_0': 104, '_1': 108 }, + { '_0': 105, '_1': 100 }, + { '_0': 105, '_1': 104 }, + { '_0': 105, '_1': 105 }, + { '_0': 105, '_1': 106 }, + { '_0': 105, '_1': 107 }, + { '_0': 105, '_1': 108 }, + { '_0': 106, '_1': 100 }, + { '_0': 106, '_1': 104 }, + { '_0': 106, '_1': 105 }, + { '_0': 106, '_1': 106 }, + { '_0': 106, '_1': 107 }, + { '_0': 106, '_1': 108 }, + { '_0': 107, '_1': 101 }, + { '_0': 108, '_1': 102 }, + ] + - + - query: + SELECT A.id, B.id + FROM OuterRecord AS A, OuterRecord AS B + WHERE A.middle.middle_blah.blah = B."inner".inner_blah.blah_blah + # Comparison on compatible primitive field. Should succeed + - explain: "SCAN(<,>) | FLATMAP q0 -> { SCAN(<,>) | FILTER q0.middle.middle_blah.blah EQUALS _.inner.inner_blah.blah_blah AS q1 RETURN (q0.id AS _0, q1.id AS _1) }" + - + - query: + SELECT A.id, B.id + FROM OuterRecord AS A, OuterRecord AS B + WHERE A.middle."inner".inner_blah = B."inner".inner_blah + # Fails because we do not support struct comparison. When we do, this should start to succeed as the types are the same + - error: XX000 + - + - query: + SELECT A.id, B.id + FROM OuterRecord AS A, OuterRecord AS B + WHERE A.middle.middle_blah = B."inner".inner_blah + # Fails because we do not support struct comparison. However, even when we do, the types should still be incompatible due to field name issues + - error: XX000 + - + - query: + SELECT A.id, B.id + FROM OuterRecord AS A, OuterRecord AS B + WHERE A.middle.middle_whatever = B."inner".inner_whatever + # Fails because we do not support struct comparison. However, when we do, this should succeed as the types are structurally equal (and have the same name) + - error: XX000 + - + - query: + SELECT A.id, B.id + FROM OuterRecord AS A, OuterRecord AS B + WHERE A.middle.middle_anything = B."inner".inner_payload + # Fails because we do not support struct comparison. However, when we do, this should succeed as the types are structurally equal + - error: XX000 + + # Select * + # - + # # Unfortunately, we cannot run this query because of issues with parsing the enum through JDBC. + # # If we did include this test case, we'd have to disable all mixed mode tests on this file. + # # See: https://github.com/FoundationDB/fdb-record-layer/issues/3754 + # - query: SELECT * FROM OuterRecord WHERE middle.middle_id = 'alpha'; + # - explain: "SCAN(<,>) | FILTER _.middle.middle_id EQUALS promote(@c10 AS STRING)" + # - maxRows: 0 + # - result: [ + # { id: 100, middle: { middle_id: "alpha", inner: { inner_id: 1, inner_type: "A", inner_category: "ONE", inner_sign: "ALFA", inner_blah: { blah_blah: 10 }, inner_whatever: { whatever: "foo" }, inner_payload: { datum: false } }, middle_type: "A", middle_category: "ONE", middle_grouping: "ALFA", middle_blah: { blah: 100 }, middle_whatever: { whatever: "blah_foo" }, middle_anything: { datum: false } }, inner: { inner_id: 1, inner_type: "A", inner_category: "ONE", inner_sign: "ALFA", inner_blah: { blah_blah: 1000 }, inner_whatever: { whatever: "second_foo" }, inner_payload: { datum: true } } }, + # { id: 101, middle: { middle_id: "alpha", inner: { inner_id: 1, inner_type: "A", inner_category: "ONE", inner_sign: "ALFA", inner_blah: { blah_blah: 10 }, inner_whatever: { whatever: "foo" }, inner_payload: { datum: false } }, middle_type: "A", middle_category: "ONE", middle_grouping: "ALFA", middle_blah: { blah: 100 }, middle_whatever: { whatever: "blah_foo" }, middle_anything: { datum: false } }, inner: { inner_id: 2, inner_type: "B", inner_category: "TWO", inner_sign: "BRAVO", inner_blah: { blah_blah: 1000 }, inner_whatever: { whatever: "second_foo" }, inner_payload: { datum: true } } }, + # { id: 102, middle: { middle_id: "alpha", inner: { inner_id: 1, inner_type: "A", inner_category: "ONE", inner_sign: "ALFA", inner_blah: { blah_blah: 10 }, inner_whatever: { whatever: "foo" }, inner_payload: { datum: false } }, middle_type: "A", middle_category: "ONE", middle_grouping: "ALFA", middle_blah: { blah: 100 }, middle_whatever: { whatever: "blah_foo" }, middle_anything: { datum: false } }, inner: { inner_id: 3, inner_type: "C", inner_category: "THREE", inner_sign: "CHARLIE", inner_blah: { blah_blah: 1000 }, inner_whatever: { whatever: "second_foo" }, inner_payload: { datum: true } } }, + # { id: 103, middle: { middle_id: "alpha", inner: { inner_id: 1, inner_type: "A", inner_category: "ONE", inner_sign: "ALFA", inner_blah: { blah_blah: 10 }, inner_whatever: { whatever: "foo" }, inner_payload: { datum: false } }, middle_type: "A", middle_category: "ONE", middle_grouping: "ALFA", middle_blah: { blah: 100 }, middle_whatever: { whatever: "blah_foo" }, middle_anything: { datum: false } }, inner: { inner_id: 4, inner_type: "D", inner_category: "FOUR", inner_sign: "DELTA", inner_blah: { blah_blah: 1000 }, inner_whatever: { whatever: "second_foo" }, inner_payload: { datum: true } } }, + # { id: 107, middle: { middle_id: "alpha", inner: { inner_id: 1, inner_type: "A", inner_category: "ONE", inner_sign: "ALFA", inner_blah: { blah_blah: 10 }, inner_whatever: { whatever: "foo" }, inner_payload: { datum: false } }, middle_type: "B", middle_category: "TWO", middle_grouping: "BRAVO", middle_blah: { blah: 103 }, middle_whatever: { whatever: "blah_bar" }, middle_anything: { datum: true } }, inner: { inner_id: 1, inner_type: "A", inner_category: "ONE", inner_sign: "ALFA", inner_blah: { blah_blah: 1000 }, inner_whatever: { whatever: "second_foo" }, inner_payload: { datum: true } } }, + # { id: 108, middle: { middle_id: "alpha", inner: { inner_id: 1, inner_type: "A", inner_category: "ONE", inner_sign: "ALFA", inner_blah: { blah_blah: 10 }, inner_whatever: { whatever: "foo" }, inner_payload: { datum: true } }, middle_type: "C", middle_category: "THREE", middle_grouping: "CHARLIE", middle_blah: { blah: 105 }, middle_whatever: { whatever: "blah_baz" }, middle_anything: { datum: true } }, inner: { inner_id: 1, inner_type: "A", inner_category: "ONE", inner_sign: "ALFA", inner_blah: { blah_blah: 1000 }, inner_whatever: { whatever: "second_foo" }, inner_payload: { datum: true } } }, + # ] +--- +setup: + connect: "jdbc:embed:/__SYS?schema=CATALOG" + steps: + - query: drop schema template NESTED_TYPE_NAME_CLASH_TEMPLATE + - query: drop database /FRL/NESTED_TYPE_NAME_CLASH_YAML +...