Skip to content

Commit 02df27b

Browse files
committed
sql: introduce a non-experimental version of SHOW FINGERPRINTS
In 2017, we implemented SHOW EXPERIMENTAL_FINGERPRINTS, which provides FNV fingerprints of all the indexes in a table. The implementation of this command involved casting all the columns in each index to either a string or bytes value so that it could be consumed by fnv64(). This meant that values that cast to the same string value were not diffentiated by the hash function. For this reason, the feature was deemed "experimental" and not for use by users. SHOW EXPERIMENTAL_FINGERPRINTS was useful enough to find its way into various DR and CDC tests to determine whether or not data was preserved correctly. This patch introduces SHOW FINGERPRINTS, which uses crdb_internal.datums_to_bytes() to transform the input data into encoded bytes for use by fnv64(). This version of fingerprinting should be more sensitive to changes in data. Now, data that prints the same won't necessarily produce the same hash. Additionally, adding NULL values will impact the hash as well. FNV was originally chosen for SHOW EXPERIMENTAL_FINGERPRINTS and not changed by this patch because it's approximately four times as fast as SHA256/512 and cryptographic security is not required by this particular use case. This patch also changes the output to be a 0-padded hexidecimal representation of the hash instead of an integer. No changes to external references to SHOW EXPERIMENTAL_FINGERPRINTS are made here so that other groups can migrate at their own pace. Epic: CRDB-49047 Release note (sql change): We have introduced the "SHOW FINGERPRINTS FOR TABLE" SQL command, which produces a FNV hash of each index a table. FNV is used here for performance reasons.
1 parent ae0b3d7 commit 02df27b

File tree

8 files changed

+375
-70
lines changed

8 files changed

+375
-70
lines changed

docs/generated/sql/bnf/stmt_block.bnf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,7 @@ unreserved_keyword ::=
12321232
| 'FAILURE'
12331233
| 'FILES'
12341234
| 'FILTER'
1235+
| 'FINGERPRINTS'
12351236
| 'FIRST'
12361237
| 'FOLLOWING'
12371238
| 'FORMAT'
@@ -4174,6 +4175,7 @@ bare_label_keywords ::=
41744175
| 'FALSE'
41754176
| 'FAMILY'
41764177
| 'FILES'
4178+
| 'FINGERPRINTS'
41774179
| 'FIRST'
41784180
| 'FLOAT'
41794181
| 'FOLLOWING'

pkg/crosscluster/logical/logical_replication_job_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1652,9 +1652,9 @@ func compareReplicatedTables(
16521652
indexB, err := catalog.MustFindIndexByName(descB, indexA.GetName())
16531653
require.NoError(t, err)
16541654

1655-
aFingerprintQuery, err := sql.BuildFingerprintQueryForIndex(descA, indexA, []string{})
1655+
aFingerprintQuery, err := sql.BuildExperimentalFingerprintQueryForIndex(descA, indexA, []string{})
16561656
require.NoError(t, err)
1657-
bFingerprintQuery, err := sql.BuildFingerprintQueryForIndex(descB, indexB, []string{})
1657+
bFingerprintQuery, err := sql.BuildExperimentalFingerprintQueryForIndex(descB, indexB, []string{})
16581658
require.NoError(t, err)
16591659
t.Logf("fingerprinting index %s", indexA.GetName())
16601660
runnerB.CheckQueryResults(t, bFingerprintQuery, runnerA.QueryStr(t, aFingerprintQuery))

pkg/sql/logictest/testdata/logic_test/show_fingerprints

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
88
t_pkey NULL
99
t_b_idx NULL
1010

11+
query TT rowsort
12+
SHOW FINGERPRINTS FROM TABLE t
13+
----
14+
t_pkey NULL
15+
t_b_idx NULL
16+
1117
statement ok
1218
INSERT INTO t VALUES (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)
1319

@@ -18,28 +24,59 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
1824
t_pkey -7903300865687235210
1925
t_b_idx -5073888452016928166
2026

27+
query TT rowsort
28+
SHOW FINGERPRINTS FROM TABLE t
29+
----
30+
t_pkey 461f727cc14973a5
31+
t_b_idx d74ed1186a9d4682
32+
33+
# Test that if the data doesn't change, neither do the hashes
34+
query TT rowsort
35+
SHOW FINGERPRINTS FROM TABLE t
36+
----
37+
t_pkey 461f727cc14973a5
38+
t_b_idx d74ed1186a9d4682
39+
2140
# Test excluded columns
2241
query TT rowsort
2342
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t WITH EXCLUDE COLUMNS = ('c')
2443
----
2544
t_pkey -2938394162542358272
2645
t_b_idx -5073888452016928166
2746

47+
query TT rowsort
48+
SHOW FINGERPRINTS FROM TABLE t WITH EXCLUDE COLUMNS = ('c')
49+
----
50+
t_pkey d74dbe186a97ae30
51+
t_b_idx d74ed1186a9d4682
52+
2853
# Test multiple excluded columns
2954
query TT rowsort
3055
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t WITH EXCLUDE COLUMNS = ('a', 'b')
3156
----
3257
t_pkey -3539648437866042702
3358
t_b_idx 590700560494856532
3459

60+
query TT rowsort
61+
SHOW FINGERPRINTS FROM TABLE t WITH EXCLUDE COLUMNS = ('a', 'b')
62+
----
63+
t_pkey 0831f107b4ea89e0
64+
t_b_idx af63bd4c8601b757
65+
3566
# START TIMESTAMP is only for VIRTUAL CLUSTERS
3667
query error pgcode 22023 cannot use the START TIMESTAMP option when fingerprinting a table.
3768
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t WITH START TIMESTAMP = '132412341234.000000'
3869

70+
query error pgcode 22023 cannot use the START TIMESTAMP option when fingerprinting a table.
71+
SHOW FINGERPRINTS FROM TABLE t WITH START TIMESTAMP = '132412341234.000000'
72+
3973
# EXCLUDE COLUMNS is only for tables
4074
query error pgcode 22023 cannot use the EXCLUDE COLUMNS option when fingerprinting a tenant.
4175
SHOW EXPERIMENTAL_FINGERPRINTS FROM VIRTUAL CLUSTER t WITH EXCLUDE COLUMNS = ('a', 'b')
4276

77+
query error pgcode 22023 cannot use the EXCLUDE COLUMNS option when fingerprinting a tenant.
78+
SHOW FINGERPRINTS FROM VIRTUAL CLUSTER t WITH EXCLUDE COLUMNS = ('a', 'b')
79+
4380
# Test a partial index. We expect this index to have the same fingerprint
4481
# as t_b_idx since the predicate covers all values.
4582
statement ok
@@ -52,6 +89,12 @@ t_pkey -7903300865687235210
5289
t_b_idx -5073888452016928166
5390
t_b_idx1 -5073888452016928166
5491

92+
query TT rowsort
93+
SHOW FINGERPRINTS FROM TABLE t
94+
----
95+
t_pkey 461f727cc14973a5
96+
t_b_idx d74ed1186a9d4682
97+
t_b_idx1 d74ed1186a9d4682
5598

5699
statement ok
57100
DROP INDEX t_b_idx1
@@ -66,6 +109,12 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
66109
t_pkey 3722816579880544080
67110
t_b_idx -8494698744159250398
68111

112+
query TT rowsort
113+
SHOW FINGERPRINTS FROM TABLE t
114+
----
115+
t_pkey 46bf827cc1222da6
116+
t_b_idx d75fd1186a6bce95
117+
69118
statement ok
70119
UPDATE t SET c = 10
71120

@@ -76,6 +125,12 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
76125
t_pkey 4547357529681250049
77126
t_b_idx -8494698744159250398
78127

128+
query TT rowsort
129+
SHOW FINGERPRINTS FROM TABLE t
130+
----
131+
t_pkey 46bf977cc121fbd5
132+
t_b_idx d75fd1186a6bce95
133+
79134
statement ok
80135
UPDATE t SET d = 10
81136

@@ -86,6 +141,12 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
86141
t_pkey 492416650140211287
87142
t_b_idx -8497500299788131628
88143

144+
query TT rowsort
145+
SHOW FINGERPRINTS FROM TABLE t
146+
----
147+
t_pkey 46bf977cc121fbcf
148+
t_b_idx d75fd1186a6bce8f
149+
89150
statement ok
90151
ALTER TABLE t ADD COLUMN e string;
91152

@@ -97,6 +158,13 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
97158
t_pkey 492416650140211287
98159
t_b_idx -8497500299788131628
99160

161+
# Because NULLs are encoded, the new FINGERPRINTS will pick up on the new column
162+
query TT rowsort
163+
SHOW FINGERPRINTS FROM TABLE t
164+
----
165+
t_pkey 292198383001098d
166+
t_b_idx d75fd1186a6bce8f
167+
100168
statement ok
101169
UPDATE t SET e = 'foo' WHERE a = 1;
102170

@@ -107,6 +175,12 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
107175
t_pkey 1205834892498753533
108176
t_b_idx -8497500299788131628
109177

178+
query TT rowsort
179+
SHOW FINGERPRINTS FROM TABLE t
180+
----
181+
t_pkey 7a7ee2be020b59bc
182+
t_b_idx d75fd1186a6bce8f
183+
110184
statement ok
111185
DROP INDEX t@t_b_idx
112186

@@ -116,12 +190,22 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
116190
----
117191
t_pkey 1205834892498753533
118192

193+
query TT
194+
SHOW FINGERPRINTS FROM TABLE t
195+
----
196+
t_pkey 7a7ee2be020b59bc
197+
119198
# Make sure fully qualified table names work
120199
query TT
121200
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE test.t
122201
----
123202
t_pkey 1205834892498753533
124203

204+
query TT
205+
SHOW FINGERPRINTS FROM TABLE test.t
206+
----
207+
t_pkey 7a7ee2be020b59bc
208+
125209
statement ok
126210
CREATE TABLE "foo""bar" ("a""b" INT PRIMARY KEY, b INT, INDEX "id""x" (b))
127211

@@ -136,6 +220,12 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE "foo""bar"
136220
foo"bar_pkey 590693963425091008
137221
id"x 590692863913460538
138222

223+
query TT rowsort
224+
SHOW FINGERPRINTS FROM TABLE "foo""bar"
225+
----
226+
foo"bar_pkey 0831f907b4ea8440
227+
id"x 0831f807b4ea794a
228+
139229
# BYTES is special cased so make sure tables with both BYTES and non-BYTES
140230
# columns work
141231
statement ok
@@ -149,6 +239,11 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE blocks
149239
----
150240
blocks_pkey -9087023432987872405
151241

242+
query TT
243+
SHOW FINGERPRINTS FROM TABLE blocks
244+
----
245+
blocks_pkey c0de5f63471cd038
246+
152247
# Verify that we can show fingerprints from a read-only transaction (#39204).
153248
statement ok
154249
BEGIN TRANSACTION AS OF SYSTEM TIME '-1us'
@@ -158,6 +253,11 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
158253
----
159254
t_pkey 1205834892498753533
160255

256+
query TT
257+
SHOW FINGERPRINTS FROM TABLE t
258+
----
259+
t_pkey 7a7ee2be020b59bc
260+
161261
statement ok
162262
COMMIT
163263

@@ -173,3 +273,10 @@ SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t_w_expr_index
173273
t_w_expr_index_pkey -3347212893095932527
174274
t_w_expr_index_c_idx -2777058403611971387
175275
t_w_expr_index_expr_idx -2777058403611971387
276+
277+
query TT rowsort
278+
SHOW FINGERPRINTS FROM TABLE t_w_expr_index
279+
----
280+
t_w_expr_index_pkey 9842887cf772b8a5
281+
t_w_expr_index_c_idx 08321207b4eaafc3
282+
t_w_expr_index_expr_idx 08321207b4eaafc3

pkg/sql/logictest/testdata/logic_test/show_tenant_fingerprints

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,53 @@ user testuser
5858

5959
statement error user testuser does not have MANAGEVIRTUALCLUSTER system privilege
6060
SHOW EXPERIMENTAL_FINGERPRINTS FROM TENANT target
61+
62+
63+
# Test again with SHOW FINGERPRINTS
64+
user root
65+
66+
let $fingerprint2
67+
SELECT fingerprint FROM [SHOW FINGERPRINTS FROM TENANT target] AS OF SYSTEM TIME $aost
68+
69+
query T
70+
SELECT * FROM (SELECT 'fingerprint matches' FROM [ SHOW FINGERPRINTS FROM TENANT target] WHERE fingerprint = $fingerprint2) AS OF SYSTEM TIME $aost;
71+
----
72+
fingerprint matches
73+
74+
# Test virtual cluster alias as well
75+
query T
76+
SELECT * FROM (SELECT 'fingerprint matches' FROM [ SHOW FINGERPRINTS FROM VIRTUAL CLUSTER target] WHERE fingerprint = $fingerprint2) AS OF SYSTEM TIME $aost;
77+
----
78+
fingerprint matches
79+
80+
query TTTT
81+
SELECT * FROM (
82+
SELECT tenant_name, 'start_ts is NULL', 'end_ts is NOT NULL', 'fingerprint is non-zero'
83+
FROM [SHOW FINGERPRINTS FROM TENANT target]
84+
WHERE (start_ts IS NULL) AND (end_ts IS NOT NULL))
85+
AS OF SYSTEM TIME $aost;
86+
----
87+
target start_ts is NULL end_ts is NOT NULL fingerprint is non-zero
88+
89+
let $aost2
90+
SELECT cluster_logical_timestamp();
91+
92+
93+
query TTTT
94+
SELECT * FROM (
95+
SELECT tenant_name, 'start_ts is NOT NULL', 'end_ts is NOT NULL', 'fingerprint is non-zero'
96+
FROM [SHOW FINGERPRINTS FROM TENANT target WITH START TIMESTAMP = $aost]
97+
WHERE (start_ts IS NOT NULL) AND (end_ts IS NOT NULL))
98+
AS OF SYSTEM TIME $aost2;
99+
----
100+
target start_ts is NOT NULL end_ts is NOT NULL fingerprint is non-zero
101+
102+
# Test that the end timestamp has to be greater than equal to the start timestamp.
103+
statement error pgcode 22023 start timestamp.*is greater than the end timestamp.*
104+
SELECT * FROM [SHOW FINGERPRINTS FROM TENANT target WITH START TIMESTAMP = $aost2] AS OF SYSTEM TIME $aost;
105+
106+
107+
user testuser
108+
109+
statement error user testuser does not have MANAGEVIRTUALCLUSTER system privilege
110+
SHOW FINGERPRINTS FROM TENANT target

0 commit comments

Comments
 (0)