use of org.apache.ignite.internal.binary.BinaryArray in project ignite by apache.
the class QueryTypeDescriptorImpl method validateIndexes.
/**
* Validate indexed values.
*/
private void validateIndexes(Object key, Object val) throws IgniteCheckedException {
if (F.isEmpty(idxs))
return;
for (QueryIndexDescriptorImpl idx : idxs.values()) {
for (String idxField : idx.fields()) {
GridQueryProperty prop = props.get(idxField);
Object propVal;
Class<?> propType;
if (F.eq(idxField, keyFieldAlias()) || F.eq(idxField, KEY_FIELD_NAME)) {
propVal = key instanceof KeyCacheObject ? ((CacheObject) key).value(coCtx, true) : key;
propType = propVal == null ? null : propVal.getClass();
} else if (F.eq(idxField, valueFieldAlias()) || F.eq(idxField, VAL_FIELD_NAME)) {
propVal = val instanceof CacheObject ? ((CacheObject) val).value(coCtx, true) : val;
propType = propVal == null ? null : propVal.getClass();
} else {
propVal = prop.value(key, val);
propType = prop.type();
}
if (propVal == null)
continue;
if (!(propVal instanceof BinaryObject) || propVal instanceof BinaryArray) {
if (!U.box(propType).isAssignableFrom(U.box(propVal.getClass()))) {
// Some reference type arrays end up being converted to Object[]
if (!(propType.isArray() && BinaryUtils.isObjectArray(propVal.getClass()) && Arrays.stream(BinaryUtils.rawArrayFromBinary(propVal)).noneMatch(x -> x != null && !U.box(propType.getComponentType()).isAssignableFrom(U.box(x.getClass()))))) {
throw new IgniteSQLException("Type for a column '" + idxField + "' is not compatible with index definition. Expected '" + propType.getSimpleName() + "', actual type '" + propVal.getClass().getSimpleName() + "'");
}
}
} else if (coCtx.kernalContext().cacheObjects().typeId(propType.getName()) != ((BinaryObject) propVal).type().typeId()) {
// Check for classes/enums implementing indexed interfaces.
final Class<?> cls = U.classForName(((BinaryObject) propVal).type().typeName(), null, true);
if ((cls == null && propType == Object.class) || (cls != null && propType.isAssignableFrom(cls)))
continue;
throw new IgniteSQLException("Type for a column '" + idxField + "' is not compatible with index definition. Expected '" + propType.getSimpleName() + "', actual type '" + ((BinaryObject) propVal).type().typeName() + "'");
}
}
}
}
use of org.apache.ignite.internal.binary.BinaryArray in project ignite by apache.
the class QueryTypeDescriptorImpl method validateProps.
/**
* Validate properties.
*/
private void validateProps(Object key, Object val) throws IgniteCheckedException {
if (F.isEmpty(validateProps))
return;
final boolean validateTypes = coCtx.kernalContext().config().getSqlConfiguration().isValidationEnabled();
for (int i = 0; i < validateProps.size(); ++i) {
GridQueryProperty prop = validateProps.get(i);
Object propVal;
boolean isKey = false;
if (F.eq(prop.name(), keyFieldAlias()) || (keyFieldName == null && F.eq(prop.name(), KEY_FIELD_NAME))) {
propVal = key instanceof KeyCacheObject ? ((CacheObject) key).value(coCtx, true) : key;
isKey = true;
} else if (F.eq(prop.name(), valueFieldAlias()) || (valFieldName == null && F.eq(prop.name(), VAL_FIELD_NAME)))
propVal = val instanceof CacheObject ? ((CacheObject) val).value(coCtx, true) : val;
else
propVal = prop.value(key, val);
if (propVal == null && prop.notNull()) {
throw new IgniteSQLException("Null value is not allowed for column '" + prop.name() + "'", isKey ? NULL_KEY : NULL_VALUE);
}
if (validateTypes && propVal != null) {
if (!(propVal instanceof BinaryObject) || propVal instanceof BinaryArray) {
if (!U.box(prop.type()).isAssignableFrom(U.box(propVal.getClass()))) {
// Some reference type arrays end up being converted to Object[]
if (!(prop.type().isArray() && BinaryUtils.isObjectArray(propVal.getClass()) && Arrays.stream(BinaryUtils.rawArrayFromBinary(propVal)).noneMatch(x -> x != null && !U.box(prop.type().getComponentType()).isAssignableFrom(U.box(x.getClass()))))) {
throw new IgniteSQLException("Type for a column '" + prop.name() + "' is not compatible with table definition. Expected '" + prop.type().getSimpleName() + "', actual type '" + propVal.getClass().getSimpleName() + "'");
}
}
} else if (coCtx.kernalContext().cacheObjects().typeId(prop.type().getName()) != ((BinaryObject) propVal).type().typeId()) {
throw new IgniteSQLException("Type for a column '" + prop.name() + "' is not compatible with table definition. Expected '" + prop.type().getSimpleName() + "', actual type '" + ((BinaryObject) propVal).type().typeName() + "'");
}
}
if (propVal == null || prop.precision() == -1)
continue;
if (String.class == propVal.getClass() || byte[].class == propVal.getClass()) {
int propValLen = String.class == propVal.getClass() ? ((String) propVal).length() : ((byte[]) propVal).length;
if (propValLen > prop.precision()) {
throw new IgniteSQLException("Value for a column '" + prop.name() + "' is too long. " + "Maximum length: " + prop.precision() + ", actual length: " + propValLen, isKey ? TOO_LONG_KEY : TOO_LONG_VALUE);
}
} else if (BigDecimal.class == propVal.getClass()) {
BigDecimal dec = (BigDecimal) propVal;
if (dec.precision() > prop.precision()) {
throw new IgniteSQLException("Value for a column '" + prop.name() + "' is out of range. " + "Maximum precision: " + prop.precision() + ", actual precision: " + dec.precision(), isKey ? TOO_LONG_KEY : TOO_LONG_VALUE);
} else if (prop.scale() != -1 && dec.scale() > prop.scale()) {
throw new IgniteSQLException("Value for a column '" + prop.name() + "' is out of range. " + "Maximum scale : " + prop.scale() + ", actual scale: " + dec.scale(), isKey ? KEY_SCALE_OUT_OF_RANGE : VALUE_SCALE_OUT_OF_RANGE);
}
}
}
}
use of org.apache.ignite.internal.binary.BinaryArray in project ignite by apache.
the class PlatformCompute method executeJavaTask.
/**
* Execute task taking arguments from the given reader.
*
* @param reader Reader.
* @param async Execute asynchronously flag.
* @return Task result.
* @throws IgniteCheckedException On error.
*/
protected Object executeJavaTask(BinaryRawReaderEx reader, boolean async) throws IgniteCheckedException {
String taskName = reader.readString();
boolean keepBinary = reader.readBoolean();
Object arg = reader.readObjectDetached();
Collection<UUID> nodeIds = readNodeIds(reader);
IgniteCompute compute0 = computeForTask(nodeIds);
if (!keepBinary && (arg instanceof BinaryObjectImpl || arg instanceof BinaryArray))
arg = ((BinaryObject) arg).deserialize();
if (async)
return readAndListenFuture(reader, new ComputeConvertingFuture(compute0.executeAsync(taskName, arg)));
else
return toBinary(compute0.execute(taskName, arg));
}
use of org.apache.ignite.internal.binary.BinaryArray in project ignite by apache.
the class DmlUtils 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.
*/
@SuppressWarnings({ "ConstantConditions", "SuspiciousSystemArraycopy" })
public static Object convert(Object val, GridH2RowDescriptor desc, Class<?> expCls, int type, String columnName) {
if (val == null)
return null;
Class<?> currCls = val.getClass();
try {
// precise Date instance. Let's satisfy it.
if (val instanceof Date && currCls != Date.class && expCls == Date.class)
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()));
}
if (val instanceof Timestamp && LocalDateTimeUtils.LOCAL_DATE_TIME == expCls)
return LocalDateTimeUtils.valueToLocalDateTime(ValueTimestamp.get((Timestamp) val));
if (val instanceof Date && LocalDateTimeUtils.LOCAL_DATE == expCls) {
return LocalDateTimeUtils.valueToLocalDate(ValueDate.fromDateValue(DateTimeUtils.dateValueFromDate(((Date) val).getTime())));
}
if (val instanceof Time && LocalDateTimeUtils.LOCAL_TIME == expCls)
return LocalDateTimeUtils.valueToLocalTime(ValueTime.get((Time) val));
// Still, we only can convert from Object[] to something more precise.
if (type == Value.ARRAY && val instanceof BinaryArray)
return val;
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;
}
Object res = H2Utils.convert(val, desc.indexing(), type);
// without query - let's handle this
if (res instanceof Date && res.getClass() != Date.class && expCls == Date.class)
return new Date(((Date) res).getTime());
return res;
} catch (Exception e) {
throw new IgniteSQLException("Value conversion failed [column=" + columnName + ", from=" + currCls.getName() + ", to=" + expCls.getName() + ']', IgniteQueryErrorCode.CONVERSION_FAILED, e);
}
}
use of org.apache.ignite.internal.binary.BinaryArray in project ignite by apache.
the class BinaryBuilderSerializer method writeValue.
/**
* @param writer Writer.
* @param val Value.
* @param forceCol Whether to force collection type.
* @param forceMap Whether to force map type.
*/
public void writeValue(BinaryWriterExImpl writer, Object val, boolean forceCol, boolean forceMap) {
assert !(forceCol && forceMap);
if (val == null) {
writer.writeByte(GridBinaryMarshaller.NULL);
return;
}
if (val instanceof BinaryBuilderSerializationAware) {
((BinaryBuilderSerializationAware) val).writeTo(writer, this);
return;
}
if (val instanceof BinaryObjectExImpl) {
if (binaryObjToWrapper == null)
binaryObjToWrapper = new IdentityHashMap<>();
BinaryObjectBuilderImpl wrapper = binaryObjToWrapper.get(val);
if (wrapper == null) {
wrapper = BinaryObjectBuilderImpl.wrap((BinaryObject) val);
binaryObjToWrapper.put((BinaryObject) val, wrapper);
}
val = wrapper;
}
if (val instanceof BinaryObjectBuilderImpl) {
BinaryObjectBuilderImpl obj = (BinaryObjectBuilderImpl) val;
Integer posInResArr = objToPos.get(obj);
if (posInResArr == null) {
objToPos.put(obj, writer.out().position());
obj.serializeTo(writer.newWriter(obj.typeId()), this);
} else {
int handle = writer.out().position() - posInResArr;
writer.writeByte(GridBinaryMarshaller.HANDLE);
writer.writeInt(handle);
}
return;
}
if (val instanceof BinaryEnumObjectImpl) {
BinaryEnumObjectImpl obj = (BinaryEnumObjectImpl) val;
writer.writeByte(GridBinaryMarshaller.ENUM);
writer.writeInt(obj.typeId());
if (obj.typeId() == GridBinaryMarshaller.UNREGISTERED_TYPE_ID)
writer.doWriteString(obj.className());
writer.writeInt(obj.enumOrdinal());
return;
}
if (IgniteUtils.isEnum(val.getClass())) {
String clsName = ((Enum) val).getDeclaringClass().getName();
int typeId = writer.context().typeId(clsName);
// Need register class for marshaller to be able to deserialize enum value.
writer.context().registerClass(((Enum) val).getDeclaringClass(), true, false);
writer.writeByte(GridBinaryMarshaller.ENUM);
writer.writeInt(typeId);
writer.writeInt(((Enum) val).ordinal());
return;
}
if (forceCol || BinaryUtils.isSpecialCollection(val.getClass())) {
Collection<?> c = (Collection<?>) val;
writer.writeByte(GridBinaryMarshaller.COL);
writer.writeInt(c.size());
byte colType = writer.context().collectionType(c.getClass());
writer.writeByte(colType);
for (Object obj : c) writeValue(writer, obj);
return;
}
if (forceMap || BinaryUtils.isSpecialMap(val.getClass())) {
Map<?, ?> map = (Map<?, ?>) val;
writer.writeByte(GridBinaryMarshaller.MAP);
writer.writeInt(map.size());
writer.writeByte(writer.context().mapType(map.getClass()));
for (Map.Entry<?, ?> entry : map.entrySet()) {
writeValue(writer, entry.getKey());
writeValue(writer, entry.getValue());
}
return;
}
Byte flag = BinaryUtils.PLAIN_CLASS_TO_FLAG.get(val.getClass());
if (flag != null) {
BinaryUtils.writePlainObject(writer, val);
return;
}
if (val instanceof BinaryEnumArray) {
BinaryArray val0 = (BinaryArray) val;
if (val0.componentTypeId() == GridBinaryMarshaller.UNREGISTERED_TYPE_ID)
writeArray(writer, GridBinaryMarshaller.ENUM_ARR, val0.array(), val0.componentClassName());
else
writeArray(writer, GridBinaryMarshaller.ENUM_ARR, val0.array(), val0.componentTypeId());
return;
}
if (val instanceof BinaryArray) {
BinaryArray val0 = (BinaryArray) val;
if (val0.componentTypeId() == GridBinaryMarshaller.UNREGISTERED_TYPE_ID)
writeArray(writer, GridBinaryMarshaller.OBJ_ARR, val0.array(), val0.componentClassName());
else
writeArray(writer, GridBinaryMarshaller.OBJ_ARR, val0.array(), val0.componentTypeId());
return;
}
if (val instanceof Object[]) {
Class<?> compCls = ((Object[]) val).getClass().getComponentType();
int compTypeId = writer.context().typeId(compCls.getName());
if (BinaryEnumObjectImpl.class.isAssignableFrom(compCls) || val instanceof BinaryBuilderEnum[]) {
writeArray(writer, GridBinaryMarshaller.ENUM_ARR, (Object[]) val, compTypeId);
return;
}
if (compCls.isEnum()) {
Enum[] enumArr = (Enum[]) val;
writer.context().registerClass(compCls, true, false);
writer.writeByte(GridBinaryMarshaller.ENUM_ARR);
writer.writeInt(compTypeId);
writer.writeInt(enumArr.length);
for (Enum anEnum : enumArr) writeValue(writer, anEnum);
return;
}
writeArray(writer, GridBinaryMarshaller.OBJ_ARR, (Object[]) val, compTypeId);
return;
}
writer.doWriteObject(val);
}
Aggregations