You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by an...@apache.org on 2015/12/01 10:02:45 UTC

[33/50] [abbrv] ignite git commit: IGNITE-843 Merge branch 'master' into ignite-843-rc1.

http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/modules/schema-import-db/pom.xml
----------------------------------------------------------------------
diff --cc modules/schema-import-db/pom.xml
index 6d0dc2c,0000000..3b9d7e6
mode 100644,000000..100644
--- a/modules/schema-import-db/pom.xml
+++ b/modules/schema-import-db/pom.xml
@@@ -1,39 -1,0 +1,46 @@@
 +<?xml version="1.0" encoding="UTF-8"?>
 +
 +<!--
 +  ~ /*
 +  ~  * 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.
 +  ~  */
 +  -->
 +
 +<!--
 +    POM file.
 +-->
 +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
 +         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 +    <modelVersion>4.0.0</modelVersion>
 +
 +    <parent>
 +        <groupId>org.apache.ignite</groupId>
 +        <artifactId>ignite-parent</artifactId>
 +        <version>1</version>
 +        <relativePath>../../parent</relativePath>
 +    </parent>
 +
 +    <artifactId>ignite-schema-import-db</artifactId>
 +    <version>1.5.0-SNAPSHOT</version>
 +
++    <dependencies>
++        <dependency>
++            <groupId>org.apache.ignite</groupId>
++            <artifactId>ignite-core</artifactId>
++            <version>${project.version}</version>
++        </dependency>
++    </dependencies>
 +</project>

http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbTable.java
----------------------------------------------------------------------
diff --cc modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbTable.java
index 6ec9d1f,0000000..cc321c1
mode 100644,000000..100644
--- a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbTable.java
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/DbTable.java
@@@ -1,109 -1,0 +1,84 @@@
 +/*
 + *
 + *  * 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.schema.parser;
 +
++import org.apache.ignite.cache.QueryIndex;
++
 +import java.util.Collection;
- import java.util.Map;
- import java.util.Set;
 +
 +/**
 + * Database table.
 + */
 +public class DbTable {
 +    /** Schema name. */
 +    private final String schema;
 +
 +    /** Table name. */
 +    private final String tbl;
 +
 +    /** Columns. */
 +    private final Collection<DbColumn> cols;
 +
-     /** Columns in ascending order. */
-     private final Set<String> ascCols;
- 
-     /** Columns in descending order. */
-     private final Set<String> descCols;
- 
 +    /** Indexes. */
-     private final Map<String, Map<String, Boolean>> idxs;
++    private final Collection<QueryIndex> idxs;
 +
 +    /**
 +     * Default columns.
 +     *
 +     * @param schema Schema name.
 +     * @param tbl Table name.
 +     * @param cols Columns.
-      * @param ascCols Columns in ascending order.
-      * @param descCols Columns in descending order.
 +     * @param idxs Indexes;
 +     */
-     public DbTable(String schema, String tbl, Collection<DbColumn> cols, Set<String> ascCols, Set<String> descCols,
-         Map<String, Map<String, Boolean>> idxs) {
++    public DbTable(String schema, String tbl, Collection<DbColumn> cols, Collection<QueryIndex> idxs) {
 +        this.schema = schema;
 +        this.tbl = tbl;
 +        this.cols = cols;
-         this.ascCols = ascCols;
-         this.descCols = descCols;
 +        this.idxs = idxs;
 +    }
 +
 +    /**
 +     * @return Schema name.
 +     */
 +    public String schema() {
 +        return schema;
 +    }
 +
 +    /**
 +     * @return Table name.
 +     */
 +    public String table() {
 +        return tbl;
 +    }
 +
 +    /**
 +     * @return Columns.
 +     */
 +    public Collection<DbColumn> columns() {
 +        return cols;
 +    }
 +
 +    /**
-      * @return Fields in ascending order
-      */
-     public Set<String> ascendingColumns() {
-         return ascCols;
-     }
- 
-     /**
-      * @return Fields in descending order
-      */
-     public Set<String> descendingColumns() {
-         return descCols;
-     }
- 
-     /**
 +     * @return Indexes.
 +     */
-     public Map<String, Map<String, Boolean>> indexes() {
++    public Collection<QueryIndex> indexes() {
 +        return idxs;
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java
----------------------------------------------------------------------
diff --cc modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java
index db8adfd,0000000..fad5b0e
mode 100644,000000..100644
--- a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/DatabaseMetadataDialect.java
@@@ -1,97 -1,0 +1,77 @@@
 +/*
 + *
 + *  * 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.schema.parser.dialect;
 +
 +import java.sql.Connection;
 +import java.sql.SQLException;
 +import java.util.Collection;
 +import java.util.Collections;
- import java.util.HashSet;
 +import java.util.List;
- import java.util.Map;
 +import java.util.Set;
++
++import org.apache.ignite.cache.QueryIndex;
 +import org.apache.ignite.schema.parser.DbColumn;
 +import org.apache.ignite.schema.parser.DbTable;
 +
 +/**
 + * Base class for database metadata dialect.
 + */
 +public abstract class DatabaseMetadataDialect {
 +    /**
 +     * Gets schemas from database.
 +     *
 +     * @param conn Database connection.
 +     * @return Collection of schema descriptors.
 +     * @throws SQLException If failed to get schemas.
 +     */
 +    public abstract Collection<String> schemas(Connection conn) throws SQLException;
 +
 +    /**
 +     * Gets tables from database.
 +     *
 +     * @param conn Database connection.
-      * @param schemas Collention of schema names to load.
++     * @param schemas Collection of schema names to load.
 +     * @param tblsOnly If {@code true} then gets only tables otherwise gets tables and views.
 +     * @return Collection of table descriptors.
 +     * @throws SQLException If failed to get tables.
 +     */
 +    public abstract Collection<DbTable> tables(Connection conn, List<String> schemas, boolean tblsOnly)
 +        throws SQLException;
 +
 +    /**
 +     * @return Collection of database system schemas.
 +     */
 +    public Set<String> systemSchemas() {
 +        return Collections.singleton("INFORMATION_SCHEMA");
 +    }
 +
 +    /**
 +     * Create table descriptor.
 +     *
 +     * @param schema Schema name.
 +     * @param tbl Table name.
 +     * @param cols Table columns.
 +     * @param idxs Table indexes.
 +     * @return New {@code DbTable} instance.
 +     */
-     protected DbTable table(String schema, String tbl, Collection<DbColumn> cols, Map<String, Map<String, Boolean>>idxs) {
-         Set<String> ascCols = new HashSet<>();
- 
-         Set<String> descCols = new HashSet<>();
- 
-         for (Map<String, Boolean> idx : idxs.values()) {
-             if (idx.size() == 1)
-                 for (Map.Entry<String, Boolean> idxCol : idx.entrySet()) {
-                     String colName = idxCol.getKey();
- 
-                     Boolean desc = idxCol.getValue();
- 
-                     if (desc != null) {
-                         if (desc)
-                             descCols.add(colName);
-                         else
-                             ascCols.add(colName);
-                     }
-                 }
-         }
- 
-         return new DbTable(schema, tbl, cols, ascCols, descCols, idxs);
++    protected DbTable table(String schema, String tbl, Collection<DbColumn> cols, Collection<QueryIndex>idxs) {
++        return new DbTable(schema, tbl, cols, idxs);
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java
----------------------------------------------------------------------
diff --cc modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java
index f315481,0000000..c3ffa32
mode 100644,000000..100644
--- a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/JdbcMetadataDialect.java
@@@ -1,193 -1,0 +1,199 @@@
 +/*
 + *
 + *  * 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.schema.parser.dialect;
 +
 +import java.sql.Connection;
 +import java.sql.DatabaseMetaData;
 +import java.sql.ResultSet;
 +import java.sql.SQLException;
 +import java.util.ArrayList;
 +import java.util.Collection;
 +import java.util.HashSet;
 +import java.util.LinkedHashMap;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
++
++import org.apache.ignite.cache.QueryIndex;
++import org.apache.ignite.cache.QueryIndexType;
 +import org.apache.ignite.schema.parser.DbColumn;
 +import org.apache.ignite.schema.parser.DbTable;
 +
 +/**
 + * Metadata dialect that uses standard JDBC for reading metadata.
 + */
 +public class JdbcMetadataDialect extends DatabaseMetadataDialect {
 +    /** */
 +    private static final String[] TABLES_ONLY = {"TABLE"};
 +
 +    /** */
 +    private static final String[] TABLES_AND_VIEWS = {"TABLE", "VIEW"};
 +
 +    /** Schema catalog index. */
 +    private static final int TBL_CATALOG_IDX = 1;
 +
 +    /** Schema name index. */
 +    private static final int TBL_SCHEMA_IDX = 2;
 +
 +    /** Table name index. */
 +    private static final int TBL_NAME_IDX = 3;
 +
 +    /** Primary key column name index. */
 +    private static final int PK_COL_NAME_IDX = 4;
 +
 +    /** Column name index. */
 +    private static final int COL_NAME_IDX = 4;
 +
 +    /** Column data type index. */
 +    private static final int COL_DATA_TYPE_IDX = 5;
 +
 +    /** Column nullable index. */
 +    private static final int COL_NULLABLE_IDX = 11;
 +
 +    /** Index name index. */
 +    private static final int IDX_NAME_IDX = 6;
 +
 +    /** Index column name index. */
 +    private static final int IDX_COL_NAME_IDX = 9;
 +
 +    /** Index column descend index. */
 +    private static final int IDX_ASC_OR_DESC_IDX = 10;
 +
 +    /** {@inheritDoc} */
 +    @Override public Collection<String> schemas(Connection conn) throws SQLException {
 +        Collection<String> schemas = new ArrayList<>();
 +
 +        ResultSet rs = conn.getMetaData().getSchemas();
 +
 +        Set<String> sys = systemSchemas();
 +
 +        while(rs.next()) {
 +            String schema = rs.getString(1);
 +
 +            // Skip system schemas.
 +            if (sys.contains(schema))
 +                continue;
 +
 +            schemas.add(schema);
 +        }
 +
 +        return schemas;
 +    }
 +
 +    /**
 +     * @return If {@code true} use catalogs for table division.
 +     */
 +    protected boolean useCatalog() {
 +        return false;
 +    }
 +
 +    /**
 +     * @return If {@code true} use schemas for table division.
 +     */
 +    protected boolean useSchema() {
 +        return true;
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Collection<DbTable> tables(Connection conn, List<String> schemas, boolean tblsOnly)
 +        throws SQLException {
 +        DatabaseMetaData dbMeta = conn.getMetaData();
 +
 +        Set<String> sys = systemSchemas();
 +
 +        Collection<DbTable> tbls = new ArrayList<>();
 +
-         if (schemas.size() == 0)
++        if (schemas.isEmpty())
 +            schemas.add(null);
 +
 +        for (String toSchema: schemas) {
 +            try (ResultSet tblsRs = dbMeta.getTables(useCatalog() ? toSchema : null, useSchema() ? toSchema : null, "%",
 +                    tblsOnly ? TABLES_ONLY : TABLES_AND_VIEWS)) {
 +                while (tblsRs.next()) {
 +                    String tblCatalog = tblsRs.getString(TBL_CATALOG_IDX);
 +                    String tblSchema = tblsRs.getString(TBL_SCHEMA_IDX);
 +                    String tblName = tblsRs.getString(TBL_NAME_IDX);
 +
 +                    // In case of MySql we should use catalog.
 +                    String schema = tblSchema != null ? tblSchema : tblCatalog;
 +
 +                    // Skip system schemas.
 +                    if (sys.contains(schema))
 +                        continue;
 +
 +                    Set<String> pkCols = new HashSet<>();
 +
 +                    try (ResultSet pkRs = dbMeta.getPrimaryKeys(tblCatalog, tblSchema, tblName)) {
 +                        while (pkRs.next())
 +                            pkCols.add(pkRs.getString(PK_COL_NAME_IDX));
 +                    }
 +
 +                    List<DbColumn> cols = new ArrayList<>();
 +
 +                    try (ResultSet colsRs = dbMeta.getColumns(tblCatalog, tblSchema, tblName, null)) {
 +                        while (colsRs.next()) {
 +                            String colName = colsRs.getString(COL_NAME_IDX);
 +
 +                            cols.add(new DbColumn(
 +                                    colName,
 +                                    colsRs.getInt(COL_DATA_TYPE_IDX),
 +                                    pkCols.contains(colName),
 +                                    colsRs.getInt(COL_NULLABLE_IDX) == DatabaseMetaData.columnNullable));
 +                        }
 +                    }
 +
-                     Map<String, Map<String, Boolean>> idxs = new LinkedHashMap<>();
++                    Map<String, QueryIndex> idxs = new LinkedHashMap<>();
 +
 +                    try (ResultSet idxRs = dbMeta.getIndexInfo(tblCatalog, tblSchema, tblName, false, true)) {
 +                        while (idxRs.next()) {
 +                            String idxName = idxRs.getString(IDX_NAME_IDX);
 +
 +                            String colName = idxRs.getString(IDX_COL_NAME_IDX);
 +
 +                            if (idxName == null || colName == null)
 +                                continue;
 +
-                             Map<String, Boolean> idx = idxs.get(idxName);
++                            QueryIndex idx = idxs.get(idxName);
 +
 +                            if (idx == null) {
-                                 idx = new LinkedHashMap<>();
++                                idx = new QueryIndex();
++                                idx.setName(idxName);
++                                idx.setIndexType(QueryIndexType.SORTED);
++                                idx.setFields(new LinkedHashMap<String, Boolean>());
 +
 +                                idxs.put(idxName, idx);
 +                            }
 +
 +                            String askOrDesc = idxRs.getString(IDX_ASC_OR_DESC_IDX);
 +
-                             Boolean desc = askOrDesc != null ? "D".equals(askOrDesc) : null;
++                            Boolean asc = askOrDesc == null || "A".equals(askOrDesc);
 +
-                             idx.put(colName, desc);
++                            idx.getFields().put(colName, asc);
 +                        }
 +                    }
 +
-                     tbls.add(table(schema, tblName, cols, idxs));
++                    tbls.add(table(schema, tblName, cols, idxs.values()));
 +                }
 +            }
 +        }
 +
 +        return tbls;
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java
----------------------------------------------------------------------
diff --cc modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java
index 3f10672,0000000..9456b53
mode 100644,000000..100644
--- a/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java
+++ b/modules/schema-import-db/src/main/java/org/apache/ignite/schema/parser/dialect/OracleMetadataDialect.java
@@@ -1,360 -1,0 +1,366 @@@
 +/*
 + *
 + *  * 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.schema.parser.dialect;
 +
 +import java.sql.Connection;
 +import java.sql.PreparedStatement;
 +import java.sql.ResultSet;
 +import java.sql.SQLException;
 +import java.sql.Statement;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collection;
 +import java.util.Collections;
 +import java.util.HashSet;
 +import java.util.LinkedHashMap;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Set;
++
++import org.apache.ignite.cache.QueryIndex;
++import org.apache.ignite.cache.QueryIndexType;
 +import org.apache.ignite.schema.parser.DbColumn;
 +import org.apache.ignite.schema.parser.DbTable;
 +
 +import static java.sql.Types.BIGINT;
 +import static java.sql.Types.BLOB;
 +import static java.sql.Types.BOOLEAN;
 +import static java.sql.Types.CHAR;
 +import static java.sql.Types.CLOB;
 +import static java.sql.Types.DATE;
 +import static java.sql.Types.DOUBLE;
 +import static java.sql.Types.FLOAT;
 +import static java.sql.Types.INTEGER;
 +import static java.sql.Types.LONGVARBINARY;
 +import static java.sql.Types.LONGVARCHAR;
 +import static java.sql.Types.NUMERIC;
 +import static java.sql.Types.OTHER;
 +import static java.sql.Types.SMALLINT;
 +import static java.sql.Types.SQLXML;
 +import static java.sql.Types.TIMESTAMP;
 +import static java.sql.Types.TINYINT;
 +import static java.sql.Types.VARCHAR;
 +
 +/**
 + * Oracle specific metadata dialect.
 + */
 +public class OracleMetadataDialect extends DatabaseMetadataDialect {
 +    /** SQL to get columns metadata. */
 +    private static final String SQL_COLUMNS = "SELECT a.owner, a.table_name, a.column_name, a.nullable," +
 +        " a.data_type, a.data_precision, a.data_scale " +
 +        "FROM all_tab_columns a %s " +
 +        " %s " +
 +        " ORDER BY a.owner, a.table_name, a.column_id";
 +
 +    /** SQL to get list of PRIMARY KEYS columns. */
 +    private static final String SQL_PRIMARY_KEYS = "SELECT b.column_name" +
 +        " FROM all_constraints a" +
 +        "  INNER JOIN all_cons_columns b ON a.owner = b.owner AND a.constraint_name = b.constraint_name" +
 +        " WHERE a.owner = ? and a.table_name = ? AND a.constraint_type = 'P'";
 +
 +    /** SQL to get indexes metadata. */
 +    private static final String SQL_INDEXES = "SELECT i.index_name, u.column_expression, i.column_name, i.descend" +
 +        " FROM all_ind_columns i" +
 +        " LEFT JOIN user_ind_expressions u on u.index_name = i.index_name and i.table_name = u.table_name" +
 +        " WHERE i.index_owner = ? and i.table_name = ?" +
 +        " ORDER BY i.index_name, i.column_position";
 +
 +    /** Owner index. */
 +    private static final int OWNER_IDX = 1;
 +
 +    /** Table name index. */
 +    private static final int TBL_NAME_IDX = 2;
 +
 +    /** Column name index. */
 +    private static final int COL_NAME_IDX = 3;
 +
 +    /** Nullable index. */
 +    private static final int NULLABLE_IDX = 4;
 +
 +    /** Data type index. */
 +    private static final int DATA_TYPE_IDX = 5;
 +
 +    /** Numeric precision index. */
 +    private static final int DATA_PRECISION_IDX = 6;
 +
 +    /** Numeric scale index. */
 +    private static final int DATA_SCALE_IDX = 7;
 +
 +    /** Index name index. */
 +    private static final int IDX_NAME_IDX = 1;
 +
 +    /** Index name index. */
 +    private static final int IDX_EXPR_IDX = 2;
 +
 +    /** Index column name index. */
 +    private static final int IDX_COL_NAME_IDX = 3;
 +
 +    /** Index column sort order index. */
 +    private static final int IDX_COL_DESCEND_IDX = 4;
 +
 +    /** {@inheritDoc} */
 +    @Override public Set<String> systemSchemas() {
 +        return new HashSet<>(Arrays.asList("ANONYMOUS", "CTXSYS", "DBSNMP", "EXFSYS", "LBACSYS", "MDSYS", "MGMT_VIEW",
 +            "OLAPSYS", "OWBSYS", "ORDPLUGINS", "ORDSYS", "OUTLN", "SI_INFORMTN_SCHEMA", "SYS", "SYSMAN", "SYSTEM",
 +            "TSMSYS", "WK_TEST", "WKSYS", "WKPROXY", "WMSYS", "XDB",
 +
 +            "APEX_040000", "APEX_PUBLIC_USER", "DIP", "FLOWS_30000", "FLOWS_FILES", "MDDATA", "ORACLE_OCM",
 +            "SPATIAL_CSW_ADMIN_USR", "SPATIAL_WFS_ADMIN_USR", "XS$NULL",
 +
 +            "BI", "HR", "OE", "PM", "IX", "SH"));
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Collection<String> schemas(Connection conn) throws SQLException {
 +        Collection<String> schemas = new ArrayList<>();
 +
 +        ResultSet rs = conn.getMetaData().getSchemas();
 +
 +        Set<String> sysSchemas = systemSchemas();
 +
 +        while(rs.next()) {
 +            String schema = rs.getString(1);
 +
 +            if (!sysSchemas.contains(schema) && !schema.startsWith("FLOWS_"))
 +                schemas.add(schema);
 +        }
 +
 +        return schemas;
 +    }
 +
 +    /**
 +     * @param rs Result set with column type metadata from Oracle database.
 +     * @return JDBC type.
 +     * @throws SQLException If failed to decode type.
 +     */
 +    private int decodeType(ResultSet rs) throws SQLException {
 +        String type = rs.getString(DATA_TYPE_IDX);
 +
 +        if (type.startsWith("TIMESTAMP"))
 +            return TIMESTAMP;
 +        else {
 +            switch (type) {
 +                case "CHAR":
 +                case "NCHAR":
 +                    return CHAR;
 +
 +                case "VARCHAR2":
 +                case "NVARCHAR2":
 +                    return VARCHAR;
 +
 +                case "LONG":
 +                    return LONGVARCHAR;
 +
 +                case "LONG RAW":
 +                    return LONGVARBINARY;
 +
 +                case "FLOAT":
 +                    return FLOAT;
 +
 +                case "NUMBER":
 +                    int precision = rs.getInt(DATA_PRECISION_IDX);
 +                    int scale = rs.getInt(DATA_SCALE_IDX);
 +
 +                    if (scale > 0) {
 +                        if (scale < 4 && precision < 19)
 +                            return FLOAT;
 +
 +                        if (scale > 4 || precision > 19)
 +                            return DOUBLE;
 +
 +                        return NUMERIC;
 +                    }
 +                    else {
 +                        if (precision < 1)
 +                            return INTEGER;
 +
 +                        if (precision < 2)
 +                            return BOOLEAN;
 +
 +                        if (precision < 4)
 +                            return TINYINT;
 +
 +                        if (precision < 6)
 +                            return SMALLINT;
 +
 +                        if (precision < 11)
 +                            return INTEGER;
 +
 +                        if (precision < 20)
 +                            return BIGINT;
 +
 +                        return NUMERIC;
 +                    }
 +
 +                case "DATE":
 +                    return DATE;
 +
 +                case "BFILE":
 +                case "BLOB":
 +                    return BLOB;
 +
 +                case "CLOB":
 +                case "NCLOB":
 +                    return CLOB;
 +
 +                case "XMLTYPE":
 +                    return SQLXML;
 +            }
 +        }
 +
 +        return OTHER;
 +    }
 +
 +    /**
 +     * Retrieve primary key columns.
 +     *
 +     * @param stmt Prepared SQL statement to execute.
 +     * @param owner DB owner.
 +     * @param tbl Table name.
 +     * @return Primary key columns.
 +     * @throws SQLException If failed to retrieve primary key columns.
 +     */
 +    private Set<String> primaryKeys(PreparedStatement stmt, String owner, String tbl) throws SQLException {
 +        Set<String> pkCols = new HashSet<>();
 +
 +        stmt.setString(1, owner);
 +        stmt.setString(2, tbl);
 +
 +        try (ResultSet pkRs = stmt.executeQuery()) {
 +            while(pkRs.next())
 +                pkCols.add(pkRs.getString(1));
 +        }
 +
 +        return pkCols;
 +    }
 +
 +    /**
 +     * Retrieve index columns.
 +     *
 +     * @param stmt Prepared SQL statement to execute.
 +     * @param owner DB owner.
 +     * @param tbl Table name.
-      * @return Index columns.
++     * @return Indexes.
 +     * @throws SQLException If failed to retrieve indexes columns.
 +     */
-     private Map<String, Map<String, Boolean>> indexes(PreparedStatement stmt, String owner, String tbl)
++    private Collection<QueryIndex> indexes(PreparedStatement stmt, String owner, String tbl)
 +        throws SQLException {
-         Map<String, Map<String, Boolean>> idxs = new LinkedHashMap<>();
++        Map<String, QueryIndex> idxs = new LinkedHashMap<>();
 +
 +        stmt.setString(1, owner);
 +        stmt.setString(2, tbl);
 +
 +        try (ResultSet idxsRs = stmt.executeQuery()) {
 +            while (idxsRs.next()) {
 +                String idxName = idxsRs.getString(IDX_NAME_IDX);
 +
-                 Map<String, Boolean> idx = idxs.get(idxName);
++                QueryIndex idx = idxs.get(idxName);
 +
 +                if (idx == null) {
-                     idx = new LinkedHashMap<>();
++                    idx = new QueryIndex();
++                    idx.setName(idxName);
++                    idx.setIndexType(QueryIndexType.SORTED);
++                    idx.setFields(new LinkedHashMap<String, Boolean>());
 +
 +                    idxs.put(idxName, idx);
 +                }
 +
 +                String expr = idxsRs.getString(IDX_EXPR_IDX);
 +
 +                String col = expr == null ? idxsRs.getString(IDX_COL_NAME_IDX) : expr.replaceAll("\"", "");
 +
-                 idx.put(col, "DESC".equals(idxsRs.getString(IDX_COL_DESCEND_IDX)));
++                idx.getFields().put(col, !"DESC".equals(idxsRs.getString(IDX_COL_DESCEND_IDX)));
 +            }
 +        }
 +
-         return idxs;
++        return idxs.values();
 +    }
 +
 +    /** {@inheritDoc} */
 +    @Override public Collection<DbTable> tables(Connection conn, List<String> schemas, boolean tblsOnly)
 +        throws SQLException {
 +        Collection<DbTable> tbls = new ArrayList<>();
 +
 +        PreparedStatement pkStmt = conn.prepareStatement(SQL_PRIMARY_KEYS);
 +
 +        PreparedStatement idxStmt = conn.prepareStatement(SQL_INDEXES);
 +
-         if (schemas.size() == 0)
++        if (schemas.isEmpty())
 +            schemas.add(null);
 +
 +        Set<String> sysSchemas = systemSchemas();
 +
 +        try (Statement colsStmt = conn.createStatement()) {
 +            for (String schema: schemas) {
 +                if (systemSchemas().contains(schema) || (schema != null && schema.startsWith("FLOWS_")))
 +                    continue;
 +
 +                Collection<DbColumn> cols = new ArrayList<>();
 +
 +                Set<String> pkCols = Collections.emptySet();
-                 Map<String, Map<String, Boolean>> idxs = Collections.emptyMap();
++                Collection<QueryIndex> idxs = Collections.emptyList();
 +
 +                String sql = String.format(SQL_COLUMNS,
 +                        tblsOnly ? "INNER JOIN all_tables b on a.table_name = b.table_name and a.owner = b.owner" : "",
 +                        schema != null ? String.format(" WHERE a.owner = '%s' ", schema) : "");
 +
 +                try (ResultSet colsRs = colsStmt.executeQuery(sql)) {
 +                    String prevSchema = "";
 +                    String prevTbl = "";
 +
 +                    boolean first = true;
 +
 +                    while (colsRs.next()) {
 +                        String owner = colsRs.getString(OWNER_IDX);
 +                        String tbl = colsRs.getString(TBL_NAME_IDX);
 +
 +                        if (sysSchemas.contains(owner) || (schema != null && schema.startsWith("FLOWS_")))
 +                            continue;
 +
 +                        boolean changed = !owner.equals(prevSchema) || !tbl.equals(prevTbl);
 +
 +                        if (changed) {
 +                            if (first)
 +                                first = false;
 +                            else
 +                                tbls.add(table(prevSchema, prevTbl, cols, idxs));
 +
 +                            prevSchema = owner;
 +                            prevTbl = tbl;
 +                            cols = new ArrayList<>();
 +                            pkCols = primaryKeys(pkStmt, owner, tbl);
 +                            idxs = indexes(idxStmt, owner, tbl);
 +                        }
 +
 +                        String colName = colsRs.getString(COL_NAME_IDX);
 +
 +                        cols.add(new DbColumn(colName, decodeType(colsRs), pkCols.contains(colName),
 +                                !"N".equals(colsRs.getString(NULLABLE_IDX))));
 +                    }
 +
 +                    if (!cols.isEmpty())
 +                        tbls.add(table(prevSchema, prevTbl, cols, idxs));
 +                }
 +            }
 +        }
 +
 +        return tbls;
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/modules/schema-import/src/main/java/org/apache/ignite/schema/parser/DatabaseMetadataParser.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/modules/schema-import/src/main/java/org/apache/ignite/schema/ui/SchemaImportApp.java
----------------------------------------------------------------------
diff --cc modules/schema-import/src/main/java/org/apache/ignite/schema/ui/SchemaImportApp.java
index cbcddc2,495c316..124b623
--- a/modules/schema-import/src/main/java/org/apache/ignite/schema/ui/SchemaImportApp.java
+++ b/modules/schema-import/src/main/java/org/apache/ignite/schema/ui/SchemaImportApp.java
@@@ -808,7 -944,8 +808,8 @@@ public class SchemaImportApp extends Ap
  
          schemaPnl.wrap();
  
 -        schemaPnl.add(button("Load schemas", "Load schemas for specified database", new EventHandler<ActionEvent>() {
 +        schemaPnl.add(Controls.button("Load schemas", "Load schemas for specified database", new EventHandler<ActionEvent>() {
+             /** {@inheritDoc} */
              @Override public void handle(ActionEvent evt) {
                  loadSchemas();
              }

http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/parent/pom.xml
----------------------------------------------------------------------
diff --cc parent/pom.xml
index 08763b5,2d3ff5f..9550f9f
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@@ -709,7 -714,10 +714,11 @@@
                                          <exclude>dev-tools/.gradle/**/*</exclude>
                                          <exclude>dev-tools/gradle/wrapper/**/*</exclude>
                                          <exclude>dev-tools/gradlew</exclude>
+                                         <exclude>src/test/portables/repo/org/apache/ignite/portable/test2/1.1/test2-1.1.pom</exclude>
+                                         <exclude>src/test/portables/repo/org/apache/ignite/portable/test2/maven-metadata-local.xml</exclude>
+                                         <exclude>src/test/portables/repo/org/apache/ignite/portable/test1/1.1/test1-1.1.pom</exclude>
+                                         <exclude>src/test/portables/repo/org/apache/ignite/portable/test1/maven-metadata-local.xml</exclude>
 +                                        <exclude>src/main/js/package.json</exclude>
                                          <!--shmem-->
                                          <exclude>ipc/shmem/**/Makefile.in</exclude><!--auto generated files-->
                                          <exclude>ipc/shmem/**/Makefile</exclude><!--auto generated files-->

http://git-wip-us.apache.org/repos/asf/ignite/blob/25ef0f6c/pom.xml
----------------------------------------------------------------------