Index: modules/indexing/src/test/java/org/apache/ignite/internal/systemview/SqlIndexSystemViewReproducerTest.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/systemview/SqlIndexSystemViewReproducerTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/systemview/SqlIndexSystemViewReproducerTest.java
new file mode 100644
--- /dev/null	(date 1656609744723)
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/systemview/SqlIndexSystemViewReproducerTest.java	(date 1656609744723)
@@ -0,0 +1,253 @@
+package org.apache.ignite.internal.systemview;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.apache.ignite.Ignition;
+import org.apache.ignite.cache.QueryEntity;
+import org.apache.ignite.cache.affinity.AffinityKeyMapped;
+import org.apache.ignite.cache.query.FieldsQueryCursor;
+import org.apache.ignite.cache.query.SqlFieldsQuery;
+import org.apache.ignite.cache.query.annotations.QuerySqlField;
+import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.configuration.CacheConfiguration;
+import org.apache.ignite.configuration.ClientConfiguration;
+import org.apache.ignite.configuration.ClientConnectorConfiguration;
+import org.apache.ignite.configuration.IgniteConfiguration;
+import org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing;
+import org.apache.ignite.internal.processors.query.h2.SchemaManager;
+import org.apache.ignite.internal.processors.query.h2.opt.GridH2Table;
+import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
+import org.junit.Test;
+
+/**
+ *
+ */
+public class SqlIndexSystemViewReproducerTest extends GridCommonAbstractTest {
+    /** Person table. */
+    public static final String PERSON_TABLE = "PERSON";
+
+    /** Person cache. */
+    public static final String PERSON_CACHE = "PersonCache";
+
+    /** Select all. */
+    public static final String SELECT_ALL = "select * from person order by \"ID\";";
+
+    /** System view tables. */
+    public static final String SYS_VIEW_TABLES = "select * from sys.tables;";
+
+    /** System view table columns. */
+    public static final String SYS_VIEW_TABLE_COLUMNS = "select * from sys.table_columns;";
+
+    /** System view binary metadata. */
+    public static final String SYS_VIEW_BINARY_METADATA = "select * from sys.binary_metadata;";
+
+    /** System view indexes. */
+    public static final String SYS_VIEW_INDEXES = "select * from sys.indexes;";
+
+    /** {@inheritDoc} */
+    @Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
+        IgniteConfiguration cfg = super.getConfiguration(igniteInstanceName);
+
+        cfg.setClientConnectorConfiguration(new ClientConnectorConfiguration());
+
+        return cfg;
+    }
+
+    /** */
+    @Test
+    public void test() throws Exception {
+        cleanPersistenceDir();
+        startGrid(0);
+
+        createCacheWithQueryEntity();
+        populateData();
+
+        dumpGridH2TableIndexes();
+
+        List<Map<String, String>> allValuesQryEntity = resultSet(SELECT_ALL);
+        List<Map<String, String>> tablesQryEntity = resultSet(SYS_VIEW_TABLES);
+        List<Map<String, String>> tableColumnsQryEntity = resultSet(SYS_VIEW_TABLE_COLUMNS);
+        List<Map<String, String>> binaryMetadataQryEntity = resultSet(SYS_VIEW_BINARY_METADATA);
+        List<Map<String, String>> indexesViewQryEntity = resultSet(SYS_VIEW_INDEXES);
+
+//        doSleep(60_000);
+
+        stopAllGrids();
+        cleanPersistenceDir();
+        startGrid(0);
+
+        createTableAndIndex();
+        populateData();
+
+        dumpGridH2TableIndexes();
+
+        List<Map<String, String>> allValuesDdl = resultSet(SELECT_ALL);
+        List<Map<String, String>> tablesDdl = resultSet(SYS_VIEW_TABLES);
+        List<Map<String, String>> tableColumnsDdl= resultSet(SYS_VIEW_TABLE_COLUMNS);
+        List<Map<String, String>> binaryMetadataDdl= resultSet(SYS_VIEW_BINARY_METADATA);
+        List<Map<String, String>> indexesViewDdl = resultSet(SYS_VIEW_INDEXES);
+
+        // Compare select all
+        for (int i = 0; i < allValuesQryEntity.size(); i++)
+            assertEqualsMaps(allValuesQryEntity.get(i), allValuesDdl.get(i));
+
+        // Compare tables view
+        for (int i = 0; i < tablesQryEntity.size(); i++)
+            assertEqualsMaps(tablesQryEntity.get(i), tablesDdl.get(i));
+
+        // Compare table columns view
+        for (int i = 0; i < tableColumnsQryEntity.size(); i++)
+            assertEqualsMaps(tableColumnsQryEntity.get(i), tableColumnsDdl.get(i));
+
+        // Compare table columns view
+        for (int i = 0; i < binaryMetadataQryEntity.size(); i++)
+            assertEqualsMaps(binaryMetadataQryEntity.get(i), binaryMetadataDdl.get(i));
+
+//        doSleep(60_000);
+
+        // Compare indexes
+        for (int i = 0; i < indexesViewQryEntity.size(); i++)
+            assertEqualsMaps(indexesViewQryEntity.get(i), indexesViewDdl.get(i));
+    }
+
+    /** */
+    private void dumpGridH2TableIndexes() {
+        SchemaManager mgr = ((IgniteH2Indexing)grid(0).context().query().getIndexing()).schemaManager();
+
+        Collection<GridH2Table> tables = mgr.dataTables();
+
+        for (GridH2Table table : tables)
+            log.warning(">>>>>> Cache's \"" + table.cacheName() + "\" indexes:\n" +
+                String.format("%-25.30s%s\n", "Index name", "Columns") +
+                table.getIndexes().stream()
+                    .map(idx -> String.format("%-25.30s%s",
+                        idx.getName(), Arrays.toString(idx.getColumns())))
+                    .collect(Collectors.joining("\n")));
+    }
+
+    /** */
+    private void populateData() {
+        grid(0).cache(PERSON_CACHE).put(new PersonKey(2, "Jane", "Doe"),
+            new PersonInfo("OtherOrg", "Other City", 14000.0));
+
+        // Insert via SQL
+        grid(0).context().query().querySqlFields(new SqlFieldsQuery("INSERT INTO person VALUES (?, ?, ?, ?, ?, ?)").
+            setArgs(1, "John", "Doe", "OrgInc", "Default City", 12000.0), false);
+    }
+
+    /** */
+    private List<Map<String, String>> resultSet(String sql) {
+        List<Map<String, String>> res = new ArrayList<>();
+
+        try (IgniteClient client = Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10800..10810"))) {
+            FieldsQueryCursor<List<?>> qryCur = client.query(new SqlFieldsQuery(sql));
+
+
+            for (List<?> row0 : qryCur) {
+                Map<String, String> rowMap = new LinkedHashMap<>(row0.size());
+
+                for (int i = 0; i < row0.size(); i++)
+                    rowMap.put(qryCur.getFieldName(i), String.valueOf(row0.get(i)));
+
+                res.add(rowMap);
+            }
+        }
+
+        return res;
+    }
+
+    /** */
+    private void createCacheWithQueryEntity() {
+        log.warning(">>>>>> Creating cache with query entity");
+
+        QueryEntity qryEntity = new QueryEntity(PersonKey.class, PersonInfo.class).setTableName(PERSON_TABLE);
+        CacheConfiguration<Object, Object> cacheCfg = new CacheConfiguration<>(PERSON_CACHE)
+            .setQueryEntities(Collections.singleton(qryEntity))
+            .setSqlSchema("public");
+        grid(0).getOrCreateCache(cacheCfg);
+    }
+
+    /** */
+    private void createTableAndIndex() {
+        String createTblSql = "CREATE TABLE " + PERSON_TABLE + " (" +
+            "id BIGINT, " +
+            "firstName VARCHAR, " +
+            "lastName VARCHAR, " +
+            "orgName VARCHAR, " +
+            "cityName VARCHAR, " +
+            "salary DOUBLE, " +
+            "PRIMARY KEY (id, firstName, lastName)) " +
+            "WITH \"" +
+            "AFFINITY_KEY=id," +
+            "CACHE_NAME=" + PERSON_CACHE + "," +
+            "KEY_TYPE=" + PersonKey.class.getName() + "," +
+            "VALUE_TYPE=" + PersonInfo.class.getName() +
+            "\"";
+
+        log.warning(">>>>>> Creating cache with DDL:\n" + createTblSql);
+
+        grid(0).context().query().querySqlFields(new SqlFieldsQuery(createTblSql), false);
+
+        grid(0).context().query().querySqlFields(new SqlFieldsQuery("CREATE INDEX PERSONINFO_CITYNAME_IDX ON person (cityName)"),
+            false);
+    }
+
+    /** */
+    private static class PersonKey {
+        /** Id. */
+        @AffinityKeyMapped
+        @QuerySqlField
+        private final long ID;
+
+        /** First name. */
+        @QuerySqlField
+        private final String firstName;
+
+        /** Last name. */
+        @QuerySqlField
+        private final String lastName;
+
+        /**
+         * @param ID Id.
+         * @param firstName First name.
+         * @param lastName Last name.
+         */
+        private PersonKey(long ID, String firstName, String lastName) {
+            this.ID = ID;
+            this.firstName = firstName;
+            this.lastName = lastName;
+        }
+    }
+
+    /** */
+    private static class PersonInfo {
+        /** Org name. */
+        @QuerySqlField
+        private final String orgName;
+
+        /** City name. */
+        @QuerySqlField(index = true)
+        private final String cityName;
+
+        /** Salary. */
+        @QuerySqlField
+        private final double salary;
+
+        /**
+         * @param orgName Org name.
+         * @param cityName City name.
+         * @param salary Salary.
+         */
+        private PersonInfo(String orgName, String cityName, double salary) {
+            this.orgName = orgName;
+            this.cityName = cityName;
+            this.salary = salary;
+        }
+    }
+}
