1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// Copyright Materialize, Inc. and contributors. All rights reserved.
//
// Use of this software is governed by the Business Source License
// included in the LICENSE file.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0.

use std::fmt;

use serde::{Deserialize, Serialize};

use lowertest::MzReflect;
use repr::adt::numeric::{self, Numeric};
use repr::adt::system::Oid;
use repr::{strconv, ColumnType, ScalarType};

use crate::scalar::func::EagerUnaryFunc;
use crate::EvalError;

sqlfunc!(
    #[sqlname = "-"]
    fn neg_int16(a: i16) -> i16 {
        -a
    }
);

sqlfunc!(
    #[sqlname = "~"]
    fn bit_not_int16(a: i16) -> i16 {
        !a
    }
);

sqlfunc!(
    #[sqlname = "abs"]
    fn abs_int16(a: i16) -> i16 {
        a.abs()
    }
);

sqlfunc!(
    #[sqlname = "i16tof32"]
    #[preserves_uniqueness = true]
    fn cast_int16_to_float32(a: i16) -> f32 {
        f32::from(a)
    }
);

sqlfunc!(
    #[sqlname = "i16tof64"]
    #[preserves_uniqueness = true]
    fn cast_int16_to_float64(a: i16) -> f64 {
        f64::from(a)
    }
);

sqlfunc!(
    #[sqlname = "i16toi32"]
    #[preserves_uniqueness = true]
    fn cast_int16_to_int32(a: i16) -> i32 {
        i32::from(a)
    }
);

sqlfunc!(
    #[sqlname = "i16toi64"]
    #[preserves_uniqueness = true]
    fn cast_int16_to_int64(a: i16) -> i64 {
        i64::from(a)
    }
);

sqlfunc!(
    #[sqlname = "i16tooid"]
    #[preserves_uniqueness = true]
    fn cast_int16_to_oid(a: i16) -> Oid {
        Oid(i32::from(a))
    }
);

sqlfunc!(
    #[sqlname = "i16tostr"]
    #[preserves_uniqueness = true]
    fn cast_int16_to_string(a: i16) -> String {
        let mut buf = String::new();
        strconv::format_int16(&mut buf, a);
        buf
    }
);

#[derive(Ord, PartialOrd, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash, MzReflect)]
pub struct CastInt16ToNumeric(pub Option<u8>);

impl<'a> EagerUnaryFunc<'a> for CastInt16ToNumeric {
    type Input = i16;
    type Output = Result<Numeric, EvalError>;

    fn call(&self, a: i16) -> Result<Numeric, EvalError> {
        let mut a = Numeric::from(i32::from(a));
        if let Some(scale) = self.0 {
            if numeric::rescale(&mut a, scale).is_err() {
                return Err(EvalError::NumericFieldOverflow);
            }
        }
        Ok(a)
    }

    fn output_type(&self, input: ColumnType) -> ColumnType {
        ScalarType::Numeric { scale: self.0 }.nullable(input.nullable)
    }
}

impl fmt::Display for CastInt16ToNumeric {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("i16tonumeric")
    }
}