diff --git a/be/src/vec/functions/math.cpp b/be/src/vec/functions/math.cpp index e37b618525cb26..e779af741d0acd 100644 --- a/be/src/vec/functions/math.cpp +++ b/be/src/vec/functions/math.cpp @@ -371,6 +371,30 @@ struct TanhName { }; using FunctionTanh = FunctionMathUnary>; +struct CotName { + static constexpr auto name = "cot"; +}; +double cot(double x) { + return 1.0 / std::tan(x); +} +using FunctionCot = FunctionMathUnary>; + +struct SecName { + static constexpr auto name = "sec"; +}; +double sec(double x) { + return 1.0 / std::cos(x); +} +using FunctionSec = FunctionMathUnary>; + +struct CosecName { + static constexpr auto name = "cosec"; +}; +double cosec(double x) { + return 1.0 / std::sin(x); +} +using FunctionCosec = FunctionMathUnary>; + template struct RadiansImpl { static constexpr PrimitiveType ResultType = ResultOfUnaryFunc::ResultType; @@ -559,6 +583,9 @@ void register_function_math(SimpleFunctionFactory& factory) { factory.register_function(); factory.register_function(); factory.register_function(); + factory.register_function(); + factory.register_function(); + factory.register_function(); factory.register_function(); factory.register_alias("pow", "power"); factory.register_alias("pow", "dpow"); diff --git a/be/test/vec/function/function_math_test.cpp b/be/test/vec/function/function_math_test.cpp index 0e7fb5088cda4b..01c3ca111513e9 100644 --- a/be/test/vec/function/function_math_test.cpp +++ b/be/test/vec/function/function_math_test.cpp @@ -181,6 +181,37 @@ TEST(MathFunctionTest, cbrt_test) { static_cast(check_function(func_name, input_types, data_set)); } +TEST(MathFunctionTest, cot_test) { + std::string func_name = "cot"; + + InputTypeSet input_types = {PrimitiveType::TYPE_DOUBLE}; + + DataSet data_set = {{{1.0}, 0.6420926159343306}, {{M_PI / 4}, 1.0000000000000002}}; + + static_cast(check_function(func_name, input_types, data_set)); +} + +TEST(MathFunctionTest, sec_test) { + std::string func_name = "sec"; + + InputTypeSet input_types = {PrimitiveType::TYPE_DOUBLE}; + + DataSet data_set = {{{1.0}, 1.8508157176809255}, {{1000.0}, 1.7781600385912715}}; + + static_cast(check_function(func_name, input_types, data_set)); +} + +TEST(MathFunctionTest, cosec_test) { + std::string func_name = "cosec"; + + InputTypeSet input_types = {PrimitiveType::TYPE_DOUBLE}; + + DataSet data_set = { + {{1.0}, 1.1883951057781212}, {{2.0}, 1.0997501702946164}, {{1000.0}, 1.20936599707935}}; + + static_cast(check_function(func_name, input_types, data_set)); +} + TEST(MathFunctionTest, tan_test) { std::string func_name = "tan"; //tan(x) diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java index c00c2633d4067c..1eb2c79eb223c5 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java @@ -130,8 +130,10 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.ConvertTo; import org.apache.doris.nereids.trees.expressions.functions.scalar.ConvertTz; import org.apache.doris.nereids.trees.expressions.functions.scalar.Cos; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Cosec; import org.apache.doris.nereids.trees.expressions.functions.scalar.Cosh; import org.apache.doris.nereids.trees.expressions.functions.scalar.CosineDistance; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Cot; import org.apache.doris.nereids.trees.expressions.functions.scalar.CountEqual; import org.apache.doris.nereids.trees.expressions.functions.scalar.CountSubstring; import org.apache.doris.nereids.trees.expressions.functions.scalar.Crc32; @@ -377,6 +379,7 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.Rpad; import org.apache.doris.nereids.trees.expressions.functions.scalar.Rtrim; import org.apache.doris.nereids.trees.expressions.functions.scalar.RtrimIn; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Sec; import org.apache.doris.nereids.trees.expressions.functions.scalar.SecToTime; import org.apache.doris.nereids.trees.expressions.functions.scalar.Second; import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondCeil; @@ -622,7 +625,9 @@ public class BuiltinScalarFunctions implements FunctionHelper { scalar(ConvertTo.class, "convert_to"), scalar(ConvertTz.class, "convert_tz"), scalar(Cos.class, "cos"), + scalar(Cosec.class, "cosec"), scalar(Cosh.class, "cosh"), + scalar(Cot.class, "cot"), scalar(CosineDistance.class, "cosine_distance"), scalar(CountEqual.class, "countequal"), scalar(CountSubstring.class, "count_substrings"), @@ -883,6 +888,7 @@ public class BuiltinScalarFunctions implements FunctionHelper { scalar(Rpad.class, "rpad"), scalar(Rtrim.class, "rtrim"), scalar(RtrimIn.class, "rtrim_in"), + scalar(Sec.class, "sec"), scalar(Second.class, "second"), scalar(SecondCeil.class, "second_ceil"), scalar(SecondFloor.class, "second_floor"), diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java index 6ed49684fd9f3e..c05e49d83d63d1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/executable/NumericArithmetic.java @@ -928,6 +928,39 @@ public static Expression tan(DoubleLiteral first) { return checkOutputBoundary(new DoubleLiteral(Math.tan(first.getValue()))); } + /** + * cot + */ + @ExecFunction(name = "cot") + public static Expression cot(DoubleLiteral first) { + if (inputOutOfBound(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false)) { + return new NullLiteral(DoubleType.INSTANCE); + } + return checkOutputBoundary(new DoubleLiteral(1.0 / Math.tan(first.getValue()))); + } + + /** + * cot + */ + @ExecFunction(name = "sec") + public static Expression sec(DoubleLiteral first) { + if (inputOutOfBound(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false)) { + return new NullLiteral(DoubleType.INSTANCE); + } + return checkOutputBoundary(new DoubleLiteral(1.0 / Math.cos(first.getValue()))); + } + + /** + * cosec + */ + @ExecFunction(name = "cosec") + public static Expression cosec(DoubleLiteral first) { + if (inputOutOfBound(first, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, false, false)) { + return new NullLiteral(DoubleType.INSTANCE); + } + return checkOutputBoundary(new DoubleLiteral(1.0 / Math.sin(first.getValue()))); + } + /** * asin */ diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Cosec.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Cosec.java new file mode 100644 index 00000000000000..26919889a3a02f --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Cosec.java @@ -0,0 +1,68 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.trees.expressions.functions.scalar; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable; +import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.DoubleType; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/**S + * ScalarFunction 'cosec'. This class is generated by GenerateFunction. + */ +public class Cosec extends ScalarFunction + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullable { + + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE) + ); + + /** + * constructor with 1 argument. + */ + public Cosec(Expression arg) { + super("cosec", arg); + } + + /** + * withChildren. + */ + @Override + public Cosec withChildren(List children) { + Preconditions.checkArgument(children.size() == 1); + return new Cosec(children.get(0)); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitCosec(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Cot.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Cot.java new file mode 100644 index 00000000000000..842b035b6dfa87 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Cot.java @@ -0,0 +1,68 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.trees.expressions.functions.scalar; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable; +import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.DoubleType; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/** + * ScalarFunction 'cot'. This class is generated by GenerateFunction. + */ +public class Cot extends ScalarFunction + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullable { + + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE) + ); + + /** + * constructor with 1 argument. + */ + public Cot(Expression arg) { + super("cot", arg); + } + + /** + * withChildren. + */ + @Override + public Cot withChildren(List children) { + Preconditions.checkArgument(children.size() == 1); + return new Cot(children.get(0)); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitCot(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Sec.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Sec.java new file mode 100644 index 00000000000000..dc6a188cd77116 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Sec.java @@ -0,0 +1,68 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package org.apache.doris.nereids.trees.expressions.functions.scalar; + +import org.apache.doris.catalog.FunctionSignature; +import org.apache.doris.nereids.trees.expressions.Expression; +import org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature; +import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable; +import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression; +import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor; +import org.apache.doris.nereids.types.DoubleType; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableList; + +import java.util.List; + +/**S + * ScalarFunction 'sec'. This class is generated by GenerateFunction. + */ +public class Sec extends ScalarFunction + implements UnaryExpression, ExplicitlyCastableSignature, PropagateNullable { + + public static final List SIGNATURES = ImmutableList.of( + FunctionSignature.ret(DoubleType.INSTANCE).args(DoubleType.INSTANCE) + ); + + /** + * constructor with 1 argument. + */ + public Sec(Expression arg) { + super("sec", arg); + } + + /** + * withChildren. + */ + @Override + public Sec withChildren(List children) { + Preconditions.checkArgument(children.size() == 1); + return new Sec(children.get(0)); + } + + @Override + public List getSignatures() { + return SIGNATURES; + } + + @Override + public R accept(ExpressionVisitor visitor, C context) { + return visitor.visitSec(this, context); + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java index fc7fa60ccc1bf4..7dec94ed2edee9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java @@ -138,8 +138,10 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.ConvertTo; import org.apache.doris.nereids.trees.expressions.functions.scalar.ConvertTz; import org.apache.doris.nereids.trees.expressions.functions.scalar.Cos; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Cosec; import org.apache.doris.nereids.trees.expressions.functions.scalar.Cosh; import org.apache.doris.nereids.trees.expressions.functions.scalar.CosineDistance; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Cot; import org.apache.doris.nereids.trees.expressions.functions.scalar.CountEqual; import org.apache.doris.nereids.trees.expressions.functions.scalar.CountSubstring; import org.apache.doris.nereids.trees.expressions.functions.scalar.Crc32; @@ -378,6 +380,7 @@ import org.apache.doris.nereids.trees.expressions.functions.scalar.Rtrim; import org.apache.doris.nereids.trees.expressions.functions.scalar.RtrimIn; import org.apache.doris.nereids.trees.expressions.functions.scalar.ScalarFunction; +import org.apache.doris.nereids.trees.expressions.functions.scalar.Sec; import org.apache.doris.nereids.trees.expressions.functions.scalar.Second; import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondCeil; import org.apache.doris.nereids.trees.expressions.functions.scalar.SecondFloor; @@ -2146,6 +2149,18 @@ default R visitTanh(Tanh tanh, C context) { return visitScalarFunction(tanh, context); } + default R visitCot(Cot cot, C context) { + return visitScalarFunction(cot, context); + } + + default R visitSec(Sec sec, C context) { + return visitScalarFunction(sec, context); + } + + default R visitCosec(Cosec cosec, C context) { + return visitScalarFunction(cosec, context); + } + default R visitTime(Time time, C context) { return visitScalarFunction(time, context); } diff --git a/regression-test/data/query_p0/sql_functions/math_functions/test_triangle.out b/regression-test/data/query_p0/sql_functions/math_functions/test_triangle.out new file mode 100644 index 00000000000000..7fa4c9b3be9dd8 --- /dev/null +++ b/regression-test/data/query_p0/sql_functions/math_functions/test_triangle.out @@ -0,0 +1,58 @@ +-- This file is automatically generated. You should know what you did if you want to edit this +-- !test -- +1 1.0000000000000002 +2 6.123233995736766E-17 +3 -8.165619676597685E15 +4 inf +5 0.6420926159343306 +6 -0.6420926159343306 +7 \N +8 1.830487721712452 +9 -1.830487721712452 +10 1.5423510453569202 +11 -1.5423510453569202 +12 9999999.999999966 +13 9999999.999999966 +14 -2.1573538153608958 +15 2.1573538153608958 +16 8.165619676597685E15 +17 -6.123233995736766E-17 + +-- !test -- +1 1.414213562373095 +2 1.633123935319537E16 +3 -1.0 +4 1.0 +5 1.8508157176809255 +6 1.8508157176809255 +7 \N +8 1.139493927324549 +9 1.139493927324549 +10 -1.1917935066878957 +11 -1.1917935066878957 +12 1.000000000000005 +13 1.000000000000005 +14 -1.102207252910033 +15 -1.102207252910033 +16 -1.0 +17 1.633123935319537E16 + +-- !test -- +1 1.4142135623730951 +2 1.0 +3 8.165619676597685E15 +4 inf +5 1.1883951057781212 +6 -1.1883951057781212 +7 \N +8 2.085829642933488 +9 -2.085829642933488 +10 -1.8381639608896658 +11 1.8381639608896658 +12 1.0000000000000017E7 +13 1.0000000000000017E7 +14 2.3778510223839118 +15 -2.3778510223839118 +16 -8.165619676597685E15 +17 -1.0 + diff --git a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_numeric_arithmatic.groovy b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_numeric_arithmatic.groovy index 772c880e868945..048fff2973680d 100644 --- a/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_numeric_arithmatic.groovy +++ b/regression-test/suites/nereids_p0/expression/fold_constant/fold_constant_numeric_arithmatic.groovy @@ -520,6 +520,39 @@ suite("fold_constant_numeric_arithmatic") { testFoldConst("SELECT TANH(-0.5), TANH(0.5), TANH(10), TANH(-10)") testFoldConst("SELECT TANH(-20), TANH(20), TANH(1E-7), TANH(-1E-7)") +//Cot function cases + testFoldConst("SELECT COT(PI() / 4)") + testFoldConst("SELECT COT(PI())") + testFoldConst("SELECT COT(PI() / 2)") + // testFoldConst("SELECT COT(0)") need rethink inf behavior + testFoldConst("SELECT COT(1)") + testFoldConst("SELECT COT(-1)") + testFoldConst("SELECT COT(NULL)") + testFoldConst("SELECT COT(-0.5), COT(0.5), COT(10), COT(-10)") + testFoldConst("SELECT COT(-20), COT(20), COT(1E-7), COT(-1E-7)") + +//Sec function cases + testFoldConst("SELECT SEC(PI() / 4)") + testFoldConst("SELECT SEC(PI())") + // testFoldConst("SELECT SEC(PI() / 2)") need rethink inf behavior + testFoldConst("SELECT SEC(0)") + testFoldConst("SELECT SEC(1)") + testFoldConst("SELECT SEC(-1)") + testFoldConst("SELECT SEC(NULL)") + testFoldConst("SELECT SEC(-0.5), SEC(0.5), SEC(10), SEC(-10)") + testFoldConst("SELECT SEC(-20), SEC(20), SEC(1E-7), SEC(-1E-7)") + +//Cosec function cases + testFoldConst("SELECT COSEC(PI() / 4)") + // testFoldConst("SELECT COSEC(PI())") need rethink inf behavior + testFoldConst("SELECT COSEC(PI() / 2)") + // testFoldConst("SELECT COSEC(0)") need rethink inf behavior + testFoldConst("SELECT COSEC(1)") + testFoldConst("SELECT COSEC(-1)") + testFoldConst("SELECT COSEC(NULL)") + testFoldConst("SELECT COSEC(-0.5), COSEC(0.5), COSEC(10), COSEC(-10)") + testFoldConst("SELECT COSEC(-20), COSEC(20), COSEC(1E-7), COSEC(-1E-7)") + //Truncate function cases testFoldConst("SELECT TRUNCATE(123.456, 2) AS truncate_case_1") //truncate(123.456, 2) = 123.45 testFoldConst("SELECT TRUNCATE(-123.456, 1) AS truncate_case_2") //truncate(-123.456, 1) = -123.4 diff --git a/regression-test/suites/query_p0/sql_functions/math_functions/test_triangle.groovy b/regression-test/suites/query_p0/sql_functions/math_functions/test_triangle.groovy new file mode 100644 index 00000000000000..53e2b478ebd039 --- /dev/null +++ b/regression-test/suites/query_p0/sql_functions/math_functions/test_triangle.groovy @@ -0,0 +1,50 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +suite("test_triangle") { + sql """ drop table if exists test_triangle; """ + sql """ create table test_triangle( + k1 int, + v1 double + ) distributed by hash (k1) buckets 1 + properties ("replication_num"="1"); + """ + sql """ insert into test_triangle values + (1,PI() / 4), + (2,PI() / 2), + (3,PI()), + (4,0), + (5,1), + (6,-1), + (7,NULL), + (8,0.5), + (9,-0.5), + (10,10), + (11,-10), + (12,1E-7), + (13,1E-7), + (14,1E7), + (15,-1E7), + (16,-PI()), + (17,-PI()/2) + """ + + qt_test "select k1,COT(v1) from test_triangle order by k1;" + qt_test "select k1,SEC(v1) from test_triangle order by k1;" + qt_test "select k1,COSEC(v1) from test_triangle order by k1;" +} +