// AsInterface converts the ValExpr to an interface. It converts // ValTuple to []interface{}, ValArg to string, StrVal to sqltypes.String, // NumVal to sqltypes.Numeric, NullVal to nil. // Otherwise, it returns an error. func AsInterface(node ValExpr) (interface{}, error) { switch node := node.(type) { case ValTuple: vals := make([]interface{}, 0, len(node)) for _, val := range node { v, err := AsInterface(val) if err != nil { return nil, err } vals = append(vals, v) } return vals, nil case ValArg: return string(node), nil case ListArg: return string(node), nil case StrVal: return sqltypes.MakeString(node), nil case NumVal: n, err := sqltypes.BuildNumeric(string(node)) if err != nil { return nil, fmt.Errorf("type mismatch: %s", err) } return n, nil case *NullVal: return nil, nil } return nil, fmt.Errorf("unexpected node %v", node) }
func asInterface(node *Node) interface{} { switch node.Type { case VALUE_ARG: return string(node.Value) case STRING: return sqltypes.MakeString(node.Value) case NUMBER: n, err := sqltypes.BuildNumeric(string(node.Value)) if err != nil { panic(NewParserError("Type mismatch: %s", err)) } return n } panic(NewParserError("Unexpected node %v", node)) }
func TestHashResolve(t *testing.T) { hind := NewHashIndex(TEST_SHARDED, new(sandboxTopo), "") nn, _ := sqltypes.BuildNumeric("11") ks, shards, err := hind.Resolve(topo.TabletType("master"), []interface{}{1, int32(2), int64(3), uint(4), uint32(5), uint64(6), nn}) if err != nil { t.Error(err) } want := []string{"-20", "-20", "40-60", "c0-e0", "60-80", "e0-", "a0-c0"} if !reflect.DeepEqual(shards, want) { t.Errorf("got\n%#v, want\n%#v", shards, want) } if ks != TEST_SHARDED { t.Errorf("got %v, want TEST_SHARDED", ks) } _, _, err = hind.Resolve(topo.TabletType("master"), []interface{}{"aa"}) wantErr := "unexpected type for aa: string" if err == nil || err.Error() != wantErr { t.Errorf("got %v, want %v", err, wantErr) } }
func validateKey(tableInfo *TableInfo, key string, qStats *QueryServiceStats) (newKey string) { if key == "" { // TODO: Verify auto-increment table return } pieces := strings.Split(key, ".") if len(pieces) != len(tableInfo.PKColumns) { // TODO: Verify auto-increment table return "" } pkValues := make([]sqltypes.Value, len(tableInfo.PKColumns)) for i, piece := range pieces { if piece[0] == '\'' { s, err := base64.StdEncoding.DecodeString(piece[1 : len(piece)-1]) if err != nil { log.Warningf("Error decoding key %s for table %s: %v", key, tableInfo.Name, err) qStats.InternalErrors.Add("Mismatch", 1) return } pkValues[i] = sqltypes.MakeString(s) } else if piece == "null" { // TODO: Verify auto-increment table return "" } else { n, err := sqltypes.BuildNumeric(piece) if err != nil { log.Warningf("Error decoding key %s for table %s: %v", key, tableInfo.Name, err) qStats.InternalErrors.Add("Mismatch", 1) return } pkValues[i] = n } } if newKey = buildKey(pkValues); newKey != key { log.Warningf("Error: Key mismatch, received: %s, computed: %s", key, newKey) qStats.InternalErrors.Add("Mismatch", 1) } return newKey }