use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.EXISTS 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())).a(tbl.type().property(e.getKey()).notNull() ? " NOT NULL" : "");
sql.a(')');
if (log.isDebugEnabled())
log.debug("Creating DB table with SQL: " + sql);
GridH2RowDescriptor rowDesc = new GridH2RowDescriptor(this, tbl, tbl.type());
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.sql.GridSqlOperationType.EXISTS in project ignite by apache.
the class SchemaManager method onCacheTypeCreated.
/**
* Registers new class description.
*
* @param cacheInfo Cache info.
* @param idx Indexing.
* @param type Type descriptor.
* @param isSql Whether SQL enabled.
* @throws IgniteCheckedException If failed.
*/
public void onCacheTypeCreated(GridCacheContextInfo cacheInfo, IgniteH2Indexing idx, GridQueryTypeDescriptor type, boolean isSql) throws IgniteCheckedException {
String schemaName = schemaName(cacheInfo.name());
H2TableDescriptor tblDesc = new H2TableDescriptor(idx, schemaName, type, cacheInfo, isSql);
H2Schema schema = schema(schemaName);
try (H2PooledConnection conn = connMgr.connection(schema.schemaName())) {
GridH2Table h2tbl = createTable(schema.schemaName(), schema, tblDesc, conn);
schema.add(tblDesc);
if (dataTables.putIfAbsent(h2tbl.identifier(), h2tbl) != null)
throw new IllegalStateException("Table already exists: " + h2tbl.identifierString());
} catch (SQLException e) {
throw new IgniteCheckedException("Failed to register query type: " + tblDesc, e);
}
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.EXISTS in project ignite by apache.
the class SchemaManager method createIndex.
/**
* Create index dynamically.
*
* @param schemaName Schema name.
* @param tblName Table name.
* @param idxDesc Index descriptor.
* @param ifNotExists If-not-exists.
* @param cacheVisitor Cache visitor.
* @throws IgniteCheckedException If failed.
*/
public void createIndex(String schemaName, String tblName, QueryIndexDescriptorImpl idxDesc, boolean ifNotExists, SchemaIndexCacheVisitor cacheVisitor) throws IgniteCheckedException {
// Locate table.
H2Schema schema = schema(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, cacheVisitor);
h2Tbl.proposeUserIndex(h2Idx);
try {
// 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);
connMgr.executeStatement(schemaName, sql);
} catch (Exception e) {
// Rollback and re-throw.
h2Tbl.rollbackUserIndex(h2Idx.getName());
throw e;
}
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.EXISTS in project ignite by apache.
the class GridSubqueryJoinOptimizer method pullOutSubQryFromSelectExpr.
/**
* Pulls out subquery from select expression.
*
* @param select Parent query where to find and pull out subqueries.
*/
private static void pullOutSubQryFromSelectExpr(GridSqlSelect select) {
for (int i = 0; i < select.allColumns(); i++) {
boolean wasPulledOut = false;
GridSqlAst col = select.columns(false).get(i);
if (col instanceof GridSqlSubquery)
wasPulledOut = pullOutSubQryFromSelectExpr(select, null, i);
else if (col instanceof GridSqlOperation && ((GridSqlOperation) col).operationType() == EXISTS)
// We actially can't rewrite select query under exists operator. So we skip it.
continue;
else {
ASTNodeFinder finder = new ASTNodeFinder(col, ELEMENT_WITH_SUBQUERY);
ASTNodeFinder.Result res;
while ((res = finder.findNext()) != null) wasPulledOut |= pullOutSubQryFromSelectExpr(select, res.getEl(), res.getIdx());
}
if (// we have to analyze just pulled out element as well
wasPulledOut)
i--;
}
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.EXISTS in project ignite by apache.
the class GridSubqueryJoinOptimizer method pullOutSubQryFromInClause.
/**
* Pull out sub-select from IN clause to the parent select level.
* <p>
* Example:
* <pre>
* Before:
* SELECT name
* FROM emp e
* WHERE e.dep_id IN (SELECT d.id FROM dep d WHERE d.name = 'dep1')
* AND sal > 2000
*
* After:
* SELECT name
* FROM emp e
* JOIN dep d
* WHERE sal > 2000 AND d.id = e.dep_id and d.name = 'dep1
* </pre>
*
* @param parent Parent select.
* @param targetEl Target sql element. Can be {@code null}.
* @param childInd Column index.
*/
private static boolean pullOutSubQryFromInClause(GridSqlSelect parent, @Nullable GridSqlAst targetEl, int childInd) {
// extract sub-query
GridSqlSubquery subQry = targetEl != null ? targetEl.child(childInd).child(1) : parent.where().child(1);
if (!isSimpleSelect(subQry.subquery()))
return false;
GridSqlSelect subS = subQry.subquery();
GridSqlAst leftExpr = targetEl != null ? targetEl.child(childInd).child(0) : parent.where().child(0);
// 4) c1 + c2/const IN (SELECT in_col FROM ...)
if (subS.visibleColumns() != 1)
return false;
List<GridSqlElement> conditions = new ArrayList<>();
if (leftExpr instanceof GridSqlArray) {
GridSqlAst col = subS.columns(true).get(0);
if (!(col instanceof GridSqlArray) || leftExpr.size() != col.size())
return false;
for (int i = 0; i < col.size(); i++) {
GridSqlElement el = leftExpr.child(i);
conditions.add(new GridSqlOperation(EQUAL, el, col.child(i)));
}
} else if (targetEl instanceof GridSqlFunction)
return false;
else
conditions.add(new GridSqlOperation(EQUAL, leftExpr, subS.columns(true).get(0)));
// save old condition and IN expression to restore them
// in case of unsuccessfull pull out
GridSqlElement oldCond = (GridSqlElement) subS.where();
if (oldCond != null)
conditions.add(oldCond);
GridSqlElement oldInExpr = targetEl != null ? targetEl.child(childInd) : (GridSqlElement) parent.where();
// update sub-query condition and convert IN clause to EXISTS
subS.where(buildConditionBush(conditions));
GridSqlOperation existsExpr = new GridSqlOperation(EXISTS, subQry);
if (targetEl != null)
targetEl.child(childInd, existsExpr);
else
parent.where(existsExpr);
boolean res = pullOutSubQryFromExistsClause(parent, targetEl, childInd);
if (!res) {
// restore original query in case of failure
if (targetEl != null)
targetEl.child(childInd, oldInExpr);
else
parent.where(oldInExpr);
subS.where(oldCond);
}
return res;
}
Aggregations