Skip to content

Commit

Permalink
Merge pull request #127090 from xinhaoz/backport23.1-126419
Browse files Browse the repository at this point in the history
release-23.1: ui: fix query fetching store ids for db/tables
  • Loading branch information
xinhaoz authored Jul 16, 2024
2 parents 1405599 + 36e7f8d commit e84d1de
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 6 deletions.
6 changes: 5 additions & 1 deletion pkg/ui/workspaces/cluster-ui/src/api/databaseDetailsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,12 @@ const getDatabaseReplicasAndRegions: DatabaseDetailsQuery<DatabaseReplicasRegion
) => {
if (txn_result.error) {
resp.stats.replicaData.error = txn_result.error;
// We don't expect to have any rows for this query on error.
return;
}
if (!txnResultIsEmpty(txn_result)) {
resp.stats.replicaData.storeIDs = txn_result?.rows[0]?.store_ids ?? [];
}
resp.stats.replicaData.storeIDs = txn_result?.rows[0]?.store_ids ?? [];
},
handleMaxSizeError: (_dbName, _response, _dbDetail) => {
return Promise.resolve(false);
Expand Down
5 changes: 5 additions & 0 deletions pkg/ui/workspaces/cluster-ui/src/api/sqlApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ const UPGRADE_RELATED_ERRORS = [
];

export function isUpgradeError(message: string): boolean {
if (message == null) return false;
return UPGRADE_RELATED_ERRORS.some(err => message.search(err) !== -1);
}

Expand All @@ -195,6 +196,10 @@ export function isUpgradeError(message: string): boolean {
* @param message
*/
export function sqlApiErrorMessage(message: string): string {
if (!message) {
return "";
}

if (isUpgradeError(message)) {
return "This page may not be available during an upgrade.";
}
Expand Down
10 changes: 7 additions & 3 deletions pkg/ui/workspaces/cluster-ui/src/api/tableDetailsApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -463,12 +463,16 @@ const getTableReplicaStoreIDs: TableDetailsQuery<TableReplicasRow> = {
) => {
if (txn_result.error) {
resp.stats.replicaData.error = txn_result.error;
// We don't expect to have any rows for this query on error.
return;
}

// TODO #118957 (xinhaoz) Store IDs and node IDs cannot be used interchangeably.
resp.stats.replicaData.storeIDs = txn_result?.rows[0]?.store_ids ?? [];
resp.stats.replicaData.replicaCount =
txn_result?.rows[0]?.replica_count ?? 0;
if (!txnResultIsEmpty(txn_result)) {
resp.stats.replicaData.storeIDs = txn_result?.rows[0]?.store_ids ?? [];
resp.stats.replicaData.replicaCount =
txn_result?.rows[0]?.replica_count ?? 0;
}
},
};

Expand Down
37 changes: 36 additions & 1 deletion pkg/ui/workspaces/db-console/src/util/api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
indexUnusedDuration,
} from "src/util/constants";
import Severity = protos.cockroach.util.log.Severity;
import { stubSqlApiCall } from "src/util/fakeApi";
import { mockExecSQLErrors, stubSqlApiCall } from "src/util/fakeApi";

const { ZoneConfig } = cockroach.config.zonepb;
const { ZoneConfigurationLevel } = cockroach.server.serverpb;
Expand Down Expand Up @@ -285,6 +285,20 @@ describe("rest api", function () {
done();
});
});

it("should not error when any query fails", async () => {
const req = { database, csIndexUnusedDuration: indexUnusedDuration };
const mockResults = mockExecSQLErrors<clusterUiApi.DatabaseDetailsRow>(6);
stubSqlApiCall<clusterUiApi.DatabaseDetailsRow>(
clusterUiApi.createDatabaseDetailsReq(req),
mockResults,
);

// This call should not throw.
const result = await clusterUiApi.getDatabaseDetails(req);
expect(result.results).toBeDefined();
expect(result.results.error).toBeDefined();
});
});

describe("table details request", function () {
Expand Down Expand Up @@ -479,6 +493,27 @@ describe("rest api", function () {
done();
});
});

it("should not error when any query fails", async () => {
const mockResults = mockExecSQLErrors<clusterUiApi.TableDetailsRow>(10);
stubSqlApiCall<clusterUiApi.TableDetailsRow>(
clusterUiApi.createTableDetailsReq(
dbName,
tableName,
indexUnusedDuration,
),
mockResults,
);

// This call should not throw.
const result = await clusterUiApi.getTableDetails({
database: dbName,
table: tableName,
csIndexUnusedDuration: indexUnusedDuration,
});
expect(result.results).toBeDefined();
expect(result.results.error).toBeDefined();
});
});

describe("events request", function () {
Expand Down
33 changes: 32 additions & 1 deletion pkg/ui/workspaces/db-console/src/util/fakeApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
// licenses/APL.txt.

import * as $protobuf from "protobufjs";
import { SqlTxnResult } from "@cockroachlabs/cluster-ui/dist/types/api";

import { api as clusterUiApi } from "@cockroachlabs/cluster-ui";
import { cockroach } from "src/js/protos";
Expand Down Expand Up @@ -106,7 +107,17 @@ export function stubSqlApiCall<T>(
mockTxnResults: mockSqlTxnResult<T>[],
times: number = 1,
) {
const response = buildSqlExecutionResponse(mockTxnResults);
const firstError = mockTxnResults.find(mock => mock.error != null)?.error;
let err: clusterUiApi.SqlExecutionErrorMessage;
if (firstError != null) {
err = {
message: firstError.message,
code: "123",
severity: "ERROR",
source: { file: "myfile.go", line: 111, function: "myFn" },
};
}
const response = buildSqlExecutionResponse(mockTxnResults, err);
fetchMock.mock({
headers: {
Accept: "application/json",
Expand Down Expand Up @@ -185,3 +196,23 @@ function buildSqlTxnResult<RowType>(
error: mock.error,
};
}

const mockStmtExecErrorResponse = <T>(
res: Partial<SqlTxnResult<T>>,
): SqlTxnResult<T> => ({
statement: res?.statement ?? 1,
tag: "SELECT",
start: "2022-01-01T00:00:00Z",
end: "2022-01-01T00:00:01Z",
error: new Error("error"),
rows_affected: 0,
...res,
});

export const mockExecSQLErrors = <T>(
statements: number,
): mockSqlTxnResult<T>[] => {
return Array.from({ length: statements }, (_, i) =>
mockStmtExecErrorResponse<T>({ statement: i + 1 }),
);
};

0 comments on commit e84d1de

Please sign in to comment.