com.amazon.redshift.jdbc.PrimitiveArraySupport Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of redshift-jdbc42 Show documentation
Show all versions of redshift-jdbc42 Show documentation
Java JDBC 4.2 (JRE 8+) driver for Redshift database
/*
* Copyright (c) 2004, PostgreSQL Global Development Group
* See the LICENSE file in the project root for more information.
*/
package com.amazon.redshift.jdbc;
import com.amazon.redshift.core.Oid;
import com.amazon.redshift.core.TypeInfo;
import com.amazon.redshift.util.ByteConverter;
import java.sql.Connection;
import java.sql.SQLFeatureNotSupportedException;
import java.util.HashMap;
import java.util.Map;
abstract class PrimitiveArraySupport {
public abstract int getDefaultArrayTypeOid(TypeInfo tiCache);
public abstract String toArrayString(char delim, A array);
public abstract void appendArray(StringBuilder sb, char delim, A array);
public boolean supportBinaryRepresentation() {
return true;
}
public abstract byte[] toBinaryRepresentation(Connection connection, A array) throws SQLFeatureNotSupportedException;
private static final PrimitiveArraySupport LONG_ARRAY = new PrimitiveArraySupport() {
/**
* {@inheritDoc}
*/
@Override
public int getDefaultArrayTypeOid(TypeInfo tiCache) {
return Oid.INT8_ARRAY;
}
@Override
public String toArrayString(char delim, long[] array) {
final StringBuilder sb = new StringBuilder(Math.max(64, array.length * 8));
appendArray(sb, delim, array);
return sb.toString();
}
/**
* {@inheritDoc}
*/
@Override
public void appendArray(StringBuilder sb, char delim, long[] array) {
sb.append('{');
for (int i = 0; i < array.length; ++i) {
if (i > 0) {
sb.append(delim);
}
sb.append(array[i]);
}
sb.append('}');
}
/**
* {@inheritDoc}
*/
@Override
public byte[] toBinaryRepresentation(Connection connection, long[] array) {
int length = 20 + (12 * array.length);
final byte[] bytes = new byte[length];
// 1 dimension
ByteConverter.int4(bytes, 0, 1);
// no null
ByteConverter.int4(bytes, 4, 0);
// oid
ByteConverter.int4(bytes, 8, Oid.INT8);
// length
ByteConverter.int4(bytes, 12, array.length);
int idx = 20;
for (int i = 0; i < array.length; ++i) {
bytes[idx + 3] = 8;
ByteConverter.int8(bytes, idx + 4, array[i]);
idx += 12;
}
return bytes;
}
};
private static final PrimitiveArraySupport INT_ARRAY = new PrimitiveArraySupport() {
/**
* {@inheritDoc}
*/
@Override
public int getDefaultArrayTypeOid(TypeInfo tiCache) {
return Oid.INT4_ARRAY;
}
@Override
public String toArrayString(char delim, int[] array) {
final StringBuilder sb = new StringBuilder(Math.max(32, array.length * 6));
appendArray(sb, delim, array);
return sb.toString();
}
/**
* {@inheritDoc}
*/
@Override
public void appendArray(StringBuilder sb, char delim, int[] array) {
sb.append('{');
for (int i = 0; i < array.length; ++i) {
if (i > 0) {
sb.append(delim);
}
sb.append(array[i]);
}
sb.append('}');
}
/**
* {@inheritDoc}
*/
@Override
public byte[] toBinaryRepresentation(Connection connection, int[] array) {
int length = 20 + (8 * array.length);
final byte[] bytes = new byte[length];
// 1 dimension
ByteConverter.int4(bytes, 0, 1);
// no null
ByteConverter.int4(bytes, 4, 0);
// oid
ByteConverter.int4(bytes, 8, Oid.INT4);
// length
ByteConverter.int4(bytes, 12, array.length);
int idx = 20;
for (int i = 0; i < array.length; ++i) {
bytes[idx + 3] = 4;
ByteConverter.int4(bytes, idx + 4, array[i]);
idx += 8;
}
return bytes;
}
};
private static final PrimitiveArraySupport SHORT_ARRAY = new PrimitiveArraySupport() {
/**
* {@inheritDoc}
*/
@Override
public int getDefaultArrayTypeOid(TypeInfo tiCache) {
return Oid.INT2_ARRAY;
}
@Override
public String toArrayString(char delim, short[] array) {
final StringBuilder sb = new StringBuilder(Math.max(32, array.length * 4));
appendArray(sb, delim, array);
return sb.toString();
}
/**
* {@inheritDoc}
*/
@Override
public void appendArray(StringBuilder sb, char delim, short[] array) {
sb.append('{');
for (int i = 0; i < array.length; ++i) {
if (i > 0) {
sb.append(delim);
}
sb.append(array[i]);
}
sb.append('}');
}
/**
* {@inheritDoc}
*/
@Override
public byte[] toBinaryRepresentation(Connection connection, short[] array) {
int length = 20 + (6 * array.length);
final byte[] bytes = new byte[length];
// 1 dimension
ByteConverter.int4(bytes, 0, 1);
// no null
ByteConverter.int4(bytes, 4, 0);
// oid
ByteConverter.int4(bytes, 8, Oid.INT2);
// length
ByteConverter.int4(bytes, 12, array.length);
int idx = 20;
for (int i = 0; i < array.length; ++i) {
bytes[idx + 3] = 2;
ByteConverter.int2(bytes, idx + 4, array[i]);
idx += 6;
}
return bytes;
}
};
private static final PrimitiveArraySupport DOUBLE_ARRAY = new PrimitiveArraySupport() {
/**
* {@inheritDoc}
*/
@Override
public int getDefaultArrayTypeOid(TypeInfo tiCache) {
return Oid.FLOAT8_ARRAY;
}
@Override
public String toArrayString(char delim, double[] array) {
final StringBuilder sb = new StringBuilder(Math.max(64, array.length * 8));
appendArray(sb, delim, array);
return sb.toString();
}
/**
* {@inheritDoc}
*/
@Override
public void appendArray(StringBuilder sb, char delim, double[] array) {
sb.append('{');
for (int i = 0; i < array.length; ++i) {
if (i > 0) {
sb.append(delim);
}
// use quotes to account for any issues with scientific notation
sb.append('"');
sb.append(array[i]);
sb.append('"');
}
sb.append('}');
}
/**
* {@inheritDoc}
*/
@Override
public byte[] toBinaryRepresentation(Connection connection, double[] array) {
int length = 20 + (12 * array.length);
final byte[] bytes = new byte[length];
// 1 dimension
ByteConverter.int4(bytes, 0, 1);
// no null
ByteConverter.int4(bytes, 4, 0);
// oid
ByteConverter.int4(bytes, 8, Oid.FLOAT8);
// length
ByteConverter.int4(bytes, 12, array.length);
int idx = 20;
for (int i = 0; i < array.length; ++i) {
bytes[idx + 3] = 8;
ByteConverter.float8(bytes, idx + 4, array[i]);
idx += 12;
}
return bytes;
}
};
private static final PrimitiveArraySupport FLOAT_ARRAY = new PrimitiveArraySupport() {
/**
* {@inheritDoc}
*/
@Override
public int getDefaultArrayTypeOid(TypeInfo tiCache) {
return Oid.FLOAT4_ARRAY;
}
@Override
public String toArrayString(char delim, float[] array) {
final StringBuilder sb = new StringBuilder(Math.max(64, array.length * 8));
appendArray(sb, delim, array);
return sb.toString();
}
/**
* {@inheritDoc}
*/
@Override
public void appendArray(StringBuilder sb, char delim, float[] array) {
sb.append('{');
for (int i = 0; i < array.length; ++i) {
if (i > 0) {
sb.append(delim);
}
// use quotes to account for any issues with scientific notation
sb.append('"');
sb.append(array[i]);
sb.append('"');
}
sb.append('}');
}
/**
* {@inheritDoc}
*/
@Override
public byte[] toBinaryRepresentation(Connection connection, float[] array) {
int length = 20 + (8 * array.length);
final byte[] bytes = new byte[length];
// 1 dimension
ByteConverter.int4(bytes, 0, 1);
// no null
ByteConverter.int4(bytes, 4, 0);
// oid
ByteConverter.int4(bytes, 8, Oid.FLOAT4);
// length
ByteConverter.int4(bytes, 12, array.length);
int idx = 20;
for (int i = 0; i < array.length; ++i) {
bytes[idx + 3] = 4;
ByteConverter.float4(bytes, idx + 4, array[i]);
idx += 8;
}
return bytes;
}
};
private static final PrimitiveArraySupport BOOLEAN_ARRAY = new PrimitiveArraySupport() {
/**
* {@inheritDoc}
*/
@Override
public int getDefaultArrayTypeOid(TypeInfo tiCache) {
return Oid.BOOL_ARRAY;
}
@Override
public String toArrayString(char delim, boolean[] array) {
final StringBuilder sb = new StringBuilder(Math.max(64, array.length * 8));
appendArray(sb, delim, array);
return sb.toString();
}
/**
* {@inheritDoc}
*/
@Override
public void appendArray(StringBuilder sb, char delim, boolean[] array) {
sb.append('{');
for (int i = 0; i < array.length; ++i) {
if (i > 0) {
sb.append(delim);
}
sb.append(array[i] ? '1' : '0');
}
sb.append('}');
}
/**
* {@inheritDoc}
*
* @throws SQLFeatureNotSupportedException
* Because this feature is not supported.
*/
@Override
public byte[] toBinaryRepresentation(Connection connection, boolean[] array) throws SQLFeatureNotSupportedException {
int length = 20 + (5 * array.length);
final byte[] bytes = new byte[length];
// 1 dimension
ByteConverter.int4(bytes, 0, 1);
// no null
ByteConverter.int4(bytes, 4, 0);
// oid
ByteConverter.int4(bytes, 8, Oid.BOOL);
// length
ByteConverter.int4(bytes, 12, array.length);
int idx = 20;
for (int i = 0; i < array.length; ++i) {
bytes[idx + 3] = 1;
ByteConverter.bool(bytes, idx + 4, array[i]);
idx += 5;
}
return bytes;
}
};
private static final PrimitiveArraySupport STRING_ARRAY = new PrimitiveArraySupport() {
/**
* {@inheritDoc}
*/
@Override
public int getDefaultArrayTypeOid(TypeInfo tiCache) {
return Oid.VARCHAR_ARRAY;
}
@Override
public String toArrayString(char delim, String[] array) {
final StringBuilder sb = new StringBuilder(Math.max(64, array.length * 8));
appendArray(sb, delim, array);
return sb.toString();
}
/**
* {@inheritDoc}
*/
@Override
public void appendArray(StringBuilder sb, char delim, String[] array) {
sb.append('{');
for (int i = 0; i < array.length; ++i) {
if (i > 0) {
sb.append(delim);
}
if (array[i] == null) {
sb.append('N');
sb.append('U');
sb.append('L');
sb.append('L');
} else {
RedshiftArray.escapeArrayElement(sb, array[i]);
}
}
sb.append('}');
}
/**
* {@inheritDoc}
*/
@Override
public boolean supportBinaryRepresentation() {
return false;
}
/**
* {@inheritDoc}
*
* @throws SQLFeatureNotSupportedException
* Because this feature is not supported.
*/
@Override
public byte[] toBinaryRepresentation(Connection connection, String[] array) throws SQLFeatureNotSupportedException {
throw new SQLFeatureNotSupportedException();
}
};
private static final Map ARRAY_CLASS_TO_SUPPORT = new HashMap((int) (7 / .75) + 1);
static {
ARRAY_CLASS_TO_SUPPORT.put(long[].class, LONG_ARRAY);
ARRAY_CLASS_TO_SUPPORT.put(int[].class, INT_ARRAY);
ARRAY_CLASS_TO_SUPPORT.put(short[].class, SHORT_ARRAY);
ARRAY_CLASS_TO_SUPPORT.put(double[].class, DOUBLE_ARRAY);
ARRAY_CLASS_TO_SUPPORT.put(float[].class, FLOAT_ARRAY);
ARRAY_CLASS_TO_SUPPORT.put(boolean[].class, BOOLEAN_ARRAY);
ARRAY_CLASS_TO_SUPPORT.put(String[].class, STRING_ARRAY);
}
public static boolean isSupportedPrimitiveArray(Object obj) {
return obj != null && ARRAY_CLASS_TO_SUPPORT.containsKey(obj.getClass());
}
public static PrimitiveArraySupport getArraySupport(A array) {
return ARRAY_CLASS_TO_SUPPORT.get(array.getClass());
}
}