Copilot commented on code in PR #7333:
URL: https://github.com/apache/ignite-3/pull/7333#discussion_r2653036311


##########
modules/system-view/src/main/java/org/apache/ignite/internal/systemview/SystemViewManagerImpl.java:
##########
@@ -256,30 +267,223 @@ private static Map<String, ScannableView<?>> 
toScannableViews(String localNodeNa
     private static class ScannableView<T> {
         private final Publisher<InternalTuple> publisher;
 
-        private ScannableView(String localNodeName, SystemView<T> view) {
-            BinaryTupleSchema schema = tupleSchemaForView(view);
+        private ScannableView(ViewRowFactory rowFactory, SystemView<T> view) {
+            this.publisher = new TransformingPublisher<>(view.dataProvider(), 
object -> rowFactory.create(view, object));
+        }
 
-            this.publisher = new TransformingPublisher<>(view.dataProvider(), 
object -> {
-                BinaryTupleBuilder builder = new 
BinaryTupleBuilder(schema.elementCount());
+        Publisher<InternalTuple> scan() {
+            return publisher;
+        }
+    }
 
-                int offset = 0;
-                if (view instanceof NodeSystemView) {
-                    builder.appendString(localNodeName);
-                    offset++;
-                }
+    private abstract static class ViewRowFactory {
+        abstract <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> 
view, ViewSourceT source);
+    }
 
-                for (int i = 0; i < view.columns().size(); i++) {
-                    SystemViewColumn<T, ?> column = view.columns().get(i);
+    private static class NodeViewRowFactory extends ViewRowFactory {
+        private final String nodeName;
 
-                    schema.appendValue(builder, i + offset, 
column.value().apply(object));
-                }
+        private NodeViewRowFactory(String nodeName) {
+            this.nodeName = nodeName;
+        }
 
-                return new BinaryTuple(schema.elementCount(), builder.build());
-            });
+        @Override
+        <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view, 
ViewSourceT source) {
+            return new NodeViewRow<>(nodeName, view, source);
         }
+    }
 
-        Publisher<InternalTuple> scan() {
-            return publisher;
+    private static class ClusterViewRowFactory extends ViewRowFactory {
+        private static final ViewRowFactory INSTANCE = new 
ClusterViewRowFactory();
+
+        @Override
+        <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view, 
ViewSourceT source) {
+            return new ClusterViewRow<>(view, source);
         }
     }
+
+    private static class NodeViewRow<T> extends AbstractViewRow {
+        private final String nodeName;
+        private final SystemView<T> view;
+        private final T source;
+
+        private NodeViewRow(String nodeName, SystemView<T> view, T source) {
+            this.nodeName = nodeName;
+            this.view = view;
+            this.source = source;
+        }
+
+        @Override
+        public int elementCount() {
+            return view.columns().size() + 1;
+        }
+
+        @Override
+        public ByteBuffer byteBuffer() {
+            throw new UnsupportedOperationException("byteBuffer");
+        }
+
+        @Override
+        <ReturnT> ReturnT value(int columnIndex) {
+            return columnIndex == 0 
+                    ? (ReturnT) nodeName
+                    : (ReturnT) view.columns().get(columnIndex - 
1).value().apply(source);
+        }
+    }
+
+    private static class ClusterViewRow<T> extends AbstractViewRow {
+        private final SystemView<T> view;
+        private final T source;
+
+        private ClusterViewRow(SystemView<T> view, T source) {
+            this.view = view;
+            this.source = source;
+        }
+
+        @Override
+        public int elementCount() {
+            return view.columns().size();
+        }
+
+        @Override
+        public ByteBuffer byteBuffer() {
+            throw new UnsupportedOperationException("byteBuffer");
+        }
+
+        @Override
+        <ReturnT> ReturnT value(int columnIndex) {
+            return (ReturnT) 
view.columns().get(columnIndex).value().apply(source);
+        }
+    }
+
+    private abstract static class AbstractViewRow implements InternalTuple {
+        abstract <T> T value(int columnIndex);
+
+        @Override
+        public boolean hasNullValue(int columnIndex) {
+            return value(columnIndex) == null;
+        }
+
+        @Override
+        public boolean booleanValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Boolean booleanValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public byte byteValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Byte byteValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public short shortValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Short shortValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public int intValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Integer intValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public long longValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Long longValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public float floatValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Float floatValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public double doubleValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Double doubleValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public BigDecimal decimalValue(int columnIndex, int scale) {
+            BigDecimal value = value(columnIndex);
+
+            return value.setScale(scale, RoundingMode.UNNECESSARY);
+        }
+
+        @Override
+        public String stringValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public byte[] bytesValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public UUID uuidValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public LocalDate dateValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public LocalTime timeValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public LocalDateTime dateTimeValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Instant timestampValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Period periodValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Duration durationValue(int columnIndex) {
+            return value(columnIndex);
+        }
+    } 

Review Comment:
   Trailing whitespace detected after the closing brace. Please remove it to 
maintain code cleanliness.
   ```suggestion
       }
   ```



##########
modules/system-view/src/main/java/org/apache/ignite/internal/systemview/SystemViewManagerImpl.java:
##########
@@ -256,30 +267,223 @@ private static Map<String, ScannableView<?>> 
toScannableViews(String localNodeNa
     private static class ScannableView<T> {
         private final Publisher<InternalTuple> publisher;
 
-        private ScannableView(String localNodeName, SystemView<T> view) {
-            BinaryTupleSchema schema = tupleSchemaForView(view);
+        private ScannableView(ViewRowFactory rowFactory, SystemView<T> view) {
+            this.publisher = new TransformingPublisher<>(view.dataProvider(), 
object -> rowFactory.create(view, object));
+        }
 
-            this.publisher = new TransformingPublisher<>(view.dataProvider(), 
object -> {
-                BinaryTupleBuilder builder = new 
BinaryTupleBuilder(schema.elementCount());
+        Publisher<InternalTuple> scan() {
+            return publisher;
+        }
+    }
 
-                int offset = 0;
-                if (view instanceof NodeSystemView) {
-                    builder.appendString(localNodeName);
-                    offset++;
-                }
+    private abstract static class ViewRowFactory {
+        abstract <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> 
view, ViewSourceT source);
+    }
 
-                for (int i = 0; i < view.columns().size(); i++) {
-                    SystemViewColumn<T, ?> column = view.columns().get(i);
+    private static class NodeViewRowFactory extends ViewRowFactory {
+        private final String nodeName;
 
-                    schema.appendValue(builder, i + offset, 
column.value().apply(object));
-                }
+        private NodeViewRowFactory(String nodeName) {
+            this.nodeName = nodeName;
+        }
 
-                return new BinaryTuple(schema.elementCount(), builder.build());
-            });
+        @Override
+        <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view, 
ViewSourceT source) {
+            return new NodeViewRow<>(nodeName, view, source);
         }
+    }
 
-        Publisher<InternalTuple> scan() {
-            return publisher;
+    private static class ClusterViewRowFactory extends ViewRowFactory {
+        private static final ViewRowFactory INSTANCE = new 
ClusterViewRowFactory();
+
+        @Override
+        <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view, 
ViewSourceT source) {
+            return new ClusterViewRow<>(view, source);
         }
     }
+
+    private static class NodeViewRow<T> extends AbstractViewRow {
+        private final String nodeName;
+        private final SystemView<T> view;
+        private final T source;
+
+        private NodeViewRow(String nodeName, SystemView<T> view, T source) {
+            this.nodeName = nodeName;
+            this.view = view;
+            this.source = source;
+        }
+
+        @Override
+        public int elementCount() {
+            return view.columns().size() + 1;
+        }
+
+        @Override
+        public ByteBuffer byteBuffer() {
+            throw new UnsupportedOperationException("byteBuffer");
+        }
+
+        @Override
+        <ReturnT> ReturnT value(int columnIndex) {
+            return columnIndex == 0 
+                    ? (ReturnT) nodeName
+                    : (ReturnT) view.columns().get(columnIndex - 
1).value().apply(source);
+        }
+    }
+
+    private static class ClusterViewRow<T> extends AbstractViewRow {
+        private final SystemView<T> view;
+        private final T source;
+
+        private ClusterViewRow(SystemView<T> view, T source) {
+            this.view = view;
+            this.source = source;
+        }
+
+        @Override
+        public int elementCount() {
+            return view.columns().size();
+        }
+
+        @Override
+        public ByteBuffer byteBuffer() {
+            throw new UnsupportedOperationException("byteBuffer");
+        }
+
+        @Override
+        <ReturnT> ReturnT value(int columnIndex) {
+            return (ReturnT) 
view.columns().get(columnIndex).value().apply(source);
+        }
+    }
+
+    private abstract static class AbstractViewRow implements InternalTuple {
+        abstract <T> T value(int columnIndex);
+
+        @Override
+        public boolean hasNullValue(int columnIndex) {
+            return value(columnIndex) == null;
+        }
+
+        @Override
+        public boolean booleanValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Boolean booleanValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public byte byteValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Byte byteValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public short shortValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Short shortValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public int intValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Integer intValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public long longValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Long longValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public float floatValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Float floatValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public double doubleValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Double doubleValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public BigDecimal decimalValue(int columnIndex, int scale) {
+            BigDecimal value = value(columnIndex);
+

Review Comment:
   The decimalValue method will throw a NullPointerException if the value at 
columnIndex is null. Consider adding a null check before calling setScale, or 
documenting that null values should be checked using hasNullValue before 
calling this method.
   ```suggestion
   
               if (value == null) {
                   return null;
               }
   ```



##########
modules/system-view/src/main/java/org/apache/ignite/internal/systemview/SystemViewManagerImpl.java:
##########
@@ -256,30 +267,223 @@ private static Map<String, ScannableView<?>> 
toScannableViews(String localNodeNa
     private static class ScannableView<T> {
         private final Publisher<InternalTuple> publisher;
 
-        private ScannableView(String localNodeName, SystemView<T> view) {
-            BinaryTupleSchema schema = tupleSchemaForView(view);
+        private ScannableView(ViewRowFactory rowFactory, SystemView<T> view) {
+            this.publisher = new TransformingPublisher<>(view.dataProvider(), 
object -> rowFactory.create(view, object));
+        }
 
-            this.publisher = new TransformingPublisher<>(view.dataProvider(), 
object -> {
-                BinaryTupleBuilder builder = new 
BinaryTupleBuilder(schema.elementCount());
+        Publisher<InternalTuple> scan() {
+            return publisher;
+        }
+    }
 
-                int offset = 0;
-                if (view instanceof NodeSystemView) {
-                    builder.appendString(localNodeName);
-                    offset++;
-                }
+    private abstract static class ViewRowFactory {
+        abstract <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> 
view, ViewSourceT source);
+    }
 
-                for (int i = 0; i < view.columns().size(); i++) {
-                    SystemViewColumn<T, ?> column = view.columns().get(i);
+    private static class NodeViewRowFactory extends ViewRowFactory {
+        private final String nodeName;
 
-                    schema.appendValue(builder, i + offset, 
column.value().apply(object));
-                }
+        private NodeViewRowFactory(String nodeName) {
+            this.nodeName = nodeName;
+        }
 
-                return new BinaryTuple(schema.elementCount(), builder.build());
-            });
+        @Override
+        <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view, 
ViewSourceT source) {
+            return new NodeViewRow<>(nodeName, view, source);
         }
+    }
 
-        Publisher<InternalTuple> scan() {
-            return publisher;
+    private static class ClusterViewRowFactory extends ViewRowFactory {
+        private static final ViewRowFactory INSTANCE = new 
ClusterViewRowFactory();
+
+        @Override
+        <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view, 
ViewSourceT source) {
+            return new ClusterViewRow<>(view, source);
         }
     }

Review Comment:
   The ViewRowFactory abstract class and its implementations 
(NodeViewRowFactory, ClusterViewRowFactory) lack JavaDoc documentation. 
Consider adding class-level and method-level documentation to explain their 
purpose and the factory pattern being used for creating view rows.



##########
modules/system-view/src/main/java/org/apache/ignite/internal/systemview/SystemViewManagerImpl.java:
##########
@@ -256,30 +267,223 @@ private static Map<String, ScannableView<?>> 
toScannableViews(String localNodeNa
     private static class ScannableView<T> {
         private final Publisher<InternalTuple> publisher;
 
-        private ScannableView(String localNodeName, SystemView<T> view) {
-            BinaryTupleSchema schema = tupleSchemaForView(view);
+        private ScannableView(ViewRowFactory rowFactory, SystemView<T> view) {
+            this.publisher = new TransformingPublisher<>(view.dataProvider(), 
object -> rowFactory.create(view, object));
+        }
 
-            this.publisher = new TransformingPublisher<>(view.dataProvider(), 
object -> {
-                BinaryTupleBuilder builder = new 
BinaryTupleBuilder(schema.elementCount());
+        Publisher<InternalTuple> scan() {
+            return publisher;
+        }
+    }
 
-                int offset = 0;
-                if (view instanceof NodeSystemView) {
-                    builder.appendString(localNodeName);
-                    offset++;
-                }
+    private abstract static class ViewRowFactory {
+        abstract <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> 
view, ViewSourceT source);
+    }
 
-                for (int i = 0; i < view.columns().size(); i++) {
-                    SystemViewColumn<T, ?> column = view.columns().get(i);
+    private static class NodeViewRowFactory extends ViewRowFactory {
+        private final String nodeName;
 
-                    schema.appendValue(builder, i + offset, 
column.value().apply(object));
-                }
+        private NodeViewRowFactory(String nodeName) {
+            this.nodeName = nodeName;
+        }
 
-                return new BinaryTuple(schema.elementCount(), builder.build());
-            });
+        @Override
+        <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view, 
ViewSourceT source) {
+            return new NodeViewRow<>(nodeName, view, source);
         }
+    }
 
-        Publisher<InternalTuple> scan() {
-            return publisher;
+    private static class ClusterViewRowFactory extends ViewRowFactory {
+        private static final ViewRowFactory INSTANCE = new 
ClusterViewRowFactory();
+
+        @Override
+        <ViewSourceT> InternalTuple create(SystemView<ViewSourceT> view, 
ViewSourceT source) {
+            return new ClusterViewRow<>(view, source);
         }
     }
+
+    private static class NodeViewRow<T> extends AbstractViewRow {
+        private final String nodeName;
+        private final SystemView<T> view;
+        private final T source;
+
+        private NodeViewRow(String nodeName, SystemView<T> view, T source) {
+            this.nodeName = nodeName;
+            this.view = view;
+            this.source = source;
+        }
+
+        @Override
+        public int elementCount() {
+            return view.columns().size() + 1;
+        }
+
+        @Override
+        public ByteBuffer byteBuffer() {
+            throw new UnsupportedOperationException("byteBuffer");
+        }
+
+        @Override
+        <ReturnT> ReturnT value(int columnIndex) {
+            return columnIndex == 0 
+                    ? (ReturnT) nodeName
+                    : (ReturnT) view.columns().get(columnIndex - 
1).value().apply(source);
+        }
+    }
+
+    private static class ClusterViewRow<T> extends AbstractViewRow {
+        private final SystemView<T> view;
+        private final T source;
+
+        private ClusterViewRow(SystemView<T> view, T source) {
+            this.view = view;
+            this.source = source;
+        }
+
+        @Override
+        public int elementCount() {
+            return view.columns().size();
+        }
+
+        @Override
+        public ByteBuffer byteBuffer() {
+            throw new UnsupportedOperationException("byteBuffer");
+        }
+
+        @Override
+        <ReturnT> ReturnT value(int columnIndex) {
+            return (ReturnT) 
view.columns().get(columnIndex).value().apply(source);
+        }
+    }
+
+    private abstract static class AbstractViewRow implements InternalTuple {
+        abstract <T> T value(int columnIndex);
+
+        @Override
+        public boolean hasNullValue(int columnIndex) {
+            return value(columnIndex) == null;
+        }
+
+        @Override
+        public boolean booleanValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Boolean booleanValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public byte byteValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Byte byteValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public short shortValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Short shortValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public int intValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Integer intValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public long longValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Long longValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public float floatValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Float floatValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public double doubleValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Double doubleValueBoxed(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public BigDecimal decimalValue(int columnIndex, int scale) {
+            BigDecimal value = value(columnIndex);
+
+            return value.setScale(scale, RoundingMode.UNNECESSARY);
+        }
+
+        @Override
+        public String stringValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public byte[] bytesValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public UUID uuidValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public LocalDate dateValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public LocalTime timeValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public LocalDateTime dateTimeValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Instant timestampValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Period periodValue(int columnIndex) {
+            return value(columnIndex);
+        }
+
+        @Override
+        public Duration durationValue(int columnIndex) {
+            return value(columnIndex);
+        }

Review Comment:
   The NodeViewRow, ClusterViewRow, and AbstractViewRow classes lack JavaDoc 
documentation. Consider adding class-level documentation explaining that these 
classes implement late materialization for system view rows and how they differ 
from the previous BinaryTuple-based approach.



##########
modules/core/src/main/java/org/apache/ignite/internal/util/FlatteningIterator.java:
##########
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.util;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * An iterator which implements FLAT MAP operation on the input. 
+ */
+public class FlatteningIterator<T> implements Iterator<T>, AutoCloseable {
+    private final Iterator<? extends Iterable<T>> source;
+
+    private @Nullable Iterator<T> current;
+
+    /** Constructs the object. */
+    public FlatteningIterator(Iterator<? extends Iterable<T>> source) {
+        this.source = source;
+    }
+
+    @Override
+    public boolean hasNext() {
+        do {
+            if (current != null) {
+                if (current.hasNext()) {
+                    return true;
+                }
+
+                // current is completely drained, reset.
+                current = null;
+            }
+
+            if (!source.hasNext()) {
+                return false;
+            }
+
+            current = source.next().iterator();
+        } while (true);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public T next() {
+        if (!hasNext()) {
+            throw new NoSuchElementException();
+        }
+
+        assert current != null;
+
+        return current.next();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void remove() {
+        if (current == null) {
+            throw new IllegalStateException();
+        }
+
+        current.remove();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void close() throws Exception {
+        if (source instanceof AutoCloseable) {
+            ((AutoCloseable) source).close();
+        }
+    }
+}

Review Comment:
   The new FlatteningIterator class lacks test coverage. Consider adding unit 
tests to verify the iterator behavior, including edge cases such as empty 
iterables, null handling in hasNext/next, and proper AutoCloseable behavior.



##########
modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/SystemViewsBenchmark.java:
##########
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.benchmark;
+
+import java.io.IOException;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.sql.IgniteSql;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark that runs sql queries over system views to measure its 
performance.
+ */
+@State(Scope.Benchmark)
+@Fork(1)
+@Threads(1)
+@Warmup(iterations = 10, time = 2)
+@Measurement(iterations = 20, time = 2)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@SuppressWarnings({"WeakerAccess", "unused"})
+public class SystemViewsBenchmark extends AbstractMultiNodeBenchmark {
+    private IgniteSql sql;
+
+    @Param("3")
+    private int clusterSize;
+
+    /** Fills the table with data. */
+    @Setup
+    public void setUp() throws IOException {
+        sql = publicIgnite.sql();
+    }
+
+    /** Benchmark to measure performance of queries over TABLE-COLUMNS system 
view. */
+    @Benchmark
+    @OutputTimeUnit(TimeUnit.MICROSECONDS)
+    public void getPrimaryKeys(FiveHundredTablesState state, Blackhole bh) {
+        try (var rs = sql.execute(null, "SELECT column_name \n"
+                + "FROM SYSTEM.table_columns \n"
+                + "WHERE table_name = ? \n"
+                + "AND pk_column_ordinal IS NOT NULL;", state.tableName())) {
+            while (rs.hasNext()) {
+                bh.consume(rs.next());
+            }
+        }
+    }
+
+    /** Benchmark to measure performance of queries over TABLE-COLUMNS system 
view. */
+    @Benchmark
+    @OutputTimeUnit(TimeUnit.MICROSECONDS)
+    public void getColumnsType(FiveHundredTablesState state, Blackhole bh) {
+        try (var rs = sql.execute(null, "SELECT column_name,column_type\n"
+                + "FROM SYSTEM.table_columns  \n"

Review Comment:
   Trailing whitespace detected at the end of the line. Please remove it to 
maintain code cleanliness.
   ```suggestion
                   + "FROM SYSTEM.table_columns\n"
   ```



##########
modules/core/src/main/java/org/apache/ignite/internal/util/FlatteningIterator.java:
##########
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.util;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * An iterator which implements FLAT MAP operation on the input. 

Review Comment:
   Trailing whitespace detected at the end of the JavaDoc comment. Please 
remove it to maintain code cleanliness.
   ```suggestion
    * An iterator which implements FLAT MAP operation on the input.
   ```



##########
modules/runner/src/integrationTest/java/org/apache/ignite/internal/benchmark/SystemViewsBenchmark.java:
##########
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package org.apache.ignite.internal.benchmark;
+
+import java.io.IOException;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.concurrent.TimeUnit;
+import org.apache.ignite.sql.IgniteSql;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.infra.Blackhole;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+
+/**
+ * Benchmark that runs sql queries over system views to measure its 
performance.
+ */
+@State(Scope.Benchmark)
+@Fork(1)
+@Threads(1)
+@Warmup(iterations = 10, time = 2)
+@Measurement(iterations = 20, time = 2)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@SuppressWarnings({"WeakerAccess", "unused"})
+public class SystemViewsBenchmark extends AbstractMultiNodeBenchmark {
+    private IgniteSql sql;
+
+    @Param("3")
+    private int clusterSize;
+
+    /** Fills the table with data. */
+    @Setup
+    public void setUp() throws IOException {
+        sql = publicIgnite.sql();
+    }
+
+    /** Benchmark to measure performance of queries over TABLE-COLUMNS system 
view. */
+    @Benchmark
+    @OutputTimeUnit(TimeUnit.MICROSECONDS)
+    public void getPrimaryKeys(FiveHundredTablesState state, Blackhole bh) {
+        try (var rs = sql.execute(null, "SELECT column_name \n"
+                + "FROM SYSTEM.table_columns \n"
+                + "WHERE table_name = ? \n"
+                + "AND pk_column_ordinal IS NOT NULL;", state.tableName())) {
+            while (rs.hasNext()) {
+                bh.consume(rs.next());
+            }
+        }
+    }
+
+    /** Benchmark to measure performance of queries over TABLE-COLUMNS system 
view. */
+    @Benchmark
+    @OutputTimeUnit(TimeUnit.MICROSECONDS)
+    public void getColumnsType(FiveHundredTablesState state, Blackhole bh) {
+        try (var rs = sql.execute(null, "SELECT column_name,column_type\n"
+                + "FROM SYSTEM.table_columns  \n"
+                + "WHERE table_name = ?;", state.tableName())) {
+            while (rs.hasNext()) {
+                bh.consume(rs.next());
+            }
+        }
+    }
+
+    /** State that creates 500 tables with 10 columns each and 2 columns 
primary key. */
+    @State(Scope.Benchmark)
+    public static class FiveHundredTablesState {
+        private static final int TABLES_COUNT = 500;
+
+        /** Creates necessary tables. */
+        @Setup
+        public void setUp() throws IOException {
+            IgniteSql sql = publicIgnite.sql();
+
+            int columnsCount = 10;
+
+            StringBuilder scriptBuilder = new StringBuilder(
+                    "CREATE ZONE my_zone (PARTITIONS 1, REPLICAS 1) STORAGE 
PROFILES ['default'];"
+            ).append("ALTER ZONE my_zone SET DEFAULT;");
+
+            for (int t = 0; t < TABLES_COUNT; t++) {
+                scriptBuilder.append("CREATE TABLE 
my_table_").append(t).append("(");
+
+                for (int c = 0; c < columnsCount; c++) {
+                    if (c > 0) {
+                        scriptBuilder.append(", ");
+                    }
+
+                    scriptBuilder.append("c_").append(c).append(" INT");
+                }
+
+                scriptBuilder.append(", PRIMARY KEY (c_1, c_2));");
+            }
+
+            sql.executeScript(scriptBuilder.toString());
+        }
+
+        @SuppressWarnings("MethodMayBeStatic")
+        String tableName() {
+            return "MY_TABLE_" + 
ThreadLocalRandom.current().nextInt(TABLES_COUNT);
+        }
+    }
+
+    /**
+     * Benchmark's entry point.
+     */
+    public static void main(String[] args) throws RunnerException {
+        Options opt = new OptionsBuilder()
+                .include(".*" + SystemViewsBenchmark.class.getSimpleName() + 
".*")
+                .build();
+
+        new Runner(opt).run();
+    }
+
+    @Override
+    protected void createDistributionZoneOnStartup() {
+        // NO-OP
+    }
+
+    @Override
+    protected void createTablesOnStartup() {
+        // NO-OP
+    }
+
+    @Override
+    protected int nodes() {
+        return clusterSize;
+    }
+}
+
+

Review Comment:
   Extra blank lines at the end of the file. Please remove them to maintain 
consistent formatting.
   ```suggestion
   
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to