phoenix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jya...@apache.org
Subject git commit: PHOENIX-78: MetaDataUtil must respect ClientKeyValue usage
Date Fri, 28 Feb 2014 01:34:27 GMT
Repository: incubator-phoenix
Updated Branches:
  refs/heads/master 8bbce3c10 -> d919a6c21


PHOENIX-78: MetaDataUtil must respect ClientKeyValue usage


Project: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/commit/d919a6c2
Tree: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/tree/d919a6c2
Diff: http://git-wip-us.apache.org/repos/asf/incubator-phoenix/diff/d919a6c2

Branch: refs/heads/master
Commit: d919a6c21a7edf5d11b937cd640753b5b77265b2
Parents: 8bbce3c
Author: Jesse Yates <jyates@apache.org>
Authored: Thu Feb 27 17:33:48 2014 -0800
Committer: Jesse Yates <jyates@apache.org>
Committed: Thu Feb 27 17:33:48 2014 -0800

----------------------------------------------------------------------
 .../apache/phoenix/client/ClientKeyValue.java   | 16 +++++
 .../phoenix/client/ClientKeyValueBuilder.java   | 15 ++++-
 .../phoenix/client/GenericKeyValueBuilder.java  | 13 ++++
 .../apache/phoenix/client/KeyValueBuilder.java  | 21 ++++++-
 .../coprocessor/MetaDataEndpointImpl.java       |  4 +-
 .../query/ConnectionQueryServicesImpl.java      | 17 +++---
 .../org/apache/phoenix/util/MetaDataUtil.java   | 62 ++++++++++++++------
 .../apache/phoenix/util/MetaDataUtilTest.java   | 56 +++++++++++++++++-
 8 files changed, 175 insertions(+), 29 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/d919a6c2/phoenix-core/src/main/java/org/apache/phoenix/client/ClientKeyValue.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/client/ClientKeyValue.java b/phoenix-core/src/main/java/org/apache/phoenix/client/ClientKeyValue.java
index 3288c4d..5b6aacf 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/client/ClientKeyValue.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/client/ClientKeyValue.java
@@ -500,4 +500,20 @@ public class ClientKeyValue extends KeyValue {
     throw new UnsupportedOperationException(ClientKeyValue.class.getSimpleName()
         + " does not support a single backing buffer.");
   }
+
+  public ImmutableBytesWritable getRawRow() {
+    return this.row;
+  }
+
+  public ImmutableBytesWritable getRawFamily() {
+    return this.family;
+  }
+
+  public ImmutableBytesWritable getRawQualifier() {
+    return this.qualifier;
+  }
+
+  public ImmutableBytesWritable getRawValue() {
+    return this.value;
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/d919a6c2/phoenix-core/src/main/java/org/apache/phoenix/client/ClientKeyValueBuilder.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/client/ClientKeyValueBuilder.java
b/phoenix-core/src/main/java/org/apache/phoenix/client/ClientKeyValueBuilder.java
index 5fd740d..71a1ddd 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/client/ClientKeyValueBuilder.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/client/ClientKeyValueBuilder.java
@@ -20,7 +20,7 @@ package org.apache.phoenix.client;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.KeyValue.Type;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
-
+import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 
 /**
@@ -62,4 +62,17 @@ public class ClientKeyValueBuilder extends KeyValueBuilder {
             ImmutableBytesWritable qualifier, long ts) {
         return new ClientKeyValue(row, family, qualifier, ts, Type.Delete, null);
   }
+
+  @Override
+  public int compareQualifier(KeyValue kv, byte[] key, int offset, int length) {
+        byte[] qual = kv.getQualifier();
+        return Bytes.compareTo(qual, 0, qual.length, key, offset, length);
+  }
+
+  @Override
+  public void getValueAsPtr(KeyValue kv, ImmutableBytesWritable ptr) {
+        ClientKeyValue ckv = (ClientKeyValue) kv;
+        ImmutableBytesWritable value = ckv.getRawValue();
+        ptr.set(value.get(), value.getOffset(), value.getLength());
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/d919a6c2/phoenix-core/src/main/java/org/apache/phoenix/client/GenericKeyValueBuilder.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/client/GenericKeyValueBuilder.java
b/phoenix-core/src/main/java/org/apache/phoenix/client/GenericKeyValueBuilder.java
index 27124bb..38e65f3 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/client/GenericKeyValueBuilder.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/client/GenericKeyValueBuilder.java
@@ -22,6 +22,8 @@ import org.apache.hadoop.hbase.KeyValue.Type;
 import org.apache.hadoop.hbase.client.Delete;
 import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 
 import static org.apache.phoenix.hbase.index.util.ImmutableBytesPtr.copyBytesIfNecessary;
 
@@ -66,4 +68,15 @@ public class GenericKeyValueBuilder extends KeyValueBuilder {
     return new KeyValue(copyBytesIfNecessary(row), copyBytesIfNecessary(family),
         copyBytesIfNecessary(qualifier), ts, type, value == null? null: copyBytesIfNecessary(value));
   }
+
+  @Override
+  public int compareQualifier(KeyValue kv, byte[] key, int offset, int length) {
+    return Bytes.compareTo(kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength(),
key,
+      offset, length);
+  }
+
+  @Override
+  public void getValueAsPtr(KeyValue kv, ImmutableBytesWritable writable) {
+    writable.set(kv.getBuffer(), kv.getValueOffset(), kv.getValueLength());
+  }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/d919a6c2/phoenix-core/src/main/java/org/apache/phoenix/client/KeyValueBuilder.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/client/KeyValueBuilder.java b/phoenix-core/src/main/java/org/apache/phoenix/client/KeyValueBuilder.java
index 93cef34..9980aa5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/client/KeyValueBuilder.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/client/KeyValueBuilder.java
@@ -24,6 +24,8 @@ import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.client.Delete;
 import org.apache.hadoop.hbase.client.Put;
 import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.util.MetaDataUtil;
 
 /**
@@ -103,4 +105,21 @@ public abstract class KeyValueBuilder {
 
   public abstract KeyValue buildDeleteColumn(ImmutableBytesWritable row,
             ImmutableBytesWritable family, ImmutableBytesWritable qualifier, long ts);
-}
\ No newline at end of file
+
+  /**
+   * Compare the qualifier based on the type of keyvalue. Assumes that the {@link KeyValue}
passed
+   * in was generated by the {@link KeyValueBuilder}
+   * @param kv to compare against
+   * @param key to compare
+   * @param offset in the passed key
+   * @param length length of the key from the offset to check
+   * @return the byte difference between the passed keyvalue's qualifier and the passed key
+   */
+  public abstract int compareQualifier(KeyValue kv, byte[] key, int offset, int length);
+
+  /**
+   * @param kv to read
+   * @param ptr set with the value from the {@link KeyValue}
+   */
+  public abstract void getValueAsPtr(KeyValue kv, ImmutableBytesWritable ptr);
+}

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/d919a6c2/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
index 09d2c6b..efe913c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/coprocessor/MetaDataEndpointImpl.java
@@ -82,6 +82,7 @@ import org.apache.hadoop.hbase.regionserver.RegionScanner;
 import org.apache.hadoop.hbase.util.Bytes;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
 import org.apache.phoenix.cache.GlobalCache;
+import org.apache.phoenix.client.GenericKeyValueBuilder;
 import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.hbase.index.util.IndexManagementUtil;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
@@ -843,7 +844,8 @@ public class MetaDataEndpointImpl extends BaseEndpointCoprocessor implements
Met
                     // Disallow mutation of an index table
                     return new MetaDataMutationResult(MutationCode.UNALLOWED_TABLE_MUTATION,
EnvironmentEdgeManager.currentTimeMillis(), null);
                 } else {
-                    PTableType expectedType = MetaDataUtil.getTableType(tableMetadata);
+                    // server-side, except for indexing, we always expect the keyvalues to
be standard KeyValues
+                    PTableType expectedType = MetaDataUtil.getTableType(tableMetadata, GenericKeyValueBuilder.INSTANCE,
new ImmutableBytesPtr());
                     // We said to drop a table, but found a view or visa versa
                     if (type != expectedType) {
                         return new MetaDataMutationResult(MutationCode.TABLE_NOT_FOUND, EnvironmentEdgeManager.currentTimeMillis(),
null);

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/d919a6c2/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
index f0c7491..33e97e5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/query/ConnectionQueryServicesImpl.java
@@ -72,6 +72,7 @@ import org.apache.phoenix.exception.SQLExceptionInfo;
 import org.apache.phoenix.execute.MutationState;
 import org.apache.phoenix.hbase.index.Indexer;
 import org.apache.phoenix.hbase.index.covered.CoveredColumnsIndexBuilder;
+import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.index.PhoenixIndexBuilder;
 import org.apache.phoenix.index.PhoenixIndexCodec;
 import org.apache.phoenix.jdbc.PhoenixConnection;
@@ -882,15 +883,15 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices
implement
             // For views this will ensure that metadata already exists
             ensureTableCreated(tableName, tableType, tableProps, families, splits, true);
         }
-
+        ImmutableBytesWritable ptr = new ImmutableBytesWritable();
         if (tableType == PTableType.INDEX && physicalTableName != null) { // Index
on view
             // Physical index table created up front for multi tenant
             // TODO: if viewIndexId is Short.MIN_VALUE, then we don't need to attempt to
create it
-            if (!MetaDataUtil.isMultiTenant(m)) {
+            if (!MetaDataUtil.isMultiTenant(m, kvBuilder, ptr)) {
                 ensureViewIndexTableCreated(physicalTableName, MetaDataUtil.getClientTimeStamp(m));
             }
-        } else if (tableType == PTableType.TABLE && MetaDataUtil.isMultiTenant(m))
{ // Create view index table up front for multi tenant tables
-            ensureViewIndexTableCreated(tableName, tableProps, families, MetaDataUtil.isSalted(m)
? splits : null, MetaDataUtil.getClientTimeStamp(m));
+        } else if (tableType == PTableType.TABLE && MetaDataUtil.isMultiTenant(m,
kvBuilder, ptr)) { // Create view index table up front for multi tenant tables
+            ensureViewIndexTableCreated(tableName, tableProps, families, MetaDataUtil.isSalted(m,
kvBuilder, ptr) ? splits : null, MetaDataUtil.getClientTimeStamp(m));
         }
         
         byte[] tableKey = SchemaUtil.getTableKey(tenantIdBytes, schemaBytes, tableBytes);
@@ -1069,6 +1070,7 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices
implement
         if (tableMetaData.size() == 1 && tableMetaData.get(0).isEmpty()) {
             return null;
         }
+        ImmutableBytesWritable ptr = new ImmutableBytesWritable();
         MetaDataMutationResult result =  metaDataCoprocessorExec(tableKey,
             new Batch.Call<MetaDataProtocol, MetaDataMutationResult>() {
                 @Override
@@ -1080,16 +1082,15 @@ public class ConnectionQueryServicesImpl extends DelegateQueryServices
implement
         if (result.getMutationCode() == MutationCode.COLUMN_NOT_FOUND) { // Success
             // Flush the table if transitioning DISABLE_WAL from TRUE to FALSE
             if (Boolean.FALSE.equals(PDataType.BOOLEAN.toObject(
-                    MetaDataUtil.getMutationKVByteValue(m,PhoenixDatabaseMetaData.DISABLE_WAL_BYTES))))
{
+                    MetaDataUtil.getMutationKVByteValue(m,PhoenixDatabaseMetaData.DISABLE_WAL_BYTES,
kvBuilder, ptr)))) {
                 flushTable(table.getPhysicalName().getBytes());
             }
             
             if (tableType == PTableType.TABLE) {
                 // If we're changing MULTI_TENANT to true or false, create or drop the view
index table
-                KeyValue kv = MetaDataUtil.getMutationKeyValue(m, PhoenixDatabaseMetaData.MULTI_TENANT_BYTES);
-                if (kv != null) {
+                if (MetaDataUtil.getMutationKeyValue(m, PhoenixDatabaseMetaData.MULTI_TENANT_BYTES,
kvBuilder, ptr)){
                     long timestamp = MetaDataUtil.getClientTimeStamp(m);
-                    if (Boolean.TRUE.equals(PDataType.BOOLEAN.toObject(kv.getBuffer(), kv.getValueOffset(),
kv.getValueLength()))) {
+                    if (Boolean.TRUE.equals(PDataType.BOOLEAN.toObject(ptr.get(), ptr.getOffset(),
ptr.getLength()))) {
                         this.ensureViewIndexTableCreated(table, timestamp);
                     } else {
                         this.ensureViewIndexTableDropped(table.getPhysicalName().getBytes(),
timestamp);

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/d919a6c2/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java b/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
index 9ae2558..e080d83 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/util/MetaDataUtil.java
@@ -27,8 +27,12 @@ import org.apache.hadoop.hbase.HTableDescriptor;
 import org.apache.hadoop.hbase.KeyValue;
 import org.apache.hadoop.hbase.client.Mutation;
 import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.client.ClientKeyValue;
+import org.apache.phoenix.client.KeyValueBuilder;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
+import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
 import org.apache.phoenix.jdbc.PhoenixConnection;
 import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.apache.phoenix.query.QueryConstants;
@@ -176,9 +180,13 @@ public class MetaDataUtil {
         return getSequenceNumber(getTableHeaderRow(tableMetaData));
     }
     
-    public static PTableType getTableType(List<Mutation> tableMetaData) {
-        KeyValue kv = getMutationKeyValue(getPutOnlyTableHeaderRow(tableMetaData), PhoenixDatabaseMetaData.TABLE_TYPE_BYTES);
-        return kv == null ? null : PTableType.fromSerializedValue(kv.getBuffer()[kv.getValueOffset()]);
+    public static PTableType getTableType(List<Mutation> tableMetaData, KeyValueBuilder
builder,
+      ImmutableBytesPtr value) {
+        if (getMutationKeyValue(getPutOnlyTableHeaderRow(tableMetaData),
+            PhoenixDatabaseMetaData.TABLE_TYPE_BYTES, builder, value)) {
+            return PTableType.fromSerializedValue(value.get()[value.getOffset()]);
+        }
+        return null;
     }
     
     public static long getParentSequenceNumber(List<Mutation> tableMetaData) {
@@ -189,21 +197,38 @@ public class MetaDataUtil {
         return tableMetaData.get(0);
     }
 
-    public static byte[] getMutationKVByteValue(Mutation headerRow, byte[] key) {
-        KeyValue kv = getMutationKeyValue(headerRow, key);
-        // FIXME: byte copy
-        return kv == null ? ByteUtil.EMPTY_BYTE_ARRAY : kv.getValue();
-    }
-
-    public static KeyValue getMutationKeyValue(Mutation headerRow, byte[] key) {
+    public static byte[] getMutationKVByteValue(Mutation headerRow, byte[] key,
+        KeyValueBuilder builder, ImmutableBytesWritable ptr) {
+        if (getMutationKeyValue(headerRow, key, builder, ptr)) {
+            return ByteUtil.copyKeyBytesIfNecessary(ptr);
+        }
+        return ByteUtil.EMPTY_BYTE_ARRAY;
+    }
+
+  /**
+   * Get the mutation who's qualifier matches the passed key
+   * <p>
+   * We need to pass in an {@link ImmutableBytesPtr} to pass the result back to make life
easier
+   * when dealing with a regular {@link KeyValue} vs. a {@link ClientKeyValue} as the latter
doesn't
+   * support things like {@link KeyValue#getBuffer()}
+   * @param headerRow mutation to check
+   * @param key to check
+   * @param builder that created the {@link KeyValue KeyValues} in the {@link Mutation}
+   * @param ptr to update with the value of the mutation
+   * @return the value of the matching {@link KeyValue}
+   */
+  public static boolean getMutationKeyValue(Mutation headerRow, byte[] key,
+      KeyValueBuilder builder, ImmutableBytesWritable ptr) {
         List<KeyValue> kvs = headerRow.getFamilyMap().get(PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES);
         if (kvs != null) {
             for (KeyValue kv : kvs) {
-                if (Bytes.compareTo(kv.getBuffer(), kv.getQualifierOffset(), kv.getQualifierLength(),
key, 0,
-                        key.length) == 0) { return kv; }
+                if (builder.compareQualifier(kv, key, 0, key.length) ==0) {
+                    builder.getValueAsPtr(kv, ptr);
+                    return true;
+                }
             }
         }
-        return null;
+        return false;
     }
 
     /**
@@ -241,12 +266,15 @@ public class MetaDataUtil {
         return ByteUtil.concat(tenantId == null ? ByteUtil.EMPTY_BYTE_ARRAY : tenantId, QueryConstants.SEPARATOR_BYTE_ARRAY,
schemaName == null ? ByteUtil.EMPTY_BYTE_ARRAY : schemaName, QueryConstants.SEPARATOR_BYTE_ARRAY,
tableName, QueryConstants.SEPARATOR_BYTE_ARRAY, QueryConstants.SEPARATOR_BYTE_ARRAY, indexName);
     }
     
-    public static boolean isMultiTenant(Mutation m) {
-        return Boolean.TRUE.equals(PDataType.BOOLEAN.toObject(MetaDataUtil.getMutationKVByteValue(m,
PhoenixDatabaseMetaData.MULTI_TENANT_BYTES)));
+    public static boolean isMultiTenant(Mutation m, KeyValueBuilder builder, ImmutableBytesWritable
ptr) {
+        if (getMutationKeyValue(m, PhoenixDatabaseMetaData.MULTI_TENANT_BYTES, builder, ptr))
{
+            return Boolean.TRUE.equals(PDataType.BOOLEAN.toObject(ptr));
+        }
+        return false;
     }
     
-    public static boolean isSalted(Mutation m) {
-        return MetaDataUtil.getMutationKeyValue(m, PhoenixDatabaseMetaData.SALT_BUCKETS_BYTES)
!= null;
+    public static boolean isSalted(Mutation m, KeyValueBuilder builder, ImmutableBytesWritable
ptr) {
+        return MetaDataUtil.getMutationKeyValue(m, PhoenixDatabaseMetaData.SALT_BUCKETS_BYTES,
builder, ptr);
     }
     
     public static byte[] getViewIndexPhysicalName(byte[] physicalTableName) {

http://git-wip-us.apache.org/repos/asf/incubator-phoenix/blob/d919a6c2/phoenix-core/src/test/java/org/apache/phoenix/util/MetaDataUtilTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/util/MetaDataUtilTest.java b/phoenix-core/src/test/java/org/apache/phoenix/util/MetaDataUtilTest.java
index 6daf0e3..95f245e 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/util/MetaDataUtilTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/util/MetaDataUtilTest.java
@@ -17,8 +17,18 @@
  */
 package org.apache.phoenix.util;
 
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
+import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.phoenix.client.ClientKeyValueBuilder;
+import org.apache.phoenix.client.GenericKeyValueBuilder;
+import org.apache.phoenix.client.KeyValueBuilder;
+import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
+import org.apache.phoenix.jdbc.PhoenixDatabaseMetaData;
 import org.junit.Test;
 
 
@@ -41,4 +51,48 @@ public class MetaDataUtilTest {
         assertFalse(MetaDataUtil.areClientAndServerCompatible(MetaDataUtil.encodeVersion(2,2,0),
2, 1));
         assertFalse(MetaDataUtil.areClientAndServerCompatible(MetaDataUtil.encodeVersion(3,1,10),
4, 2));
     }
+
+  /**
+   * Ensure it supports both the {@link GenericKeyValueBuilder} and {@link ClientKeyValueBuilder}
+   * @throws Exception on failure
+   */
+  @Test
+  public void testGetMutationKeyValue() throws Exception {
+    KeyValueBuilder builder = GenericKeyValueBuilder.INSTANCE;
+    byte[] row = Bytes.toBytes("row");
+    byte[] family = PhoenixDatabaseMetaData.TABLE_FAMILY_BYTES;
+    byte[] qualifier = Bytes.toBytes("qual");
+    byte[] value = Bytes.toBytes("generic-value");
+    KeyValue kv = builder.buildPut(wrap(row), wrap(family), wrap(qualifier), wrap(value));
+    Put put = new Put(row);
+    KeyValueBuilder.addQuietly(put, builder, kv);
+
+    // read back out the value
+    ImmutableBytesPtr ptr = new ImmutableBytesPtr();
+    assertTrue(MetaDataUtil.getMutationKeyValue(put, qualifier, builder, ptr));
+    assertEquals("Value returned doesn't match stored value for " + builder.getClass().getName()
+        + "!", 0,
+      ByteUtil.BYTES_PTR_COMPARATOR.compare(ptr, wrap(value)));
+
+    // try again, this time with the clientkeyvalue builder
+    builder = ClientKeyValueBuilder.INSTANCE;
+    value = Bytes.toBytes("client-value");
+    kv = builder.buildPut(wrap(row), wrap(family), wrap(qualifier), wrap(value));
+    put = new Put(row);
+    KeyValueBuilder.addQuietly(put, builder, kv);
+
+    // read back out the value
+    assertTrue(MetaDataUtil.getMutationKeyValue(put, qualifier, builder, ptr));
+    assertEquals("Value returned doesn't match stored value for " + builder.getClass().getName()
+        + "!", 0,
+      ByteUtil.BYTES_PTR_COMPARATOR.compare(ptr, wrap(value)));
+
+    // ensure that we don't get matches for qualifiers that don't match
+    assertFalse(MetaDataUtil.getMutationKeyValue(put, Bytes.toBytes("not a match"), builder,
ptr));
+  }
+
+  private static ImmutableBytesPtr wrap(byte[] bytes) {
+    return new ImmutableBytesPtr(bytes);
+  }
 }
+


Mime
View raw message