@@ -62,12 +62,14 @@ use databend_common_compress::CompressAlgorithm;
6262use databend_common_compress:: DecompressDecoder ;
6363use databend_common_exception:: ErrorCode ;
6464use databend_common_exception:: Result ;
65+ use databend_common_expression:: cast_scalar;
6566use databend_common_expression:: display:: display_tuple_field_name;
6667use databend_common_expression:: expr;
6768use databend_common_expression:: infer_schema_type;
6869use databend_common_expression:: shrink_scalar;
6970use databend_common_expression:: type_check;
7071use databend_common_expression:: type_check:: check_number;
72+ use databend_common_expression:: type_check:: common_super_type;
7173use databend_common_expression:: type_check:: convert_escape_pattern;
7274use databend_common_expression:: types:: decimal:: DecimalScalar ;
7375use databend_common_expression:: types:: decimal:: DecimalSize ;
@@ -81,6 +83,7 @@ use databend_common_expression::types::F32;
8183use databend_common_expression:: udf_client:: UDFFlightClient ;
8284use databend_common_expression:: BlockEntry ;
8385use databend_common_expression:: Column ;
86+ use databend_common_expression:: ColumnBuilder ;
8487use databend_common_expression:: ColumnIndex ;
8588use databend_common_expression:: Constant ;
8689use databend_common_expression:: ConstantFolder ;
@@ -3459,6 +3462,15 @@ impl<'a> TypeChecker<'a> {
34593462 // Omit unary + operator
34603463 self . resolve ( child)
34613464 }
3465+ UnaryOperator :: Minus => {
3466+ if let Expr :: Literal { value, .. } = child {
3467+ let box ( value, data_type) = self . resolve_minus_literal_scalar ( span, value) ?;
3468+ let scalar_expr = ScalarExpr :: ConstantExpr ( ConstantExpr { span, value } ) ;
3469+ return Ok ( Box :: new ( ( scalar_expr, data_type) ) ) ;
3470+ }
3471+ let name = op. to_func_name ( ) ;
3472+ self . resolve_function ( span, name. as_str ( ) , vec ! [ ] , & [ child] )
3473+ }
34623474 other => {
34633475 let name = other. to_func_name ( ) ;
34643476 self . resolve_function ( span, name. as_str ( ) , vec ! [ ] , & [ child] )
@@ -4871,18 +4883,121 @@ impl<'a> TypeChecker<'a> {
48714883 Ok ( Box :: new ( ( value, data_type) ) )
48724884 }
48734885
4874- // TODO(leiysky): use an array builder function instead, since we should allow declaring
4875- // an array with variable as element.
4886+ pub fn resolve_minus_literal_scalar (
4887+ & self ,
4888+ span : Span ,
4889+ literal : & databend_common_ast:: ast:: Literal ,
4890+ ) -> Result < Box < ( Scalar , DataType ) > > {
4891+ let value = match literal {
4892+ Literal :: UInt64 ( v) => {
4893+ if * v <= i64:: MAX as u64 {
4894+ Scalar :: Number ( NumberScalar :: Int64 ( -( * v as i64 ) ) )
4895+ } else {
4896+ Scalar :: Decimal ( DecimalScalar :: Decimal128 (
4897+ -( * v as i128 ) ,
4898+ DecimalSize :: new_unchecked ( i128:: MAX_PRECISION , 0 ) ,
4899+ ) )
4900+ }
4901+ }
4902+ Literal :: Decimal256 {
4903+ value,
4904+ precision,
4905+ scale,
4906+ } => Scalar :: Decimal ( DecimalScalar :: Decimal256 (
4907+ i256 ( * value) . checked_mul ( i256:: minus_one ( ) ) . unwrap ( ) ,
4908+ DecimalSize :: new_unchecked ( * precision, * scale) ,
4909+ ) ) ,
4910+ Literal :: Float64 ( v) => Scalar :: Number ( NumberScalar :: Float64 ( ( -* v) . into ( ) ) ) ,
4911+ Literal :: Null => Scalar :: Null ,
4912+ Literal :: String ( _) | Literal :: Boolean ( _) => {
4913+ return Err ( ErrorCode :: InvalidArgument ( format ! (
4914+ "Invalid minus operator for {}" ,
4915+ literal
4916+ ) )
4917+ . set_span ( span) ) ;
4918+ }
4919+ } ;
4920+ let value = shrink_scalar ( value) ;
4921+ let data_type = value. as_ref ( ) . infer_data_type ( ) ;
4922+ Ok ( Box :: new ( ( value, data_type) ) )
4923+ }
4924+
4925+ // Fast path for constant arrays so we don't need to go through the scalar `array()` function
4926+ // (which performs full type-checking and constant-folding). Non-constant elements still use
4927+ // the generic resolver to preserve the previous behaviour.
48764928 fn resolve_array ( & mut self , span : Span , exprs : & [ Expr ] ) -> Result < Box < ( ScalarExpr , DataType ) > > {
48774929 let mut elems = Vec :: with_capacity ( exprs. len ( ) ) ;
4930+ let mut constant_values: Option < Vec < ( Scalar , DataType ) > > =
4931+ Some ( Vec :: with_capacity ( exprs. len ( ) ) ) ;
4932+ let mut element_type: Option < DataType > = None ;
4933+
48784934 for expr in exprs {
4879- let box ( arg, _data_type) = self . resolve ( expr) ?;
4935+ let box ( arg, data_type) = self . resolve ( expr) ?;
4936+ if let Some ( values) = constant_values. as_mut ( ) {
4937+ let maybe_constant = match & arg {
4938+ ScalarExpr :: ConstantExpr ( constant) => Some ( constant. value . clone ( ) ) ,
4939+ ScalarExpr :: TypedConstantExpr ( constant, _) => Some ( constant. value . clone ( ) ) ,
4940+ _ => None ,
4941+ } ;
4942+ if let Some ( value) = maybe_constant {
4943+ element_type = if let Some ( current_ty) = element_type. clone ( ) {
4944+ common_super_type (
4945+ current_ty. clone ( ) ,
4946+ data_type. clone ( ) ,
4947+ & BUILTIN_FUNCTIONS . default_cast_rules ,
4948+ )
4949+ } else {
4950+ Some ( data_type. clone ( ) )
4951+ } ;
4952+
4953+ if element_type. is_some ( ) {
4954+ values. push ( ( value, data_type) ) ;
4955+ } else {
4956+ constant_values = None ;
4957+ element_type = None ;
4958+ }
4959+ } else {
4960+ constant_values = None ;
4961+ element_type = None ;
4962+ }
4963+ }
48804964 elems. push ( arg) ;
48814965 }
48824966
4967+ if let ( Some ( values) , Some ( element_ty) ) = ( constant_values, element_type) {
4968+ let mut casted = Vec :: with_capacity ( values. len ( ) ) ;
4969+ for ( value, ty) in values {
4970+ if ty == element_ty {
4971+ casted. push ( value) ;
4972+ } else {
4973+ casted. push ( cast_scalar ( span, value, & element_ty, & BUILTIN_FUNCTIONS ) ?) ;
4974+ }
4975+ }
4976+ return Ok ( Self :: build_constant_array ( span, element_ty, casted) ) ;
4977+ }
4978+
48834979 self . resolve_scalar_function_call ( span, "array" , vec ! [ ] , elems)
48844980 }
48854981
4982+ fn build_constant_array (
4983+ span : Span ,
4984+ element_ty : DataType ,
4985+ values : Vec < Scalar > ,
4986+ ) -> Box < ( ScalarExpr , DataType ) > {
4987+ let mut builder = ColumnBuilder :: with_capacity ( & element_ty, values. len ( ) ) ;
4988+ for value in & values {
4989+ builder. push ( value. as_ref ( ) ) ;
4990+ }
4991+ let scalar = Scalar :: Array ( builder. build ( ) ) ;
4992+ Box :: new ( (
4993+ ScalarExpr :: ConstantExpr ( ConstantExpr {
4994+ span,
4995+ value : scalar,
4996+ } ) ,
4997+ DataType :: Array ( Box :: new ( element_ty) ) ,
4998+ ) )
4999+ }
5000+
48865001 fn resolve_map (
48875002 & mut self ,
48885003 span : Span ,
0 commit comments