@@ -844,18 +844,25 @@ func TestNormalizeStmtForBinding(t *testing.T) {
844844 sql string
845845 normalized string
846846 }{
847+ // The inner addition is redundant inside a function argument and can be
848+ // restored without changing the expression boundary.
847849 {
848850 "select 1 from b where abs((x + 1)) = 2" ,
849851 "select ? from `b` where `abs` ( `x` + ? ) = ?" ,
850852 },
853+ // Addition has lower precedence than multiplication, so the left child
854+ // parentheses are semantic.
851855 {
852856 "select 1 from b where (x + 1) * y = 2" ,
853857 "select ? from `b` where ( `x` + ? ) * `y` = ?" ,
854858 },
859+ // OR has lower precedence than AND and must stay grouped as the right child.
855860 {
856861 "select 1 from b where x = 1 and (y = 1 or y = 2)" ,
857862 "select ? from `b` where `x` = ? and ( `y` = ? or `y` = ? )" ,
858863 },
864+ // Unary NOT keeps its operand parenthesized so the restore output does not
865+ // expose a different parse boundary.
859866 {
860867 "select 1 from b where not (x = 1)" ,
861868 "select ? from `b` where not ( `x` = ? )" ,
@@ -864,14 +871,19 @@ func TestNormalizeStmtForBinding(t *testing.T) {
864871 "select 1 from b where (not x) = 1" ,
865872 "select ? from `b` where ( not `x` ) = ?" ,
866873 },
874+ // Bitwise XOR binds tighter than addition, so `(x + y) ^ z` must preserve
875+ // the addition group.
867876 {
868877 "select 1 from b where (x + y) ^ z = 1" ,
869878 "select ? from `b` where ( `x` + `y` ) ^ `z` = ?" ,
870879 },
880+ // Bitwise XOR also binds tighter than multiplication in MySQL.
871881 {
872882 "select 1 from b where (x * y) ^ z = 1" ,
873883 "select ? from `b` where ( `x` * `y` ) ^ `z` = ?" ,
874884 },
885+ // The XOR child binds tighter than addition, so the right-child
886+ // parentheses are redundant here.
875887 {
876888 "select 1 from b where x + (y ^ z) = 1" ,
877889 "select ? from `b` where `x` + `y` ^ `z` = ?" ,
0 commit comments