From d6c7fbc2db2f7e3d17455e23255cda9cc41e0935 Mon Sep 17 00:00:00 2001 From: "vitess-bot[bot]" <108069721+vitess-bot[bot]@users.noreply.github.com> Date: Thu, 13 Jun 2024 14:19:03 +0200 Subject: [PATCH] [release-18.0] Fix `vtexplain` not handling `UNION` queries with `weight_string` results correctly. (#16129) (#16156) Signed-off-by: Arthur Schreiber Co-authored-by: vitess-bot[bot] <108069721+vitess-bot[bot]@users.noreply.github.com> Co-authored-by: Arthur Schreiber --- .../multi-output/selectsharded-output.txt | 34 +++++++++++-------- .../testdata/selectsharded-queries.sql | 4 ++- go/vt/vtexplain/vtexplain_test.go | 23 +++++++++++++ go/vt/vtexplain/vtexplain_vttablet.go | 12 +++++-- 4 files changed, 55 insertions(+), 18 deletions(-) diff --git a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt index 7ae20ca1a7f..1654cb63ded 100644 --- a/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt +++ b/go/vt/vtexplain/testdata/multi-output/selectsharded-output.txt @@ -99,10 +99,10 @@ select 1, "hello", 3.14, null from user limit 10 /* select constant sql values * ---------------------------------------------------------------------- select * from (select id from user) s /* scatter paren select */ -1 ks_sharded/-40: select s.id from (select id from `user`) as s limit 10001 /* scatter paren select */ -1 ks_sharded/40-80: select s.id from (select id from `user`) as s limit 10001 /* scatter paren select */ -1 ks_sharded/80-c0: select s.id from (select id from `user`) as s limit 10001 /* scatter paren select */ -1 ks_sharded/c0-: select s.id from (select id from `user`) as s limit 10001 /* scatter paren select */ +1 ks_sharded/-40: select id from (select id from `user`) as s limit 10001 /* scatter paren select */ +1 ks_sharded/40-80: select id from (select id from `user`) as s limit 10001 /* scatter paren select */ +1 ks_sharded/80-c0: select id from (select id from `user`) as s limit 10001 /* scatter paren select */ +1 ks_sharded/c0-: select id from (select id from `user`) as s limit 10001 /* scatter paren select */ ---------------------------------------------------------------------- select name from user where id = (select id from t1) /* non-correlated subquery as value */ @@ -114,21 +114,21 @@ select name from user where id = (select id from t1) /* non-correlated subquery select name from user where id in (select id from t1) /* non-correlated subquery in IN clause */ 1 ks_unsharded/-: select id from t1 limit 10001 /* non-correlated subquery in IN clause */ -2 ks_sharded/-40: select `name` from `user` where 1 = 1 and id in (1) limit 10001 /* non-correlated subquery in IN clause */ +2 ks_sharded/-40: select `name` from `user` where 1 and id in (1) limit 10001 /* non-correlated subquery in IN clause */ ---------------------------------------------------------------------- select name from user where id not in (select id from t1) /* non-correlated subquery in NOT IN clause */ 1 ks_unsharded/-: select id from t1 limit 10001 /* non-correlated subquery in NOT IN clause */ -2 ks_sharded/-40: select `name` from `user` where 1 = 0 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ -2 ks_sharded/40-80: select `name` from `user` where 1 = 0 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ -2 ks_sharded/80-c0: select `name` from `user` where 1 = 0 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ -2 ks_sharded/c0-: select `name` from `user` where 1 = 0 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ +2 ks_sharded/-40: select `name` from `user` where not 1 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ +2 ks_sharded/40-80: select `name` from `user` where not 1 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ +2 ks_sharded/80-c0: select `name` from `user` where not 1 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ +2 ks_sharded/c0-: select `name` from `user` where not 1 or id not in (1) limit 10001 /* non-correlated subquery in NOT IN clause */ ---------------------------------------------------------------------- select name from user where exists (select id from t1) /* non-correlated subquery as EXISTS */ -1 ks_unsharded/-: select 1 from t1 limit 1 /* non-correlated subquery as EXISTS */ +1 ks_unsharded/-: select 1 from t1 limit 10001 /* non-correlated subquery as EXISTS */ 2 ks_sharded/-40: select `name` from `user` where 1 limit 10001 /* non-correlated subquery as EXISTS */ 2 ks_sharded/40-80: select `name` from `user` where 1 limit 10001 /* non-correlated subquery as EXISTS */ 2 ks_sharded/80-c0: select `name` from `user` where 1 limit 10001 /* non-correlated subquery as EXISTS */ @@ -137,10 +137,10 @@ select name from user where exists (select id from t1) /* non-correlated subquer ---------------------------------------------------------------------- select * from name_info order by info /* select * and order by varchar column */ -1 ks_sharded/-40: select `name`, info from name_info order by info asc limit 10001 /* select * and order by varchar column */ -1 ks_sharded/40-80: select `name`, info from name_info order by info asc limit 10001 /* select * and order by varchar column */ -1 ks_sharded/80-c0: select `name`, info from name_info order by info asc limit 10001 /* select * and order by varchar column */ -1 ks_sharded/c0-: select `name`, info from name_info order by info asc limit 10001 /* select * and order by varchar column */ +1 ks_sharded/-40: select `name`, info from name_info order by name_info.info asc limit 10001 /* select * and order by varchar column */ +1 ks_sharded/40-80: select `name`, info from name_info order by name_info.info asc limit 10001 /* select * and order by varchar column */ +1 ks_sharded/80-c0: select `name`, info from name_info order by name_info.info asc limit 10001 /* select * and order by varchar column */ +1 ks_sharded/c0-: select `name`, info from name_info order by name_info.info asc limit 10001 /* select * and order by varchar column */ ---------------------------------------------------------------------- select distinct(name) from user where id = 1 /* select distinct */ @@ -207,3 +207,9 @@ SELECT id FROM orders WHERE id IN (1, "1", 1) 2 ks_sharded/40-80: select id from orders where id in (1, '1', 1) limit 10001 ---------------------------------------------------------------------- +(SELECT user.id, user.name FROM user WHERE user.id = 1) UNION (SELECT user.id, user.name FROM user WHERE user.id = 2) + +2 ks_sharded/-40: select distinct `user`.id, `user`.`name`, weight_string(`user`.id), weight_string(`user`.`name`) from `user` where `user`.id = 2 limit 10001 /* INT64 */ +2 ks_sharded/-40: select distinct `user`.id, `user`.`name`, weight_string(`user`.id), weight_string(`user`.`name`) from `user` where `user`.id = 1 limit 10001 /* INT64 */ + +---------------------------------------------------------------------- diff --git a/go/vt/vtexplain/testdata/selectsharded-queries.sql b/go/vt/vtexplain/testdata/selectsharded-queries.sql index ad003d1c457..a68b5c49073 100644 --- a/go/vt/vtexplain/testdata/selectsharded-queries.sql +++ b/go/vt/vtexplain/testdata/selectsharded-queries.sql @@ -38,4 +38,6 @@ select id from user where not id in (select col from music where music.user_id = SELECT user.id, user.name, name_info.info FROM user INNER JOIN music ON (user.id = music.user_id) LEFT OUTER JOIN name_info ON (user.name = name_info.name); -SELECT id FROM orders WHERE id IN (1, "1", 1) +SELECT id FROM orders WHERE id IN (1, "1", 1); + +(SELECT user.id, user.name FROM user WHERE user.id = 1) UNION (SELECT user.id, user.name FROM user WHERE user.id = 2); diff --git a/go/vt/vtexplain/vtexplain_test.go b/go/vt/vtexplain/vtexplain_test.go index b1e93855081..9c9208b9fd2 100644 --- a/go/vt/vtexplain/vtexplain_test.go +++ b/go/vt/vtexplain/vtexplain_test.go @@ -32,6 +32,7 @@ import ( "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/key" + querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/topo" "vitess.io/vitess/go/vt/vttablet/tabletserver/tabletenv/tabletenvtest" @@ -147,6 +148,28 @@ func TestExplain(t *testing.T) { } tests := []test{ {"unsharded", defaultTestOpts()}, + {"selectsharded", defaultTestOpts()}, + {"insertsharded", defaultTestOpts()}, + {"updatesharded", defaultTestOpts()}, + {"deletesharded", defaultTestOpts()}, + {"comments", defaultTestOpts()}, + {"options", &Options{ + ReplicationMode: "STATEMENT", + NumShards: 4, + Normalize: false, + }}, + {"target", &Options{ + ReplicationMode: "ROW", + NumShards: 4, + Normalize: false, + Target: "ks_sharded/40-80", + }}, + {"gen4", &Options{ + ReplicationMode: "ROW", + NumShards: 4, + Normalize: true, + PlannerVersion: querypb.ExecuteOptions_Gen4, + }}, } for _, tst := range tests { diff --git a/go/vt/vtexplain/vtexplain_vttablet.go b/go/vt/vtexplain/vtexplain_vttablet.go index 1af6f596416..4d2d7f816f7 100644 --- a/go/vt/vtexplain/vtexplain_vttablet.go +++ b/go/vt/vtexplain/vtexplain_vttablet.go @@ -843,9 +843,15 @@ func inferColTypeFromExpr(node sqlparser.Expr, tableColumnMap map[sqlparser.Iden colTypes = append(colTypes, colType) } case sqlparser.Callable: - // As a shortcut, functions are integral types - colNames = append(colNames, sqlparser.String(node)) - colTypes = append(colTypes, querypb.Type_INT32) + switch node := node.(type) { + case *sqlparser.WeightStringFuncExpr: + colNames = append(colNames, sqlparser.String(node)) + colTypes = append(colTypes, querypb.Type_BINARY) + default: + // As a shortcut, functions are integral types + colNames = append(colNames, sqlparser.String(node)) + colTypes = append(colTypes, querypb.Type_INT32) + } case *sqlparser.Literal: colNames = append(colNames, sqlparser.String(node)) switch node.Type {