@@ -677,7 +677,18 @@ var _ sql.CollationCoercible = (*UnaryMinus)(nil)
677677
678678// NewUnaryMinus creates a new UnaryMinus expression node.
679679func NewUnaryMinus (child sql.Expression ) * UnaryMinus {
680- return & UnaryMinus {UnaryExpression {Child : child }, child .Type ()}
680+ typ := child .Type ()
681+ switch child .Type () {
682+ case types .Int8 , types .Int16 , types .Int32 :
683+ typ = types .Int64
684+ case types .Int64 :
685+ if lit , ok := child .(* Literal ); ok {
686+ if lit .Value ().(int64 ) == math .MinInt64 {
687+ typ = types .InternalDecimalType
688+ }
689+ }
690+ }
691+ return & UnaryMinus {UnaryExpression {Child : child }, typ }
681692}
682693
683694// Eval implements the sql.Expression interface.
@@ -706,26 +717,12 @@ func (e *UnaryMinus) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
706717 return - n , nil
707718 case float32 :
708719 return - n , nil
709- case int :
710- return - n , nil
711720 case int8 :
712- if n == math .MinInt8 {
713- e .typ = types .Int16 // For non-literals to update
714- return - int16 (n ), nil
715- }
716- return - n , nil
721+ return - int64 (n ), nil
717722 case int16 :
718- if n == math .MinInt16 {
719- e .typ = types .Int32
720- return - int32 (n ), nil
721- }
722- return - n , nil
723+ return - int64 (n ), nil
723724 case int32 :
724- if n == math .MinInt32 {
725- e .typ = types .Int64
726- return - int64 (n ), nil
727- }
728- return - n , nil
725+ return - int64 (n ), nil
729726 case int64 :
730727 if n == math .MinInt64 {
731728 if _ , ok := e .Child .(* Literal ); ok {
@@ -766,28 +763,6 @@ func (e *UnaryMinus) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
766763
767764// Type implements the sql.Expression interface.
768765func (e * UnaryMinus ) Type () sql.Type {
769- // Literals can overflow their types on unary minus, so we need to promote them
770- if lit , ok := e .Child .(* Literal ); ok {
771- switch n := lit .Value ().(type ) {
772- case int8 :
773- if n == math .MinInt8 {
774- e .typ = types .Int16
775- }
776- case int16 :
777- if n == math .MinInt16 {
778- e .typ = types .Int32
779- }
780- case int32 :
781- if n == math .MinInt32 {
782- e .typ = types .Int64
783- }
784- case int64 :
785- if n == math .MinInt64 {
786- e .typ = types .InternalDecimalType
787- }
788- }
789- }
790-
791766 if ! types .IsNumber (e .typ ) {
792767 return types .Float64
793768 }
0 commit comments