class SqlIndexView {
    /** Table. */
    private final TableDescriptor tbl;

    /** Index. */
    private final IndexDescriptor idx;

    /**
     * @param tbl Table information.
     * @param idx Index information.
     */
    public SqlIndexView(TableDescriptor tbl, IndexDescriptor idx) {
        this.tbl = tbl;
        this.idx = idx;
    }

    /**
     * Returns cache group ID.
     *
     * @return Cache group ID.
     */
    @Order()
    public int cacheGroupId() {
        return tbl.cacheInfo().groupId();
    }

    /**
     * Returns Cache group name.
     *
     * @return Cache group name.
     */
    @Order(1)
    public String cacheGroupName() {
        return tbl.cacheInfo().groupName();
    }

    /**
     * Returns cache ID.
     * @return Cache ID.
     */
    @Order(2)
    public int cacheId() {
        return tbl.cacheInfo().cacheId();
    }

    /**
     * Returns cache name.
     *
     * @return Cache name.
     */
    @Order(3)
    public String cacheName() {
        return tbl.cacheInfo().name();
    }

    /**
     *  Returns schema name.
     *
     * @return Schema name.
     */
    @Order(4)
    public String schemaName() {
        return tbl.type().schemaName();
    }

    /**
     * Returns table name.
     *
     * @return Table name.
     */
    @Order(5)
    public String tableName() {
        return tbl.type().tableName();
    }

    /**
     * Returns index name.
     *
     * @return Index name.
     */
    @Order(6)
    public String indexName() {
        return idx.name();
    }

    /**
     * Returns index type.
     *
     * @return Index type.
     */
    @Order(7)
    public String indexType() {
        return idx.type().name();
    }

    /**
     * Returns all columns on which index is built.
     *
     * @return Coma separated indexed columns.
     */
    @Order(8)
    public String columns() {<FILL_FUNCTION_BODY>}

    /**
     * Returns boolean value which indicates whether this index is for primary key or not.
     *
     * @return {@code True} if primary key index, {@code false} otherwise.
     */
    @Order(9)
    public boolean isPk() {
        return idx.isPk();
    }

    /**
     * Returns boolean value which indicates whether this index is unique or not.
     *
     * @return {@code True} if unique index, {@code false} otherwise.
     */
    @Order(10)
    public boolean isUnique() {
        return idx.isPk() || (idx.isProxy() && idx.targetIdx().isPk());
    }

    /**
     * Returns inline size in bytes.
     *
     * @return Inline size.
     */
    @Order(11)
    public Integer inlineSize() {
        return idx.inlineSize();
    }
}

        return idx.keyDefinitions().entrySet().stream()
            .map(fld -> '"' + fld.getKey() + '"' +
                (fld.getValue().order().sortOrder() == SortOrder.DESC ? " DESC" : " ASC"))
            .collect(Collectors.joining(", "));
    
<no_super_class>