diff --git a/query/query.go b/query/query.go index c0de41a..7cbf9a2 100644 --- a/query/query.go +++ b/query/query.go @@ -785,7 +785,7 @@ func Fingerprint(q string) string { addSpace = false // since we only consider the keywords if it exists at a top-level (except onDupeKeyUpdate), // we only do the conversion below if the "keywords" actually open a value list (i.e., before opening a parenthesis). - if r == '(' || (isSpace(r) && (q[qi+1] == '(') || (q[qi+1] == ' ')) { + if r == '(' || (isSpace(r) && qi+1 < len(q) && ((q[qi+1] == '(') || (q[qi+1] == ' '))) { // IN () -> in(?+) // VALUES () -> values(?+) s = inValues diff --git a/query/query_test.go b/query/query_test.go index 389a0b9..427854b 100644 --- a/query/query_test.go +++ b/query/query_test.go @@ -693,3 +693,25 @@ func TestFingerprintSubqueries(t *testing.T) { }) } } + +func TestFingerprintSystemVariableQueries(t *testing.T) { + type testCase struct { + name string + query string + expected string + } + // Test cases for system variable queries + testCases := []testCase{ + { + name: "global read_only", + query: "set long_query_time = 0; SELECT @@GLOBAL.read_only AS Value", + expected: "set long_query_time = ?; select @@global.read_only as value", + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual := query.Fingerprint(tc.query) + assert.Equal(t, tc.expected, actual, "Query: %s", tc.query) + }) + } +}