Repository: vitessio/vitess
Pull request #7817 (2021-04-10 15:28:47)

[vtadmin-web] Add DataCell component
Signed-off-by: Sara Bee <855595+doeg@users.noreply.github.com>

## Description

A couple of straightforward styling changes that I keep re-implementing in my bigger branches. 😎  Figured I should just pull them out into their own thing:

- Adds a DataCell component for consistent styling. (A separate component will make more sense when we do rowspan grouping... I admit right now it's kinda overkill, haha. But! Still convenient.) 

- Renders cluster as secondary text where it "makes sense", which is (for now) when the cardinality of clusters is << the cardinality of whatever the table is rendering. Every cluster has many tablets, for example, so a separate "cluster" column is quite redundant when every row on a page is for the same cluster. Some tables, though, only have one or two columns right now, and in those cases I left the "cluster" column as a space filler. :) 

Before:
<img width="2672" alt="Screen Shot 2021-04-10 at 10 50 55 AM" src="https://user-images.githubusercontent.com/855595/114274953-b7367e00-99ee-11eb-9960-1255bcfff339.png">

After: 
<img width="2672" alt="Screen Shot 2021-04-10 at 11 19 52 AM" src="https://user-images.githubusercontent.com/855595/114274958-b998d800-99ee-11eb-8b93-f8c8e921c68b.png">


## Related Issue(s)
<!-- List related issues and pull requests: -->

N/A

## Checklist
- [ ] Should this PR be backported? No
- [x] Tests were added or are not required
- [x] Documentation was added or is not required

## Deployment Notes

N/A

## Impacted Areas in Vitess
Components that this PR will affect:

- [ ]  Query Serving
- [ ]  VReplication
- [ ]  Cluster Management
- [ ]  Build/CI
- [x]  VTAdmin



Patch:
diff --git a/go/mysql/sql_error.go b/go/mysql/sql_error.go
index 491dd3e443..fcf02abaf1 100644
--- a/go/mysql/sql_error.go
+++ b/go/mysql/sql_error.go
@@ -170,7 +170,6 @@ var stateToMysqlCode = map[vterrors.State]struct {
 	vterrors.NotSupportedYet:              {num: ERNotSupportedYet, state: SSClientError},
 	vterrors.ForbidSchemaChange:           {num: ERForbidSchemaChange, state: SSUnknownSQLState},
 	vterrors.NetPacketTooLarge:            {num: ERNetPacketTooLarge, state: SSNetError},
-	vterrors.NonUniqError:                 {num: ERNonUniq, state: SSConstraintViolation},
 	vterrors.NonUniqTable:                 {num: ERNonUniqTable, state: SSClientError},
 	vterrors.QueryInterrupted:             {num: ERQueryInterrupted, state: SSQueryInterrupted},
 	vterrors.SPDoesNotExist:               {num: ERSPDoesNotExist, state: SSClientError},
diff --git a/go/vt/vterrors/state.go b/go/vt/vterrors/state.go
index 4a9a33b122..b3103cd851 100644
--- a/go/vt/vterrors/state.go
+++ b/go/vt/vterrors/state.go
@@ -30,7 +30,6 @@ const (
 	EmptyQuery
 	ForbidSchemaChange
 	IncorrectGlobalLocalVar
-	NonUniqError
 	NonUniqTable
 	SyntaxError
 	WrongGroupField
diff --git a/go/vt/vtgate/engine/route.go b/go/vt/vtgate/engine/route.go
index 9f73a7f39f..904afce420 100644
--- a/go/vt/vtgate/engine/route.go
+++ b/go/vt/vtgate/engine/route.go
@@ -739,9 +739,6 @@ func (route *Route) description() PrimitiveDescription {
 	if orderBy != "" {
 		other["OrderBy"] = orderBy
 	}
-	if route.TruncateColumnCount > 0 {
-		other["ResultColumns"] = route.TruncateColumnCount
-	}
 
 	return PrimitiveDescription{
 		OperatorType:      "Route",
diff --git a/go/vt/vtgate/planbuilder/queryprojection.go b/go/vt/vtgate/planbuilder/queryprojection.go
deleted file mode 100644
index e638d651e1..0000000000
--- a/go/vt/vtgate/planbuilder/queryprojection.go
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
-Copyright 2021 The Vitess Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package planbuilder
-
-import (
-	vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
-	"vitess.io/vitess/go/vt/sqlparser"
-	"vitess.io/vitess/go/vt/vterrors"
-	"vitess.io/vitess/go/vt/vtgate/semantics"
-)
-
-type queryProjection struct {
-	selectExprs             []*sqlparser.AliasedExpr
-	aggrExprs               []*sqlparser.AliasedExpr
-	groupOrderingCommonExpr map[sqlparser.Expr]*sqlparser.Order
-
-	orderExprs sqlparser.OrderBy
-
-	// orderExprColMap keeps a map between the Order object and the offset into the select expressions list
-	orderExprColMap map[*sqlparser.Order]int
-}
-
-func newQueryProjection() *queryProjection {
-	return &queryProjection{
-		groupOrderingCommonExpr: map[sqlparser.Expr]*sqlparser.Order{},
-		orderExprColMap:         map[*sqlparser.Order]int{},
-	}
-}
-
-func createQPFromSelect(sel *sqlparser.Select) (*queryProjection, error) {
-	qp := newQueryProjection()
-
-	for _, selExp := range sel.SelectExprs {
-		exp, ok := selExp.(*sqlparser.AliasedExpr)
-		if !ok {
-			return nil, semantics.Gen4NotSupportedF("%T in select list", selExp)
-		}
-		fExpr, ok := exp.Expr.(*sqlparser.FuncExpr)
-		if ok && fExpr.IsAggregate() {
-			if len(fExpr.Exprs) != 1 {
-				return nil, vterrors.NewErrorf(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.SyntaxError, "multiple arguments inside the function '%s'", sqlparser.String(fExpr))
-			}
-			qp.aggrExprs = append(qp.aggrExprs, exp)
-			continue
-		}
-		if nodeHasAggregates(exp.Expr) {
-			return nil, vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "unsupported: in scatter query: complex aggregate expression")
-		}
-		qp.selectExprs = append(qp.selectExprs, exp)
-	}
-
-	qp.orderExprs = sel.OrderBy
-
-	allExpr := append(qp.selectExprs, qp.aggrExprs...)
-	for _, order := range sel.OrderBy {
-		for offset, expr := range allExpr {
-			if sqlparser.EqualsExpr(order.Expr, expr.Expr) {
-				qp.orderExprColMap[order] = offset
-				break
-			}
-			// TODO: handle alias and column offset
-		}
-	}
-
-	if sel.GroupBy == nil || sel.OrderBy == nil {
-		return qp, nil
-	}
-
-	return qp, nil
-}
diff --git a/go/vt/vtgate/planbuilder/route_planning.go b/go/vt/vtgate/planbuilder/route_planning.go
index 5724584651..dc3bfb2e85 100644
--- a/go/vt/vtgate/planbuilder/route_planning.go
+++ b/go/vt/vtgate/planbuilder/route_planning.go
@@ -46,7 +46,7 @@ func gen4Planner(_ string) func(sqlparser.Statement, sqlparser.BindVars, Context
 }
 
 func newBuildSelectPlan(sel *sqlparser.Select, vschema ContextVSchema) (engine.Primitive, error) {
-	semTable, err := semantics.Analyse(sel, vschema)
+	semTable, err := semantics.Analyse(sel) // TODO no nil no
 	if err != nil {
 		return nil, err
 	}
@@ -74,8 +74,7 @@ func newBuildSelectPlan(sel *sqlparser.Select, vschema ContextVSchema) (engine.P
 		return nil, err
 	}
 
-	plan, err = planHorizon(sel, plan, semTable)
-	if err != nil {
+	if err := planProjections(sel, plan, semTable); err != nil {
 		return nil, err
 	}
 
@@ -113,7 +112,7 @@ func planLimit(limit *sqlparser.Limit, plan logicalPlan) (logicalPlan, error) {
 	return lPlan, nil
 }
 
-func planHorizon(sel *sqlparser.Select, plan logicalPlan, semTable *semantics.SemTable) (logicalPlan, error) {
+func planProjections(sel *sqlparser.Select, plan logicalPlan, semTable *semantics.SemTable) error {
 	rb, ok := plan.(*route)
 	if ok && rb.isSingleShard() {
 		ast := rb.Select.(*sqlparser.Select)
@@ -122,40 +121,30 @@ func planHorizon(sel *sqlparser.Select, plan logicalPlan, semTable *semantics.Se
 		ast.OrderBy = sel.OrderBy
 		ast.SelectExprs = sel.SelectExprs
 		ast.Comments = sel.Comments
-		return plan, nil
-	}
-
-	// TODO real horizon planning to be done
-	if sel.Distinct {
-		return nil, semantics.Gen4NotSupportedF("DISTINCT")
-	}
-	if sel.GroupBy != nil {
-		return nil, semantics.Gen4NotSupportedF("GROUP BY")
-	}
-	qp, err := createQPFromSelect(sel)
-	if err != nil {
-		return nil, err
-	}
-	for _, e := range qp.selectExprs {
-		if _, err := pushProjection(e, plan, semTable); err != nil {
-			return nil, err
+	} else {
+		// TODO real horizon planning to be done
+		if sel.Distinct {
+			return semantics.Gen4NotSupportedF("DISTINCT")
 		}
-	}
-
-	if len(qp.aggrExprs) > 0 {
-		plan, err = planAggregations(qp, plan, semTable)
-		if err != nil {
-			return nil, err
+		if sel.GroupBy != nil {
+			return semantics.Gen4NotSupportedF("GROUP BY")
 		}
-	}
-	if len(sel.OrderBy) > 0 {
-		plan, err = planOrderBy(qp, plan, semTable)
-		if err != nil {
-			return nil, err
+		for _, expr := range sel.SelectExprs {
+			switch e := expr.(type) {
+			case *sqlparser.AliasedExpr:
+				if nodeHasAggregates(e.Expr) {
+					return semantics.Gen4NotSupportedF("aggregation [%s]", sqlparser.String(e))
+				}
+				if _, err := pushProjection(e, plan, semTable); err != nil {
+					return err
+				}
+			default:
+				return semantics.Gen4NotSupportedF("%T", e)
+			}
 		}
-	}
 
-	return plan, nil
+	}
+	return nil
 }
 
 type (
diff --git a/go/vt/vtgate/planbuilder/select.go b/go/vt/vtgate/planbuilder/select.go
index 2f4e906ae5..c349f70ba2 100644
--- a/go/vt/vtgate/planbuilder/select.go
+++ b/go/vt/vtgate/planbuilder/select.go
@@ -20,8 +20,6 @@ import (
 	"errors"
 	"fmt"
 
-	"vitess.io/vitess/go/sqltypes"
-
 	"vitess.io/vitess/go/vt/orchestrator/external/golib/log"
 
 	"vitess.io/vitess/go/vt/vtgate/semantics"
@@ -102,7 +100,7 @@ func shouldRetryWithCNFRewriting(plan logicalPlan) bool {
 
 }
 
-func pushProjection(expr *sqlparser.AliasedExpr, plan logicalPlan, semTable *semantics.SemTable) (int, error) {
+func pushProjection(expr *sqlparser.AliasedExpr, plan logicalPlan, semTable *semantics.SemTable) (firstOffset int, err error) {
 	switch node := plan.(type) {
 	case *route:
 		sel := node.Select.(*sqlparser.Select)
@@ -135,87 +133,77 @@ func pushProjection(expr *sqlparser.AliasedExpr, plan logicalPlan, semTable *sem
 	}
 }
 
-func planAggregations(qp *queryProjection, plan logicalPlan, semTable *semantics.SemTable) (logicalPlan, error) {
-	eaggr := &engine.OrderedAggregate{}
-	oa := &orderedAggregate{
-		resultsBuilder: newResultsBuilder(plan, eaggr),
-		eaggr:          eaggr,
-	}
-	for _, e := range qp.aggrExprs {
-		offset, err := pushProjection(e, plan, semTable)
-		if err != nil {
-			return nil, err
-		}
-		fExpr := e.Expr.(*sqlparser.FuncExpr)
-		opcode := engine.SupportedAggregates[fExpr.Name.Lowered()]
-		oa.eaggr.Aggregates = append(oa.eaggr.Aggregates, engine.AggregateParams{
-			Opcode: opcode,
-			Col:    offset,
-		})
+func pushPredicate(exprs []sqlparser.Expr, plan logicalPlan, semTable *semantics.SemTable) (err error) {
+	if len(exprs) == 0 {
+		return nil
 	}
-	return oa, nil
-}
-
-func planOrderBy(qp *queryProjection, plan logicalPlan, semTable *semantics.SemTable) (logicalPlan, error) {
-	switch plan := plan.(type) {
+	switch node := plan.(type) {
 	case *route:
-		for _, order := range qp.orderExprs {
-			offset, exists := qp.orderExprColMap[order]
-			if !exists {
-				return nil, semantics.Gen4NotSupportedF("order by column not exists in select list")
+		sel := node.Select.(*sqlparser.Select)
+		finalExpr := reorderExpression(exprs[0], node.tables, semTable)
+		for i, expr := range exprs {
+			if i == 0 {
+				continue
 			}
-			colName, ok := order.Expr.(*sqlparser.ColName)
-			if !ok {
-				return nil, semantics.Gen4NotSupportedF("order by non-column expression")
+			finalExpr = &sqlparser.AndExpr{
+				Left:  finalExpr,
+				Right: reorderExpression(expr, node.tables, semTable),
 			}
-
-			table := semTable.Dependencies(colName)
-			tableInfo, err := semTable.TableInfoFor(table)
-			if err != nil {
-				return nil, err
+		}
+		if sel.Where != nil {
+			finalExpr = &sqlparser.AndExpr{
+				Left:  sel.Where.Expr,
+				Right: finalExpr,
 			}
-			weightStringNeeded := true
-			for _, c := range tableInfo.Table.Columns {
-				if colName.Name.Equal(c.Name) {
-					if sqltypes.IsNumber(c.Type) {
-						weightStringNeeded = false
-					}
-					break
-				}
+		}
+		sel.Where = &sqlparser.Where{
+			Type: sqlparser.WhereClause,
+			Expr: finalExpr,
+		}
+		return nil
+	case *joinV4:
+		var lhs, rhs []sqlparser.Expr
+		lhsSolves := node.Left.ContainsTables()
+		rhsSolves := node.Right.ContainsTables()
+		for _, expr := range exprs {
+			deps := semTable.Dependencies(expr)
+			switch {
+			case deps.IsSolvedBy(lhsSolves):
+				lhs = append(lhs, expr)
+			case deps.IsSolvedBy(rhsSolves):
+				rhs = append(rhs, expr)
+			default:
+				return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "unknown dependencies for %s", sqlparser.String(expr))
 			}
+		}
+		err := pushPredicate(lhs, node.Left, semTable)
+		if err != nil {
+			return err
+		}
+		err = pushPredicate(rhs, node.Right, semTable)
+		return err
+	default:
+		return vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "%T not yet supported", node)
+	}
+}
 
-			weightStringOffset := -1
-			if weightStringNeeded {
-				expr := &sqlparser.AliasedExpr{
-					Expr: &sqlparser.FuncExpr{
-						Name: sqlparser.NewColIdent("weight_string"),
-						Exprs: []sqlparser.SelectExpr{
-							&sqlparser.AliasedExpr{
-								Expr: order.Expr,
-							},
-						},
-					},
-				}
-				weightStringOffset, err = pushProjection(expr, plan, semTable)
-				if err != nil {
-					return nil, err
-				}
-			}
-			if weightStringOffset != -1 {
-				plan.eroute.TruncateColumnCount = len(qp.selectExprs) + len(qp.aggrExprs)
+func reorderExpression(expr sqlparser.Expr, solves semantics.TableSet, semTable *semantics.SemTable) sqlparser.Expr {
+	switch compExpr := expr.(type) {
+	case *sqlparser.ComparisonExpr:
+		if compExpr.Operator == sqlparser.EqualOp {
+			if !dependsOnRoute(solves, compExpr.Left, semTable) && dependsOnRoute(solves, compExpr.Right, semTable) {
+				compExpr.Left, compExpr.Right = compExpr.Right, compExpr.Left
 			}
-
-			plan.eroute.OrderBy = append(plan.eroute.OrderBy, engine.OrderbyParams{
-				Col:             offset,
-				WeightStringCol: weightStringOffset,
-				Desc:            order.Direction == sqlparser.DescOrder,
-			})
-			plan.Select.AddOrder(order)
 		}
-		return plan, nil
-	default:
-		return nil, semantics.Gen4NotSupportedF("ordering on complex query")
 	}
+	return expr
+}
+
+func dependsOnRoute(solves semantics.TableSet, expr sqlparser.Expr, semTable *semantics.SemTable) bool {
+	if node, ok := expr.(*sqlparser.ColName); ok {
+		return semTable.Dependencies(node).IsSolvedBy(solves)
+	}
+	return !sqlparser.IsValue(expr)
 }
 
 var errSQLCalcFoundRows = vterrors.NewErrorf(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.CantUseOptionHere, "Incorrect usage/placement of 'SQL_CALC_FOUND_ROWS'")
diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go
index ef81f01d80..fe7c65a86d 100644
--- a/go/vt/vtgate/semantics/analyzer.go
+++ b/go/vt/vtgate/semantics/analyzer.go
@@ -17,8 +17,6 @@ limitations under the License.
 package semantics
 
 import (
-	"fmt"
-
 	vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
 	"vitess.io/vitess/go/vt/sqlparser"
 	"vitess.io/vitess/go/vt/vterrors"
@@ -27,21 +25,18 @@ import (
 type (
 	// analyzer is a struct to work with analyzing the query.
 	analyzer struct {
-		si SchemaInformation
-
-		Tables []*TableInfo
-		scopes []*scope
+		Tables []table
 
+		scopes   []*scope
 		exprDeps map[sqlparser.Expr]TableSet
 		err      error
 	}
 )
 
 // newAnalyzer create the semantic analyzer
-func newAnalyzer(si SchemaInformation) *analyzer {
+func newAnalyzer() *analyzer {
 	return &analyzer{
 		exprDeps: map[sqlparser.Expr]TableSet{},
-		si:       si,
 	}
 }
 
@@ -78,7 +73,7 @@ func (a *analyzer) analyzeDown(cursor *sqlparser.Cursor) bool {
 }
 
 func (a *analyzer) resolveColumn(colName *sqlparser.ColName, current *scope) (TableSet, error) {
-	var t *TableInfo
+	var t table
 	var err error
 	if colName.Qualifier.IsEmpty() {
 		t, err = a.resolveUnQualifiedColumn(current, colName)
@@ -88,7 +83,7 @@ func (a *analyzer) resolveColumn(colName *sqlparser.ColName, current *scope) (Ta
 	if err != nil {
 		return 0, err
 	}
-	return a.tableSetFor(t.ASTNode), nil
+	return a.tableSetFor(t), nil
 }
 
 func (a *analyzer) analyzeTableExprs(tablExprs sqlparser.TableExprs) error {
@@ -124,7 +119,7 @@ func (a *analyzer) analyzeTableExpr(tableExpr sqlparser.TableExpr) error {
 }
 
 // resolveQualifiedColumn handles `tabl.col` expressions
-func (a *analyzer) resolveQualifiedColumn(current *scope, expr *sqlparser.ColName) (*TableInfo, error) {
+func (a *analyzer) resolveQualifiedColumn(current *scope, expr *sqlparser.ColName) (table, error) {
 	qualifier := expr.Qualifier.Name.String()
 
 	for current != nil {
@@ -139,33 +134,18 @@ func (a *analyzer) resolveQualifiedColumn(current *scope, expr *sqlparser.ColNam
 }
 
 // resolveUnQualifiedColumn
-func (a *analyzer) resolveUnQualifiedColumn(current *scope, expr *sqlparser.ColName) (*TableInfo, error) {
+func (a *analyzer) resolveUnQualifiedColumn(current *scope, expr *sqlparser.ColName) (table, error) {
 	if len(current.tables) == 1 {
 		for _, tableExpr := range current.tables {
 			return tableExpr, nil
 		}
 	}
-
-	var tblInfo *TableInfo
-	for _, tbl := range current.tables {
-		if !tbl.Table.ColumnListAuthoritative {
-			return nil, vterrors.NewErrorf(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.NonUniqError, fmt.Sprintf("Column '%s' in field list is ambiguous", sqlparser.String(expr)))
-		}
-		for _, col := range tbl.Table.Columns {
-			if expr.Name.Equal(col.Name) {
-				if tblInfo != nil {
-					return nil, vterrors.NewErrorf(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.NonUniqError, fmt.Sprintf("Column '%s' in field list is ambiguous", sqlparser.String(expr)))
-				}
-				tblInfo = tbl
-			}
-		}
-	}
-	return tblInfo, nil
+	return nil, Gen4NotSupportedF("unable to map column to a table: %s", sqlparser.String(expr))
 }
 
-func (a *analyzer) tableSetFor(t *sqlparser.AliasedTableExpr) TableSet {
+func (a *analyzer) tableSetFor(t table) TableSet {
 	for i, t2 := range a.Tables {
-		if t == t2.ASTNode {
+		if t == t2 {
 			return TableSet(1 << i)
 		}
 	}
@@ -181,22 +161,14 @@ func (a *analyzer) bindTable(alias *sqlparser.AliasedTableExpr, expr sqlparser.S
 		}
 		a.popScope()
 		scope := a.currentScope()
-		return scope.addTable(alias.As.String(), &TableInfo{alias, nil})
+		return scope.addTable(alias.As.String(), alias)
 	case sqlparser.TableName:
-		tbl, vdx, _, _, _, err := a.si.FindTableOrVindex(t)
-		if err != nil {
-			return err
-		}
-		if tbl == nil && vdx != nil {
-			return Gen4NotSupportedF("vindex in FROM")
-		}
 		scope := a.currentScope()
-		table := &TableInfo{alias, tbl}
-		a.Tables = append(a.Tables, table)
+		a.Tables = append(a.Tables, alias)
 		if alias.As.IsEmpty() {
-			return scope.addTable(t.Name.String(), table)
+			return scope.addTable(t.Name.String(), alias)
 		}
-		return scope.addTable(alias.As.String(), table)
+		return scope.addTable(alias.As.String(), alias)
 	}
 	return nil
 }
diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go
index 31a187c276..674b6c1b6d 100644
--- a/go/vt/vtgate/semantics/semantic_state.go
+++ b/go/vt/vtgate/semantics/semantic_state.go
@@ -17,21 +17,14 @@ limitations under the License.
 package semantics
 
 import (
-	"vitess.io/vitess/go/vt/key"
-	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
 	vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
 	"vitess.io/vitess/go/vt/vterrors"
-	"vitess.io/vitess/go/vt/vtgate/vindexes"
 
 	"vitess.io/vitess/go/vt/sqlparser"
 )
 
 type (
-	// TableInfo contains the alias table expr and vindex table
-	TableInfo struct {
-		ASTNode *sqlparser.AliasedTableExpr
-		Table   *vindexes.Table
-	}
+	table = *sqlparser.AliasedTableExpr
 
 	// TableSet is how a set of tables is expressed.
 	// Tables get unique bits assigned in the order that they are encountered during semantic analysis
@@ -40,18 +33,13 @@ type (
 
 	// SemTable contains semantic analysis information about the query.
 	SemTable struct {
-		Tables           []*TableInfo
+		Tables           []table
 		exprDependencies map[sqlparser.Expr]TableSet
 	}
 
 	scope struct {
 		parent *scope
-		tables map[string]*TableInfo
-	}
-
-	// SchemaInformation is used tp provide table information from Vschema.
-	SchemaInformation interface {
-		FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error)
+		tables map[string]*sqlparser.AliasedTableExpr
 	}
 )
 
@@ -61,23 +49,15 @@ func NewSemTable() *SemTable {
 }
 
 // TableSetFor returns the bitmask for this particular tableshoe
-func (st *SemTable) TableSetFor(t *sqlparser.AliasedTableExpr) TableSet {
+func (st *SemTable) TableSetFor(t table) TableSet {
 	for idx, t2 := range st.Tables {
-		if t == t2.ASTNode {
+		if t == t2 {
 			return 1 << idx
 		}
 	}
 	return 0
 }
 
-// TableInfoFor returns the table info for the table set. It should contains only single table.
-func (st *SemTable) TableInfoFor(id TableSet) (*TableInfo, error) {
-	if id.NumberOfTables() > 1 {
-		return nil, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] should only be used for single tables")
-	}
-	return st.Tables[id.TableOffset()], nil
-}
-
 // Dependencies return the table dependencies of the expression.
 func (st *SemTable) Dependencies(expr sqlparser.Expr) TableSet {
 	deps, found := st.exprDependencies[expr]
@@ -100,10 +80,10 @@ func (st *SemTable) Dependencies(expr sqlparser.Expr) TableSet {
 }
 
 func newScope(parent *scope) *scope {
-	return &scope{tables: map[string]*TableInfo{}, parent: parent}
+	return &scope{tables: map[string]*sqlparser.AliasedTableExpr{}, parent: parent}
 }
 
-func (s *scope) addTable(name string, table *TableInfo) error {
+func (s *scope) addTable(name string, table *sqlparser.AliasedTableExpr) error {
 	_, found := s.tables[name]
 	if found {
 		return vterrors.NewErrorf(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.NonUniqTable, "Not unique table/alias: '%s'", name)
@@ -113,8 +93,8 @@ func (s *scope) addTable(name string, table *TableInfo) error {
 }
 
 // Analyse analyzes the parsed query.
-func Analyse(statement sqlparser.Statement, si SchemaInformation) (*SemTable, error) {
-	analyzer := newAnalyzer(si)
+func Analyse(statement sqlparser.Statement) (*SemTable, error) {
+	analyzer := newAnalyzer()
 	// Initial scope
 	err := analyzer.analyze(statement)
 	if err != nil {
@@ -140,16 +120,6 @@ func (ts TableSet) NumberOfTables() int {
 	return count
 }
 
-// TableOffset returns the offset in the Tables array from TableSet
-func (ts TableSet) TableOffset() int {
-	offset := 0
-	for ts > 1 {
-		ts = ts >> 1
-		offset++
-	}
-	return offset
-}
-
 // Constituents returns an slice with all the
 // individual tables in their own TableSet identifier
 func (ts TableSet) Constituents() (result []TableSet) {
diff --git a/web/vtadmin/src/components/dataTable/DataCell.tsx b/web/vtadmin/src/components/dataTable/DataCell.tsx
new file mode 100644
index 0000000000..58b69a6257
--- /dev/null
+++ b/web/vtadmin/src/components/dataTable/DataCell.tsx
@@ -0,0 +1,28 @@
+/**
+ * Copyright 2021 The Vitess Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import * as React from 'react';
+import cx from 'classnames';
+
+interface Props
+    extends React.DetailedHTMLProps<React.TdHTMLAttributes<HTMLTableDataCellElement>, HTMLTableDataCellElement> {}
+
+export const DataCell: React.FunctionComponent<Props> = ({ children, className, ...tdProps }) => {
+    return (
+        <td {...tdProps} className={cx(className, 'font-family-monospace')}>
+            {children}
+        </td>
+    );
+};
diff --git a/web/vtadmin/src/components/routes/Clusters.tsx b/web/vtadmin/src/components/routes/Clusters.tsx
index b964137302..4faea83575 100644
--- a/web/vtadmin/src/components/routes/Clusters.tsx
+++ b/web/vtadmin/src/components/routes/Clusters.tsx
@@ -19,6 +19,7 @@ import { useClusters } from '../../hooks/api';
 import { useDocumentTitle } from '../../hooks/useDocumentTitle';
 import { DataTable } from '../dataTable/DataTable';
 import { vtadmin as pb } from '../../proto/vtadmin';
+import { DataCell } from '../dataTable/DataCell';
 
 export const Clusters = () => {
     useDocumentTitle('Clusters');
@@ -31,8 +32,8 @@ export const Clusters = () => {
     const renderRows = (rows: pb.Cluster[]) =>
         rows.map((cluster, idx) => (
             <tr key={idx}>
-                <td>{cluster.name}</td>
-                <td>{cluster.id}</td>
+                <DataCell>{cluster.name}</DataCell>
+                <DataCell>{cluster.id}</DataCell>
             </tr>
         ));
 
diff --git a/web/vtadmin/src/components/routes/Gates.tsx b/web/vtadmin/src/components/routes/Gates.tsx
index 0dee951b04..b60aa8347f 100644
--- a/web/vtadmin/src/components/routes/Gates.tsx
+++ b/web/vtadmin/src/components/routes/Gates.tsx
@@ -18,6 +18,7 @@ import * as React from 'react';
 import { useGates } from '../../hooks/api';
 import { useDocumentTitle } from '../../hooks/useDocumentTitle';
 import { vtadmin as pb } from '../../proto/vtadmin';
+import { DataCell } from '../dataTable/DataCell';
 import { DataTable } from '../dataTable/DataTable';
 
 export const Gates = () => {
@@ -31,8 +32,8 @@ export const Gates = () => {
     const renderRows = (gates: pb.VTGate[]) =>
         gates.map((gate, idx) => (
             <tr key={idx}>
-                <td>{gate.cluster?.name}</td>
-                <td>{gate.hostname}</td>
+                <DataCell>{gate.cluster?.name}</DataCell>
+                <DataCell>{gate.hostname}</DataCell>
             </tr>
         ));
 
diff --git a/web/vtadmin/src/components/routes/Keyspaces.tsx b/web/vtadmin/src/components/routes/Keyspaces.tsx
index 785ced18af..88d6b70741 100644
--- a/web/vtadmin/src/components/routes/Keyspaces.tsx
+++ b/web/vtadmin/src/components/routes/Keyspaces.tsx
@@ -18,6 +18,7 @@ import * as React from 'react';
 import { useKeyspaces } from '../../hooks/api';
 import { useDocumentTitle } from '../../hooks/useDocumentTitle';
 import { vtadmin as pb } from '../../proto/vtadmin';
+import { DataCell } from '../dataTable/DataCell';
 import { DataTable } from '../dataTable/DataTable';
 
 export const Keyspaces = () => {
@@ -31,8 +32,8 @@ export const Keyspaces = () => {
     const renderRows = (rows: pb.Keyspace[]) =>
         rows.map((keyspace, idx) => (
             <tr key={idx}>
-                <td>{keyspace.cluster?.name}</td>
-                <td>{keyspace.keyspace?.name}</td>
+                <DataCell>{keyspace.cluster?.name}</DataCell>
+                <DataCell>{keyspace.keyspace?.name}</DataCell>
             </tr>
         ));
 
diff --git a/web/vtadmin/src/components/routes/Schemas.tsx b/web/vtadmin/src/components/routes/Schemas.tsx
index edaabcbfc3..82691ac71e 100644
--- a/web/vtadmin/src/components/routes/Schemas.tsx
+++ b/web/vtadmin/src/components/routes/Schemas.tsx
@@ -21,6 +21,7 @@ import { useTableDefinitions } from '../../hooks/api';
 import { useDocumentTitle } from '../../hooks/useDocumentTitle';
 import { filterNouns } from '../../util/filterNouns';
 import { Button } from '../Button';
+import { DataCell } from '../dataTable/DataCell';
 import { DataTable } from '../dataTable/DataTable';
 import { Icons } from '../Icon';
 import { TextInput } from '../TextInput';
@@ -53,9 +54,13 @@ export const Schemas = () => {
                     : null;
             return (
                 <tr key={idx}>
-                    <td>{row.cluster}</td>
-                    <td>{row.keyspace}</td>
-                    <td>{href ? <Link to={href}>{row.table}</Link> : row.table}</td>
+                    <DataCell>
+                        <div>{row.keyspace}</div>
+                        <div className="font-size-small text-color-secondary">{row.cluster}</div>
+                    </DataCell>
+                    <DataCell className="font-weight-bold">
+                        {href ? <Link to={href}>{row.table}</Link> : row.table}
+                    </DataCell>
                 </tr>
             );
         });
@@ -76,7 +81,7 @@ export const Schemas = () => {
                 </Button>
             </div>
 
-            <DataTable columns={['Cluster', 'Keyspace', 'Table']} data={filteredData} renderRows={renderRows} />
+            <DataTable columns={['Keyspace', 'Table']} data={filteredData} renderRows={renderRows} />
         </div>
     );
 };
diff --git a/web/vtadmin/src/components/routes/Tablets.tsx b/web/vtadmin/src/components/routes/Tablets.tsx
index 93112e0af6..a3b2938931 100644
--- a/web/vtadmin/src/components/routes/Tablets.tsx
+++ b/web/vtadmin/src/components/routes/Tablets.tsx
@@ -25,6 +25,7 @@ import { Icons } from '../Icon';
 import { filterNouns } from '../../util/filterNouns';
 import style from './Tablets.module.scss';
 import { Button } from '../Button';
+import { DataCell } from '../dataTable/DataCell';
 
 export const Tablets = () => {
     useDocumentTitle('Tablets');
@@ -39,13 +40,15 @@ export const Tablets = () => {
     const renderRows = React.useCallback((rows: typeof filteredData) => {
         return rows.map((t, tdx) => (
             <tr key={tdx}>
-                <td>{t.cluster}</td>
-                <td>{t.keyspace}</td>
-                <td>{t.shard}</td>
-                <td>{t.type}</td>
-                <td>{t.state}</td>
-                <td>{t.alias}</td>
-                <td>{t.hostname}</td>
+                <DataCell>
+                    <div>{t.keyspace}</div>
+                    <div className="font-size-small text-color-secondary">{t.cluster}</div>
+                </DataCell>
+                <DataCell>{t.shard}</DataCell>
+                <DataCell>{t.type}</DataCell>
+                <DataCell>{t.state}</DataCell>
+                <DataCell>{t.alias}</DataCell>
+                <DataCell>{t.hostname}</DataCell>
             </tr>
         ));
     }, []);
@@ -66,7 +69,7 @@ export const Tablets = () => {
                 </Button>
             </div>
             <DataTable
-                columns={['Cluster', 'Keyspace', 'Shard', 'Type', 'State', 'Alias', 'Hostname']}
+                columns={['Keyspace', 'Shard', 'Type', 'State', 'Alias', 'Hostname']}
                 data={filteredData}
                 renderRows={renderRows}
             />
diff --git a/web/vtadmin/src/components/routes/Workflows.tsx b/web/vtadmin/src/components/routes/Workflows.tsx
index c906a8af72..23abc9e551 100644
--- a/web/vtadmin/src/components/routes/Workflows.tsx
+++ b/web/vtadmin/src/components/routes/Workflows.tsx
@@ -19,6 +19,7 @@ import { Link } from 'react-router-dom';
 
 import { useWorkflows } from '../../hooks/api';
 import { useDocumentTitle } from '../../hooks/useDocumentTitle';
+import { DataCell } from '../dataTable/DataCell';
 import { DataTable } from '../dataTable/DataTable';
 
 export const Workflows = () => {
@@ -39,10 +40,18 @@ export const Workflows = () => {
 
             return (
                 <tr key={idx}>
-                    <td>{href ? <Link to={href}>{workflow?.name}</Link> : workflow?.name}</td>
-                    <td>{cluster?.name}</td>
-                    <td>{workflow?.source?.keyspace || <span className="text-color-secondary">n/a</span>}</td>
-                    <td>{workflow?.target?.keyspace || <span className="text-color-secondary">n/a</span>}</td>
+                    <DataCell>
+                        <div className="font-weight-bold">
+                            {href ? <Link to={href}>{workflow?.name}</Link> : workflow?.name}
+                        </div>
+                        <div className="font-size-small text-color-secondary">{cluster?.name}</div>
+                    </DataCell>
+                    <DataCell>
+                        {workflow?.source?.keyspace || <span className="text-color-secondary">n/a</span>}
+                    </DataCell>
+                    <DataCell>
+                        {workflow?.target?.keyspace || <span className="text-color-secondary">n/a</span>}
+                    </DataCell>
                 </tr>
             );
         });
@@ -50,11 +59,7 @@ export const Workflows = () => {
     return (
         <div className="max-width-content">
             <h1>Workflows</h1>
-            <DataTable
-                columns={['Workflow', 'Cluster', 'Source', 'Target']}
-                data={sortedData}
-                renderRows={renderRows}
-            />
+            <DataTable columns={['Workflow', 'Source', 'Target']} data={sortedData} renderRows={renderRows} />
         </div>
     );
 };
diff --git a/web/vtadmin/src/index.css b/web/vtadmin/src/index.css
index 4ae678cd30..1b2d466978 100644
--- a/web/vtadmin/src/index.css
+++ b/web/vtadmin/src/index.css
@@ -185,12 +185,32 @@ table th {
   text-align: left;
 }
 
-table tbody td {
+table tbody tr {
   border: solid 1px var(--tableBorderColor);
+}
+
+table tbody td {
   padding: var(--tableCellPadding);
+  vertical-align: top;
+}
+
+table tbody td[rowSpan] {
+  border-right: solid 1px var(--tableBorderColor);
 }
 
 /* One-liner utilities */
+.font-family-monospace {
+  font-family: var(--fontFamilyMonospace);
+}
+
+.font-size-small {
+  font-size: var(--fontSizeSmall);
+}
+
+.font-weight-bold {
+  font-weight: 700;
+}
+
 .max-width-content {
   max-width: var(--contentWidth);
 }


Test patch:
diff --git a/go/vt/vtgate/planbuilder/querygraph_test.go b/go/vt/vtgate/planbuilder/querygraph_test.go
index d353d04aa6..43717a4a46 100644
--- a/go/vt/vtgate/planbuilder/querygraph_test.go
+++ b/go/vt/vtgate/planbuilder/querygraph_test.go
@@ -22,10 +22,6 @@ import (
 	"strings"
 	"testing"
 
-	"vitess.io/vitess/go/vt/key"
-	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
-	"vitess.io/vitess/go/vt/vtgate/vindexes"
-
 	"github.com/stretchr/testify/assert"
 
 	"vitess.io/vitess/go/test/utils"
@@ -123,7 +119,7 @@ func TestQueryGraph(t *testing.T) {
 		t.Run(fmt.Sprintf("%d %s", i, sql), func(t *testing.T) {
 			tree, err := sqlparser.Parse(sql)
 			require.NoError(t, err)
-			semTable, err := semantics.Analyse(tree, &fakeSI{})
+			semTable, err := semantics.Analyse(tree)
 			require.NoError(t, err)
 			qgraph, err := createQGFromSelect(tree.(*sqlparser.Select), semTable)
 			require.NoError(t, err)
@@ -136,7 +132,7 @@ func TestQueryGraph(t *testing.T) {
 func TestString(t *testing.T) {
 	tree, err := sqlparser.Parse("select * from a,b join c on b.id = c.id where a.id = b.id and b.col IN (select 42) and func() = 'foo'")
 	require.NoError(t, err)
-	semTable, err := semantics.Analyse(tree, &fakeSI{})
+	semTable, err := semantics.Analyse(tree)
 	require.NoError(t, err)
 	qgraph, err := createQGFromSelect(tree.(*sqlparser.Select), semTable)
 	require.NoError(t, err)
@@ -236,13 +232,3 @@ func (qg *queryGraph) noDepsString() string {
 	}
 	return fmt.Sprintf("\nForAll: %s", sqlparser.String(qg.noDeps))
 }
-
-var _ semantics.SchemaInformation = (*fakeSI)(nil)
-
-type fakeSI struct {
-	tables map[string]*vindexes.Table
-}
-
-func (s *fakeSI) FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error) {
-	return s.tables[sqlparser.String(tablename)], nil, "", 0, nil, nil
-}
diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.txt b/go/vt/vtgate/planbuilder/testdata/aggr_cases.txt
index ac0345f41a..7c76066eec 100644
--- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.txt
@@ -119,7 +119,6 @@ Gen4 plan same as above
         "FieldQuery": "select count(*), a, textcol1, b, weight_string(textcol1), weight_string(a), weight_string(b) from `user` where 1 != 1 group by a, textcol1, b",
         "OrderBy": "1 ASC, 2 ASC, 3 ASC",
         "Query": "select count(*), a, textcol1, b, weight_string(textcol1), weight_string(a), weight_string(b) from `user` group by a, textcol1, b order by a asc, textcol1 asc, b asc",
-        "ResultColumns": 5,
         "Table": "`user`"
       }
     ]
@@ -181,7 +180,6 @@ Gen4 plan same as above
             "FieldQuery": "select count(*) as k, a, textcol1, b, weight_string(textcol1), weight_string(a), weight_string(b) from `user` where 1 != 1 group by a, textcol1, b",
             "OrderBy": "2 ASC, 1 ASC, 3 ASC",
             "Query": "select count(*) as k, a, textcol1, b, weight_string(textcol1), weight_string(a), weight_string(b) from `user` group by a, textcol1, b order by textcol1 asc, a asc, b asc",
-            "ResultColumns": 5,
             "Table": "`user`"
           }
         ]
@@ -215,7 +213,6 @@ Gen4 plan same as above
     ]
   }
 }
-Gen4 plan same as above
 
 # sum aggregate
 "select sum(col) from user"
@@ -242,7 +239,6 @@ Gen4 plan same as above
     ]
   }
 }
-Gen4 plan same as above
 
 # min aggregate
 "select min(col) from user"
@@ -269,7 +265,6 @@ Gen4 plan same as above
     ]
   }
 }
-Gen4 plan same as above
 
 # max aggregate
 "select max(col) from user"
@@ -296,7 +291,6 @@ Gen4 plan same as above
     ]
   }
 }
-Gen4 plan same as above
 
 # distinct and group by together for scatter route
 "select distinct col1, col2 from user group by col1"
@@ -319,7 +313,6 @@ Gen4 plan same as above
         "FieldQuery": "select col1, col2, weight_string(col1), weight_string(col2) from `user` where 1 != 1 group by col1",
         "OrderBy": "0 ASC, 1 ASC, 0 ASC",
         "Query": "select distinct col1, col2, weight_string(col1), weight_string(col2) from `user` group by col1 order by col1 asc, col2 asc, col1 asc",
-        "ResultColumns": 2,
         "Table": "`user`"
       }
     ]
@@ -421,7 +414,6 @@ Gen4 plan same as above
         "FieldQuery": "select col, count(*), weight_string(col) from `user` where 1 != 1 group by col",
         "OrderBy": "0 ASC",
         "Query": "select col, count(*), weight_string(col) from `user` group by col order by col asc",
-        "ResultColumns": 2,
         "Table": "`user`"
       }
     ]
@@ -454,7 +446,6 @@ Gen4 plan same as above
         "FieldQuery": "select `name`, count(*), weight_string(`name`) from `user` where 1 != 1 group by `name`",
         "OrderBy": "0 ASC",
         "Query": "select `name`, count(*), weight_string(`name`) from `user` group by `name` order by `name` asc",
-        "ResultColumns": 2,
         "Table": "`user`"
       }
     ]
@@ -614,7 +605,6 @@ Gen4 plan same as above
     ]
   }
 }
-Gen4 plan same as above
 
 # scatter aggregate using distinct
 "select distinct col from user"
@@ -637,7 +627,6 @@ Gen4 plan same as above
         "FieldQuery": "select col, weight_string(col) from `user` where 1 != 1",
         "OrderBy": "0 ASC",
         "Query": "select distinct col, weight_string(col) from `user` order by col asc",
-        "ResultColumns": 1,
         "Table": "`user`"
       }
     ]
@@ -665,7 +654,6 @@ Gen4 plan same as above
         "FieldQuery": "select col, weight_string(col) from `user` where 1 != 1 group by col",
         "OrderBy": "0 ASC",
         "Query": "select col, weight_string(col) from `user` group by col order by col asc",
-        "ResultColumns": 1,
         "Table": "`user`"
       }
     ]
@@ -712,7 +700,6 @@ Gen4 plan same as above
         "FieldQuery": "select col, count(distinct id), weight_string(col) from `user` where 1 != 1 group by col",
         "OrderBy": "0 ASC",
         "Query": "select col, count(distinct id), weight_string(col) from `user` group by col order by col asc",
-        "ResultColumns": 2,
         "Table": "`user`"
       }
     ]
@@ -741,7 +728,6 @@ Gen4 plan same as above
         "FieldQuery": "select col1, col2, weight_string(col1), weight_string(col2) from `user` where 1 != 1 group by col1, col2",
         "OrderBy": "0 ASC, 1 ASC",
         "Query": "select col1, col2, weight_string(col1), weight_string(col2) from `user` group by col1, col2 order by col1 asc, col2 asc",
-        "ResultColumns": 2,
         "Table": "`user`"
       }
     ]
@@ -769,7 +755,6 @@ Gen4 plan same as above
         "FieldQuery": "select col2, weight_string(col2) from `user` where 1 != 1 group by col2",
         "OrderBy": "0 ASC",
         "Query": "select col2, weight_string(col2) from `user` group by col2 order by col2 asc",
-        "ResultColumns": 1,
         "Table": "`user`"
       }
     ]
@@ -798,7 +783,6 @@ Gen4 plan same as above
         "FieldQuery": "select col1, col2, weight_string(col1), weight_string(col2) from `user` where 1 != 1 group by col1, col2",
         "OrderBy": "0 ASC, 1 ASC",
         "Query": "select col1, col2, weight_string(col1), weight_string(col2) from `user` group by col1, col2 order by col1 asc, col2 asc",
-        "ResultColumns": 2,
         "Table": "`user`"
       }
     ]
@@ -827,7 +811,6 @@ Gen4 plan same as above
         "FieldQuery": "select col1, col2, weight_string(col1), weight_string(col2) from `user` where 1 != 1 group by col1, col2",
         "OrderBy": "0 ASC, 1 ASC",
         "Query": "select col1, col2, weight_string(col1), weight_string(col2) from `user` group by col1, col2 order by col1 asc, col2 asc",
-        "ResultColumns": 2,
         "Table": "`user`"
       }
     ]
@@ -856,7 +839,6 @@ Gen4 plan same as above
         "FieldQuery": "select col1, min(distinct col2), weight_string(col1) from `user` where 1 != 1 group by col1",
         "OrderBy": "0 ASC",
         "Query": "select col1, min(distinct col2), weight_string(col1) from `user` group by col1 order by col1 asc",
-        "ResultColumns": 2,
         "Table": "`user`"
       }
     ]
@@ -890,7 +872,6 @@ Gen4 plan same as above
             "FieldQuery": "select col1, col2, weight_string(col1), weight_string(col2) from `user` where 1 != 1 group by col1, col2",
             "OrderBy": "0 ASC, 1 ASC",
             "Query": "select col1, col2, weight_string(col1), weight_string(col2) from `user` group by col1, col2 order by col1 asc, col2 asc",
-            "ResultColumns": 2,
             "Table": "`user`"
           }
         ]
@@ -925,7 +906,6 @@ Gen4 plan same as above
         "FieldQuery": "select a, b, count(*), weight_string(b), weight_string(a) from `user` where 1 != 1 group by b, a",
         "OrderBy": "1 ASC, 0 ASC",
         "Query": "select a, b, count(*), weight_string(b), weight_string(a) from `user` group by b, a order by b asc, a asc",
-        "ResultColumns": 3,
         "Table": "`user`"
       }
     ]
@@ -954,7 +934,6 @@ Gen4 plan same as above
         "FieldQuery": "select a, b, count(*), weight_string(b), weight_string(a) from `user` where 1 != 1 group by 2, 1",
         "OrderBy": "1 ASC, 0 ASC",
         "Query": "select a, b, count(*), weight_string(b), weight_string(a) from `user` group by 2, 1 order by b asc, a asc",
-        "ResultColumns": 3,
         "Table": "`user`"
       }
     ]
@@ -983,7 +962,6 @@ Gen4 plan same as above
         "FieldQuery": "select a, b, count(*), weight_string(b), weight_string(a) from `user` where 1 != 1 group by b, a",
         "OrderBy": "1 ASC, 0 ASC",
         "Query": "select a, b, count(*), weight_string(b), weight_string(a) from `user` group by b, a order by b asc, a asc",
-        "ResultColumns": 3,
         "Table": "`user`"
       }
     ]
@@ -1011,7 +989,6 @@ Gen4 plan same as above
         "FieldQuery": "select col, weight_string(col) from `user` where 1 != 1 group by 1",
         "OrderBy": "0 ASC",
         "Query": "select col, weight_string(col) from `user` group by 1 order by col asc",
-        "ResultColumns": 1,
         "Table": "`user`"
       }
     ]
@@ -1074,7 +1051,6 @@ Gen4 plan same as above
         "FieldQuery": "select a, b, c, d, count(*), weight_string(a), weight_string(b), weight_string(c) from `user` where 1 != 1 group by 1, 2, 3",
         "OrderBy": "0 ASC, 1 ASC, 2 ASC",
         "Query": "select a, b, c, d, count(*), weight_string(a), weight_string(b), weight_string(c) from `user` group by 1, 2, 3 order by 1 asc, 2 asc, 3 asc",
-        "ResultColumns": 5,
         "Table": "`user`"
       }
     ]
@@ -1103,7 +1079,6 @@ Gen4 plan same as above
         "FieldQuery": "select a, b, c, d, count(*), weight_string(a), weight_string(b), weight_string(c) from `user` where 1 != 1 group by 1, 2, 3",
         "OrderBy": "0 ASC, 1 ASC, 2 ASC",
         "Query": "select a, b, c, d, count(*), weight_string(a), weight_string(b), weight_string(c) from `user` group by 1, 2, 3 order by a asc, b asc, c asc",
-        "ResultColumns": 5,
         "Table": "`user`"
       }
     ]
@@ -1132,7 +1107,6 @@ Gen4 plan same as above
         "FieldQuery": "select a, b, c, d, count(*), weight_string(d), weight_string(b), weight_string(a), weight_string(c) from `user` where 1 != 1 group by 1, 2, 3, 4",
         "OrderBy": "3 ASC, 1 ASC, 0 ASC, 2 ASC",
         "Query": "select a, b, c, d, count(*), weight_string(d), weight_string(b), weight_string(a), weight_string(c) from `user` group by 1, 2, 3, 4 order by d asc, b asc, a asc, c asc",
-        "ResultColumns": 5,
         "Table": "`user`"
       }
     ]
@@ -1161,7 +1135,6 @@ Gen4 plan same as above
         "FieldQuery": "select a, b, c, d, count(*), weight_string(d), weight_string(b), weight_string(a), weight_string(c) from `user` where 1 != 1 group by 3, 2, 1, 4",
         "OrderBy": "3 ASC, 1 ASC, 0 ASC, 2 ASC",
         "Query": "select a, b, c, d, count(*), weight_string(d), weight_string(b), weight_string(a), weight_string(c) from `user` group by 3, 2, 1, 4 order by d asc, b asc, a asc, c asc",
-        "ResultColumns": 5,
         "Table": "`user`"
       }
     ]
@@ -1190,7 +1163,6 @@ Gen4 plan same as above
         "FieldQuery": "select a, b, c, count(*), weight_string(a), weight_string(c), weight_string(b) from `user` where 1 != 1 group by 3, 2, 1",
         "OrderBy": "0 DESC, 2 DESC, 1 ASC",
         "Query": "select a, b, c, count(*), weight_string(a), weight_string(c), weight_string(b) from `user` group by 3, 2, 1 order by 1 desc, 3 desc, b asc",
-        "ResultColumns": 4,
         "Table": "`user`"
       }
     ]
@@ -1227,7 +1199,6 @@ Gen4 plan same as above
             "FieldQuery": "select col, count(*), weight_string(col) from `user` where 1 != 1 group by col",
             "OrderBy": "0 ASC",
             "Query": "select col, count(*), weight_string(col) from `user` group by col order by col asc limit :__upper_limit",
-            "ResultColumns": 2,
             "Table": "`user`"
           }
         ]
@@ -1321,7 +1292,6 @@ Gen4 plan same as above
             "FieldQuery": "select a, count(*), weight_string(a) from `user` where 1 != 1",
             "OrderBy": "0 ASC",
             "Query": "select a, count(*), weight_string(a) from `user` order by a asc",
-            "ResultColumns": 2,
             "Table": "`user`"
           }
         ]
@@ -1355,7 +1325,6 @@ Gen4 plan same as above
             "FieldQuery": "select a, count(*), weight_string(a) from `user` where 1 != 1 group by a",
             "OrderBy": "0 ASC, 0 ASC",
             "Query": "select a, count(*), weight_string(a) from `user` group by a order by a asc, a asc",
-            "ResultColumns": 2,
             "Table": "`user`"
           }
         ]
diff --git a/go/vt/vtgate/planbuilder/testdata/from_cases.txt b/go/vt/vtgate/planbuilder/testdata/from_cases.txt
index 50b3be4af1..45aea022d1 100644
--- a/go/vt/vtgate/planbuilder/testdata/from_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/from_cases.txt
@@ -2317,12 +2317,10 @@ Gen4 plan same as above
 # non-existent table on left of join
 "select c from t join user"
 "table t not found"
-Gen4 plan same as above
 
 # non-existent table on right of join
 "select c from user join t"
 "table t not found"
-Gen4 plan same as above
 
 # information schema query that uses table_schema
 "select column_name from information_schema.columns where table_schema = (select schema())"
diff --git a/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.txt b/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.txt
index 87251e6b4c..53b2220751 100644
--- a/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/memory_sort_cases.txt
@@ -26,7 +26,6 @@
             "FieldQuery": "select a, b, count(*), weight_string(b), weight_string(a) from `user` where 1 != 1 group by a",
             "OrderBy": "0 ASC",
             "Query": "select a, b, count(*), weight_string(b), weight_string(a) from `user` group by a order by a asc",
-            "ResultColumns": 4,
             "Table": "`user`"
           }
         ]
@@ -62,7 +61,6 @@
             "FieldQuery": "select a, b, count(*) as k, weight_string(a) from `user` where 1 != 1 group by a",
             "OrderBy": "0 ASC",
             "Query": "select a, b, count(*) as k, weight_string(a) from `user` group by a order by a asc",
-            "ResultColumns": 3,
             "Table": "`user`"
           }
         ]
@@ -98,7 +96,6 @@
             "FieldQuery": "select a, b, count(*) as k, weight_string(b), weight_string(a) from `user` where 1 != 1 group by a",
             "OrderBy": "0 ASC",
             "Query": "select a, b, count(*) as k, weight_string(b), weight_string(a) from `user` group by a order by a asc",
-            "ResultColumns": 5,
             "Table": "`user`"
           }
         ]
@@ -138,7 +135,6 @@
                 "FieldQuery": "select a, b, count(*) as k, weight_string(a) from `user` where 1 != 1 group by a",
                 "OrderBy": "0 ASC",
                 "Query": "select a, b, count(*) as k, weight_string(a) from `user` group by a order by a asc",
-                "ResultColumns": 3,
                 "Table": "`user`"
               }
             ]
@@ -176,7 +172,6 @@
             "FieldQuery": "select a, b, count(*) as k, weight_string(a) from `user` where 1 != 1 group by a",
             "OrderBy": "0 ASC",
             "Query": "select a, b, count(*) as k, weight_string(a) from `user` group by a order by 1 asc",
-            "ResultColumns": 4,
             "Table": "`user`"
           }
         ]
@@ -213,7 +208,6 @@
             "FieldQuery": "select textcol1 as t, count(*) as k, weight_string(textcol1) from `user` where 1 != 1 group by textcol1",
             "OrderBy": "0 ASC, 0 ASC",
             "Query": "select textcol1 as t, count(*) as k, weight_string(textcol1) from `user` group by textcol1 order by textcol1 asc, textcol1 asc",
-            "ResultColumns": 3,
             "Table": "`user`"
           }
         ]
@@ -513,7 +507,6 @@
     "FieldQuery": "select a, weight_string(a) from `user` where 1 != 1",
     "OrderBy": "0 DESC",
     "Query": "select a, weight_string(a) from `user` order by binary a desc",
-    "ResultColumns": 1,
     "Table": "`user`"
   }
 }
@@ -539,7 +532,6 @@
         "FieldQuery": "select u.a, weight_string(u.a) from `user` as u where 1 != 1",
         "OrderBy": "0 DESC",
         "Query": "select u.a, weight_string(u.a) from `user` as u order by binary a desc",
-        "ResultColumns": 1,
         "Table": "`user`"
       },
       {
@@ -556,23 +548,3 @@
     ]
   }
 }
-
-# intcol order by
-"select id, intcol from user order by intcol"
-{
-  "QueryType": "SELECT",
-  "Original": "select id, intcol from user order by intcol",
-  "Instructions": {
-    "OperatorType": "Route",
-    "Variant": "SelectScatter",
-    "Keyspace": {
-      "Name": "user",
-      "Sharded": true
-    },
-    "FieldQuery": "select id, intcol from `user` where 1 != 1",
-    "OrderBy": "1 ASC",
-    "Query": "select id, intcol from `user` order by intcol asc",
-    "Table": "`user`"
-  }
-}
-Gen4 plan same as above
diff --git a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.txt b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.txt
index e3eb8cd3d1..b1bc45b720 100644
--- a/go/vt/vtgate/planbuilder/testdata/postprocess_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/postprocess_cases.txt
@@ -194,11 +194,9 @@ Gen4 plan same as above
     "FieldQuery": "select col, weight_string(col) from `user` where 1 != 1",
     "OrderBy": "0 ASC",
     "Query": "select col, weight_string(col) from `user` order by col asc",
-    "ResultColumns": 1,
     "Table": "`user`"
   }
 }
-Gen4 plan same as above
 
 # ORDER BY on select t.*
 "select t.*, t.col from user t order by t.col"
@@ -215,7 +213,6 @@ Gen4 plan same as above
     "FieldQuery": "select t.*, t.col, weight_string(t.col) from `user` as t where 1 != 1",
     "OrderBy": "9 ASC",
     "Query": "select t.*, t.col, weight_string(t.col) from `user` as t order by t.col asc",
-    "ResultColumns": 2,
     "Table": "`user`"
   }
 }
@@ -235,7 +232,6 @@ Gen4 plan same as above
     "FieldQuery": "select *, col, weight_string(col) from `user` where 1 != 1",
     "OrderBy": "9 ASC",
     "Query": "select *, col, weight_string(col) from `user` order by col asc",
-    "ResultColumns": 2,
     "Table": "`user`"
   }
 }
@@ -255,7 +251,6 @@ Gen4 plan same as above
     "FieldQuery": "select t.*, t.`name`, t.*, t.col, weight_string(t.col) from `user` as t where 1 != 1",
     "OrderBy": "19 ASC",
     "Query": "select t.*, t.`name`, t.*, t.col, weight_string(t.col) from `user` as t order by t.col asc",
-    "ResultColumns": 4,
     "Table": "`user`"
   }
 }
@@ -275,7 +270,6 @@ Gen4 plan same as above
     "FieldQuery": "select *, `name`, *, col, weight_string(col) from `user` where 1 != 1",
     "OrderBy": "19 ASC",
     "Query": "select *, `name`, *, col, weight_string(col) from `user` order by col asc",
-    "ResultColumns": 4,
     "Table": "`user`"
   }
 }
@@ -295,7 +289,6 @@ Gen4 plan same as above
     "FieldQuery": "select user_id, col1, col2, weight_string(user_id) from authoritative where 1 != 1",
     "OrderBy": "0 ASC",
     "Query": "select user_id, col1, col2, weight_string(user_id) from authoritative order by user_id asc",
-    "ResultColumns": 3,
     "Table": "authoritative"
   }
 }
@@ -315,7 +308,6 @@ Gen4 plan same as above
     "FieldQuery": "select user_id, col1, col2, weight_string(col1) from authoritative where 1 != 1",
     "OrderBy": "1 ASC",
     "Query": "select user_id, col1, col2, weight_string(col1) from authoritative order by col1 asc",
-    "ResultColumns": 3,
     "Table": "authoritative"
   }
 }
@@ -335,11 +327,9 @@ Gen4 plan same as above
     "FieldQuery": "select a, textcol1, b, weight_string(a), weight_string(textcol1), weight_string(b) from `user` where 1 != 1",
     "OrderBy": "0 ASC, 1 ASC, 2 ASC",
     "Query": "select a, textcol1, b, weight_string(a), weight_string(textcol1), weight_string(b) from `user` order by a asc, textcol1 asc, b asc",
-    "ResultColumns": 3,
     "Table": "`user`"
   }
 }
-Gen4 plan same as above
 
 # ORDER BY on scatter with text column, qualified name
 "select a, user.textcol1, b from user order by a, textcol1, b"
@@ -356,7 +346,6 @@ Gen4 plan same as above
     "FieldQuery": "select a, `user`.textcol1, b, weight_string(a), weight_string(`user`.textcol1), weight_string(b) from `user` where 1 != 1",
     "OrderBy": "0 ASC, 1 ASC, 2 ASC",
     "Query": "select a, `user`.textcol1, b, weight_string(a), weight_string(`user`.textcol1), weight_string(b) from `user` order by a asc, textcol1 asc, b asc",
-    "ResultColumns": 3,
     "Table": "`user`"
   }
 }
@@ -376,11 +365,9 @@ Gen4 plan same as above
     "FieldQuery": "select a, textcol1, b, textcol2, weight_string(a), weight_string(textcol1), weight_string(b), weight_string(textcol2) from `user` where 1 != 1",
     "OrderBy": "0 ASC, 1 ASC, 2 ASC, 3 ASC",
     "Query": "select a, textcol1, b, textcol2, weight_string(a), weight_string(textcol1), weight_string(b), weight_string(textcol2) from `user` order by a asc, textcol1 asc, b asc, textcol2 asc",
-    "ResultColumns": 4,
     "Table": "`user`"
   }
 }
-Gen4 plan same as above
 
 # ORDER BY invalid col number on scatter
 "select col from user order by 2"
@@ -434,7 +421,6 @@ Gen4 plan same as above
         "FieldQuery": "select col, weight_string(col) from `user` where 1 != 1",
         "OrderBy": "0 ASC",
         "Query": "select col, weight_string(col) from `user` where :__sq_has_values1 = 1 and col in ::__sq1 order by col asc",
-        "ResultColumns": 1,
         "Table": "`user`"
       }
     ]
diff --git a/go/vt/vtgate/planbuilder/testdata/select_cases.txt b/go/vt/vtgate/planbuilder/testdata/select_cases.txt
index 805066d598..b2b7906ad3 100644
--- a/go/vt/vtgate/planbuilder/testdata/select_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/select_cases.txt
@@ -852,13 +852,11 @@ Gen4 plan same as above
         "FieldQuery": "select user_id, weight_string(user_id) from music where 1 != 1",
         "OrderBy": "0 ASC",
         "Query": "select user_id, weight_string(user_id) from music order by user_id asc limit :__upper_limit",
-        "ResultColumns": 1,
         "Table": "music"
       }
     ]
   }
 }
-Gen4 plan same as above
 
 # Sharding Key Condition in Parenthesis
 "select * from user where name ='abc' AND (id = 4) limit 5"
@@ -1549,7 +1547,6 @@ Gen4 plan same as above
             "FieldQuery": "select user_id, count(id), weight_string(user_id) from music where 1 != 1 group by user_id",
             "OrderBy": "0 ASC",
             "Query": "select user_id, count(id), weight_string(user_id) from music group by user_id having count(user_id) = 1 order by user_id asc limit :__upper_limit",
-            "ResultColumns": 2,
             "Table": "music"
           }
         ]
diff --git a/go/vt/vtgate/planbuilder/testdata/union_cases.txt b/go/vt/vtgate/planbuilder/testdata/union_cases.txt
index 18c159fd04..c7572346b1 100644
--- a/go/vt/vtgate/planbuilder/testdata/union_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/union_cases.txt
@@ -122,7 +122,6 @@ Gen4 plan same as above
             "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1",
             "OrderBy": "0 DESC",
             "Query": "select id, weight_string(id) from `user` order by id desc limit :__upper_limit",
-            "ResultColumns": 1,
             "Table": "`user`"
           }
         ]
@@ -141,7 +140,6 @@ Gen4 plan same as above
             "FieldQuery": "select id, weight_string(id) from music where 1 != 1",
             "OrderBy": "0 DESC",
             "Query": "select id, weight_string(id) from music order by id desc limit :__upper_limit",
-            "ResultColumns": 1,
             "Table": "music"
           }
         ]
@@ -210,7 +208,6 @@ Gen4 plan same as above
             "FieldQuery": "select id, weight_string(id) from `user` where 1 != 1",
             "OrderBy": "0 ASC",
             "Query": "select id, weight_string(id) from `user` order by id asc limit :__upper_limit",
-            "ResultColumns": 1,
             "Table": "`user`"
           }
         ]
@@ -229,7 +226,6 @@ Gen4 plan same as above
             "FieldQuery": "select id, weight_string(id) from music where 1 != 1",
             "OrderBy": "0 DESC",
             "Query": "select id, weight_string(id) from music order by id desc limit :__upper_limit",
-            "ResultColumns": 1,
             "Table": "music"
           }
         ]
@@ -651,7 +647,6 @@ Gen4 plan same as above
             "FieldQuery": "select 1, weight_string(1) from `user` where 1 != 1",
             "OrderBy": "0 DESC",
             "Query": "select 1, weight_string(1) from `user` order by 1 desc",
-            "ResultColumns": 1,
             "Table": "`user`"
           },
           {
@@ -664,7 +659,6 @@ Gen4 plan same as above
             "FieldQuery": "select 1, weight_string(1) from `user` where 1 != 1",
             "OrderBy": "0 ASC",
             "Query": "select 1, weight_string(1) from `user` order by 1 asc",
-            "ResultColumns": 1,
             "Table": "`user`"
           }
         ]
diff --git a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt
index eab094f308..ef39f94922 100644
--- a/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt
+++ b/go/vt/vtgate/planbuilder/testdata/unsupported_cases.txt
@@ -92,7 +92,6 @@ Gen4 plan same as above
 # Complex aggregate expression on scatter
 "select 1+count(*) from user"
 "unsupported: in scatter query: complex aggregate expression"
-Gen4 plan same as above
 
 # Multi-value aggregates not supported
 "select count(a,b) from user"
diff --git a/go/vt/vtgate/semantics/analyzer_test.go b/go/vt/vtgate/semantics/analyzer_test.go
index 02cfffa9ff..dc30488cac 100644
--- a/go/vt/vtgate/semantics/analyzer_test.go
+++ b/go/vt/vtgate/semantics/analyzer_test.go
@@ -20,11 +20,6 @@ import (
 	"strings"
 	"testing"
 
-	"vitess.io/vitess/go/vt/key"
-	querypb "vitess.io/vitess/go/vt/proto/query"
-	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
-	"vitess.io/vitess/go/vt/vtgate/vindexes"
-
 	"github.com/stretchr/testify/assert"
 
 	"github.com/stretchr/testify/require"
@@ -168,7 +163,7 @@ func TestNotUniqueTableName(t *testing.T) {
 				t.Skip("table alias not implemented")
 			}
 			parse, _ := sqlparser.Parse(query)
-			_, err := Analyse(parse, &fakeSI{})
+			_, err := Analyse(parse)
 			require.Error(t, err)
 			require.Contains(t, err.Error(), "Not unique table/alias")
 		})
@@ -183,113 +178,17 @@ func TestMissingTable(t *testing.T) {
 	for _, query := range queries {
 		t.Run(query, func(t *testing.T) {
 			parse, _ := sqlparser.Parse(query)
-			_, err := Analyse(parse, &fakeSI{})
+			_, err := Analyse(parse)
 			require.Error(t, err)
 			require.Contains(t, err.Error(), "Unknown table")
 		})
 	}
 }
 
-func TestUnknownColumnMap2(t *testing.T) {
-	query := "select col from a, b"
-	authoritativeTblA := vindexes.Table{
-		Name: sqlparser.NewTableIdent("a"),
-		Columns: []vindexes.Column{{
-			Name: sqlparser.NewColIdent("col2"),
-			Type: querypb.Type_VARCHAR,
-		}},
-		ColumnListAuthoritative: true,
-	}
-	authoritativeTblB := vindexes.Table{
-		Name: sqlparser.NewTableIdent("b"),
-		Columns: []vindexes.Column{{
-			Name: sqlparser.NewColIdent("col"),
-			Type: querypb.Type_VARCHAR,
-		}},
-		ColumnListAuthoritative: true,
-	}
-	nonAuthoritativeTblA := authoritativeTblA
-	nonAuthoritativeTblA.ColumnListAuthoritative = false
-	nonAuthoritativeTblB := authoritativeTblB
-	nonAuthoritativeTblB.ColumnListAuthoritative = false
-	authoritativeTblAWithConflict := vindexes.Table{
-		Name: sqlparser.NewTableIdent("a"),
-		Columns: []vindexes.Column{{
-			Name: sqlparser.NewColIdent("col"),
-			Type: querypb.Type_VARCHAR,
-		}},
-		ColumnListAuthoritative: true,
-	}
-
-	parse, _ := sqlparser.Parse(query)
-
-	tests := []struct {
-		name   string
-		schema map[string]*vindexes.Table
-		err    bool
-	}{
-		{
-			name:   "no info about tables",
-			schema: map[string]*vindexes.Table{"a": {}, "b": {}},
-			err:    true,
-		},
-		{
-			name:   "non authoritative columns",
-			schema: map[string]*vindexes.Table{"a": &nonAuthoritativeTblA, "b": &nonAuthoritativeTblA},
-			err:    true,
-		},
-		{
-			name:   "non authoritative columns - one authoritative and one not",
-			schema: map[string]*vindexes.Table{"a": &nonAuthoritativeTblA, "b": &authoritativeTblB},
-			err:    true,
-		},
-		{
-			name:   "non authoritative columns - one authoritative and one not",
-			schema: map[string]*vindexes.Table{"a": &authoritativeTblA, "b": &nonAuthoritativeTblB},
-			err:    true,
-		},
-		{
-			name:   "authoritative columns",
-			schema: map[string]*vindexes.Table{"a": &authoritativeTblA, "b": &authoritativeTblB},
-			err:    false,
-		},
-		{
-			name:   "authoritative columns with overlap",
-			schema: map[string]*vindexes.Table{"a": &authoritativeTblAWithConflict, "b": &authoritativeTblB},
-			err:    true,
-		},
-	}
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			si := &fakeSI{tables: test.schema}
-			_, err := Analyse(parse, si)
-			if test.err {
-				require.Error(t, err)
-			} else {
-				require.NoError(t, err)
-			}
-		})
-	}
-}
-
 func parseAndAnalyze(t *testing.T, query string) (sqlparser.Statement, *SemTable) {
 	parse, err := sqlparser.Parse(query)
 	require.NoError(t, err)
-	semTable, err := Analyse(parse, &fakeSI{
-		tables: map[string]*vindexes.Table{
-			"t": {Name: sqlparser.NewTableIdent("t")},
-		},
-	})
+	semTable, err := Analyse(parse)
 	require.NoError(t, err)
 	return parse, semTable
 }
-
-var _ SchemaInformation = (*fakeSI)(nil)
-
-type fakeSI struct {
-	tables map[string]*vindexes.Table
-}
-
-func (s *fakeSI) FindTableOrVindex(tablename sqlparser.TableName) (*vindexes.Table, vindexes.Vindex, string, topodatapb.TabletType, key.Destination, error) {
-	return s.tables[sqlparser.String(tablename)], nil, "", 0, nil, nil
-}
diff --git a/go/vt/vtgate/semantics/tabletset_test.go b/go/vt/vtgate/semantics/tabletset_test.go
index 4ca005ae99..8ff41c57ec 100644
--- a/go/vt/vtgate/semantics/tabletset_test.go
+++ b/go/vt/vtgate/semantics/tabletset_test.go
@@ -23,7 +23,8 @@ import (
 )
 
 const (
-	F1 TableSet = 1 << iota
+	_ TableSet = 1 << iota
+	F1
 	F2
 	F3
 )
@@ -50,9 +51,3 @@ func TestTableSet_Constituents(t *testing.T) {
 	assert.Equal(t, []TableSet{F2, F3}, (F2 | F3).Constituents())
 	assert.Empty(t, TableSet(0).Constituents())
 }
-
-func TestTableSet_TableOffset(t *testing.T) {
-	assert.Equal(t, 0, F1.TableOffset())
-	assert.Equal(t, 1, F2.TableOffset())
-	assert.Equal(t, 2, F3.TableOffset())
-}