Search in sources :

Example 21 with Column

use of org.gridgain.internal.h2.table.Column in project ignite by apache.

the class GridSqlQueryParser method parseDropColumn.

/**
 * Parse {@code ALTER TABLE ... DROP COLUMN} statement.
 * @param dropCol H2 statement.
 * @see <a href="http://www.h2database.com/html/grammar.html#alter_table_add"></a>
 */
private GridSqlStatement parseDropColumn(AlterTableAlterColumn dropCol) {
    assert dropCol.getType() == CommandInterface.ALTER_TABLE_DROP_COLUMN;
    GridSqlAlterTableDropColumn res = new GridSqlAlterTableDropColumn();
    ArrayList<Column> h2DropCols = ALTER_COLUMN_REMOVE_COLS.get(dropCol);
    String[] gridDropCols = new String[h2DropCols.size()];
    for (int i = 0; i < h2DropCols.size(); i++) gridDropCols[i] = h2DropCols.get(i).getName();
    res.columns(gridDropCols);
    if (gridDropCols.length == 1)
        res.ifExists(!ALTER_COLUMN_IF_NOT_EXISTS.get(dropCol));
    res.ifTableExists(ALTER_COLUMN_IF_TBL_EXISTS.get(dropCol));
    Schema schema = SCHEMA_COMMAND_SCHEMA.get(dropCol);
    res.schemaName(schema.getName());
    res.tableName(ALTER_COLUMN_TBL_NAME.get(dropCol));
    return res;
}
Also used : GridSqlType.fromColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromColumn) AlterTableAlterColumn(org.h2.command.ddl.AlterTableAlterColumn) Column(org.h2.table.Column) ExpressionColumn(org.h2.expression.ExpressionColumn) IndexColumn(org.h2.table.IndexColumn) Schema(org.h2.schema.Schema) AlterTableAddConstraint(org.h2.command.ddl.AlterTableAddConstraint)

Example 22 with Column

use of org.gridgain.internal.h2.table.Column in project ignite by apache.

the class H2IndexCostedBase method getCostRangeIndex.

/**
 * Get cost range.
 *
 * @param ses Session.
 * @param masks Condition masks.
 * @param rowCount Total row count.
 * @param filters Filters array.
 * @param filter Filter array index.
 * @param sortOrder Sort order.
 * @param isScanIndex Flag if current index is a scan index.
 * @param allColumnsSet All columns to select.
 * @return The cost.
 */
public long getCostRangeIndex(Session ses, int[] masks, long rowCount, TableFilter[] filters, int filter, SortOrder sortOrder, boolean isScanIndex, HashSet<Column> allColumnsSet) {
    ObjectStatisticsImpl locTblStats = (ObjectStatisticsImpl) tbl.tableStatistics();
    if (locTblStats != null)
        rowCount = locTblStats.rowCount();
    // Small increment to account statistics outdates.
    rowCount += 1000;
    TableFilter tableFilter = (filters == null) ? null : filters[filter];
    long rowsCost = rowCost(ses, tableFilter, masks, rowCount, locTblStats);
    // If the ORDER BY clause matches the ordering of this index,
    // it will be cheaper than another index, so adjust the cost
    // accordingly.
    long sortingCost = sortingCost(rowCount, filters, filter, sortOrder, isScanIndex);
    boolean skipColumnsIntersection = false;
    if (filters != null && tableFilter != null && columns != null) {
        skipColumnsIntersection = true;
        ArrayList<IndexCondition> idxConds = tableFilter.getIndexConditions();
        // Only pk with _key used.
        if (F.isEmpty(idxConds))
            skipColumnsIntersection = false;
        for (IndexCondition cond : idxConds) {
            if (cond.getColumn() == columns[0]) {
                skipColumnsIntersection = false;
                break;
            }
        }
    }
    // If we have two indexes with the same cost, and one of the indexes can
    // satisfy the query without needing to read from the primary table
    // (scan index), make that one slightly lower cost.
    boolean needsToReadFromScanIndex = true;
    if (!isScanIndex && allColumnsSet != null && !skipColumnsIntersection && !allColumnsSet.isEmpty()) {
        boolean foundAllColumnsWeNeed = true;
        for (Column c : allColumnsSet) {
            boolean found = false;
            for (Column c2 : columns) {
                if (c == c2) {
                    found = true;
                    break;
                }
            }
            if (!found) {
                foundAllColumnsWeNeed = false;
                break;
            }
        }
        if (foundAllColumnsWeNeed)
            needsToReadFromScanIndex = false;
    }
    long rc;
    if (isScanIndex)
        rc = rowsCost + sortingCost + 20;
    else if (needsToReadFromScanIndex)
        rc = rowsCost + rowsCost + sortingCost + 20;
    else
        // The (20-x) calculation makes sure that when we pick a covering
        // index, we pick the covering index that has the smallest number of
        // columns (the more columns we have in index - the higher cost).
        // This is faster because a smaller index will fit into fewer data
        // blocks.
        rc = rowsCost + sortingCost + columns.length;
    return rc;
}
Also used : TableFilter(org.h2.table.TableFilter) Column(org.h2.table.Column) IndexColumn(org.h2.table.IndexColumn) IndexCondition(org.h2.index.IndexCondition) ObjectStatisticsImpl(org.apache.ignite.internal.processors.query.stat.ObjectStatisticsImpl)

Example 23 with Column

use of org.gridgain.internal.h2.table.Column in project ignite by apache.

the class H2IndexCostedBase method rowCost.

/**
 * Row cost calculation.
 *
 * @param ses Session.
 * @param filter Table filter.
 * @param masks Masks array.
 * @param rowCount Total rows count.
 * @param locTblStats Local table statistics.
 * @return Row cost.
 */
private long rowCost(Session ses, TableFilter filter, int[] masks, long rowCount, ObjectStatisticsImpl locTblStats) {
    double totalCardinality = 0;
    long rowsCost = rowCount;
    if (masks != null) {
        int i = 0, len = columns.length;
        while (i < len) {
            Column column = columns[i++];
            ColumnStatistics colStats = getColumnStatistics(locTblStats, column);
            int index = column.getColumnId();
            int mask = masks[index];
            if (isByteFlag(mask, IndexCondition.EQUALITY)) {
                if (i == len && getIndexType().isUnique()) {
                    rowsCost = 3;
                    break;
                }
                // Estimate by is null
                Value equalValue = getEqualValue(ses, column, filter);
                Boolean equalNull = (equalValue == null) ? null : equalValue.getType() == Value.NULL;
                rowCount = getColumnSize(colStats, rowCount, equalNull);
                if (colStats != null && equalNull == Boolean.TRUE) {
                    rowsCost = Math.min(5 + Math.max(Math.round(rowsCost * nulls(colStats)), 1), rowsCost - (i > 0 ? 1 : 0));
                    continue;
                }
                if (colStats != null && equalNull == Boolean.FALSE)
                    rowsCost = Math.max(Math.round(rowsCost * (1 - nulls(colStats))), 1);
                long distinctRows;
                if (colStats == null) {
                    double cardinality = (double) column.getSelectivity() / 100;
                    totalCardinality = 1 - (1 - totalCardinality) * (1 - cardinality);
                    distinctRows = Math.round((double) rowCount * totalCardinality);
                } else {
                    double cardinality;
                    long nonNulls = colStats.total() - colStats.nulls();
                    if (nonNulls == 0)
                        cardinality = 1;
                    else
                        cardinality = (double) colStats.distinct() / nonNulls;
                    totalCardinality = 1 - (1 - totalCardinality) * (1 - cardinality);
                    distinctRows = Math.round(rowCount * totalCardinality);
                }
                if (distinctRows <= 0)
                    distinctRows = 1;
                rowsCost = Math.min(5 + Math.max(rowsCost / distinctRows, 1), rowsCost - (i > 0 ? 1 : 0));
            } else if (isByteFlag(mask, IndexCondition.RANGE) || isByteFlag(mask, IndexCondition.START) || isByteFlag(mask, IndexCondition.END)) {
                Value min = getStartValue(ses, column, filter);
                Value max = getEndValue(ses, column, filter);
                int percent = estimatePercent(colStats, min, max);
                rowsCost = Math.min(5 + rowsCost * percent / 100, rowsCost - (i > 0 ? 1 : 0));
                break;
            } else if (isNullFilter(ses, column, filter)) {
                if (colStats != null)
                    rowsCost = Math.min(5 + colStats.nulls(), rowsCost - (i > 0 ? 1 : 0));
                break;
            } else if (isNotNullFilter(ses, column, filter)) {
                if (colStats != null)
                    rowsCost = Math.min(5 + colStats.total() - colStats.nulls(), rowsCost - (i > 0 ? 1 : 0));
                break;
            } else
                break;
        }
    }
    return rowsCost;
}
Also used : ColumnStatistics(org.apache.ignite.internal.processors.query.stat.ColumnStatistics) Column(org.h2.table.Column) IndexColumn(org.h2.table.IndexColumn) Value(org.h2.value.Value)

Example 24 with Column

use of org.gridgain.internal.h2.table.Column in project ignite by apache.

the class GridSqlQuerySplitter method keyColumn.

/**
 * Retrieves _KEY column from SELECT. This column is used for SELECT FOR UPDATE statements.
 *
 * @param sel Select statement.
 * @return Key column alias.
 */
public static GridSqlAlias keyColumn(GridSqlSelect sel) {
    GridSqlAst from = sel.from();
    GridSqlTable tbl = from instanceof GridSqlTable ? (GridSqlTable) from : ((GridSqlElement) from).child();
    GridH2Table gridTbl = tbl.dataTable();
    Column h2KeyCol = gridTbl.getColumn(QueryUtils.KEY_COL);
    GridSqlColumn keyCol = new GridSqlColumn(h2KeyCol, tbl, h2KeyCol.getName());
    keyCol.resultType(GridSqlType.fromColumn(h2KeyCol));
    GridSqlAlias al = SplitterUtils.alias(QueryUtils.KEY_FIELD_NAME, keyCol);
    return al;
}
Also used : Column(org.h2.table.Column) GridSqlSelect.childIndexForColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect.childIndexForColumn) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)

Example 25 with Column

use of org.gridgain.internal.h2.table.Column in project ignite by apache.

the class GridSqlSortColumn method toIndexColumns.

/**
 * @param tbl Table.
 * @param sortCols Sort columns.
 * @return Index columns.
 */
public static IndexColumn[] toIndexColumns(Table tbl, List<GridSqlSortColumn> sortCols) {
    assert !F.isEmpty(sortCols);
    IndexColumn[] res = new IndexColumn[sortCols.size()];
    for (int i = 0; i < res.length; i++) {
        GridSqlSortColumn sc = sortCols.get(i);
        Column col = tbl.getColumn(sc.column());
        IndexColumn c = new IndexColumn();
        c.column = col;
        c.columnName = col.getName();
        c.sortType = sc.asc ? SortOrder.ASCENDING : SortOrder.DESCENDING;
        if (sc.nullsFirst)
            c.sortType |= SortOrder.NULLS_FIRST;
        if (sc.nullsLast)
            c.sortType |= SortOrder.NULLS_LAST;
        res[i] = c;
    }
    return res;
}
Also used : Column(org.h2.table.Column) IndexColumn(org.h2.table.IndexColumn) IndexColumn(org.h2.table.IndexColumn)

Aggregations

Column (org.h2.table.Column)300 IndexColumn (org.h2.table.IndexColumn)156 Column (org.gridgain.internal.h2.table.Column)150 ExpressionColumn (org.h2.expression.ExpressionColumn)117 Expression (org.h2.expression.Expression)94 Value (org.gridgain.internal.h2.value.Value)88 IndexColumn (org.gridgain.internal.h2.table.IndexColumn)82 ArrayList (java.util.ArrayList)81 DbException (org.gridgain.internal.h2.message.DbException)70 SQLException (java.sql.SQLException)69 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)68 Value (org.h2.value.Value)63 ExpressionColumn (org.gridgain.internal.h2.expression.ExpressionColumn)59 AlterTableRenameColumn (org.h2.command.ddl.AlterTableRenameColumn)59 Table (org.h2.table.Table)52 Expression (org.gridgain.internal.h2.expression.Expression)50 ValueExpression (org.h2.expression.ValueExpression)48 Index (org.h2.index.Index)46 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)40 Database (org.h2.engine.Database)35