func pgTypeForParserType(t parser.Type) pgType { size := -1 if s, variable := t.Size(); !variable { size = int(s) } return pgType{ oid: t.Oid(), size: size, } }
// SanitizeVarFreeExpr verifies a default expression is valid, has the // correct type and contains no variable expressions. func SanitizeVarFreeExpr(expr parser.Expr, expectedType parser.Type, context string) error { if parser.ContainsVars(expr) { return exprContainsVarsError(context, expr) } typedExpr, err := parser.TypeCheck(expr, nil, expectedType) if err != nil { return err } if defaultType := typedExpr.ResolvedType(); !expectedType.Equal(defaultType) { return incompatibleExprTypeError(context, expectedType, defaultType) } return nil }
// GenerateRandomArg generates a random, valid, SQL function argument of // the spcified type. func (r *RSG) GenerateRandomArg(typ parser.Type) string { if r.Intn(10) == 0 { return "NULL" } var v interface{} switch typ { case parser.TypeInt: i := r.Int63() i -= r.Int63() v = i case parser.TypeFloat, parser.TypeDecimal: v = r.Float64() case parser.TypeString: v = `'string'` case parser.TypeBytes: v = `b'bytes'` case parser.TypeTimestamp, parser.TypeTimestampTZ: t := time.Unix(0, r.Int63()) v = fmt.Sprintf(`'%s'`, t.Format(time.RFC3339Nano)) case parser.TypeBool: if r.Intn(2) == 0 { v = "false" } else { v = "true" } case parser.TypeDate: i := r.Int63() i -= r.Int63() d := parser.NewDDate(parser.DDate(i)) v = fmt.Sprintf(`'%s'`, d) case parser.TypeInterval: d := duration.Duration{Nanos: r.Int63()} v = fmt.Sprintf(`'%s'`, &parser.DInterval{Duration: d}) case parser.TypeIntArray, parser.TypeStringArray, parser.TypeAnyArray, parser.TypeAny: v = "NULL" default: switch typ.(type) { case parser.TTuple: v = "NULL" default: panic(fmt.Errorf("unknown arg type: %s (%T)", typ, typ)) } } return fmt.Sprintf("%v::%s", v, typ.String()) }
// CheckColumnType verifies that a given value is compatible // with the type requested by the column. If the value is a // placeholder, the type of the placeholder gets populated. func CheckColumnType(col ColumnDescriptor, typ parser.Type, pmap *parser.PlaceholderInfo) error { if typ == parser.TypeNull { return nil } var set parser.Type switch col.Type.Kind { case ColumnType_BOOL: set = parser.TypeBool case ColumnType_INT: set = parser.TypeInt case ColumnType_FLOAT: set = parser.TypeFloat case ColumnType_DECIMAL: set = parser.TypeDecimal case ColumnType_STRING: set = parser.TypeString case ColumnType_BYTES: set = parser.TypeBytes case ColumnType_DATE: set = parser.TypeDate case ColumnType_TIMESTAMP: set = parser.TypeTimestamp case ColumnType_TIMESTAMPTZ: set = parser.TypeTimestampTZ case ColumnType_INTERVAL: set = parser.TypeInterval default: return errors.Errorf("unsupported column type: %s", col.Type.Kind) } // If the value is a placeholder, then the column check above has // populated 'set' with a type to assign to it. if p, pok := typ.(parser.TPlaceholder); pok { if err := pmap.SetType(p.Name, set); err != nil { return fmt.Errorf("cannot infer type for placeholder %s from column %q: %s", p.Name, col.Name, err) } } else if !(typ.Equal(set) || (set == parser.TypeBytes && typ == parser.TypeString)) { // Not a placeholder; check that the value cast has succeeded. return fmt.Errorf("value type %s doesn't match type %s of column %q", typ, col.Type.Kind, col.Name) } return nil }
func typByVal(typ parser.Type) parser.Datum { _, variable := typ.Size() return parser.MakeDBool(parser.DBool(!variable)) }
func typLen(typ parser.Type) *parser.DInt { if sz, variable := typ.Size(); !variable { return parser.NewDInt(parser.DInt(sz)) } return negOneVal }