Skip to content

Commit

Permalink
Warn when using unsharded only features
Browse files Browse the repository at this point in the history
Signed-off-by: Andres Taylor <andres@planetscale.com>
  • Loading branch information
systay committed Mar 9, 2021
1 parent e84e366 commit c010b73
Show file tree
Hide file tree
Showing 7 changed files with 46 additions and 10 deletions.
13 changes: 11 additions & 2 deletions go/vt/vtgate/planbuilder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ type ContextVSchema interface {
AllKeyspace() ([]*vindexes.Keyspace, error)
GetSemTable() *semantics.SemTable
Planner() PlannerVersion

// ErrorIfShardedF will return an error if the keyspace is sharded,
// and produce a warning if the vtgate if configured to do so
ErrorIfShardedF(keyspace *vindexes.Keyspace, warn, errFmt string, params ...interface{}) error

// WarnUnshardedOnly is used when a feature is only supported in unsharded mode.
// This will let the user know that they are using something
// that could become a problem if they move to a sharded keyspace
WarnUnshardedOnly(format string, params ...interface{})
}

// PlannerVersion is an alias here to make the code more readable
Expand Down Expand Up @@ -231,8 +240,8 @@ func buildLoadPlan(query string, vschema ContextVSchema) (engine.Primitive, erro

destination := vschema.Destination()
if destination == nil {
if keyspace.Sharded {
return nil, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "LOAD is not supported on sharded database")
if err := vschema.ErrorIfShardedF(keyspace, "LOAD", "LOAD is not supported on sharded database"); err != nil {
return nil, err
}
destination = key.DestinationAnyShard{}
}
Expand Down
6 changes: 2 additions & 4 deletions go/vt/vtgate/planbuilder/call_proc.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ package planbuilder

import (
"vitess.io/vitess/go/vt/key"
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/engine"
)

Expand All @@ -36,8 +34,8 @@ func buildCallProcPlan(stmt *sqlparser.CallProc, vschema ContextVSchema) (engine
}

if dest == nil {
if keyspace.Sharded {
return nil, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, errNotAllowWhenSharded)
if err := vschema.ErrorIfShardedF(keyspace, "CALL", errNotAllowWhenSharded); err != nil {
return nil, err
}
dest = key.DestinationAnyShard{}
}
Expand Down
5 changes: 3 additions & 2 deletions go/vt/vtgate/planbuilder/ddl.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ func buildGeneralDDLPlan(sql string, ddlStatement sqlparser.DDLStatement, vschem
}

if ddlStatement.IsTemporary() {
if normalDDLPlan.Keyspace.Sharded {
return nil, vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "Temporary table not supported in sharded database %s", normalDDLPlan.Keyspace.Name)
err := vschema.ErrorIfShardedF(normalDDLPlan.Keyspace, "temporary table", "Temporary table not supported in sharded database %s", normalDDLPlan.Keyspace.Name)
if err != nil {
return nil, err
}
onlineDDLPlan = nil // emptying this so it does not accidentally gets used somewhere
}
Expand Down
4 changes: 3 additions & 1 deletion go/vt/vtgate/planbuilder/dml.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,9 @@ func buildDMLPlan(vschema ContextVSchema, dmlType string, stmt sqlparser.Stateme
var subqueryArgs []sqlparser.SQLNode
subqueryArgs = append(subqueryArgs, nodes...)
subqueryArgs = append(subqueryArgs, where, orderBy, limit)
if !pb.finalizeUnshardedDMLSubqueries(subqueryArgs...) {
if pb.finalizeUnshardedDMLSubqueries(subqueryArgs...) {
vschema.WarnUnshardedOnly("subqueries can't be sharded in DML")
} else {
return nil, nil, "", vterrors.New(vtrpcpb.Code_UNIMPLEMENTED, "unsupported: sharded subqueries in DML")
}
edml.Opcode = engine.Unsharded
Expand Down
4 changes: 3 additions & 1 deletion go/vt/vtgate/planbuilder/insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,9 @@ func buildInsertPlan(stmt sqlparser.Statement, vschema ContextVSchema) (engine.P
vschemaTable = tval.vschemaTable
}
if !rb.eroute.Keyspace.Sharded {
if !pb.finalizeUnshardedDMLSubqueries(ins) {
if pb.finalizeUnshardedDMLSubqueries(ins) {
vschema.WarnUnshardedOnly("subqueries can't be sharded for INSERT")
} else {
return nil, errors.New("unsupported: sharded subquery in insert values")
}
return buildInsertUnshardedPlan(ins, vschemaTable)
Expand Down
11 changes: 11 additions & 0 deletions go/vt/vtgate/planbuilder/plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,17 @@ func (vw *vschemaWrapper) TargetString() string {
return "targetString"
}

func (vw *vschemaWrapper) WarnUnshardedOnly(_ string, _ ...interface{}) {

}

func (vw *vschemaWrapper) ErrorIfShardedF(keyspace *vindexes.Keyspace, _, errFmt string, params ...interface{}) error {
if keyspace.Sharded {
return fmt.Errorf(errFmt, params...)
}
return nil
}

func escapeNewLines(in string) string {
return strings.ReplaceAll(in, "\n", "\\n")
}
Expand Down
13 changes: 13 additions & 0 deletions go/vt/vtgate/vcursor_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,19 @@ func (vc *vcursorImpl) HasCreatedTempTable() {
vc.safeSession.GetOrCreateOptions().HasCreatedTempTables = true
}

// ErrorIfShardedF is used to allow but log on unsharded, and just error when in a sharded keyspace
func (vc *vcursorImpl) ErrorIfShardedF(ks *vindexes.Keyspace, warn, errFormat string, params ...interface{}) error {
if ks.Sharded {
return vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, errFormat, params...)
}
log.Warnf("use of feature that is only supported in unsharded mode:%s", warn)
return nil
}

func (vc *vcursorImpl) WarnUnshardedOnly(format string, params ...interface{}) {
log.Warnf(format, params...)
}

// ParseDestinationTarget parses destination target string and sets default keyspace if possible.
func parseDestinationTarget(targetString string, vschema *vindexes.VSchema) (string, topodatapb.TabletType, key.Destination, error) {
destKeyspace, destTabletType, dest, err := topoprotopb.ParseDestination(targetString, defaultTabletType)
Expand Down

0 comments on commit c010b73

Please sign in to comment.