presto-main/src/main/java/io/prestosql/connector/informationschema/InformationSchemaPageSource.java/InformationSchemaPageSource/InformationSchemaPageSource
class InformationSchemaPageSource:    public InformationSchemaPageSource(
            Session session,
            Metadata metadata,
            AccessControl accessControl,
            InformationSchemaTableHandle tableHandle,
            List<ColumnHandle> columns)
    {
        this.session = requireNonNull(session, "session is null");
        this.metadata = requireNonNull(metadata, "metadata is null");
        this.accessControl = requireNonNull(accessControl, "accessControl is null");
        requireNonNull(tableHandle, "tableHandle is null");
        requireNonNull(columns, "columns is null");

        catalogName = tableHandle.getCatalogName();
        table = tableHandle.getTable();
        prefixIterator = Suppliers.memoize(() -> {
            Set<QualifiedTablePrefix> prefixes = tableHandle.getPrefixes();
            if (isTablesEnumeratingTable(table)) {
                if (prefixes.equals(defaultPrefixes(catalogName))) {
                    prefixes = metadata.listSchemaNames(session, catalogName).stream()
                            .map(schema -> new QualifiedTablePrefix(catalogName, schema))
                            .collect(toImmutableSet());
                }
            }
            else {
                checkArgument(prefixes.equals(defaultPrefixes(catalogName)), "Catalog-wise tables have prefixes other than the default one");
            }
            return prefixes.iterator();
        });
        limit = tableHandle.getLimit();

        List<ColumnMetadata> columnMetadata = table.getTableMetadata().getColumns();

        types = columnMetadata.stream()
                .map(ColumnMetadata::getType)
                .collect(toImmutableList());

        pageBuilder = new PageBuilder(types);

        Map<String, Integer> columnNameToChannel = IntStream.range(0, columnMetadata.size())
                .boxed()
                .collect(toImmutableMap(i -> columnMetadata.get(i).getName(), Function.identity()));

        List<Integer> channels = columns.stream()
                .map(columnHandle -> (InformationSchemaColumnHandle) columnHandle)
                .map(columnHandle -> columnNameToChannel.get(columnHandle.getColumnName()))
                .collect(toImmutableList());

        projection = page -> {
            Block[] blocks = new Block[channels.size()];
            for (int i = 0; i < blocks.length; i++) {
                blocks[i] = page.getBlock(channels.get(i));
            }
            return new Page(page.getPositionCount(), blocks);
        };
    }