From e3447ad8609ee117d42d1ee711132d4658f9265a Mon Sep 17 00:00:00 2001 From: maryliag Date: Mon, 14 Nov 2022 19:20:24 -0500 Subject: [PATCH] ui: add leading zeros to hex value with less than 16 chars Previously, some fingerprint IDs in hex format would have a leading 0, that was not being returning from the DB calls. This was causing confusion when seeing the value on the UI and trying to find the same fringerprint on our tables. This commits checks the hex values used and add the missing leading zeros back. Part Of: #91763 Release note (bug fix): Add leading zeros to fingerprint IDs with less than 16 characters. --- .../cluster-ui/src/api/insightsApi.ts | 29 ++++++++++--------- .../statementsPage.selectors.ts | 8 +++-- .../transactionsTable/transactionsTable.tsx | 11 +++++-- .../cluster-ui/src/util/format.spec.ts | 11 +++++++ .../workspaces/cluster-ui/src/util/format.ts | 15 ++++++++++ .../src/views/statements/statementsPage.tsx | 7 +++-- 6 files changed, 61 insertions(+), 20 deletions(-) diff --git a/pkg/ui/workspaces/cluster-ui/src/api/insightsApi.ts b/pkg/ui/workspaces/cluster-ui/src/api/insightsApi.ts index bbd7be686749..9971dc3a447a 100644 --- a/pkg/ui/workspaces/cluster-ui/src/api/insightsApi.ts +++ b/pkg/ui/workspaces/cluster-ui/src/api/insightsApi.ts @@ -19,17 +19,18 @@ import { } from "./sqlApi"; import { BlockedContentionDetails, + FlattenedStmtInsightEvent, + getInsightFromCause, + getInsightsFromProblemsAndCauses, InsightExecEnum, InsightNameEnum, - FlattenedStmtInsightEvent, - TxnContentionInsightEvent, TxnContentionInsightDetails, + TxnContentionInsightEvent, TxnInsightEvent, - getInsightsFromProblemsAndCauses, - getInsightFromCause, } from "src/insights"; import moment from "moment"; import { INTERNAL_APP_NAME_PREFIX } from "src/activeExecutions/activeStatementUtils"; +import { CheckHexValue } from "../util"; // Transaction contention insight events. @@ -86,7 +87,7 @@ function formatTxnContentionResults( return response.execution.txn_results[0].rows.map(row => ({ transactionID: row.waiting_txn_id, - transactionFingerprintID: row.waiting_txn_fingerprint_id, + transactionFingerprintID: CheckHexValue(row.waiting_txn_fingerprint_id), startTime: moment(row.collection_ts).utc(), contentionDuration: moment.duration(row.contention_duration), contentionThreshold: moment.duration(row.threshold).asMilliseconds(), @@ -133,7 +134,7 @@ function formatTxnFingerprintsResults( } return response.execution.txn_results[0].rows.map(row => ({ - transactionFingerprintID: row.transaction_fingerprint_id, + transactionFingerprintID: CheckHexValue(row.transaction_fingerprint_id), queryIDs: row.query_ids, application: row.app_name, })); @@ -168,7 +169,7 @@ function createStmtFingerprintToQueryMap( return idToQuery; } response.execution.txn_results[0].rows.forEach(row => { - idToQuery.set(row.statement_fingerprint_id, row.query); + idToQuery.set(CheckHexValue(row.statement_fingerprint_id), row.query); }); return idToQuery; @@ -363,7 +364,9 @@ function formatTxnContentionDetailsResponse( totalContentionTime += contentionTimeInMs; blockingContentionDetails[idx] = { blockingExecutionID: value.blocking_txn_id, - blockingTxnFingerprintID: value.blocking_txn_fingerprint_id, + blockingTxnFingerprintID: CheckHexValue( + value.blocking_txn_fingerprint_id, + ), blockingQueries: null, collectionTimeStamp: moment(value.collection_ts).utc(), contentionTimeMs: contentionTimeInMs, @@ -382,7 +385,7 @@ function formatTxnContentionDetailsResponse( const contentionThreshold = moment.duration(row.threshold).asMilliseconds(); return { transactionExecutionID: row.waiting_txn_id, - transactionFingerprintID: row.waiting_txn_fingerprint_id, + transactionFingerprintID: CheckHexValue(row.waiting_txn_fingerprint_id), startTime: moment(row.collection_ts).utc(), totalContentionTimeMs: totalContentionTime, blockingContentionDetails: blockingContentionDetails, @@ -493,13 +496,11 @@ function buildTxnContentionInsightDetails( partialTxnContentionDetails.transactionFingerprintID, ); - const res = { + return { ...partialTxnContentionDetails, application: waitingTxn.application, queries: waitingTxn.queryIDs.map(id => stmtFingerprintToQuery.get(id)), }; - - return res; } type ExecutionInsightsResponseRow = { @@ -550,7 +551,7 @@ function organizeExecutionInsightsResponseIntoTxns( if (!txnInsight) { txnInsight = { transactionExecutionID: row.txn_id, - transactionFingerprintID: row.txn_fingerprint_id, + transactionFingerprintID: CheckHexValue(row.txn_fingerprint_id), implicitTxn: row.implicit_txn, databaseName: row.database_name, application: row.app_name, @@ -574,7 +575,7 @@ function organizeExecutionInsightsResponseIntoTxns( endTime: end, elapsedTimeMillis: end.diff(start, "milliseconds"), statementExecutionID: row.stmt_id, - statementFingerprintID: row.stmt_fingerprint_id, + statementFingerprintID: CheckHexValue(row.stmt_fingerprint_id), isFullScan: row.full_scan, rowsRead: row.rows_read, rowsWritten: row.rows_written, diff --git a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.selectors.ts b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.selectors.ts index f2d8ec08bc15..06fa07c2a0a7 100644 --- a/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.selectors.ts +++ b/pkg/ui/workspaces/cluster-ui/src/statementsPage/statementsPage.selectors.ts @@ -12,6 +12,7 @@ import { createSelector } from "reselect"; import { aggregateStatementStats, appAttr, + CheckHexValue, combineStatementStats, ExecutionStatistics, flattenStatementStats, @@ -177,8 +178,9 @@ export const selectStatements = createSelector( if (!(key in statsByStatementKey)) { statsByStatementKey[key] = { statementFingerprintID: stmt.statement_fingerprint_id?.toString(), - statementFingerprintHexID: + statementFingerprintHexID: CheckHexValue( stmt.statement_fingerprint_id?.toString(16), + ), statement: stmt.statement, statementSummary: stmt.statement_summary, aggregatedTs: stmt.aggregated_ts, @@ -197,7 +199,9 @@ export const selectStatements = createSelector( const stmt = statsByStatementKey[key]; return { aggregatedFingerprintID: stmt.statementFingerprintID, - aggregatedFingerprintHexID: stmt.statementFingerprintHexID, + aggregatedFingerprintHexID: CheckHexValue( + stmt.statementFingerprintHexID, + ), label: stmt.statement, summary: stmt.statementSummary, aggregatedTs: stmt.aggregatedTs, diff --git a/pkg/ui/workspaces/cluster-ui/src/transactionsTable/transactionsTable.tsx b/pkg/ui/workspaces/cluster-ui/src/transactionsTable/transactionsTable.tsx index ed45505f5cd8..17ff5b72e8fb 100644 --- a/pkg/ui/workspaces/cluster-ui/src/transactionsTable/transactionsTable.tsx +++ b/pkg/ui/workspaces/cluster-ui/src/transactionsTable/transactionsTable.tsx @@ -28,7 +28,14 @@ import { import { statisticsTableTitles } from "../statsTableUtil/statsTableUtil"; import { tableClasses } from "./transactionsTableClasses"; import { transactionLink } from "./transactionsCells"; -import { Count, FixLong, longToInt, TimestampToString, unset } from "src/util"; +import { + CheckHexValue, + Count, + FixLong, + longToInt, + TimestampToString, + unset, +} from "src/util"; import { SortSetting } from "../sortedtable"; import { getStatementsByFingerprintId, @@ -243,7 +250,7 @@ export function makeTransactionsColumns( name: "transactionFingerprintId", title: statisticsTableTitles.transactionFingerprintId(statType), cell: (item: TransactionInfo) => - item.stats_data?.transaction_fingerprint_id.toString(16), + CheckHexValue(item.stats_data?.transaction_fingerprint_id.toString(16)), sort: (item: TransactionInfo) => item.stats_data?.transaction_fingerprint_id.toString(16), showByDefault: false, diff --git a/pkg/ui/workspaces/cluster-ui/src/util/format.spec.ts b/pkg/ui/workspaces/cluster-ui/src/util/format.spec.ts index f3c250aac373..818ac7374db7 100644 --- a/pkg/ui/workspaces/cluster-ui/src/util/format.spec.ts +++ b/pkg/ui/workspaces/cluster-ui/src/util/format.spec.ts @@ -15,6 +15,7 @@ import { BytesFitScale, byteUnits, HexStringToInt64String, + CheckHexValue, } from "./format"; describe("Format utils", () => { @@ -59,4 +60,14 @@ describe("Format utils", () => { ); }); }); + + describe("CheckHexValue", () => { + it("add leading 0 to hex values", () => { + expect(CheckHexValue(undefined)).toBe(""); + expect(CheckHexValue(null)).toBe(""); + expect(CheckHexValue("fb9111f22f2213b7")).toBe("fb9111f22f2213b7"); + expect(CheckHexValue("b9111f22f2213b7")).toBe("0b9111f22f2213b7"); + expect(CheckHexValue("9111f22f2213b7")).toBe("009111f22f2213b7"); + }); + }); }); diff --git a/pkg/ui/workspaces/cluster-ui/src/util/format.ts b/pkg/ui/workspaces/cluster-ui/src/util/format.ts index b0d2e5577609..60c1ddfbd913 100644 --- a/pkg/ui/workspaces/cluster-ui/src/util/format.ts +++ b/pkg/ui/workspaces/cluster-ui/src/util/format.ts @@ -256,6 +256,21 @@ export function HexStringToInt64String(s: string): string { return dec; } +// CheckHexValue adds the leading 0 on strings with hex value that +// have a length < 16. +export function CheckHexValue(s: string): string { + if (s === undefined || s === null || s.length === 0) { + return ""; + } + if (s?.length === 16) { + return s; + } + while (s.length < 16) { + s = `0${s}`; + } + return s; +} + // capitalize capitalizes a string. export function capitalize(str: string): string { if (!str) return str; diff --git a/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.tsx b/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.tsx index 5223d596b408..b513716c150b 100644 --- a/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.tsx +++ b/pkg/ui/workspaces/db-console/src/views/statements/statementsPage.tsx @@ -142,8 +142,9 @@ export const selectStatements = createSelector( if (!(key in statsByStatementKey)) { statsByStatementKey[key] = { statementFingerprintID: stmt.statement_fingerprint_id?.toString(), - statementFingerprintHexID: + statementFingerprintHexID: util.CheckHexValue( stmt.statement_fingerprint_id?.toString(16), + ), statement: stmt.statement, statementSummary: stmt.statement_summary, aggregatedTs: stmt.aggregated_ts, @@ -162,7 +163,9 @@ export const selectStatements = createSelector( const stmt = statsByStatementKey[key]; return { aggregatedFingerprintID: stmt.statementFingerprintID, - aggregatedFingerprintHexID: stmt.statementFingerprintHexID, + aggregatedFingerprintHexID: util.CheckHexValue( + stmt.statementFingerprintHexID, + ), label: stmt.statement, summary: stmt.statementSummary, aggregatedTs: stmt.aggregatedTs,