This is an automated email from the ASF dual-hosted git repository.

mbudiu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/main by this push:
     new 0808a1db21 [CALCITE-6472] Add degree based trigonometric functions to 
PostgreSQL function library
0808a1db21 is described below

commit 0808a1db21e8d60a06fd00f2ec160ce99485595f
Author: Norman Jordan <[email protected]>
AuthorDate: Tue Jul 16 11:40:49 2024 -0700

    [CALCITE-6472] Add degree based trigonometric functions to PostgreSQL 
function library
    
    Added the following functions to only the PostgreSQL function library:
    * COSD
    * SIND
    * TAND
    * ACOSD
    * ASIND
    * ATAND
---
 .../calcite/adapter/enumerable/RexImpTable.java    |  12 ++
 .../org/apache/calcite/runtime/SqlFunctions.java   |  88 ++++++++++++
 .../calcite/sql/fun/SqlLibraryOperators.java       |  54 +++++++
 .../org/apache/calcite/util/BuiltInMethod.java     |   6 +
 site/_docs/reference.md                            |   6 +
 .../org/apache/calcite/test/SqlOperatorTest.java   | 160 +++++++++++++++++++++
 6 files changed, 326 insertions(+)

diff --git 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
index 7e17beb93e..e20e4a82f2 100644
--- a/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
+++ b/core/src/main/java/org/apache/calcite/adapter/enumerable/RexImpTable.java
@@ -119,6 +119,7 @@ import static 
org.apache.calcite.linq4j.tree.ExpressionType.Subtract;
 import static org.apache.calcite.linq4j.tree.ExpressionType.UnaryPlus;
 import static org.apache.calcite.sql.fun.SqlInternalOperators.LITERAL_AGG;
 import static org.apache.calcite.sql.fun.SqlInternalOperators.THROW_UNLESS;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.ACOSD;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ACOSH;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAYS_OVERLAP;
@@ -145,7 +146,9 @@ import static 
org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_REVERSE;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_SIZE;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_TO_STRING;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ARRAY_UNION;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.ASIND;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ASINH;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.ATAND;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.ATANH;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.BITAND_AGG;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.BITOR_AGG;
@@ -169,6 +172,7 @@ import static 
org.apache.calcite.sql.fun.SqlLibraryOperators.CONCAT_WS_MSSQL;
 import static 
org.apache.calcite.sql.fun.SqlLibraryOperators.CONCAT_WS_POSTGRESQL;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.CONCAT_WS_SPARK;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.CONTAINS_SUBSTR;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.COSD;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.COSH;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.COTH;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.CSC;
@@ -270,6 +274,7 @@ import static 
org.apache.calcite.sql.fun.SqlLibraryOperators.SECH;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SHA1;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SHA256;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SHA512;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.SIND;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SINH;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SORT_ARRAY;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.SOUNDEX;
@@ -279,6 +284,7 @@ import static 
org.apache.calcite.sql.fun.SqlLibraryOperators.SPLIT;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.STARTS_WITH;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.STRCMP;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.STR_TO_MAP;
+import static org.apache.calcite.sql.fun.SqlLibraryOperators.TAND;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.TANH;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.TIME;
 import static org.apache.calcite.sql.fun.SqlLibraryOperators.TIMESTAMP;
@@ -685,14 +691,18 @@ public class RexImpTable {
       defineReflective(RANDOM, BuiltInMethod.RAND.method);
 
       defineMethod(ACOS, BuiltInMethod.ACOS.method, NullPolicy.STRICT);
+      defineMethod(ACOSD, BuiltInMethod.ACOSD.method, NullPolicy.STRICT);
       defineMethod(ACOSH, BuiltInMethod.ACOSH.method, NullPolicy.STRICT);
       defineMethod(ASIN, BuiltInMethod.ASIN.method, NullPolicy.STRICT);
+      defineMethod(ASIND, BuiltInMethod.ASIND.method, NullPolicy.STRICT);
       defineMethod(ASINH, BuiltInMethod.ASINH.method, NullPolicy.STRICT);
       defineMethod(ATAN, BuiltInMethod.ATAN.method, NullPolicy.STRICT);
       defineMethod(ATAN2, BuiltInMethod.ATAN2.method, NullPolicy.STRICT);
+      defineMethod(ATAND, BuiltInMethod.ATAND.method, NullPolicy.STRICT);
       defineMethod(ATANH, BuiltInMethod.ATANH.method, NullPolicy.STRICT);
       defineMethod(CBRT, BuiltInMethod.CBRT.method, NullPolicy.STRICT);
       defineMethod(COS, BuiltInMethod.COS.method, NullPolicy.STRICT);
+      defineMethod(COSD, BuiltInMethod.COSD.method, NullPolicy.STRICT);
       defineMethod(COSH, BuiltInMethod.COSH.method, NullPolicy.STRICT);
       defineMethod(COT, BuiltInMethod.COT.method, NullPolicy.STRICT);
       defineMethod(COTH, BuiltInMethod.COTH.method, NullPolicy.STRICT);
@@ -709,8 +719,10 @@ public class RexImpTable {
       defineMethod(SECH, BuiltInMethod.SECH.method, NullPolicy.STRICT);
       defineMethod(SIGN, BuiltInMethod.SIGN.method, NullPolicy.STRICT);
       defineMethod(SIN, BuiltInMethod.SIN.method, NullPolicy.STRICT);
+      defineMethod(SIND, BuiltInMethod.SIND.method, NullPolicy.STRICT);
       defineMethod(SINH, BuiltInMethod.SINH.method, NullPolicy.STRICT);
       defineMethod(TAN, BuiltInMethod.TAN.method, NullPolicy.STRICT);
+      defineMethod(TAND, BuiltInMethod.TAND.method, NullPolicy.STRICT);
       defineMethod(TANH, BuiltInMethod.TANH.method, NullPolicy.STRICT);
       defineMethod(TRUNC_BIG_QUERY, BuiltInMethod.STRUNCATE.method, 
NullPolicy.STRICT);
       defineMethod(TRUNCATE, BuiltInMethod.STRUNCATE.method, 
NullPolicy.STRICT);
diff --git a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java 
b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
index 5ff6e6a7ed..65bc1a0142 100644
--- a/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
+++ b/core/src/main/java/org/apache/calcite/runtime/SqlFunctions.java
@@ -3128,6 +3128,20 @@ public class SqlFunctions {
     return Math.acos(b0);
   }
 
+  // ACOSD
+  /** SQL <code>ACOSD</code> operator applied to BigDecimal values. */
+  public static double acosd(BigDecimal b0) {
+    return acosd(b0.doubleValue());
+  }
+
+  /** SQL <code>ACOSD</code> operator applied to double values. */
+  public static double acosd(double b0) {
+    if (b0 < -1.0 || b0 > 1.0) {
+      throw new IllegalArgumentException("input is out of range");
+    }
+    return Math.toDegrees(Math.acos(b0));
+  }
+
   // ACOSH
   /** SQL <code>ACOSH</code> operator applied to BigDecimal values. */
   public static double acosh(BigDecimal b0) {
@@ -3153,6 +3167,20 @@ public class SqlFunctions {
     return Math.asin(b0);
   }
 
+  // ASIND
+  /** SQL <code>ASIND</code> operator applied to BigDecimal values. */
+  public static double asind(BigDecimal b0) {
+    return asind(b0.doubleValue());
+  }
+
+  /** SQL <code>ASIND</code> operator applied to double values. */
+  public static double asind(double b0) {
+    if (b0 < -1.0 || b0 > 1.0) {
+      throw new IllegalArgumentException("input is out of range");
+    }
+    return Math.toDegrees(Math.asin(b0));
+  }
+
   // ASINH
   /** SQL <code>ASINH</code> operator applied to BigDecimal values. */
   public static double asinh(BigDecimal b0) {
@@ -3183,6 +3211,21 @@ public class SqlFunctions {
     return Math.atan(b0);
   }
 
+  // ATAND
+  /** SQL <code>ATAN</code> operator applied to BigDecimal values. */
+  public static double atand(BigDecimal b0) {
+    return atand(b0.doubleValue());
+  }
+
+  /** SQL <code>ATAND</code> operator applied to double values. */
+  public static double atand(double b0) {
+    if (Double.isNaN(b0)) {
+      return Double.NaN;
+    } else {
+      return Math.toDegrees(Math.atan(b0));
+    }
+  }
+
   // ATAN2
   /** SQL <code>ATAN2</code> operator applied to double/BigDecimal values. */
   public static double atan2(double b0, BigDecimal b1) {
@@ -3248,6 +3291,21 @@ public class SqlFunctions {
     return Math.cos(b0);
   }
 
+  // COSD
+  /** SQL <code>COSD</code> operator applied to BigDecimal values. */
+  public static double cosd(BigDecimal b0) {
+    return cosd(b0.doubleValue());
+  }
+
+  /** SQL <code>COSD</code> operator applied to double values. */
+  public static double cosd(double b0) {
+    if (Double.isInfinite(b0)) {
+      throw new IllegalArgumentException("input is out of range");
+    } else {
+      return Math.cos(Math.toRadians(b0));
+    }
+  }
+
   // COSH
   /** SQL <code>COSH</code> operator applied to BigDecimal values. */
   public static double cosh(BigDecimal b) {
@@ -3472,6 +3530,21 @@ public class SqlFunctions {
     return Math.sin(b0);
   }
 
+  // SIND
+  /** SQL <code>SIND</code> operator applied to BigDecimal values. */
+  public static double sind(BigDecimal b0) {
+    return sind(b0.doubleValue());
+  }
+
+  /** SQL <code>SIND</code> operator applied to double values. */
+  public static double sind(double b0) {
+    if (Double.isInfinite(b0)) {
+      throw new IllegalArgumentException("input is out of range");
+    } else {
+      return Math.sin(Math.toRadians(b0));
+    }
+  }
+
   // SINH
   /** SQL <code>SINH</code> operator applied to BigDecimal values. */
   public static double sinh(BigDecimal b) {
@@ -3494,6 +3567,21 @@ public class SqlFunctions {
     return Math.tan(b0);
   }
 
+  // TAND
+  /** SQL <code>TAND</code> operator applied to BigDecimal values. */
+  public static double tand(BigDecimal b0) {
+    return tand(b0.doubleValue());
+  }
+
+  /** SQL <code>TAND</code> operator applied to double values. */
+  public static double tand(double b0) {
+    if (Double.isInfinite(b0)) {
+      throw new IllegalArgumentException("input is out of range");
+    } else {
+      return Math.tan(Math.toRadians(b0));
+    }
+  }
+
   // TANH
   /** SQL <code>TANH</code> operator applied to BigDecimal values. */
   public static double tanh(BigDecimal b) {
diff --git 
a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java 
b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
index 7d7795b63b..df3dcbd002 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlLibraryOperators.java
@@ -2215,6 +2215,60 @@ public abstract class SqlLibraryOperators {
           OperandTypes.NUMERIC,
           SqlFunctionCategory.NUMERIC);
 
+  /** The {@code COSD(numeric)} function; returns the cosine
+   * of {@code value}. {@code value} is treated as degrees. */
+  @LibraryOperator(libraries = {POSTGRESQL}, exceptLibraries = {REDSHIFT})
+  public static final SqlFunction COSD =
+      SqlBasicFunction.create("COSD",
+          ReturnTypes.DOUBLE_NULLABLE,
+          OperandTypes.NUMERIC,
+          SqlFunctionCategory.NUMERIC);
+
+  /** The {@code SIND(numeric)} function; returns the sine
+   * of {@code value}. {@code value} is treated as degrees. */
+  @LibraryOperator(libraries = {POSTGRESQL}, exceptLibraries = {REDSHIFT})
+  public static final SqlFunction SIND =
+      SqlBasicFunction.create("SIND",
+          ReturnTypes.DOUBLE_NULLABLE,
+          OperandTypes.NUMERIC,
+          SqlFunctionCategory.NUMERIC);
+
+  /** The {@code TAND(numeric)} function; returns the tangent
+   * of {@code value}. {@code value} is treated as degrees. */
+  @LibraryOperator(libraries = {POSTGRESQL}, exceptLibraries = {REDSHIFT})
+  public static final SqlFunction TAND =
+      SqlBasicFunction.create("TAND",
+          ReturnTypes.DOUBLE_NULLABLE,
+          OperandTypes.NUMERIC,
+          SqlFunctionCategory.NUMERIC);
+
+  /** The {@code ACOSD(numeric)} function; returns the inverse cosine
+   * of {@code value} in degrees. */
+  @LibraryOperator(libraries = {POSTGRESQL}, exceptLibraries = {REDSHIFT})
+  public static final SqlFunction ACOSD =
+      SqlBasicFunction.create("ACOSD",
+          ReturnTypes.DOUBLE_NULLABLE,
+          OperandTypes.NUMERIC,
+          SqlFunctionCategory.NUMERIC);
+
+  /** The {@code ACOSD(numeric)} function; returns the inverse sine
+   * of {@code value} in degrees. */
+  @LibraryOperator(libraries = {POSTGRESQL}, exceptLibraries = {REDSHIFT})
+  public static final SqlFunction ASIND =
+      SqlBasicFunction.create("ASIND",
+          ReturnTypes.DOUBLE_NULLABLE,
+          OperandTypes.NUMERIC,
+          SqlFunctionCategory.NUMERIC);
+
+  /** The {@code ACOSD(numeric)} function; returns the inverse tangent
+   * of {@code value} in degrees. */
+  @LibraryOperator(libraries = {POSTGRESQL}, exceptLibraries = {REDSHIFT})
+  public static final SqlFunction ATAND =
+      SqlBasicFunction.create("ATAND",
+          ReturnTypes.DOUBLE_NULLABLE,
+          OperandTypes.NUMERIC,
+          SqlFunctionCategory.NUMERIC);
+
   /** The "COTH(value)" function; returns the hyperbolic secant
    * of {@code value}. */
   @LibraryOperator(libraries = {ALL})
diff --git a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java 
b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
index f62739f07c..3dd78e8772 100644
--- a/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
+++ b/core/src/main/java/org/apache/calcite/util/BuiltInMethod.java
@@ -496,14 +496,18 @@ public enum BuiltInMethod {
   CEIL(SqlFunctions.class, "ceil", int.class, int.class),
   ABS(SqlFunctions.class, "abs", long.class),
   ACOS(SqlFunctions.class, "acos", double.class),
+  ACOSD(SqlFunctions.class, "acosd", double.class),
   ACOSH(SqlFunctions.class, "acosh", double.class),
   ASIN(SqlFunctions.class, "asin", double.class),
+  ASIND(SqlFunctions.class, "asind", double.class),
   ASINH(SqlFunctions.class, "asinh", double.class),
   ATAN(SqlFunctions.class, "atan", double.class),
   ATAN2(SqlFunctions.class, "atan2", double.class, double.class),
+  ATAND(SqlFunctions.class, "atand", double.class),
   ATANH(SqlFunctions.class, "atanh", double.class),
   CBRT(SqlFunctions.class, "cbrt", double.class),
   COS(SqlFunctions.class, "cos", double.class),
+  COSD(SqlFunctions.class, "cosd", double.class),
   COSH(SqlFunctions.class, "cosh", long.class),
   COT(SqlFunctions.class, "cot", double.class),
   COTH(SqlFunctions.class, "coth", double.class),
@@ -532,7 +536,9 @@ public enum BuiltInMethod {
   SECH(SqlFunctions.class, "sech", double.class),
   SIGN(SqlFunctions.class, "sign", long.class),
   SIN(SqlFunctions.class, "sin", double.class),
+  SIND(SqlFunctions.class, "sind", double.class),
   TAN(SqlFunctions.class, "tan", double.class),
+  TAND(SqlFunctions.class, "tand", double.class),
   TANH(SqlFunctions.class, "tanh", long.class),
   SINH(SqlFunctions.class, "sinh", long.class),
   TRUNCATE(SqlFunctions.class, "truncate", String.class, int.class),
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index 1bb3502dc6..180c3aab51 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -2690,6 +2690,7 @@ In the following:
 |:- |:-----------------------------------------------|:-----------
 | p | expr :: type                                   | Casts *expr* to *type*
 | m | expr1 <=> expr2                                | Whether two values are 
equal, treating null values as the same, and it's similar to `IS NOT DISTINCT 
FROM`
+| p | ACOSD(numeric)                                 | Returns the inverse 
cosine of *numeric* in degrees as a double. Returns NaN if *numeric* is NaN. 
Fails if *numeric* is less than -1.0 or greater than 1.0.
 | * | ACOSH(numeric)                                 | Returns the inverse 
hyperbolic cosine of *numeric*
 | s | ARRAY([expr [, expr ]*])                       | Construct an array in 
Apache Spark. The function allows users to use `ARRAY()` to create an empty 
array
 | s | ARRAY_APPEND(array, element)                   | Appends an *element* to 
the end of the *array* and returns the result. Type of *element* should be 
similar to type of the elements of the *array*. If the *array* is null, the 
function will return null. If an *element* that is null, the null *element* 
will be added to the end of the *array*
@@ -2715,7 +2716,9 @@ In the following:
 | s | ARRAYS_OVERLAP(array1, array2)                 | Returns true if *array1 
contains at least a non-null element present also in *array2*. If the arrays 
have no common element and they are both non-empty and either of them contains 
a null element null is returned, false otherwise
 | s | ARRAYS_ZIP(array [, array ]*)                  | Returns a merged 
*array* of structs in which the N-th struct contains all N-th values of input 
arrays
 | s | SORT_ARRAY(array [, ascendingOrder])           | Sorts the *array* in 
ascending or descending order according to the natural ordering of the array 
elements. The default order is ascending if *ascendingOrder* is not specified. 
Null elements will be placed at the beginning of the returned array in 
ascending order or at the end of the returned array in descending order
+| p | ASIND(numeric)                                 | Returns the inverse 
sine of *numeric* in degrees as a double. Returns NaN if *numeric* is NaN. 
Fails if *numeric* is less than -1.0 or greater than 1.0.
 | * | ASINH(numeric)                                 | Returns the inverse 
hyperbolic sine of *numeric*
+| p | ATAND(numeric)                                 | Returns the inverse 
tangent of *numeric* in degrees as a double. Returns NaN if *numeric* is NaN.
 | * | ATANH(numeric)                                 | Returns the inverse 
hyperbolic tangent of *numeric*
 | f | BITAND_AGG(value)                              | Equivalent to 
`BIT_AND(value)`
 | f | BITOR_AGG(value)                               | Equivalent to 
`BIT_OR(value)`
@@ -2738,6 +2741,7 @@ In the following:
 | b | CONTAINS_SUBSTR(expression, string [ , json_scope =&gt; json_scope_value 
]) | Returns whether *string* exists as a substring in *expression*. Optional 
*json_scope* argument specifies what scope to search if *expression* is in JSON 
format. Returns NULL if a NULL exists in *expression* that does not result in a 
match
 | q | CONVERT(type, expression [ , style ])          | Equivalent to 
`CAST(expression AS type)`; ignores the *style* operand
 | p r | CONVERT_TIMEZONE(tz1, tz2, datetime)         | Converts the timezone 
of *datetime* from *tz1* to *tz2*
+| p | COSD(numeric)                                  | Returns the cosine of 
*numeric* in degrees as a double. Returns NaN if *numeric* is NaN. Fails if 
*numeric* is greater than the maximum double value.
 | * | COSH(numeric)                                  | Returns the hyperbolic 
cosine of *numeric*
 | * | COTH(numeric)                                  | Returns the hyperbolic 
cotangent of *numeric*
 | * | CSC(numeric)                                   | Returns the cosecant of 
*numeric* in radians
@@ -2873,6 +2877,7 @@ In the following:
 | b m p r s | SHA1(string)                           | Calculates a SHA-1 hash 
value of *string* and returns it as a hex string
 | b p | SHA256(string)                               | Calculates a SHA-256 
hash value of *string* and returns it as a hex string
 | b p | SHA512(string)                               | Calculates a SHA-512 
hash value of *string* and returns it as a hex string
+| p | SIND(numeric)                                  | Returns the sine of 
*numeric* in degrees as a double. Returns NaN if *numeric* is NaN. Fails if 
*numeric* is greater than the maximum double value.
 | * | SINH(numeric)                                  | Returns the hyperbolic 
sine of *numeric*
 | b m o p r | SOUNDEX(string)                        | Returns the phonetic 
representation of *string*; throws if *string* is encoded with multi-byte 
encoding such as UTF-8
 | s | SOUNDEX(string)                                | Returns the phonetic 
representation of *string*; return original *string* if *string* is encoded 
with multi-byte encoding such as UTF-8
@@ -2883,6 +2888,7 @@ In the following:
 | m | STRCMP(string, string)                         | Returns 0 if both of 
the strings are same and returns -1 when the first argument is smaller than the 
second and 1 when the second one is smaller than the first one
 | b r p | STRPOS(string, substring)                  | Equivalent to 
`POSITION(substring IN string)`
 | b m o p r | SUBSTR(string, position [, substringLength ]) | Returns a 
portion of *string*, beginning at character *position*, *substringLength* 
characters long. SUBSTR calculates lengths using characters as defined by the 
input character set
+| p | TAND(numeric)                                  | Returns the tangent of 
*numeric* in degrees as a double. Returns NaN if *numeric* is NaN. Fails if 
*numeric is greater than the maximum double value.
 | * | TANH(numeric)                                  | Returns the hyperbolic 
tangent of *numeric*
 | b | TIME(hour, minute, second)                     | Returns a TIME value 
*hour*, *minute*, *second* (all of type INTEGER)
 | b | TIME(timestamp)                                | Extracts the TIME from 
*timestamp* (a local time; BigQuery's DATETIME type)
diff --git a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java 
b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
index 9d42569d01..4427dcd83f 100644
--- a/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
+++ b/testkit/src/main/java/org/apache/calcite/test/SqlOperatorTest.java
@@ -8696,6 +8696,30 @@ public class SqlOperatorTest {
     f.checkNull("acos(cast(null as double))");
   }
 
+  @Test void testAcosdFunc() {
+    final SqlOperatorFixture f = fixture().withLibrary(SqlLibrary.POSTGRESQL);
+    f.setFor(SqlLibraryOperators.ACOSD, VmName.EXPAND);
+    f.checkType("acosd(0)", "DOUBLE NOT NULL");
+    f.checkType("acosd(cast(1 as float))", "DOUBLE NOT NULL");
+    f.checkType("acosd(case when false then 0.5 else null end)", "DOUBLE");
+    f.enableTypeCoercion(false)
+        .checkFails("^acosd('abc')^",
+            "Cannot apply 'ACOSD' to arguments of type "
+                + "'ACOSD\\(<CHAR\\(3\\)>\\)'\\. Supported form\\(s\\): "
+                + "'ACOSD\\(<NUMERIC>\\)'",
+            false);
+    f.checkType("acosd('abc')", "DOUBLE NOT NULL");
+    f.checkScalarApprox("acosd(0.5)", "DOUBLE NOT NULL",
+        isWithin(60.0d, 0.01d));
+    f.checkScalarApprox("acosd(cast(0.5 as decimal(3, 1)))", "DOUBLE NOT NULL",
+        isWithin(60.0d, 0.1d));
+    f.checkFails("acosd(-2.0)", "input is out of range", true);
+    f.checkScalarExact("acosd(cast('NaN' as double))", "DOUBLE NOT NULL", 
"NaN");
+    f.checkFails("acosd(cast('Infinity' as double))", "input is out of range", 
true);
+    f.checkNull("acosd(cast(null as integer))");
+    f.checkNull("acosd(cast(null as double))");
+  }
+
   @Test void testAsinFunc() {
     final SqlOperatorFixture f = fixture();
     f.setFor(SqlStdOperatorTable.ASIN, VmName.EXPAND);
@@ -8717,6 +8741,30 @@ public class SqlOperatorTest {
     f.checkNull("asin(cast(null as double))");
   }
 
+  @Test void testAsindFunc() {
+    final SqlOperatorFixture f = fixture().withLibrary(SqlLibrary.POSTGRESQL);
+    f.setFor(SqlLibraryOperators.ASIND, VmName.EXPAND);
+    f.checkType("asind(0)", "DOUBLE NOT NULL");
+    f.checkType("asind(cast(1 as float))", "DOUBLE NOT NULL");
+    f.checkType("asind(case when false then 0.5 else null end)", "DOUBLE");
+    f.enableTypeCoercion(false)
+        .checkFails("^asind('abc')^",
+            "Cannot apply 'ASIND' to arguments of type "
+                + "'ASIND\\(<CHAR\\(3\\)>\\)'\\. Supported form\\(s\\): "
+                + "'ASIND\\(<NUMERIC>\\)'",
+            false);
+    f.checkType("asind('abc')", "DOUBLE NOT NULL");
+    f.checkScalarApprox("asind(0.5)", "DOUBLE NOT NULL",
+        isWithin(30.0d, 0.01d));
+    f.checkScalarApprox("asind(cast(0.5 as decimal(3, 1)))", "DOUBLE NOT NULL",
+        isWithin(30.0d, 0.01d));
+    f.checkFails("asind(-2.0)", "input is out of range", true);
+    f.checkScalarExact("asind(cast('NaN' as double))", "DOUBLE NOT NULL", 
"NaN");
+    f.checkFails("asind(cast('Infinity' as double))", "input is out of range", 
true);
+    f.checkNull("asind(cast(null as integer))");
+    f.checkNull("asind(cast(null as double))");
+  }
+
   @Test void testAtanFunc() {
     final SqlOperatorFixture f = fixture();
     f.setFor(SqlStdOperatorTable.ATAN, VmName.EXPAND);
@@ -8762,6 +8810,33 @@ public class SqlOperatorTest {
     f.checkNull("atan2(1, cast(null as double))");
   }
 
+  @Test void testAtandFunc() {
+    final SqlOperatorFixture f = fixture().withLibrary(SqlLibrary.POSTGRESQL);
+    f.setFor(SqlLibraryOperators.ATAND, VmName.EXPAND);
+    f.checkType("atand(2)", "DOUBLE NOT NULL");
+    f.checkType("atand(cast(2 as float))", "DOUBLE NOT NULL");
+    f.checkType("atand(case when false then 2 else null end)", "DOUBLE");
+    f.enableTypeCoercion(false)
+        .checkFails("^atand('abc')^",
+            "Cannot apply 'ATAND' to arguments of type "
+                + "'ATAND\\(<CHAR\\(3\\)>\\)'\\. Supported form\\(s\\): "
+                + "'ATAND\\(<NUMERIC>\\)'",
+            false);
+    f.checkType("atand('abc')", "DOUBLE NOT NULL");
+    f.checkScalarApprox("atand(1.73)", "DOUBLE NOT NULL",
+        isWithin(60.0d, 0.1d));
+    f.checkScalarApprox("atand(cast(1.73 as decimal(3, 2)))", "DOUBLE NOT 
NULL",
+        isWithin(60.0d, 0.1d));
+    f.checkScalarApprox("atand(-2000.0)", "DOUBLE NOT NULL", isWithin(-89.97d, 
0.1d));
+    f.checkScalarExact("atand(cast('NaN' as double))", "DOUBLE NOT NULL", 
"NaN");
+    f.checkScalarApprox("atand(cast('Infinity' as double))", "DOUBLE NOT NULL",
+        isWithin(90.0d, 0.01d));
+    f.checkScalarApprox("atand(cast('-Infinity' as double))", "DOUBLE NOT 
NULL",
+        isWithin(-90.0d, 0.01d));
+    f.checkNull("atand(cast(null as integer))");
+    f.checkNull("atand(cast(null as double))");
+  }
+
   @Test void testAcoshFunc() {
     final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.ACOSH);
     f0.checkFails("^acosh(1)^",
@@ -8876,6 +8951,34 @@ public class SqlOperatorTest {
     f.checkNull("cos(cast(null as double))");
   }
 
+  @Test void testCosdFunc() {
+    final SqlOperatorFixture f = fixture().withLibrary(SqlLibrary.POSTGRESQL);
+    f.setFor(SqlLibraryOperators.COSD, VmName.EXPAND);
+    f.checkType("cosd(60)", "DOUBLE NOT NULL");
+    f.checkType("cosd(cast(60 as float))", "DOUBLE NOT NULL");
+    f.checkType("cosd(case when false then 60 else null end)", "DOUBLE");
+    f.enableTypeCoercion(false)
+        .checkFails("^cosd('abc')^",
+            "Cannot apply 'COSD' to arguments of type "
+                + "'COSD\\(<CHAR\\(3\\)>\\)'\\. Supported form\\(s\\): "
+                + "'COSD\\(<NUMERIC>\\)'",
+            false);
+    f.checkType("cosd('abc')", "DOUBLE NOT NULL");
+    f.checkScalarApprox("cosd(60)", "DOUBLE NOT NULL",
+        isWithin(0.5d, 0.01d));
+    f.checkScalarApprox("cosd(420)", "DOUBLE NOT NULL",
+        isWithin(0.5d, 0.01d));
+    f.checkScalarApprox("cosd(-60)", "DOUBLE NOT NULL",
+        isWithin(0.5d, 0.01d));
+    f.checkScalarApprox("cosd(cast(60 as decimal(1, 0)))", "DOUBLE NOT NULL",
+        isWithin(0.5d, 0.01d));
+    f.checkScalarExact("cosd(cast('NaN' as double))", "DOUBLE NOT NULL",
+        "NaN");
+    f.checkFails("cosd(cast('Infinity' as double))", "input is out of range", 
true);
+    f.checkNull("cosd(cast(null as integer))");
+    f.checkNull("cosd(cast(null as double))");
+  }
+
   @Test void testCoshFunc() {
     final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.COSH);
     f0.checkFails("^cosh(1)^",
@@ -9269,6 +9372,35 @@ public class SqlOperatorTest {
     f.checkNull("sin(cast(null as double))");
   }
 
+  @Test void testSindFunc() {
+    final SqlOperatorFixture f = fixture().withLibrary(SqlLibrary.POSTGRESQL);
+    f.setFor(SqlLibraryOperators.SIND, VmName.EXPAND);
+    f.checkType("sind(30)", "DOUBLE NOT NULL");
+    f.checkType("sind(cast(30 as float))", "DOUBLE NOT NULL");
+    f.checkType("sind(case when false then 30 else null end)", "DOUBLE");
+    f.enableTypeCoercion(false)
+        .checkFails("^sind('abc')^",
+            "Cannot apply 'SIND' to arguments of type "
+                + "'SIND\\(<CHAR\\(3\\)>\\)'\\. Supported form\\(s\\): "
+                + "'SIND\\(<NUMERIC>\\)'",
+            false);
+    f.checkType("sind('abc')", "DOUBLE NOT NULL");
+    f.checkScalarApprox("sind(30)", "DOUBLE NOT NULL",
+        isWithin(0.5d, 0.01d));
+    f.checkScalarApprox("sind(390)", "DOUBLE NOT NULL",
+        isWithin(0.5d, 0.01d));
+    f.checkScalarApprox("sind(-30)", "DOUBLE NOT NULL",
+        isWithin(-0.5d, 0.01d));
+    f.checkScalarApprox("sind(cast(30 as decimal(1, 0)))", "DOUBLE NOT NULL",
+        isWithin(0.5d, 0.01d));
+    f.checkScalarExact("sin(cast('NaN' as double))", "DOUBLE NOT NULL",
+        "NaN");
+    f.checkScalarExact("sin(cast('Infinity' as double))", "DOUBLE NOT NULL",
+        "NaN");
+    f.checkNull("sind(cast(null as integer))");
+    f.checkNull("sind(cast(null as double))");
+  }
+
   @Test void testSinhFunc() {
     final SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.SINH);
     f0.checkFails("^sinh(1)^",
@@ -9310,6 +9442,34 @@ public class SqlOperatorTest {
     f.checkNull("tan(cast(null as double))");
   }
 
+  @Test void testTandFunc() {
+    final SqlOperatorFixture f = fixture().withLibrary(SqlLibrary.POSTGRESQL);
+    f.setFor(SqlLibraryOperators.TAND, VmName.EXPAND);
+    f.checkType("tand(60)", "DOUBLE NOT NULL");
+    f.checkType("tand(cast(60 as float))", "DOUBLE NOT NULL");
+    f.checkType("tand(case when false then 30 else null end)", "DOUBLE");
+    f.enableTypeCoercion(false)
+        .checkFails("^tand('abc')^",
+            "Cannot apply 'TAND' to arguments of type "
+                + "'TAND\\(<CHAR\\(3\\)>\\)'\\. Supported form\\(s\\): "
+                + "'TAND\\(<NUMERIC>\\)'",
+            false);
+    f.checkType("tand('abc')", "DOUBLE NOT NULL");
+    f.checkScalarApprox("tand(60)", "DOUBLE NOT NULL",
+        isWithin(1.73d, 1.74d));
+    f.checkScalarApprox("cosd(420)", "DOUBLE NOT NULL",
+        isWithin(1.73d, 1.74d));
+    f.checkScalarApprox("cosd(-60)", "DOUBLE NOT NULL",
+        isWithin(1.73d, 1.74d));
+    f.checkScalarApprox("tand(cast(60 as decimal(1, 0)))", "DOUBLE NOT NULL",
+        isWithin(1.73d, 1.74d));
+    f.checkScalarExact("tand(cast('NaN' as double))", "DOUBLE NOT NULL",
+        "NaN");
+    f.checkFails("tand(cast('Infinity' as double))", "input is out of range", 
true);
+    f.checkNull("tand(cast(null as integer))");
+    f.checkNull("tand(cast(null as double))");
+  }
+
   @Test void testTanhFunc() {
     SqlOperatorFixture f0 = fixture().setFor(SqlLibraryOperators.TANH);
     f0.checkFails("^tanh(1)^",

Reply via email to