statement ok
CREATE TABLE t (a INT PRIMARY KEY, b INT, c INT, d INT, INDEX (b) STORING (d))

# Empty data
query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
----
t_pkey   NULL
t_b_idx  NULL

statement ok
INSERT INTO t VALUES (1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)

# Add some initial data
query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
----
t_pkey   -7903300865687235210
t_b_idx  -5073888452016928166

# Test excluded columns
query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t WITH EXCLUDE COLUMNS = ('c')
----
t_pkey   -2938394162542358272
t_b_idx  -5073888452016928166

# Test multiple excluded columns
query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t WITH EXCLUDE COLUMNS = ('a', 'b')
----
t_pkey   -3539648437866042702
t_b_idx  590700560494856532

# START TIMESTAMP is only for VIRTUAL CLUSTERS
query error pgcode 22023 cannot use the START TIMESTAMP option when fingerprinting a table.
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t WITH START TIMESTAMP = '132412341234.000000'

# EXCLUDE COLUMNS is only for tables
query error pgcode 22023 cannot use the EXCLUDE COLUMNS option when fingerprinting a tenant.
SHOW EXPERIMENTAL_FINGERPRINTS FROM VIRTUAL CLUSTER t WITH EXCLUDE COLUMNS = ('a', 'b')

# Test a partial index. We expect this index to have the same fingerprint
# as t_b_idx since the predicate covers all values.
statement ok
CREATE INDEX ON t(b) STORING (d) WHERE b > 0

query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
----
t_pkey   -7903300865687235210
t_b_idx  -5073888452016928166
t_b_idx1  -5073888452016928166


statement ok
DROP INDEX t_b_idx1

statement ok
UPDATE t SET b = 9

# b is encoded in both indexes, so both should change
query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
----
t_pkey   3722816579880544080
t_b_idx  -8494698744159250398

statement ok
UPDATE t SET c = 10

# c is encoded only in primary, so t_b_idx shouldn't change
query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
----
t_pkey   4547357529681250049
t_b_idx  -8494698744159250398

statement ok
UPDATE t SET d = 10

# d is encoded in both indexes, so both should change
query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
----
t_pkey   492416650140211287
t_b_idx  -8497500299788131628

statement ok
ALTER TABLE t ADD COLUMN e string;

# Table changed, but the new column is all NULLs so neither fingerprint should
# change
query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
----
t_pkey   492416650140211287
t_b_idx  -8497500299788131628

statement ok
UPDATE t SET e = 'foo' WHERE a = 1;

# Column e is not in index t_b_idx so its fingerprint shouldn't change
query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
----
t_pkey   1205834892498753533
t_b_idx  -8497500299788131628

statement ok
DROP INDEX t@t_b_idx

# Double check that dropping an index doesn't affect the fingerprint of primary
query TT
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
----
t_pkey  1205834892498753533

# Make sure fully qualified table names work
query TT
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE test.t
----
t_pkey  1205834892498753533

statement ok
CREATE TABLE "foo""bar" ("a""b" INT PRIMARY KEY, b INT, INDEX "id""x" (b))

statement ok
INSERT INTO "foo""bar" VALUES (1, 2), (3, 4), (5, 6)

# Make sure we handle table, index, and column name escaping correctly in the
# internally generated query.
query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE "foo""bar"
----
foo"bar_pkey  590693963425091008
id"x          590692863913460538

# BYTES is special cased so make sure tables with both BYTES and non-BYTES
# columns work
statement ok
CREATE TABLE blocks (block_id INT PRIMARY KEY, raw_bytes BYTES NOT NULL)

statement ok
INSERT INTO blocks VALUES (1, b'\x01')

query TT
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE blocks
----
blocks_pkey  -9087023432987872405

# Verify that we can show fingerprints from a read-only transaction (#39204).
statement ok
BEGIN TRANSACTION AS OF SYSTEM TIME '-1us'

query TT
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t
----
t_pkey  1205834892498753533

statement ok
COMMIT

statement ok
CREATE TABLE t_w_expr_index (a INT PRIMARY KEY, b INT, c INT AS (b + 42) STORED, INDEX (c), INDEX ((b+42)))

statement ok
INSERT INTO t_w_expr_index VALUES (1, 1), (2, 2), (3, 3)

query TT rowsort
SHOW EXPERIMENTAL_FINGERPRINTS FROM TABLE t_w_expr_index
----
t_w_expr_index_pkey     -3347212893095932527
t_w_expr_index_c_idx    -2777058403611971387
t_w_expr_index_expr_idx -2777058403611971387
