blob: 579931344f6d820f90655da7e241c23b52405fe1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.phoenix.schema.types;
import java.sql.Types;
import java.text.Format;
import java.util.Base64;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.util.ByteUtil;
public class PVarbinary extends PBinaryBase {
public static final PVarbinary INSTANCE = new PVarbinary();
private PVarbinary() {
super("VARBINARY", Types.VARBINARY, byte[].class, null, 22);
}
@Override
public byte[] toBytes(Object object) {
if (object == null) {
return ByteUtil.EMPTY_BYTE_ARRAY;
}
return (byte[]) object;
}
@Override
public int toBytes(Object object, byte[] bytes, int offset) {
if (object == null) {
return 0;
}
byte[] o = (byte[]) object;
// assumes there's enough room
System.arraycopy(bytes, offset, o, 0, o.length);
return o.length;
}
/**
* Override because we must always create a new byte array
*/
@Override
public byte[] toBytes(Object object, SortOrder sortOrder) {
byte[] bytes = toBytes(object);
// Override because we need to allocate a new buffer in this case
if (sortOrder == SortOrder.DESC) {
return SortOrder.invert(bytes, 0, new byte[bytes.length], 0, bytes.length);
}
return bytes;
}
@Override
public Object toObject(byte[] bytes, int offset, int length, PDataType actualType,
SortOrder sortOrder, Integer maxLength, Integer scale) {
if (length == 0) {
return null;
}
if (offset == 0 && bytes.length == length && sortOrder == SortOrder.ASC) {
return bytes;
}
byte[] bytesCopy = new byte[length];
System.arraycopy(bytes, offset, bytesCopy, 0, length);
if (sortOrder == SortOrder.DESC) {
bytesCopy = SortOrder.invert(bytes, offset, bytesCopy, 0, length);
offset = 0;
}
return bytesCopy;
}
@Override
public Object toObject(Object object, PDataType actualType) {
return actualType.toBytes(object);
}
@Override
public boolean isFixedWidth() {
return false;
}
@Override
public int estimateByteSize(Object o) {
byte[] value = (byte[]) o;
return value == null ? 1 : value.length;
}
@Override
public Integer getByteSize() {
return null;
}
@Override
public boolean isCoercibleTo(PDataType targetType) {
return equalsAny(targetType, this, PBinary.INSTANCE);
}
@Override
public int compareTo(Object lhs, Object rhs, PDataType rhsType) {
if (lhs == null && rhs == null) {
return 0;
} else if (lhs == null) {
return -1;
} else if (rhs == null) {
return 1;
}
if (equalsAny(rhsType, this, PBinary.INSTANCE)) {
return Bytes.compareTo((byte[]) lhs, (byte[]) rhs);
} else {
byte[] rhsBytes = rhsType.toBytes(rhs);
return Bytes.compareTo((byte[]) lhs, rhsBytes);
}
}
@Override
public Object toObject(String value) {
if (value == null || value.length() == 0) {
return null;
}
Object object = Base64.getDecoder().decode(value);
if (object == null) { throw newIllegalDataException(
"Input: [" + value + "] is not base64 encoded"); }
return object;
}
@Override
public String toStringLiteral(byte[] b, int o, int length, Format formatter) {
StringBuilder buf = new StringBuilder();
buf.append("X'");
if (length > 0) {
buf.append(Bytes.toHex(b, o, length));
}
buf.append("'");
return buf.toString();
}
@Override
public String toStringLiteral(Object o, Format formatter) {
return toStringLiteral((byte[])o, 0, ((byte[]) o).length, formatter);
}
@Override
public Object getSampleValue(Integer maxLength, Integer arrayLength) {
int length = maxLength != null && maxLength > 0 ? maxLength : 1;
byte[] b = new byte[length];
RANDOM.get().nextBytes(b);
return b;
}
}