use of org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor in project ignite by apache.
the class IgniteH2Indexing method createTable.
/**
* Create db table by using given table descriptor.
*
* @param schemaName Schema name.
* @param schema Schema.
* @param tbl Table descriptor.
* @param conn Connection.
* @throws SQLException If failed to create db table.
* @throws IgniteCheckedException If failed.
*/
private void createTable(String schemaName, H2Schema schema, H2TableDescriptor tbl, Connection conn) throws SQLException, IgniteCheckedException {
assert schema != null;
assert tbl != null;
String keyType = dbTypeFromClass(tbl.type().keyClass());
String valTypeStr = dbTypeFromClass(tbl.type().valueClass());
SB sql = new SB();
String keyValVisibility = tbl.type().fields().isEmpty() ? " VISIBLE" : " INVISIBLE";
sql.a("CREATE TABLE ").a(tbl.fullTableName()).a(" (").a(KEY_FIELD_NAME).a(' ').a(keyType).a(keyValVisibility).a(" NOT NULL");
sql.a(',').a(VAL_FIELD_NAME).a(' ').a(valTypeStr).a(keyValVisibility);
sql.a(',').a(VER_FIELD_NAME).a(" OTHER INVISIBLE");
for (Map.Entry<String, Class<?>> e : tbl.type().fields().entrySet()) sql.a(',').a(H2Utils.withQuotes(e.getKey())).a(' ').a(dbTypeFromClass(e.getValue()));
sql.a(')');
if (log.isDebugEnabled())
log.debug("Creating DB table with SQL: " + sql);
GridH2RowDescriptor rowDesc = new H2RowDescriptor(this, tbl, tbl.type(), schema);
H2RowFactory rowFactory = tbl.rowFactory(rowDesc);
GridH2Table h2Tbl = H2TableEngine.createTable(conn, sql.toString(), rowDesc, rowFactory, tbl);
for (GridH2IndexBase usrIdx : tbl.createUserIndexes()) addInitialUserIndex(schemaName, tbl, usrIdx);
if (dataTables.putIfAbsent(h2Tbl.identifier(), h2Tbl) != null)
throw new IllegalStateException("Table already exists: " + h2Tbl.identifierString());
}
use of org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor in project ignite by apache.
the class H2TableDescriptor method createSystemIndexes.
/** {@inheritDoc} */
@Override
public ArrayList<Index> createSystemIndexes(GridH2Table tbl) {
ArrayList<Index> idxs = new ArrayList<>();
IndexColumn keyCol = tbl.indexColumn(KEY_COL, SortOrder.ASCENDING);
IndexColumn affCol = tbl.getAffinityKeyColumn();
if (affCol != null && H2Utils.equals(affCol, keyCol))
affCol = null;
GridH2RowDescriptor desc = tbl.rowDescriptor();
Index hashIdx = createHashIndex(tbl, "_key_PK_hash", H2Utils.treeIndexColumns(desc, new ArrayList<IndexColumn>(2), keyCol, affCol));
if (hashIdx != null)
idxs.add(hashIdx);
// Add primary key index.
Index pkIdx = idx.createSortedIndex(schema, "_key_PK", tbl, true, H2Utils.treeIndexColumns(desc, new ArrayList<IndexColumn>(2), keyCol, affCol), -1);
idxs.add(pkIdx);
if (type().valueClass() == String.class) {
try {
luceneIdx = new GridLuceneIndex(idx.kernalContext(), schema.offheap(), tbl.cacheName(), type);
} catch (IgniteCheckedException e1) {
throw new IgniteException(e1);
}
}
boolean affIdxFound = false;
GridQueryIndexDescriptor textIdx = type.textIndex();
if (textIdx != null) {
try {
luceneIdx = new GridLuceneIndex(idx.kernalContext(), schema.offheap(), tbl.cacheName(), type);
} catch (IgniteCheckedException e1) {
throw new IgniteException(e1);
}
}
// Locate index where affinity column is first (if any).
if (affCol != null) {
for (GridQueryIndexDescriptor idxDesc : type.indexes().values()) {
if (idxDesc.type() != QueryIndexType.SORTED)
continue;
String firstField = idxDesc.fields().iterator().next();
Column col = tbl.getColumn(firstField);
IndexColumn idxCol = tbl.indexColumn(col.getColumnId(), idxDesc.descending(firstField) ? SortOrder.DESCENDING : SortOrder.ASCENDING);
affIdxFound |= H2Utils.equals(idxCol, affCol);
}
}
// Add explicit affinity key index if nothing alike was found.
if (affCol != null && !affIdxFound) {
idxs.add(idx.createSortedIndex(schema, "AFFINITY_KEY", tbl, false, H2Utils.treeIndexColumns(desc, new ArrayList<IndexColumn>(2), affCol, keyCol), -1));
}
return idxs;
}
use of org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor in project ignite by apache.
the class IgniteH2Indexing method dynamicIndexCreate.
/** {@inheritDoc} */
@Override
public void dynamicIndexCreate(final String schemaName, final String tblName, final QueryIndexDescriptorImpl idxDesc, boolean ifNotExists, SchemaIndexCacheVisitor cacheVisitor) throws IgniteCheckedException {
// Locate table.
H2Schema schema = schemas.get(schemaName);
H2TableDescriptor desc = (schema != null ? schema.tableByName(tblName) : null);
if (desc == null)
throw new IgniteCheckedException("Table not found in internal H2 database [schemaName=" + schemaName + ", tblName=" + tblName + ']');
GridH2Table h2Tbl = desc.table();
// Create index.
final GridH2IndexBase h2Idx = desc.createUserIndex(idxDesc);
h2Tbl.proposeUserIndex(h2Idx);
try {
// Populate index with existing cache data.
final GridH2RowDescriptor rowDesc = h2Tbl.rowDescriptor();
SchemaIndexCacheVisitorClosure clo = new SchemaIndexCacheVisitorClosure() {
@Override
public void apply(KeyCacheObject key, int part, CacheObject val, GridCacheVersion ver, long expTime, long link) throws IgniteCheckedException {
if (expTime == 0L)
expTime = Long.MAX_VALUE;
GridH2Row row = rowDesc.createRow(key, part, val, ver, expTime);
row.link(link);
h2Idx.put(row);
}
};
cacheVisitor.visit(clo);
// At this point index is in consistent state, promote it through H2 SQL statement, so that cached
// prepared statements are re-built.
String sql = H2Utils.indexCreateSql(desc.fullTableName(), h2Idx, ifNotExists);
executeSql(schemaName, sql);
} catch (Exception e) {
// Rollback and re-throw.
h2Tbl.rollbackUserIndex(h2Idx.getName());
throw e;
}
}
use of org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor in project ignite by apache.
the class DmlStatementsProcessor method rowToKeyValue.
/**
* Convert row presented as an array of Objects into key-value pair to be inserted to cache.
* @param cctx Cache context.
* @param row Row to process.
* @param plan Update plan.
* @throws IgniteCheckedException if failed.
*/
@SuppressWarnings({ "unchecked", "ConstantConditions", "ResultOfMethodCallIgnored" })
private IgniteBiTuple<?, ?> rowToKeyValue(GridCacheContext cctx, List<?> row, UpdatePlan plan) throws IgniteCheckedException {
GridH2RowDescriptor rowDesc = plan.tbl.rowDescriptor();
GridQueryTypeDescriptor desc = rowDesc.type();
Object key = plan.keySupplier.apply(row);
if (QueryUtils.isSqlType(desc.keyClass())) {
assert plan.keyColIdx != -1;
key = convert(key, rowDesc, desc.keyClass(), plan.colTypes[plan.keyColIdx]);
}
Object val = plan.valSupplier.apply(row);
if (QueryUtils.isSqlType(desc.valueClass())) {
assert plan.valColIdx != -1;
val = convert(val, rowDesc, desc.valueClass(), plan.colTypes[plan.valColIdx]);
}
if (key == null)
throw new IgniteSQLException("Key for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_KEY);
if (val == null)
throw new IgniteSQLException("Value for INSERT or MERGE must not be null", IgniteQueryErrorCode.NULL_VALUE);
Map<String, Object> newColVals = new HashMap<>();
for (int i = 0; i < plan.colNames.length; i++) {
if (i == plan.keyColIdx || i == plan.valColIdx)
continue;
String colName = plan.colNames[i];
GridQueryProperty prop = desc.property(colName);
assert prop != null;
Class<?> expCls = prop.type();
newColVals.put(colName, convert(row.get(i), rowDesc, expCls, plan.colTypes[i]));
}
// We update columns in the order specified by the table for a reason - table's
// column order preserves their precedence for correct update of nested properties.
Column[] cols = plan.tbl.getColumns();
// First 3 columns are _key, _val and _ver. Skip 'em.
for (int i = DEFAULT_COLUMNS_COUNT; i < cols.length; i++) {
if (plan.tbl.rowDescriptor().isKeyValueOrVersionColumn(i))
continue;
String colName = cols[i].getName();
if (!newColVals.containsKey(colName))
continue;
Object colVal = newColVals.get(colName);
desc.setValue(colName, key, val, colVal);
}
if (cctx.binaryMarshaller()) {
if (key instanceof BinaryObjectBuilder)
key = ((BinaryObjectBuilder) key).build();
if (val instanceof BinaryObjectBuilder)
val = ((BinaryObjectBuilder) val).build();
}
return new IgniteBiTuple<>(key, val);
}
use of org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor in project ignite by apache.
the class H2TableDescriptor method createUserIndex.
/**
* Create user index.
*
* @param idxDesc Index descriptor.
* @return Index.
*/
public GridH2IndexBase createUserIndex(GridQueryIndexDescriptor idxDesc) {
IndexColumn keyCol = tbl.indexColumn(KEY_COL, SortOrder.ASCENDING);
IndexColumn affCol = tbl.getAffinityKeyColumn();
List<IndexColumn> cols = new ArrayList<>(idxDesc.fields().size() + 2);
for (String field : idxDesc.fields()) {
Column col = tbl.getColumn(field);
cols.add(tbl.indexColumn(col.getColumnId(), idxDesc.descending(field) ? SortOrder.DESCENDING : SortOrder.ASCENDING));
}
GridH2RowDescriptor desc = tbl.rowDescriptor();
if (idxDesc.type() == QueryIndexType.SORTED) {
cols = H2Utils.treeIndexColumns(desc, cols, keyCol, affCol);
return idx.createSortedIndex(schema, idxDesc.name(), tbl, false, cols, idxDesc.inlineSize());
} else if (idxDesc.type() == QueryIndexType.GEOSPATIAL) {
return H2Utils.createSpatialIndex(tbl, idxDesc.name(), cols.toArray(new IndexColumn[cols.size()]));
}
throw new IllegalStateException("Index type: " + idxDesc.type());
}
Aggregations