func makeDefaultExprs( cols []sqlbase.ColumnDescriptor, parse *parser.Parser, evalCtx *parser.EvalContext, ) ([]parser.TypedExpr, error) { // Check to see if any of the columns have DEFAULT expressions. If there // are no DEFAULT expressions, we don't bother with constructing the // defaults map as the defaults are all NULL. haveDefaults := false for _, col := range cols { if col.DefaultExpr != nil { haveDefaults = true break } } if !haveDefaults { return nil, nil } // Build the default expressions map from the parsed SELECT statement. defaultExprs := make([]parser.TypedExpr, 0, len(cols)) exprStrings := make([]string, 0, len(cols)) for _, col := range cols { if col.DefaultExpr != nil { exprStrings = append(exprStrings, *col.DefaultExpr) } } exprs, err := parser.ParseExprsTraditional(exprStrings) if err != nil { return nil, err } defExprIdx := 0 for _, col := range cols { if col.DefaultExpr == nil { defaultExprs = append(defaultExprs, parser.DNull) continue } expr := exprs[defExprIdx] typedExpr, err := parser.TypeCheck(expr, nil, col.Type.ToDatumType()) if err != nil { return nil, err } if typedExpr, err = parse.NormalizeExpr(evalCtx, typedExpr); err != nil { return nil, err } defaultExprs = append(defaultExprs, typedExpr) defExprIdx++ } return defaultExprs, nil }
func makeDefaultExprs( cols []ColumnDescriptor, parse *parser.Parser, evalCtx parser.EvalContext, ) ([]parser.Expr, error) { // Check to see if any of the columns have DEFAULT expressions. If there // are no DEFAULT expressions, we don't bother with constructing the // defaults map as the defaults are all NULL. haveDefaults := false for _, col := range cols { if col.DefaultExpr != nil { haveDefaults = true break } } if !haveDefaults { return nil, nil } // Build the default expressions map from the parsed SELECT statement. defaultExprs := make([]parser.Expr, 0, len(cols)) for _, col := range cols { if col.DefaultExpr == nil { defaultExprs = append(defaultExprs, parser.DNull) continue } expr, err := parser.ParseExprTraditional(*col.DefaultExpr) if err != nil { return nil, err } expr, err = parse.NormalizeExpr(evalCtx, expr) if err != nil { return nil, err } if parser.ContainsVars(expr) { return nil, util.Errorf("default expression contains variables") } defaultExprs = append(defaultExprs, expr) } return defaultExprs, nil }
// MakeColumnDefDescs creates the column descriptor for a column, as well as the // index descriptor if the column is a primary key or unique. func MakeColumnDefDescs(d *parser.ColumnTableDef) (*ColumnDescriptor, *IndexDescriptor, error) { col := &ColumnDescriptor{ Name: string(d.Name), Nullable: d.Nullable.Nullability != parser.NotNull && !d.PrimaryKey, } if d.Nullable.ConstraintName != "" { col.NullableConstraintName = string(d.Nullable.ConstraintName) } var colDatumType parser.Datum switch t := d.Type.(type) { case *parser.BoolColType: col.Type.Kind = ColumnType_BOOL colDatumType = parser.TypeBool case *parser.IntColType: col.Type.Kind = ColumnType_INT col.Type.Width = int32(t.N) colDatumType = parser.TypeInt if t.IsSerial() { if d.DefaultExpr.Expr != nil { return nil, nil, fmt.Errorf("SERIAL column %q cannot have a default value", col.Name) } s := "unique_rowid()" col.DefaultExpr = &s } case *parser.FloatColType: col.Type.Kind = ColumnType_FLOAT col.Type.Precision = int32(t.Prec) colDatumType = parser.TypeFloat case *parser.DecimalColType: col.Type.Kind = ColumnType_DECIMAL col.Type.Width = int32(t.Scale) col.Type.Precision = int32(t.Prec) colDatumType = parser.TypeDecimal case *parser.DateColType: col.Type.Kind = ColumnType_DATE colDatumType = parser.TypeDate case *parser.TimestampColType: col.Type.Kind = ColumnType_TIMESTAMP colDatumType = parser.TypeTimestamp case *parser.TimestampTZColType: col.Type.Kind = ColumnType_TIMESTAMPTZ colDatumType = parser.TypeTimestampTZ case *parser.IntervalColType: col.Type.Kind = ColumnType_INTERVAL colDatumType = parser.TypeInterval case *parser.StringColType: col.Type.Kind = ColumnType_STRING col.Type.Width = int32(t.N) colDatumType = parser.TypeString case *parser.BytesColType: col.Type.Kind = ColumnType_BYTES colDatumType = parser.TypeBytes default: return nil, nil, errors.Errorf("unexpected type %T", t) } if col.Type.Kind == ColumnType_DECIMAL { switch { case col.Type.Precision == 0 && col.Type.Width > 0: // TODO (seif): Find right range for error message. return nil, nil, errors.New("invalid NUMERIC precision 0") case col.Type.Precision < col.Type.Width: return nil, nil, fmt.Errorf("NUMERIC scale %d must be between 0 and precision %d", col.Type.Width, col.Type.Precision) } } if d.DefaultExpr.Expr != nil { // Verify the default expression type is compatible with the column type. if err := SanitizeVarFreeExpr(d.DefaultExpr.Expr, colDatumType, "DEFAULT"); err != nil { return nil, nil, err } var p parser.Parser if p.AggregateInExpr(d.DefaultExpr.Expr) { return nil, nil, fmt.Errorf("Aggregate functions are not allowed in DEFAULT expressions") } if d.DefaultExpr.ConstraintName != "" { col.DefaultExprConstraintName = string(d.DefaultExpr.ConstraintName) } s := d.DefaultExpr.Expr.String() col.DefaultExpr = &s } var idx *IndexDescriptor if d.PrimaryKey || d.Unique { idx = &IndexDescriptor{ Unique: true, ColumnNames: []string{string(d.Name)}, ColumnDirections: []IndexDescriptor_Direction{IndexDescriptor_ASC}, } if d.UniqueConstraintName != "" { idx.Name = string(d.UniqueConstraintName) } } return col, idx, nil }