use of org.h2.table.IndexColumn in project ignite by apache.
the class GridH2Table method checkIndexPresence.
/**
* Checks index presence, return {@link Index} if index with same name or same fields and search direction already
* exist or {@code null} othervise.
*
* @param curIdx Index to check.
* @return Index if equal or subset index exist.
* @throws IgniteCheckedException If failed.
*/
@Nullable
private Index checkIndexPresence(Index curIdx) throws IgniteCheckedException {
IndexColumn[] curColumns = curIdx.getIndexColumns();
Index registredIdx = null;
for (Index idx : idxs) {
if (!(idx instanceof H2TreeIndex))
continue;
if (F.eq(curIdx.getName(), idx.getName()))
throw new IgniteCheckedException("Index already exists: " + idx.getName());
IndexColumn[] idxColumns = idx.getIndexColumns();
for (int i = 0; i < Math.min(idxColumns.length, curColumns.length); ++i) {
IndexColumn idxCol = idxColumns[i];
IndexColumn curCol = curColumns[i];
// pk attach at the end of listed fields.
if (curCol.column.getColumnId() == 0 && registredIdx != null)
continue;
if (H2Utils.equals(idxCol, curCol) && idxCol.sortType == curCol.sortType)
registredIdx = idx;
else {
registredIdx = null;
break;
}
}
if (registredIdx != null)
return registredIdx;
}
return null;
}
use of org.h2.table.IndexColumn in project ignite by apache.
the class H2IndexCostedBase method sortingCost.
/**
* Estimate sorting cost.
*
* @param rowCount Total rows count.
* @param filters Filters array.
* @param filter Column filter index.
* @param sortOrder Sort order.
* @param isScanIndex Flag if current index is a scan index.
* @return Sorting cost.
*/
private long sortingCost(long rowCount, TableFilter[] filters, int filter, SortOrder sortOrder, boolean isScanIndex) {
if (sortOrder == null)
return 0;
long sortingCost = 100 + rowCount / 10;
if (!isScanIndex) {
boolean sortOrderMatches = true;
int coveringCount = 0;
int[] sortTypes = sortOrder.getSortTypes();
TableFilter tableFilter = filters == null ? null : filters[filter];
for (int i = 0, len = sortTypes.length; i < len; i++) {
if (i >= indexColumns.length) {
// more of the order by columns.
break;
}
Column col = sortOrder.getColumn(i, tableFilter);
if (col == null) {
sortOrderMatches = false;
break;
}
IndexColumn indexCol = indexColumns[i];
if (!col.equals(indexCol.column)) {
sortOrderMatches = false;
break;
}
int sortType = sortTypes[i];
if (sortType != indexCol.sortType) {
sortOrderMatches = false;
break;
}
coveringCount++;
}
if (sortOrderMatches)
// "coveringCount" makes sure that when we have two
// or more covering indexes, we choose the one
// that covers more.
sortingCost = 100 - coveringCount;
}
return sortingCost;
}
use of org.h2.table.IndexColumn in project ignite by apache.
the class CollocationModel method isAffinityColumn.
/**
* @param f Table filter.
* @param expCol Expression column.
* @param validate Query validation flag.
* @return {@code true} It it is an affinity column.
*/
@SuppressWarnings("IfMayBeConditional")
private static boolean isAffinityColumn(TableFilter f, ExpressionColumn expCol, boolean validate) {
Column col = expCol.getColumn();
if (col == null)
return false;
Table t = col.getTable();
if (t.isView()) {
Query qry;
if (f.getIndex() != null)
qry = getSubQuery(f);
else
qry = GridSqlQueryParser.VIEW_QUERY.get((TableView) t);
return isAffinityColumn(qry, expCol, validate);
}
if (t instanceof GridH2Table) {
GridH2Table t0 = (GridH2Table) t;
if (validate && t0.isCustomAffinityMapper())
throw customAffinityError((t0).cacheName());
IndexColumn affCol = t0.getAffinityKeyColumn();
return affCol != null && col.getColumnId() == affCol.column.getColumnId();
}
return false;
}
use of org.h2.table.IndexColumn in project ignite by apache.
the class CollocationModel method joinedWithCollocated.
/**
* @param f Filter.
* @return Affinity join type.
*/
@SuppressWarnings("ForLoopReplaceableByForEach")
private CollocationModelAffinity joinedWithCollocated(int f) {
TableFilter tf = childFilters[f];
GridH2Table tbl = (GridH2Table) tf.getTable();
if (validate) {
if (tbl.isCustomAffinityMapper())
throw customAffinityError(tbl.cacheName());
if (F.isEmpty(tf.getIndexConditions())) {
throw new CacheException("Failed to prepare distributed join query: " + "join condition does not use index [joinedCache=" + tbl.cacheName() + ", plan=" + tf.getSelect().getPlanSQL() + ']');
}
}
IndexColumn affCol = tbl.getAffinityKeyColumn();
boolean affKeyCondFound = false;
if (affCol != null) {
ArrayList<IndexCondition> idxConditions = tf.getIndexConditions();
int affColId = affCol.column.getColumnId();
for (int i = 0; i < idxConditions.size(); i++) {
IndexCondition c = idxConditions.get(i);
int colId = c.getColumn().getColumnId();
int cmpType = c.getCompareType();
if ((cmpType == Comparison.EQUAL || cmpType == Comparison.EQUAL_NULL_SAFE) && (colId == affColId || tbl.rowDescriptor().isKeyColumn(colId)) && c.isEvaluatable()) {
affKeyCondFound = true;
Expression exp = c.getExpression();
exp = exp.getNonAliasExpression();
if (exp instanceof ExpressionColumn) {
ExpressionColumn expCol = (ExpressionColumn) exp;
// This is one of our previous joins.
TableFilter prevJoin = expCol.getTableFilter();
if (prevJoin != null) {
CollocationModel cm = child(indexOf(prevJoin), true);
// different affinity columns from different tables.
if (cm != null && !cm.view) {
CollocationModelType t = cm.type(true);
if (t.isPartitioned() && t.isCollocated() && isAffinityColumn(prevJoin, expCol, validate))
return CollocationModelAffinity.COLLOCATED_JOIN;
}
}
}
}
}
}
return affKeyCondFound ? CollocationModelAffinity.HAS_AFFINITY_CONDITION : CollocationModelAffinity.NONE;
}
use of org.h2.table.IndexColumn in project ignite by apache.
the class H2TableDescriptor method extractKeyColumns.
/**
* Create list of affinity and key index columns. Key, if it possible, partitions into simple components.
*
* @param tbl GridH2Table instance
* @param keyCol Key index column.
* @param affCol Affinity index column.
*
* @return List of key and affinity columns. Key's, if it possible, splitted into simple components.
*/
@NotNull
private List<IndexColumn> extractKeyColumns(GridH2Table tbl, IndexColumn keyCol, IndexColumn affCol) {
ArrayList<IndexColumn> keyCols;
if (isSql) {
keyCols = new ArrayList<>(type.fields().size() + 1);
// Check if key is simple type.
if (QueryUtils.isSqlType(type.keyClass()))
keyCols.add(keyCol);
else {
if (!type.primaryKeyFields().isEmpty()) {
for (String keyName : type.primaryKeyFields()) {
GridQueryProperty prop = type.property(keyName);
assert prop.key() : keyName + " is not a key field";
Column col = tbl.getColumn(prop.name());
keyCols.add(tbl.indexColumn(col.getColumnId(), SortOrder.ASCENDING));
}
} else {
for (String propName : type.fields().keySet()) {
GridQueryProperty prop = type.property(propName);
if (prop.key()) {
Column col = tbl.getColumn(propName);
keyCols.add(tbl.indexColumn(col.getColumnId(), SortOrder.ASCENDING));
}
}
}
// we have to fall back to whole-key index.
if (keyCols.isEmpty())
keyCols.add(keyCol);
}
} else {
keyCols = new ArrayList<>(2);
keyCols.add(keyCol);
}
if (affCol != null && !H2Utils.containsColumn(keyCols, affCol))
keyCols.add(affCol);
else
keyCols.trimToSize();
return Collections.unmodifiableList(keyCols);
}
Aggregations