Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions go/vt/tabletserver/codex.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ func buildValueList(tableInfo *TableInfo, pkValues []interface{}, bindVars map[s

func resolvePKValues(tableInfo *TableInfo, pkValues []interface{}, bindVars map[string]interface{}) (resolved []interface{}, length int, err error) {
length = -1
setLength := func(list []sqltypes.Value) {
setLengthFunc := func(list []sqltypes.Value) error {
if length == -1 {
length = len(list)
} else if len(list) != length {
panic(NewTabletError(ErrFail, "mismatched lengths for values %v", pkValues))
return NewTabletError(ErrFail, "mismatched lengths for values %v", pkValues)
}
return nil
}
resolved = make([]interface{}, len(pkValues))
for i, val := range pkValues {
Expand All @@ -61,7 +62,9 @@ func resolvePKValues(tableInfo *TableInfo, pkValues []interface{}, bindVars map[
if err != nil {
return nil, 0, err
}
setLength(list)
if err := setLengthFunc(list); err != nil {
return nil, 0, err
}
resolved[i] = list
}
case []interface{}:
Expand All @@ -72,7 +75,9 @@ func resolvePKValues(tableInfo *TableInfo, pkValues []interface{}, bindVars map[
return nil, 0, err
}
}
setLength(list)
if err := setLengthFunc(list); err != nil {
return nil, 0, err
}
resolved[i] = list
default:
resolved[i], err = resolveValue(tableInfo.GetPKColumn(i), val, nil)
Expand Down Expand Up @@ -144,7 +149,7 @@ func resolveValue(col *schema.TableColumn, value interface{}, bindVars map[strin
case sqltypes.Value:
result = v
default:
panic(NewTabletError(ErrFail, "incompatible value type %v", v))
return result, NewTabletError(ErrFail, "incompatible value type %v", v)
}

if err = validateValue(col, result); err != nil {
Expand Down Expand Up @@ -185,12 +190,12 @@ func validateValue(col *schema.TableColumn, value sqltypes.Value) error {

// getLimit resolves the rowcount or offset of the limit clause value.
// It returns -1 if it's not set.
func getLimit(limit interface{}, bv map[string]interface{}) int64 {
func getLimit(limit interface{}, bv map[string]interface{}) (int64, error) {
switch lim := limit.(type) {
case string:
lookup, ok := bv[lim[1:]]
if !ok {
panic(NewTabletError(ErrFail, "missing bind var %s", lim))
return -1, NewTabletError(ErrFail, "missing bind var %s", lim)
}
var newlim int64
switch l := lookup.(type) {
Expand All @@ -201,16 +206,16 @@ func getLimit(limit interface{}, bv map[string]interface{}) int64 {
case int:
newlim = int64(l)
default:
panic(NewTabletError(ErrFail, "want number type for %s, got %T", lim, lookup))
return -1, NewTabletError(ErrFail, "want number type for %s, got %T", lim, lookup)
}
if newlim < 0 {
panic(NewTabletError(ErrFail, "negative limit %d", newlim))
return -1, NewTabletError(ErrFail, "negative limit %d", newlim)
}
return newlim
return newlim, nil
case int64:
return lim
return lim, nil
default:
return -1
return -1, nil
}
}

Expand Down
79 changes: 40 additions & 39 deletions go/vt/tabletserver/codex_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,8 @@ func TestCodexResolvePKValues(t *testing.T) {
pkValues = make([]interface{}, 0, 10)
pkValues = append(pkValues, []interface{}{":" + key})
pkValues = append(pkValues, []interface{}{":" + key2, ":" + key3})
func() {
defer testUtils.checkTabletErrorWithRecover(t, ErrFail, "mismatched lengths")
_, _, err = resolvePKValues(&tableInfo, pkValues, bindVariables)
}()
_, _, err = resolvePKValues(&tableInfo, pkValues, bindVariables)
testUtils.checkTabletError(t, err, ErrFail, "mismatched lengths")
}

func TestCodexResolveListArg(t *testing.T) {
Expand Down Expand Up @@ -322,11 +320,8 @@ func TestCodexResolveValueWithIncompatibleValueType(t *testing.T) {
[]string{"pk1", "pk2", "col1"},
[]string{"int", "varbinary(128)", "int"},
[]string{"pk1", "pk2"})

func() {
defer testUtils.checkTabletErrorWithRecover(t, ErrFail, "incompatible value type ")
resolveValue(tableInfo.GetPKColumn(0), 0, nil)
}()
_, err := resolveValue(tableInfo.GetPKColumn(0), 0, nil)
testUtils.checkTabletError(t, err, ErrFail, "incompatible value type ")
}

func TestCodexValidateRow(t *testing.T) {
Expand All @@ -352,46 +347,52 @@ func TestCodexGetLimit(t *testing.T) {
"uint": uint(1),
}
testUtils := newTestUtils()
// to handle panics
func() {
defer testUtils.checkTabletErrorWithRecover(t, ErrFail, "missing bind var")
getLimit(":unknown", bv)
}()
if result := getLimit(int64(1), bv); result != 1 {
_, err := getLimit(":unknown", bv)
if err == nil {
t.Fatal("got nil, want error: missing bind var")
}
testUtils.checkTabletError(t, err, ErrFail, "missing bind var")
result, err := getLimit(int64(1), bv)
if err != nil {
t.Fatalf("getLimit(1, bv) = %v, want nil", err)
}
if result != 1 {
t.Fatalf("got %d, want 1", result)
}
if result := getLimit(nil, bv); result != -1 {
result, err = getLimit(nil, bv)
if err != nil {
t.Fatalf("getLimit(nil, bv) = %v, want nil", err)
}
if result != -1 {
t.Fatalf("got %d, want -1", result)
}
func() {
defer func() {
x := recover().(error).Error()
want := "error: negative limit -1"
if x != want {
t.Fatalf("got %s, want %s", x, want)
}
}()
getLimit(":negative", bv)
}()
if result := getLimit(":int64", bv); result != 1 {

result, err = getLimit(":negative", bv)
if err == nil {
t.Fatalf("getLimit(':negative', bv) should return an error")
}
want := "error: negative limit -1"
if err.Error() != want {
t.Fatalf("got %s, want %s", err.Error(), want)
}
if result, _ := getLimit(":int64", bv); result != 1 {
t.Fatalf("got %d, want 1", result)
}
if result := getLimit(":int32", bv); result != 1 {
if result, _ := getLimit(":int32", bv); result != 1 {
t.Fatalf("got %d, want 1", result)
}
if result := getLimit(":int", bv); result != 1 {
if result, _ := getLimit(":int", bv); result != 1 {
t.Fatalf("got %d, want 1", result)
}
func() {
defer func() {
x := recover().(error).Error()
want := "error: want number type for :uint, got uint"
if x != want {
t.Fatalf("got %s, want %s", x, want)
}
}()
getLimit(":uint", bv)
}()

_, err = getLimit(":uint", bv)
if err == nil {
t.Fatalf("getLimit(':uint', bv) should return an error")
}
want = "error: want number type for :uint, got uint"
if err.Error() != want {
t.Fatalf("got %s, want %s", err.Error(), want)
}
}

func TestCodexBuildKey(t *testing.T) {
Expand Down
3 changes: 2 additions & 1 deletion go/vt/tabletserver/dbconn.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package tabletserver

import (
"errors"
"fmt"
"time"

Expand Down Expand Up @@ -67,7 +68,7 @@ func (dbc *DBConn) Exec(ctx context.Context, query string, maxrows int, wantfiel
return nil, NewTabletErrorSql(ErrFatal, err)
}
}
panic("unreachable")
return nil, NewTabletErrorSql(ErrFatal, errors.New("dbconn.Exec: unreachable code"))
}

func (dbc *DBConn) execOnce(ctx context.Context, query string, maxrows int, wantfields bool) (*mproto.QueryResult, error) {
Expand Down
Loading