use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class GridH2Table method addColumns.
/**
* Add new columns to this table.
*
* @param cols Columns to add.
* @param ifNotExists Ignore this command if {@code cols} has size of 1 and column with given name already exists.
*/
public void addColumns(List<QueryField> cols, boolean ifNotExists) {
assert !ifNotExists || cols.size() == 1;
lock(true);
try {
int pos = columns.length;
Column[] newCols = new Column[columns.length + cols.size()];
// First, let's copy existing columns to new array
System.arraycopy(columns, 0, newCols, 0, columns.length);
// And now, let's add new columns
for (QueryField col : cols) {
if (doesColumnExist(col.name())) {
if (ifNotExists && cols.size() == 1)
return;
else
throw new IgniteSQLException("Column already exists [tblName=" + getName() + ", colName=" + col.name() + ']');
}
try {
Column c = new Column(col.name(), DataType.getTypeFromClass(Class.forName(col.typeName())));
c.setNullable(col.isNullable());
newCols[pos++] = c;
} catch (ClassNotFoundException e) {
throw new IgniteSQLException("H2 data type not found for class: " + col.typeName(), e);
}
}
setColumns(newCols);
desc.refreshMetadataFromTypeDescriptor();
setModified();
} finally {
unlock(true);
}
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class GridH2Table method dropColumns.
/**
* @param cols
* @param ifExists
*/
public void dropColumns(List<String> cols, boolean ifExists) {
assert !ifExists || cols.size() == 1;
lock(true);
try {
int size = columns.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 > DEFAULT_COLUMNS_COUNT;
Column[] newCols = new Column[size];
int dst = 0;
for (int i = 0; i < columns.length; i++) {
Column column = columns[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();
}
setModified();
} finally {
unlock(true);
}
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class DmlAstUtils method elementOrDefault.
/**
* Do what we can to compute default value for this column (mimics H2 behavior).
* @see Table#getDefaultValue
* @see Column#validateConvertUpdateSequence
* @param el SQL element.
* @param col Column.
* @return {@link GridSqlConst#NULL}, if {@code el} is null, or {@code el} if
* it's not {@link GridSqlKeyword#DEFAULT}, or computed default value.
*/
private static GridSqlElement elementOrDefault(GridSqlElement el, GridSqlColumn col) {
if (el == null)
return GridSqlConst.NULL;
if (el != GridSqlKeyword.DEFAULT)
return el;
Column h2Col = col.column();
Expression dfltExpr = h2Col.getDefaultExpression();
Value dfltVal;
try {
dfltVal = dfltExpr != null ? dfltExpr.getValue(null) : null;
} catch (Exception ignored) {
throw new IgniteSQLException("Failed to evaluate default value for a column " + col.columnName());
}
if (dfltVal != null)
return new GridSqlConst(dfltVal);
int type = h2Col.getType();
DataType dt = DataType.getDataType(type);
if (dt.decimal)
dfltVal = ValueInt.get(0).convertTo(type);
else if (dt.type == Value.TIMESTAMP)
dfltVal = ValueTimestamp.fromMillis(U.currentTimeMillis());
else if (dt.type == Value.TIME)
dfltVal = ValueTime.fromNanos(0);
else if (dt.type == Value.DATE)
dfltVal = ValueDate.fromMillis(U.currentTimeMillis());
else
dfltVal = ValueString.get("").convertTo(type);
return new GridSqlConst(dfltVal);
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException in project ignite by apache.
the class IgniteH2Indexing method queryDistributedSql.
/** {@inheritDoc} */
@SuppressWarnings("unchecked")
@Override
public <K, V> QueryCursor<Cache.Entry<K, V>> queryDistributedSql(String schemaName, SqlQuery qry, boolean keepBinary, int mainCacheId) {
String type = qry.getType();
H2TableDescriptor tblDesc = tableDescriptor(schemaName, type);
if (tblDesc == null)
throw new IgniteSQLException("Failed to find SQL table for type: " + type, IgniteQueryErrorCode.TABLE_NOT_FOUND);
String sql;
try {
sql = generateQuery(qry.getSql(), qry.getAlias(), tblDesc);
} catch (IgniteCheckedException e) {
throw new IgniteException(e);
}
SqlFieldsQuery fqry = new SqlFieldsQuery(sql);
fqry.setArgs(qry.getArgs());
fqry.setPageSize(qry.getPageSize());
fqry.setDistributedJoins(qry.isDistributedJoins());
fqry.setPartitions(qry.getPartitions());
fqry.setLocal(qry.isLocal());
if (qry.getTimeout() > 0)
fqry.setTimeout(qry.getTimeout(), TimeUnit.MILLISECONDS);
final QueryCursor<List<?>> res = queryDistributedSqlFields(schemaName, fqry, keepBinary, null, mainCacheId);
final Iterable<Cache.Entry<K, V>> converted = new Iterable<Cache.Entry<K, V>>() {
@Override
public Iterator<Cache.Entry<K, V>> iterator() {
final Iterator<List<?>> iter0 = res.iterator();
return new Iterator<Cache.Entry<K, V>>() {
@Override
public boolean hasNext() {
return iter0.hasNext();
}
@Override
public Cache.Entry<K, V> next() {
List<?> l = iter0.next();
return new CacheEntryImpl<>((K) l.get(0), (V) l.get(1));
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
// No metadata for SQL queries.
return new QueryCursorImpl<Cache.Entry<K, V>>(converted) {
@Override
public void close() {
res.close();
}
};
}
use of org.apache.ignite.internal.processors.query.IgniteSQLException 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);
}
Aggregations