Beispiel #1
0
// CreateTransaction saves the metadata of a 2pc transaction as Prepared.
func (tpc *TwoPC) CreateTransaction(ctx context.Context, conn *TxConnection, dtid string, participants []*querypb.Target) error {
	bindVars := map[string]interface{}{
		"dtid":     dtid,
		"cur_time": int64(time.Now().UnixNano()),
	}
	_, err := tpc.exec(ctx, conn, tpc.insertTransaction, bindVars)
	if err != nil {
		return err
	}

	rows := make([][]sqltypes.Value, len(participants))
	for i, participant := range participants {
		rows[i] = []sqltypes.Value{
			sqltypes.MakeTrusted(sqltypes.VarBinary, []byte(dtid)),
			sqltypes.MakeTrusted(sqltypes.Int64, strconv.AppendInt(nil, int64(i+1), 10)),
			sqltypes.MakeTrusted(sqltypes.VarBinary, []byte(participant.Keyspace)),
			sqltypes.MakeTrusted(sqltypes.VarBinary, []byte(participant.Shard)),
		}
	}
	bindVars = map[string]interface{}{
		"vals": rows,
	}
	_, err = tpc.exec(ctx, conn, tpc.insertParticipants, bindVars)
	return err
}
Beispiel #2
0
func TestCodexResolveListArg(t *testing.T) {
	testUtils := newTestUtils()
	tableInfo := createTableInfo("Table",
		[]string{"pk1", "pk2", "col1"},
		[]querypb.Type{sqltypes.Int64, sqltypes.VarBinary, sqltypes.Int32},
		[]string{"pk1", "pk2"})

	key := "var"
	bindVariables := make(map[string]interface{})
	bindVariables[key] = []interface{}{fmt.Errorf("error is not supported")}

	_, err := resolveListArg(tableInfo.GetPKColumn(0), "::"+key, bindVariables)
	testUtils.checkTabletError(t, err, ErrFail, "")

	// This should successfully convert.
	bindVariables[key] = []interface{}{"1"}
	v, err := resolveListArg(tableInfo.GetPKColumn(0), "::"+key, bindVariables)
	if err != nil {
		t.Error(err)
	}
	wantV := []sqltypes.Value{sqltypes.MakeTrusted(sqltypes.Int64, []byte("1"))}
	if !reflect.DeepEqual(v, wantV) {
		t.Errorf("resolvePKValues: %#v, want %#v", v, wantV)
	}

	bindVariables[key] = []interface{}{10}
	result, err := resolveListArg(tableInfo.GetPKColumn(0), "::"+key, bindVariables)
	if err != nil {
		t.Fatalf("should not get an error, but got error: %v", err)
	}
	testUtils.checkEqual(t, []sqltypes.Value{sqltypes.MakeTrusted(sqltypes.Int64, []byte("10"))}, result)
}
func TestMiscTypes(t *testing.T) {
	client := framework.NewClient()
	defer client.Execute("delete from vitess_misc", nil)

	_, err := client.Execute(
		"insert into vitess_misc values(:id, :b, :d, :dt, :t)",
		map[string]interface{}{
			"id": 1,
			"b":  "\x01",
			"d":  "2012-01-01",
			"dt": "2012-01-01 15:45:45",
			"t":  "15:45:45",
		},
	)
	if err != nil {
		t.Error(err)
		return
	}
	qr, err := client.Execute("select * from vitess_misc where id = 1", nil)
	if err != nil {
		t.Error(err)
		return
	}
	want := sqltypes.Result{
		Fields: []*querypb.Field{
			{
				Name: "id",
				Type: sqltypes.Int32,
			}, {
				Name: "b",
				Type: sqltypes.Bit,
			}, {
				Name: "d",
				Type: sqltypes.Date,
			}, {
				Name: "dt",
				Type: sqltypes.Datetime,
			}, {
				Name: "t",
				Type: sqltypes.Time,
			},
		},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
				sqltypes.MakeTrusted(sqltypes.Bit, []byte("\x01")),
				sqltypes.MakeTrusted(sqltypes.Date, []byte("2012-01-01")),
				sqltypes.MakeTrusted(sqltypes.Datetime, []byte("2012-01-01 15:45:45")),
				sqltypes.MakeTrusted(sqltypes.Time, []byte("15:45:45")),
			},
		},
	}
	if !reflect.DeepEqual(*qr, want) {
		t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
	}
}
func TestFractionals(t *testing.T) {
	client := framework.NewClient()
	defer client.Execute("delete from vitess_fracts", nil)

	_, err := client.Execute(
		"insert into vitess_fracts values(:id, :deci, :num, :f, :d)",
		map[string]interface{}{
			"id":   1,
			"deci": "1.99",
			"num":  "2.99",
			"f":    3.99,
			"d":    4.99,
		},
	)
	if err != nil {
		t.Error(err)
		return
	}
	qr, err := client.Execute("select * from vitess_fracts where id = 1", nil)
	if err != nil {
		t.Error(err)
		return
	}
	want := sqltypes.Result{
		Fields: []*querypb.Field{
			{
				Name: "id",
				Type: sqltypes.Int32,
			}, {
				Name: "deci",
				Type: sqltypes.Decimal,
			}, {
				Name: "num",
				Type: sqltypes.Decimal,
			}, {
				Name: "f",
				Type: sqltypes.Float32,
			}, {
				Name: "d",
				Type: sqltypes.Float64,
			},
		},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
				sqltypes.MakeTrusted(sqltypes.Decimal, []byte("1.99")),
				sqltypes.MakeTrusted(sqltypes.Decimal, []byte("2.99")),
				sqltypes.MakeTrusted(sqltypes.Float32, []byte("3.99")),
				sqltypes.MakeTrusted(sqltypes.Float64, []byte("4.99")),
			},
		},
	}
	if !reflect.DeepEqual(*qr, want) {
		t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
	}
}
Beispiel #5
0
func createTestTableUpdatedStats(tableName string) []sqltypes.Value {
	return []sqltypes.Value{
		sqltypes.MakeString([]byte(tableName)),
		sqltypes.MakeString([]byte("USER TABLE")),
		sqltypes.MakeTrusted(sqltypes.Int32, []byte("0")),
		sqltypes.MakeString([]byte("")),
		sqltypes.MakeTrusted(sqltypes.Int32, []byte("4")),
		sqltypes.MakeTrusted(sqltypes.Int32, []byte("5")),
		sqltypes.MakeTrusted(sqltypes.Int32, []byte("6")),
		sqltypes.MakeTrusted(sqltypes.Int32, []byte("7")),
	}
}
Beispiel #6
0
func createTestTableBaseShowTable(tableName string) []sqltypes.Value {
	return []sqltypes.Value{
		sqltypes.MakeString([]byte(tableName)),
		sqltypes.MakeString([]byte("USER TABLE")),
		sqltypes.MakeTrusted(sqltypes.Int32, []byte("1427325875")),
		sqltypes.MakeString([]byte("")),
		sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
		sqltypes.MakeTrusted(sqltypes.Int32, []byte("2")),
		sqltypes.MakeTrusted(sqltypes.Int32, []byte("3")),
		sqltypes.MakeTrusted(sqltypes.Int32, []byte("4")),
	}
}
Beispiel #7
0
func TestCodexBuildKey(t *testing.T) {
	testUtils := newTestUtils()
	newKey := buildKey([]sqltypes.Value{
		sqltypes.MakeTrusted(sqltypes.Int64, []byte("1")),
		sqltypes.MakeTrusted(sqltypes.Int64, []byte("2")),
	})
	testUtils.checkEqual(t, "1.2", newKey)

	newKey = buildKey([]sqltypes.Value{
		sqltypes.MakeString([]byte("a")),
		sqltypes.NULL,
	})
	testUtils.checkEqual(t, "", newKey)
}
Beispiel #8
0
func TestDBAStatements(t *testing.T) {
	client := framework.NewClient()

	qr, err := client.Execute("show variables like 'version'", nil)
	if err != nil {
		t.Error(err)
		return
	}
	wantCol := sqltypes.MakeTrusted(sqltypes.VarChar, []byte("version"))
	if !reflect.DeepEqual(qr.Rows[0][0], wantCol) {
		t.Errorf("Execute: \n%#v, want \n%#v", qr.Rows[0][0], wantCol)
	}

	qr, err = client.Execute("describe vitess_a", nil)
	if err != nil {
		t.Error(err)
		return
	}
	if qr.RowsAffected != 4 {
		t.Errorf("RowsAffected: %d, want 4", qr.RowsAffected)
	}

	qr, err = client.Execute("explain vitess_a", nil)
	if err != nil {
		t.Error(err)
		return
	}
	if qr.RowsAffected != 4 {
		t.Errorf("RowsAffected: %d, want 4", qr.RowsAffected)
	}
}
Beispiel #9
0
func TestQueryExecutorPlanDmlSubQuery(t *testing.T) {
	db := setUpQueryExecutorTest()
	query := "update test_table set addr = 3 where name = 1 limit 1000"
	expandedQuery := "select pk from test_table where name = 1 limit 1000 for update"
	want := &sqltypes.Result{}
	db.AddQuery(query, want)
	db.AddQuery(expandedQuery, &sqltypes.Result{
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{sqltypes.MakeTrusted(sqltypes.Int32, []byte("2"))},
		},
	})
	updateQuery := "update test_table set addr = 3 where pk in (2) /* _stream test_table (pk ) (2 ); */"
	db.AddQuery(updateQuery, want)
	ctx := context.Background()
	tsv := newTestTabletServer(ctx, enableStrict, db)
	txid := newTransaction(tsv)
	qre := newTestQueryExecutor(ctx, tsv, query, txid)
	defer tsv.StopService()
	defer testCommitHelper(t, tsv, qre)
	checkPlanID(t, planbuilder.PlanDMLSubquery, qre.plan.PlanID)
	got, err := qre.Execute()
	if err != nil {
		t.Fatalf("qre.Execute() = %v, want nil", err)
	}
	if !reflect.DeepEqual(got, want) {
		t.Fatalf("got: %v, want: %v", got, want)
	}
	wantqueries := []string{updateQuery}
	gotqueries := fetchRecordedQueries(qre)
	if !reflect.DeepEqual(gotqueries, wantqueries) {
		t.Errorf("queries: %v, want %v", gotqueries, wantqueries)
	}
}
Beispiel #10
0
func TestLookupHashAutoMapBadData(t *testing.T) {
	result := &sqltypes.Result{
		Fields: []*querypb.Field{{
			Type: sqltypes.Float64,
		}},
		Rows: [][]sqltypes.Value{
			[]sqltypes.Value{
				sqltypes.MakeTrusted(sqltypes.Float64, []byte("1.1")),
			},
		},
		RowsAffected: 1,
	}
	vc := &vcursor{result: result}
	_, err := lha.(planbuilder.NonUnique).Map(vc, []interface{}{1, int32(2)})
	want := "unexpected type"
	if err == nil || !strings.Contains(err.Error(), want) {
		t.Errorf("lha.Map: %v, must contain %v", err, want)
	}

	result.Fields = []*querypb.Field{{
		Type: sqltypes.Float32,
	}}
	vc = &vcursor{result: result}
	_, err = lha.(planbuilder.NonUnique).Map(vc, []interface{}{1, int32(2)})
	want = `lookup.Map: unexpected type for 1.1: float64`
	if err == nil || err.Error() != want {
		t.Errorf("lha.Map: %v, want %v", err, want)
	}
}
Beispiel #11
0
func (vc *vcursor) Execute(query *querytypes.BoundQuery) (*sqltypes.Result, error) {
	vc.query = query
	if vc.mustFail {
		return nil, errors.New("execute failed")
	}
	switch {
	case strings.HasPrefix(query.Sql, "select"):
		if vc.result != nil {
			return vc.result, nil
		}
		result := &sqltypes.Result{
			Fields: []*querypb.Field{{
				Type: sqltypes.Int32,
			}},
			RowsAffected: uint64(vc.numRows),
		}
		for i := 0; i < vc.numRows; i++ {
			result.Rows = append(result.Rows, []sqltypes.Value{
				sqltypes.MakeTrusted(sqltypes.Int64, []byte(fmt.Sprintf("%d", i+1))),
			})
		}
		return result, nil
	case strings.HasPrefix(query.Sql, "insert"):
		return &sqltypes.Result{InsertID: 1}, nil
	case strings.HasPrefix(query.Sql, "delete"):
		return &sqltypes.Result{}, nil
	}
	panic("unexpected")
}
Beispiel #12
0
func TestQueryExecutorPlanInsertSubQuery(t *testing.T) {
	db := setUpQueryExecutorTest()
	query := "insert into test_table(pk) select pk from test_table where pk = 1 limit 1000"
	want := &sqltypes.Result{
		Rows: [][]sqltypes.Value{},
	}
	db.AddQuery(query, want)
	selectQuery := "select pk from test_table where pk = 1 limit 1000"
	db.AddQuery(selectQuery, &sqltypes.Result{
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{sqltypes.MakeTrusted(sqltypes.Int32, []byte("2"))},
		},
	})

	insertQuery := "insert into test_table(pk) values (2) /* _stream test_table (pk ) (2 ); */"

	db.AddQuery(insertQuery, &sqltypes.Result{})
	ctx := context.Background()
	tsv := newTestTabletServer(ctx, enableRowCache|enableStrict, db)
	qre := newTestQueryExecutor(ctx, tsv, query, newTransaction(tsv))

	defer tsv.StopService()
	defer testCommitHelper(t, tsv, qre)
	checkPlanID(t, planbuilder.PlanInsertSubquery, qre.plan.PlanID)
	got, err := qre.Execute()
	if err != nil {
		t.Fatalf("qre.Execute() = %v, want nil", err)
	}
	if !reflect.DeepEqual(got, want) {
		t.Fatalf("got: %v, want: %v", got, want)
	}
}
Beispiel #13
0
// FetchNext returns the next row for a query
func (conn *Connection) FetchNext() (row []sqltypes.Value, err error) {
	vtrow := C.vt_fetch_next(&conn.c)
	if vtrow.has_error != 0 {
		return nil, conn.lastError("")
	}
	rowPtr := (*[maxSize]*[maxSize]byte)(unsafe.Pointer(vtrow.mysql_row))
	if rowPtr == nil {
		return nil, nil
	}
	colCount := int(conn.c.num_fields)
	cfields := (*[maxSize]C.MYSQL_FIELD)(unsafe.Pointer(conn.c.fields))
	row = make([]sqltypes.Value, colCount)
	lengths := (*[maxSize]uint64)(unsafe.Pointer(vtrow.lengths))
	totalLength := uint64(0)
	for i := 0; i < colCount; i++ {
		totalLength += lengths[i]
	}
	arena := make([]byte, 0, int(totalLength))
	for i := 0; i < colCount; i++ {
		colLength := lengths[i]
		colPtr := rowPtr[i]
		if colPtr == nil {
			continue
		}
		start := len(arena)
		arena = append(arena, colPtr[:colLength]...)
		// MySQL values can be trusted.
		row[i] = sqltypes.MakeTrusted(
			sqltypes.MySQLToType(int64(cfields[i]._type), int64(cfields[i].flags)),
			arena[start:start+int(colLength)],
		)
	}
	return row, nil
}
Beispiel #14
0
func (qre *QueryExecutor) execNextval() (*sqltypes.Result, error) {
	t := qre.plan.TableInfo
	t.Seq.Lock()
	defer t.Seq.Unlock()
	if t.NextVal >= t.LastVal {
		_, err := qre.execAsTransaction(func(conn *TxConnection) (*sqltypes.Result, error) {
			query := fmt.Sprintf("select next_id, cache, increment from `%s` where id = 0 for update", qre.plan.TableName)
			qr, err := qre.execSQL(conn, query, false)
			if err != nil {
				return nil, err
			}
			if len(qr.Rows) != 1 {
				return nil, fmt.Errorf("unexpected rows from reading sequence %s (possible mis-route): %d", qre.plan.TableName, len(qr.Rows))
			}
			nextID, err := qr.Rows[0][0].ParseInt64()
			if err != nil {
				return nil, fmt.Errorf("error loading sequence %s: %v", qre.plan.TableName, err)
			}
			cache, err := qr.Rows[0][1].ParseInt64()
			if err != nil {
				return nil, fmt.Errorf("error loading sequence %s: %v", qre.plan.TableName, err)
			}
			if cache < 1 {
				return nil, fmt.Errorf("invalid cache value for sequence %s: %d", qre.plan.TableName, cache)
			}
			inc, err := qr.Rows[0][2].ParseInt64()
			if err != nil {
				return nil, fmt.Errorf("error loading sequence %s: %v", qre.plan.TableName, err)
			}
			if inc < 1 {
				return nil, fmt.Errorf("invalid increment for sequence %s: %d", qre.plan.TableName, inc)
			}
			newLast := nextID + cache*inc
			query = fmt.Sprintf("update `%s` set next_id = %d where id = 0", qre.plan.TableName, newLast)
			conn.RecordQuery(query)
			_, err = qre.execSQL(conn, query, false)
			if err != nil {
				return nil, err
			}
			t.NextVal = nextID
			t.Increment = inc
			t.LastVal = newLast
			return nil, nil
		})
		if err != nil {
			return nil, err
		}
	}
	ret := t.NextVal
	t.NextVal += t.Increment
	return &sqltypes.Result{
		Fields: sequenceFields,
		Rows: [][]sqltypes.Value{{
			sqltypes.MakeTrusted(sqltypes.Int64, strconv.AppendInt(nil, ret, 10)),
		}},
		RowsAffected: 1,
	}, nil
}
Beispiel #15
0
func TestBinary(t *testing.T) {
	client := framework.NewClient()
	defer client.Execute("delete from vitess_test where intval in (4,5)", nil)

	binaryData := "\x00'\"\b\n\r\t\x1a\\\x00\x0f\xf0\xff"
	// Test without bindvars.
	_, err := client.Execute(
		"insert into vitess_test values "+
			"(4, null, null, '\\0\\'\\\"\\b\\n\\r\\t\\Z\\\\\x00\x0f\xf0\xff')",
		nil,
	)
	if err != nil {
		t.Error(err)
		return
	}
	qr, err := client.Execute("select binval from vitess_test where intval=4", nil)
	if err != nil {
		t.Error(err)
		return
	}
	want := sqltypes.Result{
		Fields: []*querypb.Field{
			{
				Name: "binval",
				Type: sqltypes.VarBinary,
			},
		},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			[]sqltypes.Value{
				sqltypes.MakeTrusted(sqltypes.VarBinary, []byte(binaryData)),
			},
		},
	}
	if !reflect.DeepEqual(*qr, want) {
		t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
	}

	// Test with bindvars.
	_, err = client.Execute(
		"insert into vitess_test values(5, null, null, :bindata)",
		map[string]interface{}{"bindata": binaryData},
	)
	if err != nil {
		t.Error(err)
		return
	}
	qr, err = client.Execute("select binval from vitess_test where intval=5", nil)
	if err != nil {
		t.Error(err)
		return
	}
	if !reflect.DeepEqual(*qr, want) {
		t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
	}
}
Beispiel #16
0
func TestMultiInsertGenerator(t *testing.T) {
	router, sbc, _, sbclookup := createRouterEnv()

	sbclookup.SetResults([]*sqltypes.Result{{
		Rows: [][]sqltypes.Value{{
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("1")),
		}},
		RowsAffected: 1,
		InsertID:     1,
	}})
	result, err := routerExec(router, "insert into user(v, name) values (2, 'myname1'), (3, 'myname2')", nil)
	if err != nil {
		t.Error(err)
	}
	wantQueries := []querytypes.BoundQuery{{
		Sql: "insert into user(v, name, Id) values (2, :_name0, :_Id0), (3, :_name1, :_Id1) /* vtgate:: keyspace_id:166b40b44aba4bd6 */",
		BindVariables: map[string]interface{}{
			"_Id0":   int64(1),
			"__seq0": int64(1),
			"_name0": []byte("myname1"),
			"_Id1":   int64(1),
			"__seq1": int64(1),
			"_name1": []byte("myname2"),
		},
	}}
	if !reflect.DeepEqual(sbc.Queries, wantQueries) {
		t.Errorf("sbc.Queries: %+v, want %+v\n", sbc.Queries, wantQueries)
	}
	wantQueries = []querytypes.BoundQuery{{
		Sql:           "select next value from `user_seq`",
		BindVariables: map[string]interface{}{},
	}, {
		Sql: "insert into name_user_map(name, user_id) values (:name, :user_id)",
		BindVariables: map[string]interface{}{
			"name":    []byte("myname1"),
			"user_id": int64(1),
		},
	}, {
		Sql:           "select next value from `user_seq`",
		BindVariables: map[string]interface{}{},
	}, {
		Sql: "insert into name_user_map(name, user_id) values (:name, :user_id)",
		BindVariables: map[string]interface{}{
			"name":    []byte("myname2"),
			"user_id": int64(1),
		},
	}}
	if !reflect.DeepEqual(sbclookup.Queries, wantQueries) {
		t.Errorf("sbclookup.Queries: \n%#v, want \n%#v\n", sbclookup.Queries, wantQueries)
	}
	wantResult := *sandboxconn.SingleRowResult
	wantResult.InsertID = 1
	if !reflect.DeepEqual(result, &wantResult) {
		t.Errorf("result: %+v, want %+v", result, &wantResult)
	}
}
Beispiel #17
0
// TODO(erez): Rename to TestTabletServerSplitQuery once migration to SplitQuery is done.
func TestTabletServerSplitQueryV2(t *testing.T) {
	db := setUpTabletServerTest()
	db.AddQuery("SELECT MIN(pk), MAX(pk) FROM test_table", &sqltypes.Result{
		Fields: []*querypb.Field{
			{Name: "pk", Type: sqltypes.Int32},
		},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("100")),
			},
		},
	})
	testUtils := newTestUtils()
	config := testUtils.newQueryServiceConfig()
	tsv := NewTabletServer(config)
	dbconfigs := testUtils.newDBConfigs(db)
	target := querypb.Target{TabletType: topodatapb.TabletType_RDONLY}
	err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs))
	if err != nil {
		t.Fatalf("StartService failed: %v", err)
	}
	defer tsv.StopService()
	ctx := context.Background()
	sql := "select * from test_table where count > :count"
	splits, err := tsv.SplitQueryV2(
		ctx,
		&querypb.Target{TabletType: topodatapb.TabletType_RDONLY},
		sql,
		nil,        /* bindVariables */
		[]string{}, /* splitColumns */
		10,         /* splitCount */
		0,          /* numRowsPerQueryPart */
		querypb.SplitQueryRequest_EQUAL_SPLITS)
	if err != nil {
		t.Fatalf("TabletServer.SplitQuery should succeed: %v, but get error: %v", sql, err)
	}
	if len(splits) != 10 {
		t.Fatalf("got: %v, want: %v.\nsplits: %+v", len(splits), 10, splits)
	}
}
Beispiel #18
0
func TestLeftJoinStream(t *testing.T) {
	router, sbc1, sbc2, _ := createRouterEnv()
	result1 := []*sqltypes.Result{{
		Fields: []*querypb.Field{
			{"id", sqltypes.Int32},
			{"col", sqltypes.Int32},
		},
		RowsAffected: 1,
		InsertID:     0,
		Rows: [][]sqltypes.Value{{
			sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
			sqltypes.MakeTrusted(sqltypes.Int32, []byte("3")),
		}},
	}}
	emptyResult := []*sqltypes.Result{{
		Fields: []*querypb.Field{
			{"id", sqltypes.Int32},
		},
	}}
	sbc1.setResults(result1)
	sbc2.setResults(emptyResult)
	result, err := routerStream(router, "select u1.id, u2.id from user u1 left join user u2 on u2.id = u1.col where u1.id = 1")
	if err != nil {
		t.Error(err)
	}
	wantResult := &sqltypes.Result{
		Fields: []*querypb.Field{
			singleRowResult.Fields[0],
			singleRowResult.Fields[0],
		},
		Rows: [][]sqltypes.Value{
			{
				singleRowResult.Rows[0][0],
				{},
			},
		},
		RowsAffected: 0,
	}
	if !reflect.DeepEqual(result, wantResult) {
		t.Errorf("result: %+v, want %+v", result, wantResult)
	}
}
Beispiel #19
0
// DeleteRedo deletes the redo log for the dtid.
func (tpc *TwoPC) DeleteRedo(ctx context.Context, conn *TxConnection, dtid string) error {
	bindVars := map[string]interface{}{
		"dtid": sqltypes.MakeTrusted(sqltypes.VarBinary, []byte(dtid)),
	}
	_, err := tpc.exec(ctx, conn, tpc.deleteRedoTx, bindVars)
	if err != nil {
		return err
	}
	_, err = tpc.exec(ctx, conn, tpc.deleteRedoStmt, bindVars)
	return err
}
Beispiel #20
0
func TestTabletServerSplitQuery(t *testing.T) {
	db := setUpTabletServerTest()
	db.AddQuery("SELECT MIN(pk), MAX(pk) FROM test_table", &sqltypes.Result{
		Fields: []*querypb.Field{
			{Name: "pk", Type: sqltypes.Int32},
		},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("100")),
			},
		},
	})
	db.AddQuery("SELECT pk FROM test_table LIMIT 0", &sqltypes.Result{
		Fields: []*querypb.Field{
			{Name: "pk", Type: sqltypes.Int32},
		},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
			},
		},
	})
	testUtils := newTestUtils()
	config := testUtils.newQueryServiceConfig()
	tsv := NewTabletServer(config)
	dbconfigs := testUtils.newDBConfigs(db)
	target := querypb.Target{TabletType: topodatapb.TabletType_MASTER}
	err := tsv.StartService(target, dbconfigs, testUtils.newMysqld(&dbconfigs))
	if err != nil {
		t.Fatalf("StartService failed: %v", err)
	}
	defer tsv.StopService()
	ctx := context.Background()
	sql := "select * from test_table where count > :count"
	if _, err := tsv.SplitQuery(ctx, &target, sql, nil, "", 10); err != nil {
		t.Fatalf("TabletServer.SplitQuery should success: %v, but get error: %v", sql, err)
	}
}
Beispiel #21
0
func TestSequence(t *testing.T) {
	want := sqltypes.Result{
		Fields: []*querypb.Field{{
			Name: "nextval",
			Type: sqltypes.Int64,
		}},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{{
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("0")),
		}},
	}
	for wantval := int64(1); wantval < 10; wantval += 2 {
		want.Rows[0][0] = sqltypes.MakeTrusted(sqltypes.Int64, strconv.AppendInt(nil, wantval, 10))
		qr, err := framework.NewClient().Execute("select next value from vitess_seq", nil)
		if err != nil {
			t.Error(err)
			return
		}
		if !reflect.DeepEqual(*qr, want) {
			t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
		}
	}
	// Verify that the table got updated according to chunk size.
	want = sqltypes.Result{
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{{
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("13")),
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("3")),
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("2")),
		}},
	}
	qr, err := framework.NewClient().Execute("select next_id, cache, increment from vitess_seq", nil)
	if err != nil {
		t.Error(err)
		return
	}
	qr.Fields = nil
	if !reflect.DeepEqual(*qr, want) {
		t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
	}
}
Beispiel #22
0
func TestSQLValue(t *testing.T) {
	val := sqltypes.MakeTrusted(sqltypes.VarBinary, []byte("Test"))
	got, err := binVindex.(Unique).Map(nil, []interface{}{val})
	if err != nil {
		t.Error(err)
	}
	out := string(got[0])
	want := "\f\xbcf\x11\xf5T\vЀ\x9a8\x8d\xc9Za["
	if out != want {
		t.Errorf("Map(%#v): %#v, want %#v", val, out, want)
	}
}
Beispiel #23
0
func TestBatchRead(t *testing.T) {
	client := framework.NewClient()
	queries := []querytypes.BoundQuery{{
		Sql:           "select * from vitess_a where id = :a",
		BindVariables: map[string]interface{}{"a": 2},
	}, {
		Sql:           "select * from vitess_b where id = :b",
		BindVariables: map[string]interface{}{"b": 2},
	}}
	qr1 := sqltypes.Result{
		Fields: []*querypb.Field{{
			Name: "eid",
			Type: sqltypes.Int64,
		}, {
			Name: "id",
			Type: sqltypes.Int32,
		}, {
			Name: "name",
			Type: sqltypes.VarChar,
		}, {
			Name: "foo",
			Type: sqltypes.VarBinary,
		}},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{
				sqltypes.MakeTrusted(sqltypes.Int64, []byte("1")),
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("2")),
				sqltypes.MakeTrusted(sqltypes.VarChar, []byte("bcde")),
				sqltypes.MakeTrusted(sqltypes.VarBinary, []byte("fghi")),
			},
		},
	}
	qr2 := sqltypes.Result{
		Fields: []*querypb.Field{{
			Name: "eid",
			Type: sqltypes.Int64,
		}, {
			Name: "id",
			Type: sqltypes.Int32,
		}},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{
				sqltypes.MakeTrusted(sqltypes.Int64, []byte("1")),
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("2")),
			},
		},
	}
	want := []sqltypes.Result{qr1, qr2}

	qrl, err := client.ExecuteBatch(queries, false)
	if err != nil {
		t.Error(err)
		return
	}
	if !reflect.DeepEqual(qrl, want) {
		t.Errorf("ExecueBatch: \n%#v, want \n%#v", qrl, want)
	}
}
Beispiel #24
0
func TestQueryExecutorPlanPKIn(t *testing.T) {
	db := setUpQueryExecutorTest()
	query := "select * from test_table where pk in (1, 2, 3) limit 1000"
	expandedQuery := "select pk, name, addr from test_table where pk in (1, 2, 3)"
	want := &sqltypes.Result{
		Fields:       getTestTableFields(),
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("20")),
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("30")),
			},
		},
	}
	db.AddQuery(query, want)
	db.AddQuery(expandedQuery, want)
	db.AddQuery("select * from test_table where 1 != 1", &sqltypes.Result{
		Fields: getTestTableFields(),
	})
	ctx := context.Background()
	tsv := newTestTabletServer(ctx, enableRowCache|enableSchemaOverrides|enableStrict, db)
	qre := newTestQueryExecutor(ctx, tsv, query, 0)
	defer tsv.StopService()
	checkPlanID(t, planbuilder.PlanPKIn, qre.plan.PlanID)
	got, err := qre.Execute()
	if err != nil {
		t.Fatalf("qre.Execute() = %v, want nil", err)
	}
	if !reflect.DeepEqual(got, want) {
		t.Fatalf("got: %v, want: %v", got, want)
	}

	cachedQuery := "select pk, name, addr from test_table where pk in (1)"
	db.AddQuery(cachedQuery, &sqltypes.Result{
		Fields:       getTestTableFields(),
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("20")),
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("30")),
			},
		},
	})

	nonCachedQuery := "select pk, name, addr from test_table where pk in (2, 3)"
	db.AddQuery(nonCachedQuery, &sqltypes.Result{})
	db.AddQuery(cachedQuery, want)
	// run again, this time pk=1 should hit the rowcache
	got, err = qre.Execute()
	if err != nil {
		t.Fatalf("qre.Execute() = %v, want nil", err)
	}
	if !reflect.DeepEqual(got, want) {
		t.Fatalf("got: %v, want: %v", got, want)
	}
}
Beispiel #25
0
func TestVarJoinStream(t *testing.T) {
	router, sbc1, sbc2, _ := createRouterEnv()
	result1 := []*sqltypes.Result{{
		Fields: []*querypb.Field{
			{"id", sqltypes.Int32},
			{"col", sqltypes.Int32},
		},
		RowsAffected: 1,
		InsertID:     0,
		Rows: [][]sqltypes.Value{{
			sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
			sqltypes.MakeTrusted(sqltypes.Int32, []byte("3")),
		}},
	}}
	sbc1.setResults(result1)
	_, err := routerStream(router, "select u1.id, u2.id from user u1 join user u2 on u2.id = u1.col where u1.id = 1")
	if err != nil {
		t.Error(err)
	}
	wantQueries := []querytypes.BoundQuery{{
		Sql:           "select u1.id, u1.col from user as u1 where u1.id = 1",
		BindVariables: map[string]interface{}{},
	}}
	if !reflect.DeepEqual(sbc1.Queries, wantQueries) {
		t.Errorf("sbc1.Queries: %+v, want %+v\n", sbc1.Queries, wantQueries)
	}
	wantQueries = []querytypes.BoundQuery{{
		Sql:           "select u2.id from user as u2 where u2.id = :u1_col",
		BindVariables: map[string]interface{}{},
	}}
	// We have to use string representation because bindvars type is too complex.
	got := fmt.Sprintf("%+v", sbc2.Queries)
	want := "[{Sql:select u2.id from user as u2 where u2.id = :u1_col BindVariables:map[u1_col:3]}]"
	if got != want {
		t.Errorf("sbc2.Queries: %s, want %s\n", got, want)
	}
}
Beispiel #26
0
// SaveRedo saves the statements in the redo log using the supplied connection.
func (tpc *TwoPC) SaveRedo(ctx context.Context, conn *TxConnection, dtid string, queries []string) error {
	bindVars := map[string]interface{}{
		"dtid":         dtid,
		"time_created": int64(time.Now().UnixNano()),
	}
	_, err := tpc.exec(ctx, conn, tpc.insertRedoTx, bindVars)
	if err != nil {
		return err
	}

	rows := make([][]sqltypes.Value, len(queries))
	for i, query := range queries {
		rows[i] = []sqltypes.Value{
			sqltypes.MakeTrusted(sqltypes.VarBinary, []byte(dtid)),
			sqltypes.MakeTrusted(sqltypes.Int64, strconv.AppendInt(nil, int64(i+1), 10)),
			sqltypes.MakeTrusted(sqltypes.VarBinary, []byte(query)),
		}
	}
	bindVars = map[string]interface{}{
		"vals": rows,
	}
	_, err = tpc.exec(ctx, conn, tpc.insertRedoStmt, bindVars)
	return err
}
Beispiel #27
0
// TestUnorthodox is for testing syntactically invalid constructs
// that we use internally for efficient SQL generation.
func TestUnorthodox(t *testing.T) {
	query := "insert into `%s` values %a"
	bindVars := map[string]interface{}{
		"vals": [][]sqltypes.Value{{
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("1")),
			sqltypes.MakeString([]byte("foo('a')")),
		}, {
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("2")),
			sqltypes.MakeString([]byte("bar(`b`)")),
		}},
	}
	buf := NewTrackedBuffer(nil)
	buf.Myprintf(query, "t", ":vals")
	pq := buf.ParsedQuery()
	bytes, err := pq.GenerateQuery(bindVars)
	if err != nil {
		t.Error(err)
	}
	got := string(bytes)
	want := "insert into `t` values (1, 'foo(\\'a\\')'), (2, 'bar(`b`)')"
	if got != want {
		t.Errorf("GenerateQuery: %s, want %s", got, want)
	}
}
Beispiel #28
0
// AddColumn adds a column to the Table.
func (ta *Table) AddColumn(name string, columnType querypb.Type, defval sqltypes.Value, extra string) {
	index := len(ta.Columns)
	ta.Columns = append(ta.Columns, TableColumn{Name: strings.ToLower(name)})
	ta.Columns[index].Type = columnType
	if extra == "auto_increment" {
		ta.Columns[index].IsAuto = true
		// Ignore default value, if any
		return
	}
	if defval.IsNull() {
		return
	}
	// Schema values are trusted.
	ta.Columns[index].Default = sqltypes.MakeTrusted(ta.Columns[index].Type, defval.Raw())
}
Beispiel #29
0
func TestQueryExecutorPlanNextval(t *testing.T) {
	db := setUpQueryExecutorTest()
	selQuery := "select next_id, cache, increment from `seq` where id = 0 for update"
	db.AddQuery(selQuery, &sqltypes.Result{
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{{
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("1")),
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("3")),
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("2")),
		}},
	})
	updateQuery := "update `seq` set next_id = 7 where id = 0"
	db.AddQuery(updateQuery, &sqltypes.Result{})
	ctx := context.Background()
	tsv := newTestTabletServer(ctx, enableRowCache|enableStrict, db)
	defer tsv.StopService()
	qre := newTestQueryExecutor(ctx, tsv, "select next value from seq", 0)
	checkPlanID(t, planbuilder.PlanNextval, qre.plan.PlanID)
	got, err := qre.Execute()
	if err != nil {
		t.Fatalf("qre.Execute() = %v, want nil", err)
	}
	want := &sqltypes.Result{
		Fields: []*querypb.Field{{
			Name: "nextval",
			Type: sqltypes.Int64,
		}},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{{
			sqltypes.MakeTrusted(sqltypes.Int64, []byte("1")),
		}},
	}
	if !reflect.DeepEqual(got, want) {
		t.Fatalf("qre.Execute() =\n%#v, want:\n%#v", got, want)
	}
}
func TestCharaterSet(t *testing.T) {
	qr, err := framework.NewClient().Execute("select * from vitess_test where intval=1", nil)
	if err != nil {
		t.Error(err)
		return
	}
	want := sqltypes.Result{
		Fields: []*querypb.Field{
			{
				Name: "intval",
				Type: sqltypes.Int32,
			}, {
				Name: "floatval",
				Type: sqltypes.Float32,
			}, {
				Name: "charval",
				Type: sqltypes.VarChar,
			}, {
				Name: "binval",
				Type: sqltypes.VarBinary,
			},
		},
		RowsAffected: 1,
		Rows: [][]sqltypes.Value{
			{
				sqltypes.MakeTrusted(sqltypes.Int32, []byte("1")),
				sqltypes.MakeTrusted(sqltypes.Float32, []byte("1.12345")),
				sqltypes.MakeTrusted(sqltypes.VarChar, []byte("\xc2\xa2")),
				sqltypes.MakeTrusted(sqltypes.VarBinary, []byte("\x00\xff")),
			},
		},
	}
	if !reflect.DeepEqual(*qr, want) {
		t.Errorf("Execute: \n%#v, want \n%#v", *qr, want)
	}
}