Beispiel #1
0
// Convert takes a type and a value, and returns the type:
// - nil for NULL value
// - int64 for integer number types that fit in 64 bits
//   (signed or unsigned are all converted to signed)
// - float64 for floating point values that fit in a float
// - []byte for everything else
func Convert(mysqlType int64, val sqltypes.Value) (interface{}, error) {
	if val.IsNull() {
		return nil, nil
	}

	switch mysqlType {
	case VT_TINY, VT_SHORT, VT_LONG, VT_LONGLONG, VT_INT24:
		return strconv.ParseInt(val.String(), 0, 64)
	case VT_FLOAT, VT_DOUBLE:
		return strconv.ParseFloat(val.String(), 64)
	}
	return val.Raw(), nil
}
Beispiel #2
0
func (si *SchemaInfo) updateLastChange(createTime sqltypes.Value) {
	if createTime.IsNull() {
		return
	}
	t, err := strconv.ParseInt(createTime.String(), 10, 64)
	if err != nil {
		relog.Warning("Could not parse time %s: %v", createTime.String(), err)
		return
	}
	if si.lastChange.Unix() < t {
		si.lastChange = time.Unix(t, 0)
	}
}
Beispiel #3
0
func validateValue(col *schema.TableColumn, value sqltypes.Value) error {
	if value.IsNull() {
		return nil
	}
	if sqltypes.IsIntegral(col.Type) {
		if !value.IsNumeric() {
			return NewTabletError(ErrFail, vtrpc.ErrorCode_BAD_INPUT, "type mismatch, expecting numeric type for %v for column: %v", value, col)
		}
	} else if col.Type == sqltypes.VarBinary {
		if !value.IsString() {
			return NewTabletError(ErrFail, vtrpc.ErrorCode_BAD_INPUT, "type mismatch, expecting string type for %v for column: %v", value, col)
		}
	}
	return nil
}
Beispiel #4
0
func validateValue(col *schema.TableColumn, value sqltypes.Value) {
	if value.IsNull() {
		return
	}
	switch col.Category {
	case schema.CAT_NUMBER:
		if !value.IsNumeric() {
			panic(NewTabletError(FAIL, "Type mismatch, expecting numeric type for %v", value))
		}
	case schema.CAT_VARBINARY:
		if !value.IsString() {
			panic(NewTabletError(FAIL, "Type mismatch, expecting string type for %v", value))
		}
	}
}
Beispiel #5
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 #6
0
func validateValue(col *schema.TableColumn, value sqltypes.Value) error {
	if value.IsNull() {
		return nil
	}
	switch col.Category {
	case schema.CAT_NUMBER:
		if !value.IsNumeric() {
			return NewTabletError(ErrFail, "type mismatch, expecting numeric type for %v for column: %v", value, col)
		}
	case schema.CAT_VARBINARY:
		if !value.IsString() {
			return NewTabletError(ErrFail, "type mismatch, expecting string type for %v for column: %v", value, col)
		}
	}
	return nil
}
Beispiel #7
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: 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
	}
	if sqltypes.IsIntegral(ta.Columns[index].Type) {
		ta.Columns[index].Default = sqltypes.MakeNumeric(defval.Raw())
	} else {
		ta.Columns[index].Default = sqltypes.MakeString(defval.Raw())
	}
}
Beispiel #8
0
// getWhereClause returns a whereClause based on desired upper and lower
// bounds for primary key.
func (qs *QuerySplitter) getWhereClause(whereClause *sqlparser.Where, bindVars map[string]interface{}, start, end sqltypes.Value) *sqlparser.Where {
	var startClause *sqlparser.ComparisonExpr
	var endClause *sqlparser.ComparisonExpr
	var clauses sqlparser.BoolExpr
	// No upper or lower bound, just return the where clause of original query
	if start.IsNull() && end.IsNull() {
		return whereClause
	}
	pk := &sqlparser.ColName{
		Name: sqlparser.SQLName(qs.splitColumn),
	}
	if !start.IsNull() {
		startClause = &sqlparser.ComparisonExpr{
			Operator: sqlparser.GreaterEqualStr,
			Left:     pk,
			Right:    sqlparser.ValArg([]byte(":" + startBindVarName)),
		}
		bindVars[startBindVarName] = start.ToNative()
	}
	// splitColumn < end
	if !end.IsNull() {
		endClause = &sqlparser.ComparisonExpr{
			Operator: sqlparser.LessThanStr,
			Left:     pk,
			Right:    sqlparser.ValArg([]byte(":" + endBindVarName)),
		}
		bindVars[endBindVarName] = end.ToNative()
	}
	if startClause == nil {
		clauses = endClause
	} else {
		if endClause == nil {
			clauses = startClause
		} else {
			// splitColumn >= start AND splitColumn < end
			clauses = &sqlparser.AndExpr{
				Left:  startClause,
				Right: endClause,
			}
		}
	}
	if whereClause != nil {
		clauses = &sqlparser.AndExpr{
			Left:  &sqlparser.ParenBoolExpr{Expr: whereClause.Expr},
			Right: &sqlparser.ParenBoolExpr{Expr: clauses},
		}
	}
	return &sqlparser.Where{
		Type: sqlparser.WhereStr,
		Expr: clauses,
	}
}
Beispiel #9
0
// getWhereClause returns a whereClause based on desired upper and lower
// bounds for primary key.
func (qs *QuerySplitter) getWhereClause(start, end sqltypes.Value) *sqlparser.Where {
	var startClause *sqlparser.ComparisonExpr
	var endClause *sqlparser.ComparisonExpr
	var clauses sqlparser.BoolExpr
	// No upper or lower bound, just return the where clause of original query
	if start.IsNull() && end.IsNull() {
		return qs.sel.Where
	}
	pk := &sqlparser.ColName{
		Name: []byte(qs.splitColumn),
	}
	// splitColumn >= start
	if !start.IsNull() {
		startClause = &sqlparser.ComparisonExpr{
			Operator: sqlparser.AST_GE,
			Left:     pk,
			Right:    sqlparser.NumVal((start).Raw()),
		}
	}
	// splitColumn < end
	if !end.IsNull() {
		endClause = &sqlparser.ComparisonExpr{
			Operator: sqlparser.AST_LT,
			Left:     pk,
			Right:    sqlparser.NumVal((end).Raw()),
		}
	}
	if startClause == nil {
		clauses = endClause
	} else {
		if endClause == nil {
			clauses = startClause
		} else {
			// splitColumn >= start AND splitColumn < end
			clauses = &sqlparser.AndExpr{
				Left:  startClause,
				Right: endClause,
			}
		}
	}
	if qs.sel.Where != nil {
		clauses = &sqlparser.AndExpr{
			Left:  qs.sel.Where.Expr,
			Right: clauses,
		}
	}
	return &sqlparser.Where{
		Type: sqlparser.AST_WHERE,
		Expr: clauses,
	}
}
Beispiel #10
0
func (ti *TableInfo) computePrefix(conn PoolConnection, createTime sqltypes.Value, hashRegistry map[string]string) string {
	if createTime.IsNull() {
		relog.Warning("%s has no time stamp. Will not be cached.", ti.Name)
		return ""
	}
	createTable, err := conn.ExecuteFetch(fmt.Sprintf("show create table %s", ti.Name), 10000, false)
	if err != nil {
		relog.Warning("Couldnt read table info: %v", err)
		return ""
	}
	// Normalize & remove auto_increment because it changes on every insert
	norm1 := strings.ToLower(createTable.Rows[0][1].String())
	norm2 := autoIncr.ReplaceAllLiteralString(norm1, "")
	thash := base64fnv(norm2 + createTime.String())
	if _, ok := hashRegistry[thash]; ok {
		relog.Warning("Hash collision for %s (schema revert?). Will not be cached", ti.Name)
		return ""
	}
	hashRegistry[thash] = ti.Name
	return thash
}
Beispiel #11
0
// Convert takes a type and a value, and returns the type:
// - nil for NULL value
// - uint64 for unsigned BIGINT values
// - int64 for all other integer values (signed and unsigned)
// - float64 for floating point values that fit in a float
// - []byte for everything else
func Convert(field Field, val sqltypes.Value) (interface{}, error) {
	if val.IsNull() {
		return nil, nil
	}

	switch field.Type {
	case VT_LONGLONG:
		if field.Flags&VT_UNSIGNED_FLAG == VT_UNSIGNED_FLAG {
			return strconv.ParseUint(val.String(), 0, 64)
		}
		return strconv.ParseInt(val.String(), 0, 64)
	case VT_TINY, VT_SHORT, VT_LONG, VT_INT24:
		// Regardless of whether UNSIGNED_FLAG is set in field.Flags, we map all
		// signed and unsigned values to a signed Go type because
		// - Go doesn't officially support uint64 in their SQL interface
		// - there is no loss of the value
		// The only exception we make are for unsigned BIGINTs, see VT_LONGLONG above.
		return strconv.ParseInt(val.String(), 0, 64)
	case VT_FLOAT, VT_DOUBLE:
		return strconv.ParseFloat(val.String(), 64)
	}
	return val.Raw(), nil
}
Beispiel #12
0
func (ta *Table) 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 #13
0
// getWhereClause returns a whereClause based on desired upper and lower
// bounds for primary key.
func (qs *QuerySplitter) getWhereClause(whereClause *sqlparser.Where, bindVars map[string]interface{}, start, end sqltypes.Value) *sqlparser.Where {
	var startClause *sqlparser.ComparisonExpr
	var endClause *sqlparser.ComparisonExpr
	var clauses sqlparser.BoolExpr
	// No upper or lower bound, just return the where clause of original query
	if start.IsNull() && end.IsNull() {
		return whereClause
	}
	pk := &sqlparser.ColName{
		Name: sqlparser.SQLName(qs.splitColumn),
	}
	if !start.IsNull() {
		startClause = &sqlparser.ComparisonExpr{
			Operator: sqlparser.AST_GE,
			Left:     pk,
			Right:    sqlparser.ValArg([]byte(":" + startBindVarName)),
		}
		if start.IsNumeric() {
			v, _ := start.ParseInt64()
			bindVars[startBindVarName] = v
		} else if start.IsString() {
			bindVars[startBindVarName] = start.Raw()
		} else if start.IsFractional() {
			v, _ := start.ParseFloat64()
			bindVars[startBindVarName] = v
		}
	}
	// splitColumn < end
	if !end.IsNull() {
		endClause = &sqlparser.ComparisonExpr{
			Operator: sqlparser.AST_LT,
			Left:     pk,
			Right:    sqlparser.ValArg([]byte(":" + endBindVarName)),
		}
		if end.IsNumeric() {
			v, _ := end.ParseInt64()
			bindVars[endBindVarName] = v
		} else if end.IsString() {
			bindVars[endBindVarName] = end.Raw()
		} else if end.IsFractional() {
			v, _ := end.ParseFloat64()
			bindVars[endBindVarName] = v
		}
	}
	if startClause == nil {
		clauses = endClause
	} else {
		if endClause == nil {
			clauses = startClause
		} else {
			// splitColumn >= start AND splitColumn < end
			clauses = &sqlparser.AndExpr{
				Left:  startClause,
				Right: endClause,
			}
		}
	}
	if whereClause != nil {
		clauses = &sqlparser.AndExpr{
			Left:  &sqlparser.ParenBoolExpr{Expr: whereClause.Expr},
			Right: &sqlparser.ParenBoolExpr{Expr: clauses},
		}
	}
	return &sqlparser.Where{
		Type: sqlparser.AST_WHERE,
		Expr: clauses,
	}
}