This is an automated email from the ASF dual-hosted git repository.
ankitsultana pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new f3bef4caad0 [federation] Add warnings for unavailable remote clusters
in BrokerResponse for multi-cluster routing (#17510)
f3bef4caad0 is described below
commit f3bef4caad0f426502a06ada6365f285070aeca2
Author: Shaurya Chaturvedi <[email protected]>
AuthorDate: Wed Jan 14 18:17:24 2026 -0800
[federation] Add warnings for unavailable remote clusters in BrokerResponse
for multi-cluster routing (#17510)
---
.../broker/broker/helix/BaseBrokerStarter.java | 7 +-
.../helix/MultiClusterHelixBrokerStarter.java | 19 +++-
.../BaseSingleStageBrokerRequestHandler.java | 9 ++
.../MultiStageBrokerRequestHandler.java | 9 ++
.../core/routing/MultiClusterRoutingContext.java | 31 ++++++-
.../multicluster/MultiClusterIntegrationTest.java | 103 +++++++++++++++++++--
.../apache/pinot/spi/exception/QueryErrorCode.java | 1 +
7 files changed, 163 insertions(+), 16 deletions(-)
diff --git
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
index 8ab0498d5a7..6a5369dccfd 100644
---
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
+++
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/BaseBrokerStarter.java
@@ -309,9 +309,6 @@ public abstract class BaseBrokerStarter implements
ServiceStartable {
_isStarting = true;
Utils.logVersions();
- LOGGER.info("Connecting spectator Helix manager");
- initSpectatorHelixManager();
-
LOGGER.info("Setting up broker request handler");
// Set up metric registry and broker metrics
_metricsRegistry =
PinotMetricUtils.getPinotMetricsRegistry(_brokerConf.subset(Broker.METRICS_CONFIG_PREFIX));
@@ -328,6 +325,10 @@ public abstract class BaseBrokerStarter implements
ServiceStartable {
_brokerConf.getProperty(Broker.AdaptiveServerSelector.CONFIG_OF_TYPE,
Broker.AdaptiveServerSelector.DEFAULT_TYPE), 1);
BrokerMetrics.register(_brokerMetrics);
+
+ LOGGER.info("Connecting spectator Helix manager");
+ initSpectatorHelixManager();
+
// Set up request handling classes
_serverRoutingStatsManager = new ServerRoutingStatsManager(_brokerConf,
_brokerMetrics);
_serverRoutingStatsManager.init();
diff --git
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/MultiClusterHelixBrokerStarter.java
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/MultiClusterHelixBrokerStarter.java
index a19454fec9b..b4ae2ba211b 100644
---
a/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/MultiClusterHelixBrokerStarter.java
+++
b/pinot-broker/src/main/java/org/apache/pinot/broker/broker/helix/MultiClusterHelixBrokerStarter.java
@@ -22,8 +22,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.helix.HelixConstants.ChangeType;
import org.apache.helix.HelixManager;
import org.apache.helix.HelixManagerFactory;
@@ -66,6 +68,9 @@ public class MultiClusterHelixBrokerStarter extends
BaseBrokerStarter {
protected MultiClusterRoutingContext _multiClusterRoutingContext;
protected Map<String, ClusterChangeMediator> _remoteClusterChangeMediator;
+ // Tracks clusters that failed to connect (for adding warnings to query
responses)
+ protected Set<String> _unavailableClusters;
+
public MultiClusterHelixBrokerStarter() {
}
@@ -121,6 +126,7 @@ public class MultiClusterHelixBrokerStarter extends
BaseBrokerStarter {
}
private void initRemoteClusterSpectatorHelixManagers() throws Exception {
+ _unavailableClusters = new HashSet<>();
if (_remoteZkServers == null || _remoteZkServers.isEmpty()) {
LOGGER.info("[multi-cluster] No remote ZK servers configured - skipping
spectator Helix manager init");
return;
@@ -141,6 +147,7 @@ public class MultiClusterHelixBrokerStarter extends
BaseBrokerStarter {
LOGGER.info("[multi-cluster] Connected to remote cluster '{}' at ZK:
{}", clusterName, zkServers);
} catch (Exception e) {
LOGGER.error("[multi-cluster] Failed to connect to cluster '{}' at ZK:
{}", clusterName, zkServers, e);
+ _unavailableClusters.add(clusterName);
_brokerMetrics.addMeteredGlobalValue(BrokerMeter.MULTI_CLUSTER_BROKER_STARTUP_FAILURE,
1);
}
}
@@ -152,6 +159,10 @@ public class MultiClusterHelixBrokerStarter extends
BaseBrokerStarter {
LOGGER.info("[multi-cluster] Connected to {}/{} remote clusters: {}",
_remoteSpectatorHelixManager.size(),
_remoteZkServers.size(), _remoteSpectatorHelixManager.keySet());
}
+ if (!_unavailableClusters.isEmpty()) {
+ LOGGER.warn("[multi-cluster] The following clusters are unavailable and
will generate warnings "
+ + "in query responses: {}", _unavailableClusters);
+ }
}
protected void stopRemoteClusterComponents() {
@@ -271,9 +282,11 @@ public class MultiClusterHelixBrokerStarter extends
BaseBrokerStarter {
}
_multiClusterRoutingContext = new
MultiClusterRoutingContext(tableCacheMap, _routingManager,
- _multiClusterRoutingManager);
- LOGGER.info("[multi-cluster] Created federation provider with {}/{}
clusters (1 primary + {} remote)",
- tableCacheMap.size(), _remoteSpectatorHelixManager.size() + 1,
tableCacheMap.size() - 1);
+ _multiClusterRoutingManager, _unavailableClusters);
+ LOGGER.info("[multi-cluster] Created federation provider with {}/{}
clusters (1 primary + {} remote), "
+ + "{} unavailable",
+ tableCacheMap.size(), _remoteSpectatorHelixManager.size() + 1,
tableCacheMap.size() - 1,
+ _unavailableClusters.size());
}
private void initRemoteClusterRouting() {
diff --git
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseSingleStageBrokerRequestHandler.java
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseSingleStageBrokerRequestHandler.java
index b578d29e716..140d22ae97f 100644
---
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseSingleStageBrokerRequestHandler.java
+++
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/BaseSingleStageBrokerRequestHandler.java
@@ -849,6 +849,15 @@ public abstract class BaseSingleStageBrokerRequestHandler
extends BaseBrokerRequ
for (QueryProcessingException errorMsg : errorMsgs) {
brokerResponse.addException(errorMsg);
}
+
+ // Add warnings for unavailable remote clusters in multi-cluster routing.
+ if (_multiClusterRoutingContext != null &&
QueryOptionsUtils.isMultiClusterRoutingEnabled(
+ pinotQuery.getQueryOptions(), false)) {
+ for (QueryProcessingException clusterException :
_multiClusterRoutingContext.getUnavailableClusterExceptions()) {
+ brokerResponse.addException(clusterException);
+ }
+ }
+
brokerResponse.setNumSegmentsPrunedByBroker(numPrunedSegmentsTotal);
long executionEndTimeNs = System.nanoTime();
_brokerMetrics.addPhaseTiming(rawTableName,
BrokerQueryPhase.QUERY_EXECUTION,
diff --git
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/MultiStageBrokerRequestHandler.java
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/MultiStageBrokerRequestHandler.java
index 717b8fb1430..f589d90ee96 100644
---
a/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/MultiStageBrokerRequestHandler.java
+++
b/pinot-broker/src/main/java/org/apache/pinot/broker/requesthandler/MultiStageBrokerRequestHandler.java
@@ -678,6 +678,15 @@ public class MultiStageBrokerRequestHandler extends
BaseBrokerRequestHandler {
}
requestContext.setNumUnavailableSegments(numUnavailableSegments);
+ // Add warnings for unavailable remote clusters in multi-cluster routing
+ if (_multiClusterRoutingContext != null &&
QueryOptionsUtils.isMultiClusterRoutingEnabled(query.getOptions(),
+ false)) {
+ for (QueryProcessingException clusterException
+ : _multiClusterRoutingContext.getUnavailableClusterExceptions()) {
+ brokerResponse.addException(clusterException);
+ }
+ }
+
fillOldBrokerResponseStats(brokerResponse, queryResults.getQueryStats(),
dispatchableSubPlan);
long totalTimeMs = System.currentTimeMillis() -
requestContext.getRequestArrivalTimeMillis();
_brokerMetrics.addTimedValue(BrokerTimer.MULTI_STAGE_QUERY_TOTAL_TIME_MS,
totalTimeMs, TimeUnit.MILLISECONDS);
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/routing/MultiClusterRoutingContext.java
b/pinot-core/src/main/java/org/apache/pinot/core/routing/MultiClusterRoutingContext.java
index c40f3aee6f5..48454c58a0b 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/routing/MultiClusterRoutingContext.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/routing/MultiClusterRoutingContext.java
@@ -18,10 +18,16 @@
*/
package org.apache.pinot.core.routing;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.annotation.Nullable;
import org.apache.pinot.common.config.provider.TableCache;
+import org.apache.pinot.common.response.broker.QueryProcessingException;
import org.apache.pinot.common.utils.config.QueryOptionsUtils;
+import org.apache.pinot.spi.exception.QueryErrorCode;
/**
@@ -40,18 +46,22 @@ public class MultiClusterRoutingContext {
@Nullable
private final RoutingManager _multiClusterRoutingManager;
+ // Set of cluster names that failed to connect (for warning in query
responses)
+ private final Set<String> _unavailableClusters;
+
/**
- * Constructor for FederationProvider with routing managers.
+ * Constructor for FederationProvider with routing managers and unavailable
clusters.
*
* @param tableCacheMap Map of cluster name to TableCache
* @param localRoutingManager Local routing manager for non-federated queries
* @param multiClusterRoutingManager Multi cluster routing manager for
cross-cluster queries (can be null)
*/
public MultiClusterRoutingContext(Map<String, TableCache> tableCacheMap,
RoutingManager localRoutingManager,
- @Nullable RoutingManager multiClusterRoutingManager) {
+ @Nullable RoutingManager multiClusterRoutingManager, Set<String>
unavailableClusters) {
_tableCacheMap = tableCacheMap;
_localRoutingManager = localRoutingManager;
_multiClusterRoutingManager = multiClusterRoutingManager;
+ _unavailableClusters = unavailableClusters != null ? unavailableClusters :
Collections.emptySet();
}
public Map<String, TableCache> getTableCacheMap() {
@@ -81,4 +91,21 @@ public class MultiClusterRoutingContext {
public RoutingManager getMultiClusterRoutingManager() {
return _multiClusterRoutingManager;
}
+
+ public boolean hasUnavailableClusters() {
+ return !_unavailableClusters.isEmpty();
+ }
+
+ public List<QueryProcessingException> getUnavailableClusterExceptions() {
+ if (_unavailableClusters.isEmpty()) {
+ return Collections.emptyList();
+ }
+ List<QueryProcessingException> exceptions = new ArrayList<>();
+ for (String clusterName : _unavailableClusters) {
+ String message = String.format("Remote cluster '%s' is not connected. "
+ + "Query results may be incomplete.", clusterName);
+ exceptions.add(new
QueryProcessingException(QueryErrorCode.REMOTE_CLUSTER_UNAVAILABLE, message));
+ }
+ return exceptions;
+ }
}
diff --git
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/multicluster/MultiClusterIntegrationTest.java
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/multicluster/MultiClusterIntegrationTest.java
index 7173e6f6008..dc434cfd75a 100644
---
a/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/multicluster/MultiClusterIntegrationTest.java
+++
b/pinot-integration-tests/src/test/java/org/apache/pinot/integration/tests/multicluster/MultiClusterIntegrationTest.java
@@ -65,6 +65,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
@@ -92,9 +93,12 @@ public class MultiClusterIntegrationTest extends ClusterTest
{
protected static final int TABLE_SIZE_CLUSTER_2 = 1000;
protected static final int SEGMENTS_PER_CLUSTER = 3;
protected static final String JOIN_COLUMN = "OriginCityName";
+ protected static final String UNAVAILABLE_CLUSTER_NAME =
"UnavailableCluster";
+ protected static final String UNAVAILABLE_ZK_ADDRESS = "localhost:29999";
protected ClusterComponents _cluster1;
protected ClusterComponents _cluster2;
+ protected ClusterComponents _brokerWithUnavailableCluster;
protected List<File> _cluster1AvroFiles;
protected List<File> _cluster2AvroFiles;
@@ -122,9 +126,40 @@ public class MultiClusterIntegrationTest extends
ClusterTest {
startCluster(_cluster1, _cluster2, CLUSTER_1_CONFIG);
startCluster(_cluster2, _cluster1, CLUSTER_2_CONFIG);
+ // Start an alternate broker with one valid and one unavailable remote
cluster
+ startBrokerWithUnavailableCluster();
+
LOGGER.info("MultiClusterIntegrationTest setup complete");
}
+ /**
+ * Starts a broker configured with cluster2 (valid) and an unavailable
cluster (invalid ZK).
+ */
+ private void startBrokerWithUnavailableCluster() throws Exception {
+ _brokerWithUnavailableCluster = new ClusterComponents();
+ _brokerWithUnavailableCluster._brokerPort = findAvailablePort(55000);
+
+ PinotConfiguration brokerConfig = new PinotConfiguration();
+ brokerConfig.setProperty(Helix.CONFIG_OF_ZOOKEEPER_SERVER,
_cluster1._zkUrl);
+ brokerConfig.setProperty(Helix.CONFIG_OF_CLUSTER_NAME, CLUSTER_1_NAME);
+ brokerConfig.setProperty(Broker.CONFIG_OF_BROKER_HOSTNAME,
ControllerTest.LOCAL_HOST);
+ brokerConfig.setProperty(Helix.KEY_OF_BROKER_QUERY_PORT,
_brokerWithUnavailableCluster._brokerPort);
+ brokerConfig.setProperty(Broker.CONFIG_OF_BROKER_TIMEOUT_MS, 60 * 1000L);
+ brokerConfig.setProperty(Broker.CONFIG_OF_DELAY_SHUTDOWN_TIME_MS, 0);
+ brokerConfig.setProperty(CommonConstants.CONFIG_OF_TIMEZONE, "UTC");
+ brokerConfig.setProperty(Helix.CONFIG_OF_REMOTE_CLUSTER_NAMES,
+ CLUSTER_2_NAME + "," + UNAVAILABLE_CLUSTER_NAME);
+
brokerConfig.setProperty(String.format(Helix.CONFIG_OF_REMOTE_ZOOKEEPER_SERVERS,
CLUSTER_2_NAME),
+ _cluster2._zkUrl);
+
brokerConfig.setProperty(String.format(Helix.CONFIG_OF_REMOTE_ZOOKEEPER_SERVERS,
UNAVAILABLE_CLUSTER_NAME),
+ UNAVAILABLE_ZK_ADDRESS);
+
+ _brokerWithUnavailableCluster._brokerStarter = createBrokerStarter();
+ _brokerWithUnavailableCluster._brokerStarter.init(brokerConfig);
+ _brokerWithUnavailableCluster._brokerStarter.start();
+ LOGGER.info("Started broker with unavailable cluster on port {}",
_brokerWithUnavailableCluster._brokerPort);
+ }
+
// TODO: Add more tests for cross-cluster queries in subsequent iterations.
@Test
public void testMultiClusterBrokerStartsAndIsQueryable() throws Exception {
@@ -165,8 +200,11 @@ public class MultiClusterIntegrationTest extends
ClusterTest {
LOGGER.info("Multi-cluster broker test passed: both clusters started and
queryable");
}
- @Test
- public void testLogicalFederationTwoOfflineTablesSSE() throws Exception {
+ @Test(dataProvider = "brokerModes")
+ public void testLogicalFederationTwoOfflineTablesSSE(int brokerPort, boolean
expectUnavailableException)
+ throws Exception {
+ LOGGER.info("Testing SSE on broker port {}
(expectUnavailableException={})",
+ brokerPort, expectUnavailableException);
dropLogicalTableIfExists(LOGICAL_TABLE_NAME,
_cluster1._controllerBaseApiUrl);
dropLogicalTableIfExists(LOGICAL_TABLE_NAME,
_cluster2._controllerBaseApiUrl);
dropLogicalTableIfExists(LOGICAL_TABLE_NAME_2,
_cluster1._controllerBaseApiUrl);
@@ -180,12 +218,18 @@ public class MultiClusterIntegrationTest extends
ClusterTest {
loadDataIntoCluster(_cluster1AvroFiles,
LOGICAL_FEDERATION_CLUSTER_1_TABLE, _cluster1);
loadDataIntoCluster(_cluster2AvroFiles,
LOGICAL_FEDERATION_CLUSTER_2_TABLE, _cluster2);
long expectedTotal = TABLE_SIZE_CLUSTER_1 + TABLE_SIZE_CLUSTER_2;
- assertEquals(getCount(LOGICAL_TABLE_NAME, _cluster1, true), expectedTotal);
- assertEquals(getCount(LOGICAL_TABLE_NAME, _cluster2, true), expectedTotal);
+
+ String query = "SET enableMultiClusterRouting=true; SELECT COUNT(*) as
count FROM " + LOGICAL_TABLE_NAME;
+ String result = executeQueryOnBrokerPort(query, brokerPort);
+ assertEquals(parseCountResult(result), expectedTotal);
+ verifyUnavailableClusterException(result, expectUnavailableException);
}
- @Test
- public void testLogicalFederationTwoLogicalTablesMSE() throws Exception {
+ @Test(dataProvider = "brokerModes")
+ public void testLogicalFederationTwoLogicalTablesMSE(int brokerPort, boolean
expectUnavailableException)
+ throws Exception {
+ LOGGER.info("Testing MSE on broker port {}
(expectUnavailableException={})",
+ brokerPort, expectUnavailableException);
dropLogicalTableIfExists(LOGICAL_TABLE_NAME,
_cluster1._controllerBaseApiUrl);
dropLogicalTableIfExists(LOGICAL_TABLE_NAME,
_cluster2._controllerBaseApiUrl);
dropLogicalTableIfExists(LOGICAL_TABLE_NAME_2,
_cluster1._controllerBaseApiUrl);
@@ -207,10 +251,22 @@ public class MultiClusterIntegrationTest extends
ClusterTest {
+ "SELECT t1." + JOIN_COLUMN + ", COUNT(*) as count FROM " +
LOGICAL_TABLE_NAME + " t1 "
+ "JOIN " + LOGICAL_TABLE_NAME_2 + " t2 ON t1." + JOIN_COLUMN + " =
t2." + JOIN_COLUMN + " "
+ "GROUP BY t1." + JOIN_COLUMN + " LIMIT 20";
- String result = executeQuery(joinQuery, _cluster1);
+ String result = executeQueryOnBrokerPort(joinQuery, brokerPort);
assertNotNull(result);
assertTrue(result.contains("resultTable"));
assertResultRows(result);
+ verifyUnavailableClusterException(result, expectUnavailableException);
+ }
+
+ /**
+ * Data provider for broker modes: normal broker vs broker with unavailable
remote cluster.
+ */
+ @DataProvider(name = "brokerModes")
+ public Object[][] brokerModes() {
+ return new Object[][]{
+ {_cluster1._brokerPort, false}, // Normal broker - all clusters
connected
+ {_brokerWithUnavailableCluster._brokerPort, true} // Broker with
unavailable cluster
+ };
}
@Override
@@ -497,11 +553,34 @@ public class MultiClusterIntegrationTest extends
ClusterTest {
}
protected String executeQuery(String query, ClusterComponents cluster)
throws Exception {
+ return executeQueryOnBrokerPort(query, cluster._brokerPort);
+ }
+
+ protected String executeQueryOnBrokerPort(String query, int brokerPort)
throws Exception {
Map<String, Object> payload = Map.of("sql", query);
- String url = "http://localhost:" + cluster._brokerPort + "/query/sql";
+ String url = "http://localhost:" + brokerPort + "/query/sql";
return ControllerTest.sendPostRequest(url,
JsonUtils.objectToPrettyString(payload));
}
+ protected void verifyUnavailableClusterException(String result, boolean
expectException) throws Exception {
+ if (expectException) {
+ assertTrue(result.contains(UNAVAILABLE_CLUSTER_NAME),
+ "Response should mention unavailable cluster: " +
UNAVAILABLE_CLUSTER_NAME);
+ JsonNode resultJson = JsonMapper.builder().build().readTree(result);
+ JsonNode exceptions = resultJson.get("exceptions");
+ assertNotNull(exceptions, "Exceptions array should exist");
+ boolean found = false;
+ for (JsonNode ex : exceptions) {
+ if (ex.get("errorCode").asInt() == 510
+ && ex.get("message").asText().contains(UNAVAILABLE_CLUSTER_NAME)) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue(found, "Should find REMOTE_CLUSTER_UNAVAILABLE (510)
exception");
+ }
+ }
+
protected long parseCountResult(String result) {
try {
JsonNode rows =
JsonMapper.builder().build().readTree(result).path("resultTable").path("rows");
@@ -525,6 +604,14 @@ public class MultiClusterIntegrationTest extends
ClusterTest {
@AfterClass
public void tearDown() throws Exception {
+ // Stop the alternate broker with unavailable cluster
+ if (_brokerWithUnavailableCluster != null &&
_brokerWithUnavailableCluster._brokerStarter != null) {
+ try {
+ _brokerWithUnavailableCluster._brokerStarter.stop();
+ } catch (Exception e) {
+ LOGGER.warn("Error stopping broker with unavailable cluster", e);
+ }
+ }
stopCluster(_cluster1);
stopCluster(_cluster2);
}
diff --git
a/pinot-spi/src/main/java/org/apache/pinot/spi/exception/QueryErrorCode.java
b/pinot-spi/src/main/java/org/apache/pinot/spi/exception/QueryErrorCode.java
index b7fac4e03fd..ea2629b7488 100644
--- a/pinot-spi/src/main/java/org/apache/pinot/spi/exception/QueryErrorCode.java
+++ b/pinot-spi/src/main/java/org/apache/pinot/spi/exception/QueryErrorCode.java
@@ -59,6 +59,7 @@ public enum QueryErrorCode {
INTERNAL(450, "InternalError", Response.Status.INTERNAL_SERVER_ERROR),
MERGE_RESPONSE(500, "MergeResponseError",
Response.Status.INTERNAL_SERVER_ERROR),
QUERY_CANCELLATION(503, "QueryCancellationError",
Response.Status.SERVICE_UNAVAILABLE),
+ REMOTE_CLUSTER_UNAVAILABLE(510, "RemoteClusterUnavailable",
Response.Status.SERVICE_UNAVAILABLE),
/// Error detected at validation time. For example, type mismatch.
QUERY_VALIDATION(700, "QueryValidationError", Response.Status.BAD_REQUEST),
UNKNOWN_COLUMN(710, "UnknownColumnError", Response.Status.BAD_REQUEST),
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]