Search in sources :

Example 26 with Column

use of org.h2.table.Column 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);
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) GridBoundedConcurrentLinkedHashMap(org.apache.ignite.internal.util.GridBoundedConcurrentLinkedHashMap) IgniteBiTuple(org.apache.ignite.lang.IgniteBiTuple) GridQueryTypeDescriptor(org.apache.ignite.internal.processors.query.GridQueryTypeDescriptor) GridQueryProperty(org.apache.ignite.internal.processors.query.GridQueryProperty) GridH2RowDescriptor(org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor) Column(org.h2.table.Column) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) BinaryObject(org.apache.ignite.binary.BinaryObject) BinaryObjectBuilder(org.apache.ignite.binary.BinaryObjectBuilder)

Example 27 with Column

use of org.h2.table.Column in project ignite by apache.

the class DmlStatementsProcessor method convert.

/**
     * Convert value to column's expected type by means of H2.
     *
     * @param val Source value.
     * @param desc Row descriptor.
     * @param expCls Expected value class.
     * @param type Expected column type to convert to.
     * @return Converted object.
     * @throws IgniteCheckedException if failed.
     */
@SuppressWarnings({ "ConstantConditions", "SuspiciousSystemArraycopy" })
private static Object convert(Object val, GridH2RowDescriptor desc, Class<?> expCls, int type) throws IgniteCheckedException {
    if (val == null)
        return null;
    Class<?> currCls = val.getClass();
    if (val instanceof Date && currCls != Date.class && expCls == Date.class) {
        // precise Date instance. Let's satisfy it.
        return new Date(((Date) val).getTime());
    }
    // User-given UUID is always serialized by H2 to byte array, so we have to deserialize manually
    if (type == Value.UUID && currCls == byte[].class)
        return U.unmarshal(desc.context().marshaller(), (byte[]) val, U.resolveClassLoader(desc.context().gridConfig()));
    // Still, we only can convert from Object[] to something more precise.
    if (type == Value.ARRAY && currCls != expCls) {
        if (currCls != Object[].class)
            throw new IgniteCheckedException("Unexpected array type - only conversion from Object[] is assumed");
        // Why would otherwise type be Value.ARRAY?
        assert expCls.isArray();
        Object[] curr = (Object[]) val;
        Object newArr = Array.newInstance(expCls.getComponentType(), curr.length);
        System.arraycopy(curr, 0, newArr, 0, curr.length);
        return newArr;
    }
    int objType = DataType.getTypeFromClass(val.getClass());
    if (objType == type)
        return val;
    Value h2Val = desc.wrap(val, objType);
    return h2Val.convertTo(type).getObject();
}
Also used : IgniteCheckedException(org.apache.ignite.IgniteCheckedException) Value(org.h2.value.Value) BinaryObject(org.apache.ignite.binary.BinaryObject) Date(java.util.Date)

Example 28 with Column

use of org.h2.table.Column 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);
}
Also used : Column(org.h2.table.Column) Expression(org.h2.expression.Expression) Value(org.h2.value.Value) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) DataType(org.h2.value.DataType) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteException(org.apache.ignite.IgniteException) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException)

Example 29 with Column

use of org.h2.table.Column in project ignite by apache.

the class UpdatePlanBuilder method planForUpdate.

/**
     * Prepare update plan for UPDATE or DELETE.
     *
     * @param stmt UPDATE or DELETE statement.
     * @param errKeysPos index to inject param for re-run keys at. Null if it's not a re-run plan.
     * @return Update plan.
     * @throws IgniteCheckedException if failed.
     */
private static UpdatePlan planForUpdate(GridSqlStatement stmt, @Nullable Integer errKeysPos) throws IgniteCheckedException {
    GridSqlElement target;
    FastUpdateArguments fastUpdate;
    UpdateMode mode;
    if (stmt instanceof GridSqlUpdate) {
        // Let's verify that user is not trying to mess with key's columns directly
        verifyUpdateColumns(stmt);
        GridSqlUpdate update = (GridSqlUpdate) stmt;
        target = update.target();
        fastUpdate = DmlAstUtils.getFastUpdateArgs(update);
        mode = UpdateMode.UPDATE;
    } else if (stmt instanceof GridSqlDelete) {
        GridSqlDelete del = (GridSqlDelete) stmt;
        target = del.from();
        fastUpdate = DmlAstUtils.getFastDeleteArgs(del);
        mode = UpdateMode.DELETE;
    } else
        throw new IgniteSQLException("Unexpected DML operation [cls=" + stmt.getClass().getName() + ']', IgniteQueryErrorCode.UNEXPECTED_OPERATION);
    GridSqlTable tbl = gridTableForElement(target);
    GridH2Table gridTbl = tbl.dataTable();
    GridH2RowDescriptor desc = gridTbl.rowDescriptor();
    if (desc == null)
        throw new IgniteSQLException("Row descriptor undefined for table '" + gridTbl.getName() + "'", IgniteQueryErrorCode.NULL_TABLE_DESCRIPTOR);
    if (fastUpdate != null)
        return UpdatePlan.forFastUpdate(mode, gridTbl, fastUpdate);
    else {
        GridSqlSelect sel;
        if (stmt instanceof GridSqlUpdate) {
            List<GridSqlColumn> updatedCols = ((GridSqlUpdate) stmt).cols();
            int valColIdx = -1;
            String[] colNames = new String[updatedCols.size()];
            int[] colTypes = new int[updatedCols.size()];
            for (int i = 0; i < updatedCols.size(); i++) {
                colNames[i] = updatedCols.get(i).columnName();
                colTypes[i] = updatedCols.get(i).resultType().type();
                Column column = updatedCols.get(i).column();
                if (desc.isValueColumn(column.getColumnId()))
                    valColIdx = i;
            }
            boolean hasNewVal = (valColIdx != -1);
            // Statement updates distinct properties if it does not have _val in updated columns list
            // or if its list of updated columns includes only _val, i.e. is single element.
            boolean hasProps = !hasNewVal || updatedCols.size() > 1;
            // Index of new _val in results of SELECT
            if (hasNewVal)
                valColIdx += 2;
            int newValColIdx = (hasNewVal ? valColIdx : 1);
            KeyValueSupplier newValSupplier = createSupplier(desc.context(), desc.type(), newValColIdx, hasProps, false, true);
            sel = DmlAstUtils.selectForUpdate((GridSqlUpdate) stmt, errKeysPos);
            return UpdatePlan.forUpdate(gridTbl, colNames, colTypes, newValSupplier, valColIdx, sel.getSQL());
        } else {
            sel = DmlAstUtils.selectForDelete((GridSqlDelete) stmt, errKeysPos);
            return UpdatePlan.forDelete(gridTbl, sel.getSQL());
        }
    }
}
Also used : GridSqlDelete(org.apache.ignite.internal.processors.query.h2.sql.GridSqlDelete) GridSqlSelect(org.apache.ignite.internal.processors.query.h2.sql.GridSqlSelect) GridH2RowDescriptor(org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor) Column(org.h2.table.Column) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) GridSqlTable(org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable) GridH2Table(org.apache.ignite.internal.processors.query.h2.opt.GridH2Table) GridSqlColumn(org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn) IgniteSQLException(org.apache.ignite.internal.processors.query.IgniteSQLException) GridSqlElement(org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement) GridSqlUpdate(org.apache.ignite.internal.processors.query.h2.sql.GridSqlUpdate)

Example 30 with Column

use of org.h2.table.Column in project ignite by apache.

the class GridH2KeyValueRowOffheap method getOffheapValue.

/** {@inheritDoc} */
@SuppressWarnings("LockAcquiredButNotSafelyReleased")
@Override
protected Value getOffheapValue(int col) {
    GridUnsafeMemory mem = desc.memory();
    long p = ptr;
    assert p > 0 : p;
    byte[] bytes = null;
    if (col == KEY_COL) {
        int size = mem.readInt(p + OFFSET_KEY_SIZE);
        assert size > 0 : size;
        bytes = mem.readBytes(p + OFFSET_KEY, size);
    } else if (col == VAL_COL) {
        Lock l = lock(p);
        desc.guard().begin();
        try {
            long valPtr = mem.readLongVolatile(p + OFFSET_VALUE_REF);
            if (// Value was evicted.
            valPtr == 0)
                return null;
            int size = mem.readInt(valPtr);
            assert size > 0 : size;
            bytes = mem.readBytes(valPtr + OFFSET_VALUE, size);
        } finally {
            desc.guard().end();
            l.unlock();
        }
    } else
        throw new IllegalStateException("Column: " + col);
    Data data = Data.create(null, bytes);
    return data.readValue();
}
Also used : Data(org.h2.store.Data) GridUnsafeMemory(org.apache.ignite.internal.util.offheap.unsafe.GridUnsafeMemory) GridStripedLock(org.apache.ignite.internal.util.GridStripedLock) Lock(java.util.concurrent.locks.Lock)

Aggregations

Column (org.h2.table.Column)29 IgniteSQLException (org.apache.ignite.internal.processors.query.IgniteSQLException)16 IndexColumn (org.h2.table.IndexColumn)15 GridH2RowDescriptor (org.apache.ignite.internal.processors.query.h2.opt.GridH2RowDescriptor)12 GridH2Table (org.apache.ignite.internal.processors.query.h2.opt.GridH2Table)11 AlterTableAlterColumn (org.h2.command.ddl.AlterTableAlterColumn)8 ExpressionColumn (org.h2.expression.ExpressionColumn)8 ArrayList (java.util.ArrayList)7 GridSqlColumn (org.apache.ignite.internal.processors.query.h2.sql.GridSqlColumn)7 GridSqlType.fromColumn (org.apache.ignite.internal.processors.query.h2.sql.GridSqlType.fromColumn)7 AlterTableAddConstraint (org.h2.command.ddl.AlterTableAddConstraint)7 Expression (org.h2.expression.Expression)7 HashMap (java.util.HashMap)6 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)6 HashSet (java.util.HashSet)5 LinkedHashMap (java.util.LinkedHashMap)5 IgniteException (org.apache.ignite.IgniteException)5 GridSqlElement (org.apache.ignite.internal.processors.query.h2.sql.GridSqlElement)5 GridSqlTable (org.apache.ignite.internal.processors.query.h2.sql.GridSqlTable)5 ValueExpression (org.h2.expression.ValueExpression)5