use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.EXISTS in project ignite by apache.
the class GridSubqueryJoinOptimizer method pullOutSubQryFromExistsClause.
/**
* Pull out sub-select from EXISTS clause to the parent select level.
* <p>
* Example:
* <pre>
* Before:
* SELECT name
* FROM emp e
* WHERE EXISTS (SELECT 1 FROM dep d WHERE d.id = e.dep_id and 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 null.
* @param childInd Column ind.
*/
private static boolean pullOutSubQryFromExistsClause(GridSqlSelect parent, @Nullable GridSqlAst targetEl, int childInd) {
// extract sub-query
GridSqlSubquery subQry = targetEl != null ? targetEl.child(childInd).child() : parent.where().child();
if (!subQueryCanBePulledOut(subQry))
return false;
GridSqlSelect subS = subQry.subquery();
if (targetEl != null)
targetEl.child(childInd, subS.where());
else
parent.where(subS.where());
GridSqlElement parentFrom = parent.from() instanceof GridSqlElement ? (GridSqlElement) parent.from() : new GridSqlSubquery((GridSqlQuery) parent.from());
parent.from(new GridSqlJoin(parentFrom, GridSqlAlias.unwrap(subS.from()), false, null)).child();
return true;
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.EXISTS in project ignite by apache.
the class GridSqlQueryParser method parseCreateTable.
/**
* Parse {@code CREATE TABLE} statement.
*
* @param createTbl {@code CREATE TABLE} statement.
* @see <a href="http://h2database.com/html/grammar.html#create_table">H2 {@code CREATE TABLE} spec.</a>
*/
private GridSqlCreateTable parseCreateTable(CreateTable createTbl) {
GridSqlCreateTable res = new GridSqlCreateTable();
res.templateName(QueryUtils.TEMPLATE_PARTITIONED);
Query qry = CREATE_TABLE_QUERY.get(createTbl);
if (qry != null) {
throw new IgniteSQLException("CREATE TABLE ... AS ... syntax is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
List<DefineCommand> constraints = CREATE_TABLE_CONSTRAINTS.get(createTbl);
if (F.isEmpty(constraints)) {
throw new IgniteSQLException("No PRIMARY KEY defined for CREATE TABLE", IgniteQueryErrorCode.PARSING);
}
if (constraints.size() > 1) {
throw new IgniteSQLException("Too many constraints - only PRIMARY KEY is supported for CREATE TABLE", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
DefineCommand constraint = constraints.get(0);
if (!(constraint instanceof AlterTableAddConstraint)) {
throw new IgniteSQLException("Unsupported type of constraint for CREATE TABLE - only PRIMARY KEY " + "is supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
AlterTableAddConstraint alterTbl = (AlterTableAddConstraint) constraint;
if (alterTbl.getType() != Command.ALTER_TABLE_ADD_CONSTRAINT_PRIMARY_KEY) {
throw new IgniteSQLException("Unsupported type of constraint for CREATE TABLE - only PRIMARY KEY " + "is supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
Schema schema = SCHEMA_COMMAND_SCHEMA.get(createTbl);
res.schemaName(schema.getName());
CreateTableData data = CREATE_TABLE_DATA.get(createTbl);
if (data.globalTemporary) {
throw new IgniteSQLException("GLOBAL TEMPORARY keyword is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
if (data.temporary) {
throw new IgniteSQLException("TEMPORARY keyword is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
if (data.isHidden) {
throw new IgniteSQLException("HIDDEN keyword is not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
if (!data.persistIndexes) {
throw new IgniteSQLException("MEMORY and NOT PERSISTENT keywords are not supported", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
LinkedHashMap<String, GridSqlColumn> cols = new LinkedHashMap<>(data.columns.size());
for (Column col : data.columns) {
if (cols.put(col.getName(), parseColumn(col)) != null)
throw new IgniteSQLException("Duplicate column name: " + col.getName(), IgniteQueryErrorCode.PARSING);
}
if (cols.containsKey(QueryUtils.KEY_FIELD_NAME.toUpperCase()) || cols.containsKey(QueryUtils.VAL_FIELD_NAME.toUpperCase())) {
throw new IgniteSQLException("Direct specification of _KEY and _VAL columns is forbidden", IgniteQueryErrorCode.PARSING);
}
IndexColumn[] pkIdxCols = CREATE_TABLE_PK.get(createTbl);
if (F.isEmpty(pkIdxCols))
throw new AssertionError("No PRIMARY KEY columns specified");
LinkedHashSet<String> pkCols = new LinkedHashSet<>();
for (IndexColumn pkIdxCol : pkIdxCols) {
GridSqlColumn gridCol = cols.get(pkIdxCol.columnName);
if (gridCol == null) {
throw new IgniteSQLException("PRIMARY KEY column is not defined: " + pkIdxCol.columnName, IgniteQueryErrorCode.PARSING);
}
pkCols.add(gridCol.columnName());
}
int keyColsNum = pkCols.size();
int valColsNum = cols.size() - keyColsNum;
if (valColsNum == 0) {
throw new IgniteSQLException("Table must have at least one non PRIMARY KEY column.", IgniteQueryErrorCode.UNSUPPORTED_OPERATION);
}
res.columns(cols);
res.primaryKeyColumns(pkCols);
res.tableName(data.tableName);
res.ifNotExists(CREATE_TABLE_IF_NOT_EXISTS.get(createTbl));
List<String> extraParams = data.tableEngineParams != null ? new ArrayList<String>() : null;
if (data.tableEngineParams != null)
for (String s : data.tableEngineParams) extraParams.addAll(F.asList(s.split(",")));
res.params(extraParams);
if (!F.isEmpty(extraParams)) {
Map<String, String> params = new HashMap<>();
for (String p : extraParams) {
String[] parts = p.split(PARAM_NAME_VALUE_SEPARATOR);
if (parts.length > 2) {
throw new IgniteSQLException("Invalid parameter (key[=value] expected): " + p, IgniteQueryErrorCode.PARSING);
}
String name = parts[0].trim().toUpperCase();
String val = parts.length > 1 ? parts[1].trim() : null;
if (F.isEmpty(name)) {
throw new IgniteSQLException("Invalid parameter (key[=value] expected): " + p, IgniteQueryErrorCode.PARSING);
}
if (params.put(name, val) != null)
throw new IgniteSQLException("Duplicate parameter: " + p, IgniteQueryErrorCode.PARSING);
}
for (Map.Entry<String, String> e : params.entrySet()) processExtraParam(e.getKey(), e.getValue(), res);
}
// Process key wrapping.
Boolean wrapKey = res.wrapKey();
if (wrapKey != null && !wrapKey) {
if (keyColsNum > 1) {
throw new IgniteSQLException(PARAM_WRAP_KEY + " cannot be false when composite primary key exists.", IgniteQueryErrorCode.PARSING);
}
if (!F.isEmpty(res.keyTypeName())) {
throw new IgniteSQLException(PARAM_WRAP_KEY + " cannot be false when " + PARAM_KEY_TYPE + " is set.", IgniteQueryErrorCode.PARSING);
}
}
boolean wrapKey0 = (res.wrapKey() != null && res.wrapKey()) || !F.isEmpty(res.keyTypeName()) || keyColsNum > 1;
res.wrapKey(wrapKey0);
// Process value wrapping.
Boolean wrapVal = res.wrapValue();
if (wrapVal != null && !wrapVal) {
if (valColsNum > 1) {
throw new IgniteSQLException(PARAM_WRAP_VALUE + " cannot be false when multiple non-primary key " + "columns exist.", IgniteQueryErrorCode.PARSING);
}
if (!F.isEmpty(res.valueTypeName())) {
throw new IgniteSQLException(PARAM_WRAP_VALUE + " cannot be false when " + PARAM_VAL_TYPE + " is set.", IgniteQueryErrorCode.PARSING);
}
res.wrapValue(false);
} else
// By default value is always wrapped to allow for ALTER TABLE ADD COLUMN commands.
res.wrapValue(true);
if (!F.isEmpty(res.valueTypeName()) && F.eq(res.keyTypeName(), res.valueTypeName())) {
throw new IgniteSQLException("Key and value type names " + "should be different for CREATE TABLE: " + res.valueTypeName(), IgniteQueryErrorCode.PARSING);
}
if (res.affinityKey() == null) {
LinkedHashSet<String> pkCols0 = res.primaryKeyColumns();
if (!F.isEmpty(pkCols0) && pkCols0.size() == 1 && wrapKey0)
res.affinityKey(pkCols0.iterator().next());
}
return res;
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.EXISTS in project ignite by apache.
the class IgniteStatisticsHelper method aggregateLocalStatistics.
/**
* Aggregate specified partition level statistics to local level statistics.
*
* @param cfg Statistics object configuration.
* @param stats Collection of all local partition level or local level statistics by specified key to aggregate.
* @return Local level aggregated statistics.
*/
public ObjectStatisticsImpl aggregateLocalStatistics(StatisticsObjectConfiguration cfg, Collection<? extends ObjectStatisticsImpl> stats) {
StatisticsKeyMessage keyMsg = new StatisticsKeyMessage(cfg.key().schema(), cfg.key().obj(), new ArrayList<>(cfg.columns().keySet()));
// For now there can be only tables
GridH2Table tbl = schemaMgr.dataTable(keyMsg.schema(), keyMsg.obj());
if (tbl == null) {
// remove all loaded statistics.
if (log.isDebugEnabled())
log.debug(String.format("Removing statistics for object %s.%s cause table doesn't exists.", keyMsg.schema(), keyMsg.obj()));
return null;
}
return aggregateLocalStatistics(tbl, cfg, stats, log);
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.EXISTS in project ignite by apache.
the class GridH2Table method dropColumns.
/**
* Drop columns.
*
* @param cols Columns.
* @param ifExists If EXISTS flag.
*/
@SuppressWarnings("ForLoopReplaceableByForEach")
public void dropColumns(List<String> cols, boolean ifExists) {
assert !ifExists || cols.size() == 1;
lock(true);
try {
Column[] safeColumns0 = safeColumns;
int size = safeColumns0.length;
for (String name : cols) {
if (!doesColumnExist(name)) {
if (ifExists && cols.size() == 1)
return;
else
throw new IgniteSQLException("Column does not exist [tblName=" + getName() + ", colName=" + name + ']');
}
size--;
}
assert size > QueryUtils.DEFAULT_COLUMNS_COUNT;
Column[] newCols = new Column[size];
int dst = 0;
for (int i = 0; i < safeColumns0.length; i++) {
Column column = safeColumns0[i];
for (String name : cols) {
if (F.eq(name, column.getName())) {
column = null;
break;
}
}
if (column != null)
newCols[dst++] = column;
}
setColumns(newCols);
desc.refreshMetadataFromTypeDescriptor();
for (Index idx : getIndexes()) {
if (idx instanceof GridH2IndexBase)
((GridH2IndexBase) idx).refreshColumnIds();
}
incrementModificationCounter();
} finally {
unlock(true);
}
}
use of org.apache.ignite.internal.processors.query.h2.sql.GridSqlOperationType.EXISTS in project ignite by apache.
the class IgniteH2Indexing method dropTable.
/**
* Drops table form h2 database and clear all related indexes (h2 text, lucene).
*
* @param tbl Table to unregister.
* @throws IgniteCheckedException If failed to unregister.
*/
private void dropTable(H2TableDescriptor tbl) throws IgniteCheckedException {
assert tbl != null;
if (log.isDebugEnabled())
log.debug("Removing query index table: " + tbl.fullTableName());
Connection c = connectionForThread(tbl.schemaName());
Statement stmt = null;
try {
stmt = c.createStatement();
String sql = "DROP TABLE IF EXISTS " + tbl.fullTableName();
if (log.isDebugEnabled())
log.debug("Dropping database index table with SQL: " + sql);
stmt.executeUpdate(sql);
} catch (SQLException e) {
onSqlException();
throw new IgniteSQLException("Failed to drop database index table [type=" + tbl.type().name() + ", table=" + tbl.fullTableName() + "]", IgniteQueryErrorCode.TABLE_DROP_FAILED, e);
} finally {
U.close(stmt, log);
}
}
Aggregations