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;
}
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;
}
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;
}
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;
}
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;
}
Aggregations