<commit_before>/*
 * 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 org.apache.ignite.schema.parser.*;

import java.sql.*;
import java.util.*;

import static java.sql.Types.*;

/**
 * Oracle specific metadata dialect.
 */
public class OracleMetadataDialect extends DatabaseMetadataDialect {
    /** SQL to get indexes metadata. */
    private static final String SQL_INDEXES = "select a.index_owner, a.table_name, a.index_name, a.column_name," +
        " b.uniqueness" +
        " FROM all_ind_columns a" +
        " LEFT JOIN all_indexes b on" +
        "  (a.table_name = b.table_name AND a.table_owner = b.table_owner AND a.index_name  = b.index_name)";

    /** 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" +
        " FROM all_tab_columns a" +
        " %s" +
        " WHERE a.owner = '%s'" +
        " ORDER BY a.owner, a.table_name, a.column_id";

    /**
     * @param type Column type from Oracle database.
     * @return JDBC type.
     */
    private static int decodeType(String type) {
        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":
                return NUMERIC;

            case "DATE":
                return DATE;

            case "TIMESTAMP":
                return TIMESTAMP;

            case "BFILE":
            case "BLOB":
                return BLOB;

            case "CLOB":
            case "NCLOB":
            case "XMLTYPE":
                return CLOB;
        }

        return OTHER;
    }

    /**
     * @param nullable Column nullable attribute from Oracle database.
     * @return {@code true}
     */
    private static boolean decodeNullable(String nullable) {
        return "Y".equals(nullable);
    }

    /** {@inheritDoc} */
    @Override public Collection<DbTable> tables(Connection conn, boolean tblsOnly) throws SQLException {
        Collection<DbTable> tbls = new ArrayList<>();

        try (Statement stmt = conn.createStatement()) {
            Collection<DbColumn> cols = new ArrayList<>();

            String sql = String.format(SQL_COLUMNS,
                tblsOnly ? "INNER JOIN all_tables b on a.table_name = b.table_name" : "", "TEST");

            try (ResultSet colsRs = stmt.executeQuery(sql)) {
                String prevSchema = "";
                String prevTbl = "";

                while (colsRs.next()) {
                    String schema = colsRs.getString("OWNER");
                    String tbl = colsRs.getString("TABLE_NAME");

                    if (prevSchema.isEmpty()) {
                        prevSchema = schema;
                        prevTbl = tbl;
                    }

                    if (!schema.equals(prevSchema) || !tbl.equals(prevTbl)) {
                        tbls.add(new DbTable(prevSchema, prevTbl, cols, Collections.<String>emptySet(),
                            Collections.<String>emptySet(), null));

                        prevSchema = schema;
                        prevTbl = tbl;

                        cols = new ArrayList<>();
                    }
                    cols.add(new DbColumn(colsRs.getString("COLUMN_NAME"),<commit_msg># IGNITE-32: WIP Oracle dialect: support for indexes.<commit_after>/*
 * 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 org.apache.ignite.schema.parser.*;

import java.sql.*;
import java.util.*;

import static java.sql.Types.*;

/**
 * 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" +
        " FROM all_tab_columns a" +
        " %s" +
        " WHERE a.owner = '%s'" +
        " ORDER BY a.owner, a.table_name, a.column_id";

    private static final int SQL_COLS_OWNER = 1;

    private static final int SQL_COLS_TAB_NAME = 2;

    private static final int SQL_COLS_COL_NAME = 3;

    private static final int SQL_COLS_NULLABLE = 4;

    private static final int SQL_COLS_DATA_TYPE = 5;

    /** SQL to get indexes metadata. */
    private static final String SQL_INDEXES = "select index_name, column_name, descend" +
        " FROM all_ind_columns" +
        " WHERE index_owner = ? and table_name = ?" +
        "  ORDER BY index_name, column_position";

    /**
     * @param type Column type from Oracle database.
     * @return JDBC type.
     */
    private static int decodeType(String type) {
        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":
                return NUMERIC;

            case "DATE":
                return DATE;

            case "TIMESTAMP":
                return TIMESTAMP;

            case "BFILE":
            case "BLOB":
                return BLOB;

            case "CLOB":
            case "NCLOB":
            case "XMLTYPE":
                return CLOB;
        }

        return OTHER;
    }

    /**
     * @param nullable Column nullable attribute from Oracle database.
     * @return {@code true}
     */
    private static boolean decodeNullable(String nullable) {
        return "Y".equals(nullable);
    }

    /**
     * @param descend Index column sort direction from Oracle database.
     * @return {@code true} if column sorted in descent direction.
     */
    private static Boolean decodeDescend(String descend) {
        return descend != null ? "DESC".equals(descend) : null;
    }

    private static Map<String, Map<String, Boolean>> indexes(PreparedStatement stmt, String owner, String tbl)
        throws SQLException {
        Map<String, Map<String, Boolean>> idxs = new LinkedHashMap<>();

        stmt.setString(1, owner);
        stmt.setString(2, tbl);

        try (ResultSet idxsRs = stmt.executeQuery()) {
            while (idxsRs.next()) {
                String idxName = idxsRs.getString("INDEX_NAME");
            }
        }

        return idxs;
    }

    /** {@inheritDoc} */
    @Override public Collection<DbTable> tables(Connection conn, boolean tblsOnly) throws SQLException {
        Collection<DbTable> tbls = new ArrayList<>();

        PreparedStatement stmtIdxs = conn.prepareStatement(SQL_INDEXES);

        try (Statement stmt = conn.createStatement()) {
            Collection<DbColumn> cols = new ArrayList<>();

            String sql = String.format(SQL_COLUMNS,
                tblsOnly ? "INNER JOIN all_tables b on a.table_name = b.table_name" : "", "TEST");

            try (ResultSet colsRs = stmt.executeQuery(sql)) {
                String prevSchema = "";
                String prevTbl = "";

                while (colsRs.next()) {
                    String schema = colsRs.getString("OWNER");
                    String tbl = colsRs.getString("TABLE_NAME");

                    if (prevSchema.isEmpty()) {
                        prevSchema = schema;
                        prevTbl = tbl;
                    }

                    if (!schema.equals(prevSchema) || !tbl.equals(prevTbl)) {
                        tbls.add(new DbTable(prevSchema, prevTbl, cols, Collections.<String>emptySet(),
                            Collections.<String>emptySet(), null));

                        prevSchema = schema;
                        prevTbl = tbl;

                        cols = new ArrayList<>();
                    }
                    cols.add(new DbColumn(colsRs.getString("COLUMN_NAME"),
{'fraction_non_alphanumeric': 0.09571296391487612, 'fraction_numerical': 0.0021589390356738973, 'mean_word_length': 1.9082212257100148, 'pattern_counts': {'":': 30, '<': 24, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3639238', 'n_tokens_mistral': 2672, 'n_tokens_neox': 2493, 'n_words': 805}