Beispiel #1
0
// AsInterface converts the ValExpr to an interface. It converts
// ValTuple to []interface{}, ValArg to string, StrVal to sqltypes.String,
// NumVal to sqltypes.Numeric. 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 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
	}
	return nil, fmt.Errorf("unexpected node %v", node)
}
Beispiel #2
0
// To do create business
func (d *AlterDDL) Do() (interface{}, error) {
	d.Mut.Lock()
	defer d.Mut.Unlock()

	result, curTable, err := d.alterOnAllShard("alterddl")
	if err != nil {
		return nil, err
	}

	// parse the sql.
	cols := sqlparser.ParseAlterPart(d.Sql, d.TableName)
	for colName, options := range cols {
		alterAction, _ := strconv.Atoi(options["action_id"])
		colExtra := ""
		if _, isOk := options["auto_increment"]; isOk {
			colExtra = "auto_increment"
		}

		switch alterAction {
		case sqlparser.ADD_ALTER:
			curTable.AddColumn(colName, options["type"], sqltypes.MakeString([]byte("")), colExtra)
		case sqlparser.DROP_ALTER:
			curTable.RemoveColumn(colName)
		case sqlparser.CHANGE_ALTER:
			curTable.ChangeColumn(colName, options)
		}
	}

	return result, nil
}
Beispiel #3
0
func TestStarParam(t *testing.T) {
	buf := NewTrackedBuffer(nil)
	buf.Myprintf("select * from a where id in (%a)", "*")
	pq := buf.ParsedQuery()
	listvars := []sqltypes.Value{
		sqltypes.MakeNumeric([]byte("1")),
		sqltypes.MakeString([]byte("aa")),
	}
	bytes, err := pq.GenerateQuery(nil, listvars)
	if err != nil {
		t.Errorf("generate failed: %v", err)
		return
	}
	got := string(bytes)
	want := "select * from a where id in (1, 'aa')"
	if got != want {
		t.Errorf("got %s, want %s", got, want)
	}
}
Beispiel #4
0
// to restore the table column to memery.
//
func (ta *MysqlTable) RestoreColumnsByDB() error {
	shardTabOrderId := 0
	db, err := ta.GetSlaveShardDBConn(shardTabOrderId)
	if err != nil {
		return err
	}

	shardTblN := ta.Shards[shardTabOrderId].Name
	// var rows *sql.Rows
	rows, err := db.Query(fmt.Sprintf("desc `%s`", shardTblN))
	if err != nil {
		return err
	}

	if rows != nil {
		for rows.Next() {
			var colName string
			var colType string
			var colNull string
			var colKey []byte
			var colDefault []byte
			var colExtra string

			err = rows.Scan(&colName, &colType, &colNull, &colKey, &colDefault, &colExtra)
			if err != nil {
				return err
			}

			// if colNull=="" || string(colKey)=="" {}
			ta.AddColumn(colName, colType, sqltypes.MakeString(colDefault), colExtra)
		}

		rows.Close()
	}

	return nil
}
Beispiel #5
0
func (ta *MysqlTable) AddColumn(name string, columnType string, defval sqltypes.Value, extra string) {
	index := len(ta.Columns)
	ta.Columns = append(ta.Columns, TableColumn{Name: name})
	if strings.Contains(columnType, "int") {
		ta.Columns[index].Category = CAT_NUMBER
	} else if strings.HasPrefix(columnType, "varbinary") {
		ta.Columns[index].Category = CAT_VARBINARY
	} else {
		ta.Columns[index].Category = CAT_OTHER
	}
	if extra == "auto_increment" {
		ta.Columns[index].IsAuto = true
		// Ignore default value, if any
		return
	}
	if defval.IsNull() {
		return
	}
	if ta.Columns[index].Category == CAT_NUMBER {
		ta.Columns[index].Default = sqltypes.MakeNumeric(defval.Raw())
	} else {
		ta.Columns[index].Default = sqltypes.MakeString(defval.Raw())
	}
}
Beispiel #6
0
func (node StrVal) Format(buf *TrackedBuffer) {
	s := sqltypes.MakeString([]byte(node))
	s.EncodeSql(buf)
}
Beispiel #7
0
func TestParsedQuery(t *testing.T) {
	tcases := []struct {
		desc     string
		query    string
		bindVars map[string]interface{}
		listVars []sqltypes.Value
		output   string
	}{
		{
			"no subs",
			"select * from a where id = 2",
			map[string]interface{}{
				"id": 1,
			},
			nil,
			"select * from a where id = 2",
		}, {
			"simple bindvar sub",
			"select * from a where id1 = :id1 and id2 = :id2",
			map[string]interface{}{
				"id1": 1,
				"id2": nil,
			},
			nil,
			"select * from a where id1 = 1 and id2 = null",
		}, {
			"missing bind var",
			"select * from a where id1 = :id1 and id2 = :id2",
			map[string]interface{}{
				"id1": 1,
			},
			nil,
			"missing bind var id2",
		}, {
			"unencodable bind var",
			"select * from a where id1 = :id",
			map[string]interface{}{
				"id": make([]int, 1),
			},
			nil,
			"unsupported bind variable type []int: [0]",
		}, {
			"list var sub",
			"select * from a where id = :0 and name = :1",
			nil,
			[]sqltypes.Value{
				sqltypes.MakeNumeric([]byte("1")),
				sqltypes.MakeString([]byte("aa")),
			},
			"select * from a where id = 1 and name = 'aa'",
		}, {
			"list inside bind vars",
			"select * from a where id in (:vals)",
			map[string]interface{}{
				"vals": []sqltypes.Value{
					sqltypes.MakeNumeric([]byte("1")),
					sqltypes.MakeString([]byte("aa")),
				},
			},
			nil,
			"select * from a where id in (1, 'aa')",
		}, {
			"two lists inside bind vars",
			"select * from a where id in (:vals)",
			map[string]interface{}{
				"vals": [][]sqltypes.Value{
					[]sqltypes.Value{
						sqltypes.MakeNumeric([]byte("1")),
						sqltypes.MakeString([]byte("aa")),
					},
					[]sqltypes.Value{
						sqltypes.Value{},
						sqltypes.MakeString([]byte("bb")),
					},
				},
			},
			nil,
			"select * from a where id in ((1, 'aa'), (null, 'bb'))",
		}, {
			"illega list var name",
			"select * from a where id = :0a",
			nil,
			[]sqltypes.Value{
				sqltypes.MakeNumeric([]byte("1")),
				sqltypes.MakeString([]byte("aa")),
			},
			`unexpected: strconv.ParseInt: parsing "0a": invalid syntax for 0a`,
		}, {
			"out of range list var index",
			"select * from a where id = :10",
			nil,
			[]sqltypes.Value{
				sqltypes.MakeNumeric([]byte("1")),
				sqltypes.MakeString([]byte("aa")),
			},
			"index out of range: 10",
		},
	}

	for _, tcase := range tcases {
		tree, err := Parse(tcase.query)
		if err != nil {
			t.Errorf("parse failed for %s: %v", tcase.desc, err)
			continue
		}
		buf := NewTrackedBuffer(nil)
		buf.Myprintf("%v", tree)
		pq := buf.ParsedQuery()
		bytes, err := pq.GenerateQuery(tcase.bindVars, tcase.listVars)
		var got string
		if err != nil {
			got = err.Error()
		} else {
			got = string(bytes)
		}
		if got != tcase.output {
			t.Errorf("for test case: %s, got: '%s', want '%s'", tcase.desc, got, tcase.output)
		}
	}
}