PHOENIX-4700 Fix split policy on system tables other than SYSTEM.CATALOG
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/5c637e6d Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/5c637e6d Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/5c637e6d Branch: refs/heads/system-catalog Commit: 5c637e6dd4aabb9d8afe0e07a81533a96e111bfb Parents: 8dd637d Author: James Taylor <jtay...@salesforce.com> Authored: Mon Apr 23 10:14:36 2018 -0700 Committer: James Taylor <jtay...@salesforce.com> Committed: Thu Apr 26 09:55:28 2018 -0700 ---------------------------------------------------------------------- .../apache/phoenix/query/QueryConstants.java | 117 +------------------ .../SplitOnLeadingVarCharColumnsPolicy.java | 43 +++++++ .../schema/SystemFunctionSplitPolicy.java | 27 +++++ .../phoenix/schema/SystemStatsSplitPolicy.java | 27 +++++ .../phoenix/schema/SystemSplitPolicyTest.java | 97 +++++++++++++++ 5 files changed, 200 insertions(+), 111 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/phoenix/blob/5c637e6d/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java index 22fa2f4..4285334 100644 --- a/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java +++ b/phoenix-core/src/main/java/org/apache/phoenix/query/QueryConstants.java @@ -18,112 +18,7 @@ package org.apache.phoenix.query; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.APPEND_ONLY_SCHEMA; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ARG_POSITION; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ARRAY_SIZE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.AUTO_PARTITION_SEQ; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.BASE_COLUMN_COUNT; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.BUFFER_LENGTH; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CACHE_SIZE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CHAR_OCTET_LENGTH; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CLASS_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_COUNT; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_DEF; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_FAMILY; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_QUALIFIER_COUNTER; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.COLUMN_SIZE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CURRENT_VALUE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CYCLE_FLAG; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TABLE_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DATA_TYPE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DECIMAL_DIGITS; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_VALUE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DISABLE_WAL; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ENCODING_SCHEME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.FUNCTION_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POSTS_ROW_COUNT; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POSTS_WIDTH; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GUIDE_POST_KEY; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IMMUTABLE_ROWS; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IMMUTABLE_STORAGE_SCHEME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INCREMENT_BY; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_DISABLE_TIMESTAMP; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_STATE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.INDEX_TYPE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_ARRAY; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_AUTOINCREMENT; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_CONSTANT; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_NAMESPACE_MAPPED; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_NULLABLE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_ROW_TIMESTAMP; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.IS_VIEW_REFERENCED; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.JAR_PATH; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.KEY_SEQ; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.LAST_STATS_UPDATE_TIME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.LIMIT_REACHED_FLAG; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.LINK_TYPE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.MAX_VALUE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.MIN_VALUE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.MULTI_TENANT; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.NULLABLE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.NUM_ARGS; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.NUM_PREC_RADIX; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.ORDINAL_POSITION; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.PHYSICAL_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.PK_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.REF_GENERATION; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.REMARKS; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.RETURN_TYPE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SALT_BUCKETS; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SCOPE_CATALOG; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SCOPE_SCHEMA; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SCOPE_TABLE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SELF_REFERENCING_COL_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SEQUENCE_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SEQUENCE_SCHEMA; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SORT_ORDER; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SOURCE_DATA_TYPE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SQL_DATA_TYPE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SQL_DATETIME_SUB; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.START_WITH; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.STORE_NULLS; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_SCHEMA; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_CATALOG_TABLE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_FUNCTION_TABLE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_STATS_TABLE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SCHEM; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_SEQ_NUM; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TABLE_TYPE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TENANT_ID; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TRANSACTIONAL; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TRANSACTION_PROVIDER; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TYPE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TYPE_NAME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TYPE_SEQUENCE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.UPDATE_CACHE_FREQUENCY; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.USE_STATS_FOR_PARALLELIZATION; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_CONSTANT; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_INDEX_ID; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_STATEMENT; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.VIEW_TYPE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.BIND_PARAMETERS; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.CLIENT_IP; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.EXCEPTION_TRACE; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.EXPLAIN_PLAN; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.GLOBAL_SCAN_DETAILS; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.NO_OF_RESULTS_ITERATED; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.QUERY; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.QUERY_ID; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.QUERY_STATUS; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SCAN_METRICS_JSON; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.START_TIME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.TOTAL_EXECUTION_TIME; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.USER; -import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.SYSTEM_LOG_TABLE; +import static org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.*; import java.math.BigDecimal; @@ -139,6 +34,8 @@ import org.apache.phoenix.schema.PName; import org.apache.phoenix.schema.PNameFactory; import org.apache.phoenix.schema.PTable.QualifierEncodingScheme; import org.apache.phoenix.schema.SortOrder; +import org.apache.phoenix.schema.SystemFunctionSplitPolicy; +import org.apache.phoenix.schema.SystemStatsSplitPolicy; import org.apache.phoenix.schema.TableProperty; @@ -362,7 +259,7 @@ public interface QueryConstants { + PHYSICAL_NAME + "," + COLUMN_FAMILY + ","+ GUIDE_POST_KEY+"))\n" + // Install split policy to prevent a physical table's stats from being split across regions. - HTableDescriptor.SPLIT_POLICY + "='" + MetaDataSplitPolicy.class.getName() + "',\n" + + HTableDescriptor.SPLIT_POLICY + "='" + SystemStatsSplitPolicy.class.getName() + "',\n" + PhoenixDatabaseMetaData.TRANSACTIONAL + "=" + Boolean.FALSE; public static final String CREATE_SEQUENCE_METADATA = @@ -406,7 +303,7 @@ public interface QueryConstants { HConstants.VERSIONS + "=%s,\n" + HColumnDescriptor.KEEP_DELETED_CELLS + "=%s,\n"+ // Install split policy to prevent a tenant's metadata from being split across regions. - HTableDescriptor.SPLIT_POLICY + "='" + MetaDataSplitPolicy.class.getName() + "',\n" + + HTableDescriptor.SPLIT_POLICY + "='" + SystemFunctionSplitPolicy.class.getName() + "',\n" + PhoenixDatabaseMetaData.TRANSACTIONAL + "=" + Boolean.FALSE; public static final String CREATE_LOG_METADATA = @@ -431,9 +328,7 @@ public interface QueryConstants { " CONSTRAINT " + SYSTEM_TABLE_PK_NAME + " PRIMARY KEY (QUERY_ID))\n" + HConstants.VERSIONS + "= " + MetaDataProtocol.DEFAULT_LOG_VERSIONS + ",\n" + HColumnDescriptor.KEEP_DELETED_CELLS + "=%s,\n"+ - // Install split policy to prevent a tenant's metadata from being split across regions. - HTableDescriptor.SPLIT_POLICY + "='" + MetaDataSplitPolicy.class.getName() + "',\n" + - PhoenixDatabaseMetaData.TRANSACTIONAL + "=" + Boolean.FALSE+ ",\n" + + PhoenixDatabaseMetaData.TRANSACTIONAL + "=" + Boolean.FALSE+ ",\n" + HColumnDescriptor.TTL + "=" + MetaDataProtocol.DEFAULT_LOG_TTL+",\n"+ TableProperty.COLUMN_ENCODED_BYTES.toString()+" = 0"; http://git-wip-us.apache.org/repos/asf/phoenix/blob/5c637e6d/phoenix-core/src/main/java/org/apache/phoenix/schema/SplitOnLeadingVarCharColumnsPolicy.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/SplitOnLeadingVarCharColumnsPolicy.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/SplitOnLeadingVarCharColumnsPolicy.java new file mode 100644 index 0000000..d481998 --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/SplitOnLeadingVarCharColumnsPolicy.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.schema; + +import org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy; +import org.apache.phoenix.util.SchemaUtil; + +public abstract class SplitOnLeadingVarCharColumnsPolicy extends ConstantSizeRegionSplitPolicy { + abstract protected int getColumnToSplitAt(); + + protected final byte[] getSplitPoint(byte[] splitPoint) { + int offset = SchemaUtil.getVarCharLength(splitPoint, 0, splitPoint.length, getColumnToSplitAt()); + // Only split between leading columns indicated. + if (offset == splitPoint.length) { + return splitPoint; + } + // Otherwise, an attempt is being made to split in the middle of a table. + // Just return a split point at the boundary of the first two columns instead + byte[] newSplitPoint = new byte[offset + 1]; + System.arraycopy(splitPoint, 0, newSplitPoint, 0, offset+1); + return newSplitPoint; + } + + @Override + protected final byte[] getSplitPoint() { + return getSplitPoint(super.getSplitPoint()); + } +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/5c637e6d/phoenix-core/src/main/java/org/apache/phoenix/schema/SystemFunctionSplitPolicy.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/SystemFunctionSplitPolicy.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/SystemFunctionSplitPolicy.java new file mode 100644 index 0000000..58e1f9f --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/SystemFunctionSplitPolicy.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.schema; + +public class SystemFunctionSplitPolicy extends SplitOnLeadingVarCharColumnsPolicy { + + @Override + protected int getColumnToSplitAt() { + return 2; + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/5c637e6d/phoenix-core/src/main/java/org/apache/phoenix/schema/SystemStatsSplitPolicy.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/main/java/org/apache/phoenix/schema/SystemStatsSplitPolicy.java b/phoenix-core/src/main/java/org/apache/phoenix/schema/SystemStatsSplitPolicy.java new file mode 100644 index 0000000..69fe8aa --- /dev/null +++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/SystemStatsSplitPolicy.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.schema; + +public class SystemStatsSplitPolicy extends SplitOnLeadingVarCharColumnsPolicy { + + @Override + protected int getColumnToSplitAt() { + return 1; + } + +} http://git-wip-us.apache.org/repos/asf/phoenix/blob/5c637e6d/phoenix-core/src/test/java/org/apache/phoenix/schema/SystemSplitPolicyTest.java ---------------------------------------------------------------------- diff --git a/phoenix-core/src/test/java/org/apache/phoenix/schema/SystemSplitPolicyTest.java b/phoenix-core/src/test/java/org/apache/phoenix/schema/SystemSplitPolicyTest.java new file mode 100644 index 0000000..01074b4 --- /dev/null +++ b/phoenix-core/src/test/java/org/apache/phoenix/schema/SystemSplitPolicyTest.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.phoenix.schema; + +import static org.junit.Assert.assertArrayEquals; + +import org.apache.hadoop.hbase.io.ImmutableBytesWritable; +import org.apache.hadoop.hbase.util.Bytes; +import org.apache.phoenix.query.QueryConstants; +import org.apache.phoenix.schema.stats.StatisticsUtil; +import org.apache.phoenix.schema.types.PInteger; +import org.apache.phoenix.schema.types.PLong; +import org.apache.phoenix.schema.types.PVarchar; +import org.apache.phoenix.util.ByteUtil; +import org.junit.Test; + +public class SystemSplitPolicyTest { + @Test + public void testStatsSplitPolicy() { + SplitOnLeadingVarCharColumnsPolicy policy = new SystemStatsSplitPolicy(); + byte[] splitOn; + byte[] rowKey; + byte[] table; + ImmutableBytesWritable family; + table = PVarchar.INSTANCE.toBytes("FOO.BAR"); + family = QueryConstants.DEFAULT_COLUMN_FAMILY_BYTES_PTR; + rowKey = ByteUtil.concat( + PLong.INSTANCE.toBytes(20L), + PVarchar.INSTANCE.toBytes("BAS"), + QueryConstants.SEPARATOR_BYTE_ARRAY, + PInteger.INSTANCE.toBytes(100)); + splitOn = StatisticsUtil.getRowKey(table, family, rowKey); + splitOn = policy.getSplitPoint(splitOn); + assertArrayEquals(ByteUtil.concat(table, QueryConstants.SEPARATOR_BYTE_ARRAY), splitOn); + + table = PVarchar.INSTANCE.toBytes("MY_TABLE"); + family = new ImmutableBytesWritable(Bytes.toBytes("ABC")); + rowKey = ByteUtil.concat( + PVarchar.INSTANCE.toBytes("BAS"), + QueryConstants.SEPARATOR_BYTE_ARRAY, + PInteger.INSTANCE.toBytes(100), + PLong.INSTANCE.toBytes(20L)); + splitOn = StatisticsUtil.getRowKey(table, family, rowKey); + splitOn = policy.getSplitPoint(splitOn); + assertArrayEquals(ByteUtil.concat(table, QueryConstants.SEPARATOR_BYTE_ARRAY), splitOn); + } + + private static byte[] getSystemFunctionRowKey(String tenantId, String funcName, String typeName, byte[] argPos) { + return ByteUtil.concat(PVarchar.INSTANCE.toBytes(tenantId), + QueryConstants.SEPARATOR_BYTE_ARRAY, + PVarchar.INSTANCE.toBytes(funcName), + QueryConstants.SEPARATOR_BYTE_ARRAY, + PVarchar.INSTANCE.toBytes(typeName), + QueryConstants.SEPARATOR_BYTE_ARRAY, + argPos + ); + } + + private static byte[] getSystemFunctionSplitKey(String tenantId, String funcName) { + return ByteUtil.concat(PVarchar.INSTANCE.toBytes(tenantId), + QueryConstants.SEPARATOR_BYTE_ARRAY, + PVarchar.INSTANCE.toBytes(funcName), + QueryConstants.SEPARATOR_BYTE_ARRAY); + } + + @Test + public void testFunctionSplitPolicy() { + SplitOnLeadingVarCharColumnsPolicy policy = new SystemFunctionSplitPolicy(); + byte[] splitPoint; + byte[] rowKey; + byte[] expectedSplitPoint; + rowKey = getSystemFunctionRowKey("","MY_FUNC", "VARCHAR", Bytes.toBytes(3)); + expectedSplitPoint = getSystemFunctionSplitKey("","MY_FUNC"); + splitPoint = policy.getSplitPoint(rowKey); + assertArrayEquals(expectedSplitPoint, splitPoint); + + rowKey = getSystemFunctionRowKey("TENANT1","F", "", Bytes.toBytes(3)); + expectedSplitPoint = getSystemFunctionSplitKey("TENANT1","F"); + splitPoint = policy.getSplitPoint(rowKey); + assertArrayEquals(expectedSplitPoint, splitPoint); + } +}