This is an automated email from the ASF dual-hosted git repository.
apurtell pushed a commit to branch PHOENIX-7876-feature
in repository https://gitbox.apache.org/repos/asf/phoenix.git
The following commit(s) were added to refs/heads/PHOENIX-7876-feature by this
push:
new d21ddf8f0e PHOENIX-7923 Simplify EXPLAIN value classes (#2530)
d21ddf8f0e is described below
commit d21ddf8f0ef14f1ec5381add7dba56d93e313698
Author: Andrew Purtell <[email protected]>
AuthorDate: Sat Jun 13 23:18:25 2026 -0700
PHOENIX-7923 Simplify EXPLAIN value classes (#2530)
Co-authored-by: Claude Opus 4.8[1m] <[email protected]>
---
phoenix-core-client/src/main/antlr3/PhoenixSQL.g | 54 +++-
.../phoenix/compile/ExplainPlanAttributes.java | 271 +++++++--------------
.../org/apache/phoenix/iterate/ExplainTable.java | 43 +---
.../org/apache/phoenix/parse/ExplainOptions.java | 45 ----
4 files changed, 129 insertions(+), 284 deletions(-)
diff --git a/phoenix-core-client/src/main/antlr3/PhoenixSQL.g
b/phoenix-core-client/src/main/antlr3/PhoenixSQL.g
index c84d8f3b54..768eb60249 100644
--- a/phoenix-core-client/src/main/antlr3/PhoenixSQL.g
+++ b/phoenix-core-client/src/main/antlr3/PhoenixSQL.g
@@ -203,6 +203,7 @@ import java.lang.Boolean;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Collections;
+import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
@@ -319,29 +320,60 @@ package org.apache.phoenix.parse;
}
/**
- * Parse a single EXPLAIN option into the given builder. The option name
is matched
+ * Closed-set keys for the EXPLAIN option list, used to reject duplicate
options as they are
+ * encountered while parsing.
+ */
+ private enum ExplainOpt { REGIONS, VERBOSE, FORMAT }
+
+ /**
+ * Mutable accumulator for the EXPLAIN option list. Lifetime is one
explain_node parse.
+ */
+ private static final class ExplainOptsAcc {
+ boolean regions;
+ boolean verbose;
+ ExplainOptions.Format format;
+ final EnumSet<ExplainOpt> seen = EnumSet.noneOf(ExplainOpt.class);
+
+ void mark(ExplainOpt opt) {
+ if (!seen.add(opt)) {
+ throw new RuntimeException("Duplicate EXPLAIN option: " + opt);
+ }
+ }
+
+ ExplainOptions build() {
+ return new ExplainOptions(regions, verbose,
+ format == null ? ExplainOptions.Format.TEXT : format);
+ }
+ }
+
+ /**
+ * Parse a single EXPLAIN option into the given accumulator. The option
name is matched
* case-insensitively against the closed set {REGIONS, VERBOSE, FORMAT}.
REGIONS and VERBOSE are
- * flags and must not carry a value; FORMAT requires a value of TEXT or
JSON.
+ * flags and must not carry a value; FORMAT requires a value of TEXT or
JSON. Duplicate options
+ * are rejected.
*/
- private void parseExplainOption(ExplainOptions.Builder opts, String name,
String value) {
+ private void parseExplainOption(ExplainOptsAcc opts, String name, String
value) {
if ("REGIONS".equalsIgnoreCase(name)) {
if (value != null) {
throw new RuntimeException("EXPLAIN option REGIONS does not
take a value");
}
- opts.setRegions(true);
+ opts.mark(ExplainOpt.REGIONS);
+ opts.regions = true;
} else if ("VERBOSE".equalsIgnoreCase(name)) {
if (value != null) {
throw new RuntimeException("EXPLAIN option VERBOSE does not
take a value");
}
- opts.setVerbose(true);
+ opts.mark(ExplainOpt.VERBOSE);
+ opts.verbose = true;
} else if ("FORMAT".equalsIgnoreCase(name)) {
if (value == null) {
throw new RuntimeException("EXPLAIN option FORMAT requires a
value: TEXT or JSON");
}
+ opts.mark(ExplainOpt.FORMAT);
if ("TEXT".equalsIgnoreCase(value)) {
- opts.setFormat(ExplainOptions.Format.TEXT);
+ opts.format = ExplainOptions.Format.TEXT;
} else if ("JSON".equalsIgnoreCase(value)) {
- opts.setFormat(ExplainOptions.Format.JSON);
+ opts.format = ExplainOptions.Format.JSON;
} else {
throw new RuntimeException("Unknown EXPLAIN FORMAT: " + value);
}
@@ -509,11 +541,11 @@ oneStatement returns [BindableStatement ret]
finally{ contextStack.pop(); }
explain_node returns [BindableStatement ret]
-@init { ExplainOptions.Builder opts = new ExplainOptions.Builder(); }
+@init { ExplainOptsAcc opts = new ExplainOptsAcc(); }
: EXPLAIN
(
(LPAREN explain_option[opts] (COMMA explain_option[opts])* RPAREN)
- | (WITH REGIONS { opts.setRegions(true); })
+ | (WITH REGIONS { opts.mark(ExplainOpt.REGIONS);
opts.regions = true; })
)?
q=oneStatement
{
@@ -523,8 +555,8 @@ explain_node returns [BindableStatement ret]
// A single EXPLAIN option. REGIONS is a global keyword token. The remaining
option keywords
// (VERBOSE, FORMAT, TEXT, JSON) are not reserved and arrive as NAME tokens,
validated in the action.
-explain_option[ExplainOptions.Builder opts]
- : REGIONS { opts.setRegions(true); }
+explain_option[ExplainOptsAcc opts]
+ : REGIONS { opts.mark(ExplainOpt.REGIONS); opts.regions
= true; }
| k=NAME (v=NAME)? { parseExplainOption(opts, k.getText(), v ==
null ? null : v.getText()); }
;
diff --git
a/phoenix-core-client/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java
b/phoenix-core-client/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java
index 24a74a771b..29be54c6e0 100644
---
a/phoenix-core-client/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java
+++
b/phoenix-core-client/src/main/java/org/apache/phoenix/compile/ExplainPlanAttributes.java
@@ -141,188 +141,95 @@ public class ExplainPlanAttributes {
private final Integer regionLocationsTotalSize;
private final int numRegionLocationLookups;
- private static final ExplainPlanAttributes EXPLAIN_PLAN_INSTANCE = new
ExplainPlanAttributes();
-
- private ExplainPlanAttributes() {
- this.tenantId = null;
- this.viewName = null;
- this.viewBaseName = null;
- this.cdcScopes = null;
- this.txnProvider = null;
- this.rewrites = null;
- this.estimatedRows = null;
- this.estimatedSizeInBytes = null;
- this.estimateInfoTs = null;
- this.abstractExplainPlan = null;
- this.onDuplicateKeyAction = null;
- this.serverUpdateSet = null;
- this.returningRow = false;
- this.hint = null;
- this.explainScanType = null;
- this.consistency = null;
- this.tableName = null;
- this.keyRanges = null;
- this.indexName = null;
- this.indexKind = null;
- this.indexRule = null;
- this.indexRejected = null;
- this.saltBuckets = null;
- this.regionsPlanned = null;
- this.scanTimeRangeMin = null;
- this.scanTimeRangeMax = null;
- this.splitsChunk = null;
- this.useRoundRobinIterator = false;
- this.samplingRate = null;
- this.hexStringRVCOffset = null;
- this.iteratorTypeAndScanSize = null;
- this.scanEstimatedRows = null;
- this.scanEstimatedSizeInBytes = null;
- this.serverWhereFilter = null;
- this.serverDistinctFilter = null;
- this.serverMergeColumns = null;
- this.serverParsedProjections = null;
- this.serverProject = null;
- this.serverFilters = null;
- this.ignoredHints = null;
- this.serverFirstKeyOnlyProjection = false;
- this.serverEmptyColumnOnlyProjection = false;
- this.serverAggregate = null;
- this.serverGroupByLimit = null;
- this.serverSortedBy = null;
- this.serverOffset = null;
- this.serverRowLimit = null;
- this.clientFilterBy = null;
- this.clientFilters = null;
- this.clientAggregate = null;
- this.clientDistinctFilter = null;
- this.clientAfterAggregate = null;
- this.clientSortAlgo = null;
- this.clientSortedBy = null;
- this.clientOffset = null;
- this.clientRowLimit = null;
- this.clientSequenceCount = null;
- this.clientCursorName = null;
- this.clientSteps = null;
- this.lhsJoinQueryExplainPlan = null;
- this.rhsJoinQueryExplainPlan = null;
- this.subPlans = null;
- this.dynamicServerFilter = null;
- this.afterJoinFilter = null;
- this.joinScannerLimit = null;
- this.sortMergeSkipMerge = false;
- this.regionLocations = null;
- this.regionLocationsTotalSize = null;
- this.numRegionLocationLookups = 0;
- }
-
- public ExplainPlanAttributes(String tenantId, String viewName, String
viewBaseName,
- String cdcScopes, String txnProvider, List<String> rewrites, Long
estimatedRows,
- Long estimatedSizeInBytes, Long estimateInfoTs, String abstractExplainPlan,
- OnDuplicateKeyType onDuplicateKeyAction, List<String> serverUpdateSet,
boolean returningRow,
- Hint hint, String explainScanType, Consistency consistency, String
tableName, String keyRanges,
- String indexName, String indexKind, String indexRule,
List<RejectedIndexEntry> indexRejected,
- Integer saltBuckets, Integer regionsPlanned, Long scanTimeRangeMin, Long
scanTimeRangeMax,
- Integer splitsChunk, boolean useRoundRobinIterator, Double samplingRate,
- String hexStringRVCOffset, String iteratorTypeAndScanSize, Long
scanEstimatedRows,
- Long scanEstimatedSizeInBytes, String serverWhereFilter, String
serverDistinctFilter,
- Set<PColumn> serverMergeColumns, Map<String, List<String>>
serverParsedProjections,
- boolean serverFirstKeyOnlyProjection, boolean
serverEmptyColumnOnlyProjection,
- String serverAggregate, Integer serverGroupByLimit, String serverSortedBy,
Integer serverOffset,
- Long serverRowLimit, String clientFilterBy, String clientAggregate, String
clientDistinctFilter,
- String clientAfterAggregate, String clientSortAlgo, String clientSortedBy,
Integer clientOffset,
- Integer clientRowLimit, Integer clientSequenceCount, String
clientCursorName,
- List<String> clientSteps, ExplainPlanAttributes lhsJoinQueryExplainPlan,
- ExplainPlanAttributes rhsJoinQueryExplainPlan, List<ExplainPlanAttributes>
subPlans,
- String dynamicServerFilter, String afterJoinFilter, Long joinScannerLimit,
- boolean sortMergeSkipMerge, List<HRegionLocation> regionLocations,
- Integer regionLocationsTotalSize, int numRegionLocationLookups,
List<String> serverProject,
- List<ExplainFilter> serverFilters, Map<String, String> ignoredHints,
- List<ExplainFilter> clientFilters) {
- this.tenantId = tenantId;
- this.viewName = viewName;
- this.viewBaseName = viewBaseName;
- this.cdcScopes = cdcScopes;
- this.txnProvider = txnProvider;
- this.rewrites = (rewrites == null || rewrites.isEmpty())
+ private static final ExplainPlanAttributes EXPLAIN_PLAN_INSTANCE =
+ new ExplainPlanAttributesBuilder().build();
+
+ private ExplainPlanAttributes(ExplainPlanAttributesBuilder b) {
+ this.tenantId = b.tenantId;
+ this.viewName = b.viewName;
+ this.viewBaseName = b.viewBaseName;
+ this.cdcScopes = b.cdcScopes;
+ this.txnProvider = b.txnProvider;
+ this.rewrites = (b.rewrites == null || b.rewrites.isEmpty())
? null
- : Collections.unmodifiableList(new ArrayList<>(rewrites));
- this.estimatedRows = estimatedRows;
- this.estimatedSizeInBytes = estimatedSizeInBytes;
- this.estimateInfoTs = estimateInfoTs;
- this.abstractExplainPlan = abstractExplainPlan;
- this.onDuplicateKeyAction = onDuplicateKeyAction;
- this.serverUpdateSet = (serverUpdateSet == null ||
serverUpdateSet.isEmpty())
+ : Collections.unmodifiableList(new ArrayList<>(b.rewrites));
+ this.estimatedRows = b.estimatedRows;
+ this.estimatedSizeInBytes = b.estimatedSizeInBytes;
+ this.estimateInfoTs = b.estimateInfoTs;
+ this.abstractExplainPlan = b.abstractExplainPlan;
+ this.onDuplicateKeyAction = b.onDuplicateKeyAction;
+ this.serverUpdateSet = (b.serverUpdateSet == null ||
b.serverUpdateSet.isEmpty())
? null
- : Collections.unmodifiableList(new ArrayList<>(serverUpdateSet));
- this.returningRow = returningRow;
- this.hint = hint;
- this.explainScanType = explainScanType;
- this.consistency = consistency;
- this.tableName = tableName;
- this.keyRanges = keyRanges;
- this.indexName = indexName;
- this.indexKind = indexKind;
- this.indexRule = indexRule;
- this.indexRejected = (indexRejected == null || indexRejected.isEmpty())
+ : Collections.unmodifiableList(new ArrayList<>(b.serverUpdateSet));
+ this.returningRow = b.returningRow;
+ this.hint = b.hint;
+ this.explainScanType = b.explainScanType;
+ this.consistency = b.consistency;
+ this.tableName = b.tableName;
+ this.keyRanges = b.keyRanges;
+ this.indexName = b.indexName;
+ this.indexKind = b.indexKind;
+ this.indexRule = b.indexRule;
+ this.indexRejected = (b.indexRejected == null || b.indexRejected.isEmpty())
? null
- : Collections.unmodifiableList(new ArrayList<>(indexRejected));
- this.saltBuckets = saltBuckets;
- this.regionsPlanned = regionsPlanned;
- this.scanTimeRangeMin = scanTimeRangeMin;
- this.scanTimeRangeMax = scanTimeRangeMax;
- this.splitsChunk = splitsChunk;
- this.useRoundRobinIterator = useRoundRobinIterator;
- this.samplingRate = samplingRate;
- this.hexStringRVCOffset = hexStringRVCOffset;
- this.iteratorTypeAndScanSize = iteratorTypeAndScanSize;
- this.scanEstimatedRows = scanEstimatedRows;
- this.scanEstimatedSizeInBytes = scanEstimatedSizeInBytes;
- this.serverWhereFilter = serverWhereFilter;
- this.serverDistinctFilter = serverDistinctFilter;
- this.serverMergeColumns = serverMergeColumns;
- this.serverParsedProjections =
copyServerParsedProjections(serverParsedProjections);
- this.serverFirstKeyOnlyProjection = serverFirstKeyOnlyProjection;
- this.serverEmptyColumnOnlyProjection = serverEmptyColumnOnlyProjection;
- this.serverAggregate = serverAggregate;
- this.serverGroupByLimit = serverGroupByLimit;
- this.serverSortedBy = serverSortedBy;
- this.serverOffset = serverOffset;
- this.serverRowLimit = serverRowLimit;
- this.clientFilterBy = clientFilterBy;
- this.clientFilters = (clientFilters == null || clientFilters.isEmpty())
+ : Collections.unmodifiableList(new ArrayList<>(b.indexRejected));
+ this.saltBuckets = b.saltBuckets;
+ this.regionsPlanned = b.regionsPlanned;
+ this.scanTimeRangeMin = b.scanTimeRangeMin;
+ this.scanTimeRangeMax = b.scanTimeRangeMax;
+ this.splitsChunk = b.splitsChunk;
+ this.useRoundRobinIterator = b.useRoundRobinIterator;
+ this.samplingRate = b.samplingRate;
+ this.hexStringRVCOffset = b.hexStringRVCOffset;
+ this.iteratorTypeAndScanSize = b.iteratorTypeAndScanSize;
+ this.scanEstimatedRows = b.scanEstimatedRows;
+ this.scanEstimatedSizeInBytes = b.scanEstimatedSizeInBytes;
+ this.serverWhereFilter = b.serverWhereFilter;
+ this.serverDistinctFilter = b.serverDistinctFilter;
+ this.serverMergeColumns = b.serverMergeColumns;
+ this.serverParsedProjections =
copyServerParsedProjections(b.serverParsedProjections);
+ this.serverProject = (b.serverProject == null || b.serverProject.isEmpty())
? null
- : Collections.unmodifiableList(new ArrayList<>(clientFilters));
- this.clientAggregate = clientAggregate;
- this.clientDistinctFilter = clientDistinctFilter;
- this.clientAfterAggregate = clientAfterAggregate;
- this.clientSortAlgo = clientSortAlgo;
- this.clientSortedBy = clientSortedBy;
- this.clientOffset = clientOffset;
- this.clientRowLimit = clientRowLimit;
- this.clientSequenceCount = clientSequenceCount;
- this.clientCursorName = clientCursorName;
- this.clientSteps = (clientSteps == null || clientSteps.isEmpty())
+ : Collections.unmodifiableList(new ArrayList<>(b.serverProject));
+ this.serverFilters = (b.serverFilters == null || b.serverFilters.isEmpty())
? null
- : Collections.unmodifiableList(new ArrayList<>(clientSteps));
- this.lhsJoinQueryExplainPlan = lhsJoinQueryExplainPlan;
- this.rhsJoinQueryExplainPlan = rhsJoinQueryExplainPlan;
- this.subPlans = subPlans;
- this.dynamicServerFilter = dynamicServerFilter;
- this.afterJoinFilter = afterJoinFilter;
- this.joinScannerLimit = joinScannerLimit;
- this.sortMergeSkipMerge = sortMergeSkipMerge;
- this.regionLocations = regionLocations;
- this.regionLocationsTotalSize = regionLocationsTotalSize;
- this.numRegionLocationLookups = numRegionLocationLookups;
- this.serverProject = (serverProject == null || serverProject.isEmpty())
+ : Collections.unmodifiableList(new ArrayList<>(b.serverFilters));
+ this.ignoredHints = (b.ignoredHints == null || b.ignoredHints.isEmpty())
? null
- : Collections.unmodifiableList(new ArrayList<>(serverProject));
- this.serverFilters = (serverFilters == null || serverFilters.isEmpty())
+ : Collections.unmodifiableMap(new LinkedHashMap<>(b.ignoredHints));
+ this.serverFirstKeyOnlyProjection = b.serverFirstKeyOnlyProjection;
+ this.serverEmptyColumnOnlyProjection = b.serverEmptyColumnOnlyProjection;
+ this.serverAggregate = b.serverAggregate;
+ this.serverGroupByLimit = b.serverGroupByLimit;
+ this.serverSortedBy = b.serverSortedBy;
+ this.serverOffset = b.serverOffset;
+ this.serverRowLimit = b.serverRowLimit;
+ this.clientFilterBy = b.clientFilterBy;
+ this.clientFilters = (b.clientFilters == null || b.clientFilters.isEmpty())
? null
- : Collections.unmodifiableList(new ArrayList<>(serverFilters));
- this.ignoredHints = (ignoredHints == null || ignoredHints.isEmpty())
+ : Collections.unmodifiableList(new ArrayList<>(b.clientFilters));
+ this.clientAggregate = b.clientAggregate;
+ this.clientDistinctFilter = b.clientDistinctFilter;
+ this.clientAfterAggregate = b.clientAfterAggregate;
+ this.clientSortAlgo = b.clientSortAlgo;
+ this.clientSortedBy = b.clientSortedBy;
+ this.clientOffset = b.clientOffset;
+ this.clientRowLimit = b.clientRowLimit;
+ this.clientSequenceCount = b.clientSequenceCount;
+ this.clientCursorName = b.clientCursorName;
+ this.clientSteps = (b.clientSteps == null || b.clientSteps.isEmpty())
? null
- : Collections.unmodifiableMap(new LinkedHashMap<>(ignoredHints));
+ : Collections.unmodifiableList(new ArrayList<>(b.clientSteps));
+ this.lhsJoinQueryExplainPlan = b.lhsJoinQueryExplainPlan;
+ this.rhsJoinQueryExplainPlan = b.rhsJoinQueryExplainPlan;
+ this.subPlans = b.subPlans;
+ this.dynamicServerFilter = b.dynamicServerFilter;
+ this.afterJoinFilter = b.afterJoinFilter;
+ this.joinScannerLimit = b.joinScannerLimit;
+ this.sortMergeSkipMerge = b.sortMergeSkipMerge;
+ this.regionLocations = b.regionLocations;
+ this.regionLocationsTotalSize = b.regionLocationsTotalSize;
+ this.numRegionLocationLookups = b.numRegionLocationLookups;
}
public String getTenantId() {
@@ -1236,21 +1143,7 @@ public class ExplainPlanAttributes {
}
public ExplainPlanAttributes build() {
- return new ExplainPlanAttributes(tenantId, viewName, viewBaseName,
cdcScopes, txnProvider,
- rewrites, estimatedRows, estimatedSizeInBytes, estimateInfoTs,
abstractExplainPlan,
- onDuplicateKeyAction, serverUpdateSet, returningRow, hint,
explainScanType, consistency,
- tableName, keyRanges, indexName, indexKind, indexRule, indexRejected,
saltBuckets,
- regionsPlanned, scanTimeRangeMin, scanTimeRangeMax, splitsChunk,
useRoundRobinIterator,
- samplingRate, hexStringRVCOffset, iteratorTypeAndScanSize,
scanEstimatedRows,
- scanEstimatedSizeInBytes, serverWhereFilter, serverDistinctFilter,
serverMergeColumns,
- serverParsedProjections, serverFirstKeyOnlyProjection,
serverEmptyColumnOnlyProjection,
- serverAggregate, serverGroupByLimit, serverSortedBy, serverOffset,
serverRowLimit,
- clientFilterBy, clientAggregate, clientDistinctFilter,
clientAfterAggregate, clientSortAlgo,
- clientSortedBy, clientOffset, clientRowLimit, clientSequenceCount,
clientCursorName,
- clientSteps, lhsJoinQueryExplainPlan, rhsJoinQueryExplainPlan,
subPlans,
- dynamicServerFilter, afterJoinFilter, joinScannerLimit,
sortMergeSkipMerge, regionLocations,
- regionLocationsTotalSize, numRegionLocationLookups, serverProject,
serverFilters,
- ignoredHints, clientFilters);
+ return new ExplainPlanAttributes(this);
}
}
}
diff --git
a/phoenix-core-client/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
b/phoenix-core-client/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
index dff466b3c8..1045d492fc 100644
---
a/phoenix-core-client/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
+++
b/phoenix-core-client/src/main/java/org/apache/phoenix/iterate/ExplainTable.java
@@ -22,7 +22,6 @@ import java.text.Format;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
@@ -804,14 +803,13 @@ public abstract class ExplainTable {
}
try {
StringBuilder buf = new StringBuilder().append(REGION_LOCATIONS);
- Set<RegionBoundary> regionBoundaries = new HashSet<>();
+ Set<String> regionBoundaries = new LinkedHashSet<>();
List<HRegionLocation> regionLocations = new ArrayList<>();
for (HRegionLocation regionLocation : regionLocationsFromResultIterator)
{
- RegionBoundary regionBoundary = new
RegionBoundary(regionLocation.getRegion().getStartKey(),
- regionLocation.getRegion().getEndKey());
- if (!regionBoundaries.contains(regionBoundary)) {
+ String regionBoundary =
Bytes.toStringBinary(regionLocation.getRegion().getStartKey()) + ":"
+ + Bytes.toStringBinary(regionLocation.getRegion().getEndKey());
+ if (regionBoundaries.add(regionBoundary)) {
regionLocations.add(regionLocation);
- regionBoundaries.add(regionBoundary);
}
}
int maxLimitRegionLoc =
context.getConnection().getQueryServices().getConfiguration().getInt(
@@ -845,39 +843,6 @@ public abstract class ExplainTable {
}
}
- /**
- * Region boundary class with start and end key of the region.
- */
- private static class RegionBoundary {
- private final byte[] startKey;
- private final byte[] endKey;
-
- RegionBoundary(byte[] startKey, byte[] endKey) {
- this.startKey = startKey;
- this.endKey = endKey;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (o == null || getClass() != o.getClass()) {
- return false;
- }
- RegionBoundary that = (RegionBoundary) o;
- return Bytes.compareTo(startKey, that.startKey) == 0
- && Bytes.compareTo(endKey, that.endKey) == 0;
- }
-
- @Override
- public int hashCode() {
- int result = Arrays.hashCode(startKey);
- result = 31 * result + Arrays.hashCode(endKey);
- return result;
- }
- }
-
@SuppressWarnings("rawtypes")
private void appendPKColumnValue(StringBuilder buf, byte[] range, Boolean
isNull, int slotIndex,
boolean changeViewIndexId) {
diff --git
a/phoenix-core-client/src/main/java/org/apache/phoenix/parse/ExplainOptions.java
b/phoenix-core-client/src/main/java/org/apache/phoenix/parse/ExplainOptions.java
index 776f4a7059..95b1bce97c 100644
---
a/phoenix-core-client/src/main/java/org/apache/phoenix/parse/ExplainOptions.java
+++
b/phoenix-core-client/src/main/java/org/apache/phoenix/parse/ExplainOptions.java
@@ -79,49 +79,4 @@ public final class ExplainOptions {
return "ExplainOptions{regions=" + regions + ", verbose=" + verbose + ",
format=" + format
+ "}";
}
-
- /**
- * Mutable builder used by the parser to accumulate options as they are
encountered in the option
- * list. Rejects duplicate options.
- */
- public static final class Builder {
- private boolean regions;
- private boolean regionsSet;
- private boolean verbose;
- private boolean verboseSet;
- private Format format;
-
- public Builder setRegions(boolean regions) {
- if (regionsSet) {
- throw new RuntimeException("Duplicate EXPLAIN option: REGIONS");
- }
- this.regions = regions;
- this.regionsSet = true;
- return this;
- }
-
- public Builder setVerbose(boolean verbose) {
- if (verboseSet) {
- throw new RuntimeException("Duplicate EXPLAIN option: VERBOSE");
- }
- this.verbose = verbose;
- this.verboseSet = true;
- return this;
- }
-
- public Builder setFormat(Format format) {
- if (format == null) {
- throw new RuntimeException("EXPLAIN option FORMAT requires a value:
TEXT or JSON");
- }
- if (this.format != null) {
- throw new RuntimeException("Duplicate EXPLAIN option: FORMAT");
- }
- this.format = format;
- return this;
- }
-
- public ExplainOptions build() {
- return new ExplainOptions(regions, verbose, format == null ? Format.TEXT
: format);
- }
- }
}