@Override
 public PMetaData addColumn(
     PName tenantId,
     String tableName,
     List<PColumn> columns,
     long tableTimeStamp,
     long tableSeqNum,
     boolean isImmutableRows,
     boolean isWalDisabled,
     boolean isMultitenant,
     boolean storeNulls,
     boolean isTransactional,
     long updateCacheFrequency,
     boolean isNamespaceMapped,
     long resolvedTime)
     throws SQLException {
   return metaData =
       metaData.addColumn(
           tenantId,
           tableName,
           columns,
           tableTimeStamp,
           tableSeqNum,
           isImmutableRows,
           isWalDisabled,
           isMultitenant,
           storeNulls,
           isTransactional,
           updateCacheFrequency,
           isNamespaceMapped,
           resolvedTime);
 }
 @Override
 public MetaDataMutationResult updateIndexState(
     List<Mutation> tableMetadata, String parentTableName) throws SQLException {
   byte[][] rowKeyMetadata = new byte[3][];
   SchemaUtil.getVarChars(tableMetadata.get(0).getRow(), rowKeyMetadata);
   Mutation m = MetaDataUtil.getTableHeaderRow(tableMetadata);
   ImmutableBytesWritable ptr = new ImmutableBytesWritable();
   if (!MetaDataUtil.getMutationValue(m, INDEX_STATE_BYTES, kvBuilder, ptr)) {
     throw new IllegalStateException();
   }
   PIndexState newState = PIndexState.fromSerializedValue(ptr.get()[ptr.getOffset()]);
   byte[] tenantIdBytes = rowKeyMetadata[PhoenixDatabaseMetaData.TENANT_ID_INDEX];
   String schemaName = Bytes.toString(rowKeyMetadata[PhoenixDatabaseMetaData.SCHEMA_NAME_INDEX]);
   String indexName = Bytes.toString(rowKeyMetadata[PhoenixDatabaseMetaData.TABLE_NAME_INDEX]);
   String indexTableName = SchemaUtil.getTableName(schemaName, indexName);
   PName tenantId = tenantIdBytes.length == 0 ? null : PNameFactory.newName(tenantIdBytes);
   PTable index = metaData.getTableRef(new PTableKey(tenantId, indexTableName)).getTable();
   index =
       PTableImpl.makePTable(
           index,
           newState == PIndexState.USABLE
               ? PIndexState.ACTIVE
               : newState == PIndexState.UNUSABLE ? PIndexState.INACTIVE : newState);
   return new MetaDataMutationResult(MutationCode.TABLE_ALREADY_EXISTS, 0, index);
 }
 @Override
 public MetaDataMutationResult getSchema(String schemaName, long clientTimestamp)
     throws SQLException {
   try {
     PSchema schema = metaData.getSchema(new PTableKey(null, schemaName));
     new MetaDataMutationResult(MutationCode.SCHEMA_ALREADY_EXISTS, schema, 0);
   } catch (SchemaNotFoundException e) {
   }
   return new MetaDataMutationResult(MutationCode.SCHEMA_NOT_FOUND, 0, null);
 }
 @Override
 public PMetaData removeColumn(
     PName tenantId,
     String tableName,
     List<PColumn> columnsToRemove,
     long tableTimeStamp,
     long tableSeqNum,
     long resolvedTime)
     throws SQLException {
   return metaData =
       metaData.removeColumn(
           tenantId, tableName, columnsToRemove, tableTimeStamp, tableSeqNum, resolvedTime);
 }
 @Override
 public MetaDataMutationResult getTable(
     PName tenantId,
     byte[] schemaBytes,
     byte[] tableBytes,
     long tableTimestamp,
     long clientTimestamp)
     throws SQLException {
   // Return result that will cause client to use it's own metadata instead of needing
   // to get anything from the server (since we don't have a connection)
   try {
     String fullTableName = SchemaUtil.getTableName(schemaBytes, tableBytes);
     PTable table = metaData.getTableRef(new PTableKey(tenantId, fullTableName)).getTable();
     return new MetaDataMutationResult(MutationCode.TABLE_ALREADY_EXISTS, 0, table, true);
   } catch (TableNotFoundException e) {
     return new MetaDataMutationResult(MutationCode.TABLE_NOT_FOUND, 0, null);
   }
 }
 @Override
 public MetaDataMutationResult getFunctions(
     PName tenantId, List<Pair<byte[], Long>> functionNameAndTimeStampPairs, long clientTimestamp)
     throws SQLException {
   List<PFunction> functions = new ArrayList<PFunction>(functionNameAndTimeStampPairs.size());
   for (Pair<byte[], Long> functionInfo : functionNameAndTimeStampPairs) {
     try {
       PFunction function2 =
           metaData.getFunction(new PTableKey(tenantId, Bytes.toString(functionInfo.getFirst())));
       functions.add(function2);
     } catch (FunctionNotFoundException e) {
       return new MetaDataMutationResult(MutationCode.FUNCTION_NOT_FOUND, 0, null);
     }
   }
   if (functions.isEmpty()) {
     return null;
   }
   return new MetaDataMutationResult(MutationCode.FUNCTION_ALREADY_EXISTS, 0, functions, true);
 }
 @Override
 public PMetaData removeSchema(PSchema schema, long schemaTimeStamp) {
   return metaData = metaData.removeSchema(schema, schemaTimeStamp);
 }
 @Override
 public PMetaData removeTable(
     PName tenantId, String tableName, String parentTableName, long tableTimeStamp)
     throws SQLException {
   return metaData = metaData.removeTable(tenantId, tableName, parentTableName, tableTimeStamp);
 }
 @Override
 public PMetaData updateResolvedTimestamp(PTable table, long resolvedTimestamp)
     throws SQLException {
   return metaData = metaData.updateResolvedTimestamp(table, resolvedTimestamp);
 }
 @Override
 public PMetaData addTable(PTable table, long resolvedTime) throws SQLException {
   return metaData = metaData.addTable(table, resolvedTime);
 }