Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-16.0] Ensure hexval and int don't share BindVar after Normalization (#14451) #14477

Merged
merged 1 commit into from
Nov 13, 2023

Conversation

vitess-bot[bot]
Copy link
Contributor

@vitess-bot vitess-bot bot commented Nov 6, 2023

Description

This is a backport of #14451

@vitess-bot vitess-bot bot added Backport This is a backport Benchmark me Add label to PR to run benchmarks Component: Query Serving Merge Conflict Skip CI Skip CI actions from running Type: Bug labels Nov 6, 2023
Copy link
Contributor Author

vitess-bot bot commented Nov 6, 2023

Hello @williammartin, there are conflicts in this backport.

Please address them in order to merge this Pull Request. You can execute the snippet below to reset your branch and resolve the conflict manually.

Make sure you replace origin by the name of the vitessio/vitess remote

git fetch --all
gh pr checkout 14477 -R vitessio/vitess
git reset --hard origin/release-16.0
git cherry-pick -m 1 a7f0eadaacfef91c6bad51615571eb490017d677

Copy link
Contributor Author

vitess-bot bot commented Nov 6, 2023

Review Checklist

Hello reviewers! 👋 Please follow this checklist when reviewing this Pull Request.

General

  • Ensure that the Pull Request has a descriptive title.
  • Ensure there is a link to an issue (except for internal cleanup and flaky test fixes), new features should have an RFC that documents use cases and test cases.

Tests

  • Bug fixes should have at least one unit or end-to-end test, enhancement and new features should have a sufficient number of tests.

Documentation

  • Apply the release notes (needs details) label if users need to know about this change.
  • New features should be documented.
  • There should be some code comments as to why things are implemented the way they are.
  • There should be a comment at the top of each new or modified test to explain what the test does.

New flags

  • Is this flag really necessary?
  • Flag names must be clear and intuitive, use dashes (-), and have a clear help text.

If a workflow is added or modified:

  • Each item in Jobs should be named in order to mark it as required.
  • If the workflow needs to be marked as required, the maintainer team must be notified.

Backward compatibility

  • Protobuf changes should be wire-compatible.
  • Changes to _vt tables and RPCs need to be backward compatible.
  • RPC changes should be compatible with vitess-operator
  • If a flag is removed, then it should also be removed from vitess-operator and arewefastyet, if used there.
  • vtctl command output order should be stable and awk-able.

Copy link
Contributor Author

vitess-bot bot commented Nov 6, 2023

Hello! 👋

This Pull Request is now handled by arewefastyet. The current HEAD and future commits will be benchmarked.

You can find the performance comparison on the arewefastyet website.

@github-actions github-actions bot added this to the v16.0.6 milestone Nov 6, 2023
@williammartin
Copy link
Contributor

I don't have push rights to this repository, so here's the patch for this backport if it helps. Just a small change to the test since this version doesn't include type comments like /* HEXVAL */

commit 0df1e8e5b58747d730e3bd02f27a3fa8ab05e239
Author: William Martin <[email protected]>
Date:   Mon Nov 6 15:35:20 2023 +0100

    Ensure hexval and int don't share BindVar after Normalization (#14451)
    
    Signed-off-by: William Martin <[email protected]>

diff --git a/go/vt/sqlparser/normalizer.go b/go/vt/sqlparser/normalizer.go
index 6d7ee526bf..07cc1851c0 100644
--- a/go/vt/sqlparser/normalizer.go
+++ b/go/vt/sqlparser/normalizer.go
@@ -44,7 +44,7 @@ func Normalize(stmt Statement, reserved *ReservedVars, bindVars map[string]*quer
 type normalizer struct {
 	bindVars  map[string]*querypb.BindVariable
 	reserved  *ReservedVars
-	vals      map[string]string
+	vals      map[Literal]string
 	err       error
 	inDerived bool
 }
@@ -53,7 +53,7 @@ func newNormalizer(reserved *ReservedVars, bindVars map[string]*querypb.BindVari
 	return &normalizer{
 		bindVars: bindVars,
 		reserved: reserved,
-		vals:     make(map[string]string),
+		vals:     make(map[Literal]string),
 	}
 }
 
@@ -190,12 +190,11 @@ func (nz *normalizer) convertLiteralDedup(node *Literal, cursor *Cursor) {
 	}
 
 	// Check if there's a bindvar for that value already.
-	key := keyFor(bval, node)
-	bvname, ok := nz.vals[key]
+	bvname, ok := nz.vals[*node]
 	if !ok {
 		// If there's no such bindvar, make a new one.
 		bvname = nz.reserved.nextUnusedVar()
-		nz.vals[key] = bvname
+		nz.vals[*node] = bvname
 		nz.bindVars[bvname] = bval
 	}
 
@@ -203,18 +202,6 @@ func (nz *normalizer) convertLiteralDedup(node *Literal, cursor *Cursor) {
 	cursor.Replace(NewArgument(bvname))
 }
 
-func keyFor(bval *querypb.BindVariable, lit *Literal) string {
-	if bval.Type != sqltypes.VarBinary && bval.Type != sqltypes.VarChar {
-		return lit.Val
-	}
-
-	// Prefixing strings with "'" ensures that a string
-	// and number that have the same representation don't
-	// collide.
-	return "'" + lit.Val
-
-}
-
 // convertLiteral converts an Literal without the dedup.
 func (nz *normalizer) convertLiteral(node *Literal, cursor *Cursor) {
 	err := validateLiteral(node)
@@ -273,15 +260,14 @@ func (nz *normalizer) parameterize(left, right Expr) Expr {
 	if bval == nil {
 		return nil
 	}
-	key := keyFor(bval, lit)
-	bvname := nz.decideBindVarName(key, lit, col, bval)
+	bvname := nz.decideBindVarName(lit, col, bval)
 	return Argument(bvname)
 }
 
-func (nz *normalizer) decideBindVarName(key string, lit *Literal, col *ColName, bval *querypb.BindVariable) string {
+func (nz *normalizer) decideBindVarName(lit *Literal, col *ColName, bval *querypb.BindVariable) string {
 	if len(lit.Val) <= 256 {
 		// first we check if we already have a bindvar for this value. if we do, we re-use that bindvar name
-		bvname, ok := nz.vals[key]
+		bvname, ok := nz.vals[*lit]
 		if ok {
 			return bvname
 		}
@@ -291,7 +277,7 @@ func (nz *normalizer) decideBindVarName(key string, lit *Literal, col *ColName,
 	// Big values are most likely not for vindexes.
 	// We save a lot of CPU because we avoid building
 	bvname := nz.reserved.ReserveColName(col)
-	nz.vals[key] = bvname
+	nz.vals[*lit] = bvname
 	nz.bindVars[bvname] = bval
 
 	return bvname
diff --git a/go/vt/sqlparser/normalizer_test.go b/go/vt/sqlparser/normalizer_test.go
index fe3dc85b8c..27c57ae2e6 100644
--- a/go/vt/sqlparser/normalizer_test.go
+++ b/go/vt/sqlparser/normalizer_test.go
@@ -336,6 +336,14 @@ func TestNormalize(t *testing.T) {
 		in:      `select * from (select 12) as t`,
 		outstmt: `select * from (select 12 from dual) as t`,
 		outbv:   map[string]*querypb.BindVariable{},
+	}, {
+		// HexVal and Int should not share a bindvar just because they have the same value
+		in:      `select * from t where v1 = x'31' and v2 = 31`,
+		outstmt: `select * from t where v1 = :v1 and v2 = :v2`,
+		outbv: map[string]*querypb.BindVariable{
+			"v1": sqltypes.HexValBindVariable([]byte("x'31'")),
+			"v2": sqltypes.Int64BindVariable(31),
+		},
 	}}
 	for _, tc := range testcases {
 		t.Run(tc.in, func(t *testing.T) {

@arthurschreiber
Copy link
Contributor

If no one else beats me to it, I can get the conflict resolution pushed later today or tomorrow.

@vmg vmg removed the Benchmark me Add label to PR to run benchmarks label Nov 7, 2023
@arthurschreiber arthurschreiber force-pushed the backport-14451-to-release-16.0 branch from 865b997 to a678830 Compare November 11, 2023 19:35
@arthurschreiber arthurschreiber removed the Skip CI Skip CI actions from running label Nov 11, 2023
@arthurschreiber arthurschreiber force-pushed the backport-14451-to-release-16.0 branch from a678830 to 0b47a94 Compare November 11, 2023 20:23
@deepthi deepthi marked this pull request as ready for review November 11, 2023 22:05
@harshit-gangal harshit-gangal merged commit c4494a0 into release-16.0 Nov 13, 2023
221 of 222 checks passed
@harshit-gangal harshit-gangal deleted the backport-14451-to-release-16.0 branch November 13, 2023 06:15
@hmaurer hmaurer mentioned this pull request Mar 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants