/** * Encodes a int value to the byte array. * * @param target The byte array to encode to. * @param idx The starting index in the byte array. * @param value The value to encode. */ public static void float4(byte[] target, int idx, float value) { int4(target, idx, Float.floatToRawIntBits(value)); }
/** * {@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; } };
/** * Parses a float value from the byte array. * * @param bytes The byte array to parse. * @param idx The starting index of the parse in the byte array. * @return parsed float value. */ public static float float4(byte[] bytes, int idx) { return Float.intBitsToFloat(int4(bytes, idx)); }
/** * {@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; } };
/** * {@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; }
/** * {@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; }
/** * {@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; }
/** * {@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; }
public void setIntParameter(int index, int value) throws SQLException { byte[] data = new byte[4]; ByteConverter.int4(data, 0, value); bind(index, data, Oid.INT4, BINARY); }
private int calcRemainingDataLength(int[] dims, int pos, int elementOid, int thisDimension) { if (thisDimension == dims.length - 1) { for (int i = 0; i < dims[thisDimension]; ++i) { int len = ByteConverter.int4(fieldBytes, pos); pos += 4; if (len == -1) { continue; } pos += len; } } else { pos = calcRemainingDataLength(dims, elementOid, pos, thisDimension + 1); } return pos; }
private ResultSet readBinaryResultSet(int index, int count) throws SQLException { int dimensions = ByteConverter.int4(fieldBytes, 0); // int flags = ByteConverter.int4(fieldBytes, 4); // bit 0: 0=no-nulls, 1=has-nulls int elementOid = ByteConverter.int4(fieldBytes, 8); int pos = 12; int[] dims = new int[dimensions]; for (int d = 0; d < dimensions; ++d) { dims[d] = ByteConverter.int4(fieldBytes, pos); pos += 4; /* int lbound = ByteConverter.int4(fieldBytes, pos); */ pos += 4; } if (count > 0 && dimensions > 0) { dims[0] = Math.min(count, dims[0]); } List<byte[][]> rows = new ArrayList<byte[][]>(); Field[] fields = new Field[2]; storeValues(rows, fields, elementOid, dims, pos, 0, index); BaseStatement stat = (BaseStatement) connection .createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); return stat.createDriverResultSet(fields, rows); }
public static byte[] toBytes(Map<?, ?> m, Encoding encoding) throws SQLException { ByteArrayOutputStream baos = new ByteArrayOutputStream(4 + 10 * m.size()); byte[] lenBuf = new byte[4]; try { ByteConverter.int4(lenBuf, 0, m.size()); baos.write(lenBuf); for (Entry<?, ?> e : m.entrySet()) { byte[] key = encoding.encode(e.getKey().toString()); ByteConverter.int4(lenBuf, 0, key.length); baos.write(lenBuf); baos.write(key); if (e.getValue() == null) { ByteConverter.int4(lenBuf, 0, -1); baos.write(lenBuf); } else { byte[] val = encoding.encode(e.getValue().toString()); ByteConverter.int4(lenBuf, 0, val.length); baos.write(lenBuf); baos.write(val); } } } catch (IOException ioe) { throw new PSQLException( GT.tr( "Invalid character data was found. This is most likely caused by stored data containing characters that are invalid for the character set the database was created in. The most common example of this is storing 8bit data in a SQL_ASCII database."), PSQLState.DATA_ERROR, ioe); } return baos.toByteArray(); }
public static Map<String, String> fromBytes(byte[] b, Encoding encoding) throws SQLException { Map<String, String> m = new HashMap<String, String>(); int pos = 0; int numElements = ByteConverter.int4(b, pos); pos += 4; try { for (int i = 0; i < numElements; ++i) { int keyLen = ByteConverter.int4(b, pos); pos += 4; String key = encoding.decode(b, pos, keyLen); pos += keyLen; int valLen = ByteConverter.int4(b, pos); pos += 4; String val; if (valLen == -1) { val = null; } else { val = encoding.decode(b, pos, valLen); pos += valLen; } m.put(key, val); } } catch (IOException ioe) { throw new PSQLException( GT.tr( "Invalid character data was found. This is most likely caused by stored data containing characters that are invalid for the character set the database was created in. The most common example of this is storing 8bit data in a SQL_ASCII database."), PSQLState.DATA_ERROR, ioe); } return m; }
/** * Converts the SQL Date to binary representation for {@link Oid#DATE}. * * @param tz The timezone used. * @param bytes The binary encoded date value. * @param value value * @throws PSQLException If binary format could not be parsed. */ public void toBinDate(TimeZone tz, byte[] bytes, Date value) throws PSQLException { long millis = value.getTime(); if (tz == null) { tz = getDefaultTz(); } // It "getOffset" is UNTESTED // See org.postgresql.jdbc.AbstractJdbc2Statement.setDate(int, java.sql.Date, // java.util.Calendar) // The problem is we typically do not know for sure what is the exact required date/timestamp // type // Thus pgjdbc sticks to text transfer. millis += tz.getOffset(millis); long secs = toPgSecs(millis / 1000); ByteConverter.int4(bytes, 0, (int) (secs / 86400)); }
private Object readBinaryArray(int index, int count) throws SQLException { int dimensions = ByteConverter.int4(fieldBytes, 0); // int flags = ByteConverter.int4(fieldBytes, 4); // bit 0: 0=no-nulls, 1=has-nulls int elementOid = ByteConverter.int4(fieldBytes, 8); int pos = 12; int[] dims = new int[dimensions]; for (int d = 0; d < dimensions; ++d) { dims[d] = ByteConverter.int4(fieldBytes, pos); pos += 4; /* int lbound = ByteConverter.int4(fieldBytes, pos); */ pos += 4; } if (dimensions == 0) { return java.lang.reflect.Array.newInstance(elementOidToClass(elementOid), 0); } if (count > 0) { dims[0] = Math.min(count, dims[0]); } Object arr = java.lang.reflect.Array.newInstance(elementOidToClass(elementOid), dims); try { storeValues((Object[]) arr, elementOid, dims, pos, 0, index); } catch (IOException ioe) { throw new PSQLException( GT.tr( "Invalid character data was found. This is most likely caused by stored data containing characters that are invalid for the character set the database was created in. The most common example of this is storing 8bit data in a SQL_ASCII database."), PSQLState.DATA_ERROR, ioe); } return arr; }
public void setInt(int parameterIndex, int x) throws SQLException { checkClosed(); if (connection.binaryTransferSend(Oid.INT4)) { byte[] val = new byte[4]; ByteConverter.int4(val, 0, x); bindBytes(parameterIndex, val, Oid.INT4); return; } bindLiteral(parameterIndex, Integer.toString(x), Oid.INT4); }
/** * Send a function call to the PostgreSQL backend. * * @param fnId Function id * @param resultType True if the result is a numeric (Integer or Long) * @param args FastpathArguments to pass to fastpath * @return null if no data, Integer if an integer result, Long if a long result, or byte[] * otherwise * @throws SQLException if a database-access error occurs. * @deprecated please use {@link #fastpath(int, FastpathArg[])} */ @Deprecated public Object fastpath(int fnId, boolean resultType, FastpathArg[] args) throws SQLException { // Run it. byte[] returnValue = fastpath(fnId, args); // Interpret results. if (!resultType || returnValue == null) { return returnValue; } if (returnValue.length == 4) { return ByteConverter.int4(returnValue, 0); } else if (returnValue.length == 8) { return ByteConverter.int8(returnValue, 0); } else { throw new PSQLException( GT.tr("Fastpath call {0} - No result was returned and we expected a numeric.", fnId), PSQLState.NO_DATA); } }
/** * This convenience method assumes that the return value is an integer. * * @param name Function name * @param args Function arguments * @return integer result * @throws SQLException if a database-access error occurs or no result */ public int getInteger(String name, FastpathArg[] args) throws SQLException { byte[] returnValue = fastpath(name, args); if (returnValue == null) { throw new PSQLException( GT.tr("Fastpath call {0} - No result was returned and we expected an integer.", name), PSQLState.NO_DATA); } if (returnValue.length == 4) { return ByteConverter.int4(returnValue, 0); } else { throw new PSQLException(GT.tr( "Fastpath call {0} - No result was returned or wrong size while expecting an integer.", name), PSQLState.NO_DATA); } }
/** * Converts any numeric binary field to double value. This method does no overflow checking. * * @param bytes The bytes of the numeric field. * @param oid The oid of the field. * @param targetType The target type. Used for error reporting. * @return The value as double. * @throws PSQLException If the field type is not supported numeric type. */ private double readDoubleValue(byte[] bytes, int oid, String targetType) throws PSQLException { // currently implemented binary encoded fields switch (oid) { case Oid.INT2: return ByteConverter.int2(bytes, 0); case Oid.INT4: return ByteConverter.int4(bytes, 0); case Oid.INT8: // might not fit but there still should be no overflow checking return ByteConverter.int8(bytes, 0); case Oid.FLOAT4: return ByteConverter.float4(bytes, 0); case Oid.FLOAT8: return ByteConverter.float8(bytes, 0); } throw new PSQLException(GT.tr("Cannot convert the column of type {0} to requested type {1}.", Oid.toString(oid), targetType), PSQLState.DATA_TYPE_MISMATCH); }
public int getInt(int columnIndex) throws SQLException { connection.getLogger().log(Level.FINEST, " getInt columnIndex: {0}", columnIndex); checkResultSet(columnIndex); if (wasNullFlag) { return 0; // SQL NULL } if (isBinary(columnIndex)) { int col = columnIndex - 1; int oid = fields[col].getOID(); if (oid == Oid.INT4) { return ByteConverter.int4(this_row[col], 0); } return (int) readLongValue(this_row[col], oid, Integer.MIN_VALUE, Integer.MAX_VALUE, "int"); } Encoding encoding = connection.getEncoding(); if (encoding.hasAsciiNumbers()) { try { return getFastInt(columnIndex); } catch (NumberFormatException ex) { } } return toInt(getFixedString(columnIndex)); }