/** * Encode the primary key values from the table as a byte array. The values must be in the same * order as the primary key constraint. If the connection and table are both tenant-specific, the * tenant ID column must not be present in the values. * * @param conn an open connection * @param fullTableName the full table name * @param values the values of the primary key columns ordered in the same order as the primary * key constraint * @return the encoded byte array * @throws SQLException if the table cannot be found or the incorrect number of of values are * provided * @see #decodePK(Connection, String, byte[]) to decode the byte[] back to the values */ public static byte[] encodePK(Connection conn, String fullTableName, Object[] values) throws SQLException { PTable table = getTable(conn, fullTableName); PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class); int offset = (table.getBucketNum() == null ? 0 : 1) + (table.isMultiTenant() && pconn.getTenantId() != null ? 1 : 0); List<PColumn> pkColumns = table.getPKColumns(); if (pkColumns.size() - offset != values.length) { throw new SQLException( "Expected " + (pkColumns.size() - offset) + " but got " + values.length); } PDataType type = null; TrustedByteArrayOutputStream output = new TrustedByteArrayOutputStream(table.getRowKeySchema().getEstimatedValueLength()); try { for (int i = offset; i < pkColumns.size(); i++) { if (type != null && !type.isFixedWidth()) { output.write(QueryConstants.SEPARATOR_BYTE); } type = pkColumns.get(i).getDataType(); byte[] value = type.toBytes(values[i - offset]); output.write(value); } return output.toByteArray(); } finally { try { output.close(); } catch (IOException e) { throw new RuntimeException(e); // Impossible } } }
/** * Decode a byte array value back into the Object values of the primary key constraint. If the * connection and table are both tenant-specific, the tenant ID column is not expected to have * been encoded and will not appear in the returned values. * * @param conn an open connection * @param name the full table name * @param value the value that was encoded with {@link #encodePK(Connection, String, Object[])} * @return the Object values encoded in the byte array value * @throws SQLException */ public static Object[] decodePK(Connection conn, String name, byte[] value) throws SQLException { PTable table = getTable(conn, name); PhoenixConnection pconn = conn.unwrap(PhoenixConnection.class); int offset = (table.getBucketNum() == null ? 0 : 1) + (table.isMultiTenant() && pconn.getTenantId() != null ? 1 : 0); RowKeySchema schema = table.getRowKeySchema(); int nValues = schema.getMaxFields() - offset; Object[] values = new Object[nValues]; ImmutableBytesWritable ptr = new ImmutableBytesWritable(); int i = 0; schema.iterator(value, ptr, offset); while (i < nValues && schema.next(ptr, i, value.length) != null) { values[i] = schema.getField(i).getDataType().toObject(ptr); i++; } return values; }