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

zabetak pushed a commit to branch branch-1.21
in repository https://gitbox.apache.org/repos/asf/calcite.git

commit 8c941e03d8443d1e0dae12cb740e7eea09d56ab2
Author: Julian Hyde <jh...@apache.org>
AuthorDate: Thu Sep 5 20:03:48 2019 -0700

    Cosmetic code changes
    
    Improve documentation of JDBC adapter (Shuming Li)
    
    Copy-edit SQL reference
---
 .../adapter/enumerable/EnumerableHashJoin.java     |   4 +-
 .../sql/validate/implicit/TypeCoercion.java        |  72 ++++++++-------
 .../sql/validate/implicit/TypeCoercionImpl.java    |  33 ++++---
 .../apache/calcite/sql2rel/SqlToRelConverter.java  |  13 +--
 .../org/apache/calcite/plan/RelWriterTest.java     |   6 +-
 .../apache/calcite/runtime/EnumerablesTest.java    |   6 +-
 .../test/java/org/apache/calcite/util/Smalls.java  |   8 +-
 site/_docs/adapter.md                              |   6 +-
 site/_docs/reference.md                            | 100 +++++++++++++--------
 9 files changed, 143 insertions(+), 105 deletions(-)

diff --git 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableHashJoin.java
 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableHashJoin.java
index 1667260..91f3c90 100644
--- 
a/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableHashJoin.java
+++ 
b/core/src/main/java/org/apache/calcite/adapter/enumerable/EnumerableHashJoin.java
@@ -244,8 +244,8 @@ public class EnumerableHashJoin extends Join implements 
EnumerableRel {
                         Expressions.constant(joinType.generatesNullsOnLeft()))
                     .append(
                         Expressions.constant(
-                            
joinType.generatesNullsOnRight())).append(predicate)
-            ))
+                            joinType.generatesNullsOnRight()))
+                    .append(predicate)))
             .toBlock());
   }
 }
diff --git 
a/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercion.java 
b/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercion.java
index 4b759b1..9cb773a 100644
--- 
a/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercion.java
+++ 
b/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercion.java
@@ -74,7 +74,8 @@ public interface TypeCoercion {
 
   /**
    * Finds a wider type when one or both types are decimal type.
-   * If the wider decimal type's precision/scale exceeds system limitation,
+   *
+   * <p>If the wider decimal type's precision/scale exceeds system limitation,
    * this rule will truncate the decimal type to the max precision/scale.
    * For decimal and fractional types, returns a decimal type
    * which has the higher precision of the two.
@@ -86,14 +87,14 @@ public interface TypeCoercion {
   RelDataType getWiderTypeForDecimal(RelDataType type1, RelDataType type2);
 
   /**
-   * Determines common type for a comparison operator whose operands are 
String type and the
-   * other(non String type) type.
+   * Determines common type for a comparison operator whose operands are String
+   * type and the other (non String) type.
    */
   RelDataType commonTypeForBinaryComparison(RelDataType type1, RelDataType 
type2);
 
   /**
-   * Widen a SqlNode ith column type to target type, mainly used for set 
operations like UNION,
-   * INTERSECT and EXCEPT.
+   * Widen a SqlNode ith column type to target type, mainly used for set
+   * operations like UNION, INTERSECT and EXCEPT.
    *
    * @param scope       scope to query
    * @param query       SqlNode which have children nodes as columns
@@ -108,8 +109,9 @@ public interface TypeCoercion {
       RelDataType targetType);
 
   /**
-   * Handles type coercion for IN operation with or without subquery.
-   * see {@link TypeCoercionImpl} for default strategies.
+   * Handles type coercion for IN operation with or without sub-query.
+   *
+   * <p>See {@link TypeCoercionImpl} for default strategies.
    */
   boolean inOperationCoercion(SqlCallBinding binding);
 
@@ -119,32 +121,36 @@ public interface TypeCoercion {
   /**
    * Coerce CASE WHEN statement branches to one common type.
    *
-   * <p>Rules: Find common type for all the then operands and else operands, 
then
-   * try to coerce the then/else operands to the type if needed.
-   * */
+   * <p>Rules: Find common type for all the then operands and else operands,
+   * then try to coerce the then/else operands to the type if needed.
+   */
   boolean caseWhenCoercion(SqlCallBinding binding);
 
   /**
-   * Type coercion with inferred type from passed in arguments and the {@link 
SqlTypeFamily}
-   * defined in the checkers, e.g. the {@link 
org.apache.calcite.sql.type.FamilyOperandTypeChecker}.
+   * Type coercion with inferred type from passed in arguments and the
+   * {@link SqlTypeFamily} defined in the checkers, e.g. the
+   * {@link org.apache.calcite.sql.type.FamilyOperandTypeChecker}.
    *
-   * <p>Caution that We do not cast from numeric if desired type family is also
+   * <p>Caution that we do not cast from numeric if desired type family is also
    * {@link SqlTypeFamily#NUMERIC}.
    *
-   * <p>If the {@link org.apache.calcite.sql.type.FamilyOperandTypeChecker}s 
are subsumed in a
-   * {@link org.apache.calcite.sql.type.CompositeOperandTypeChecker}, check 
them based on
-   * their combination order. i.e. If we allows a (numeric, numeric) OR 
(string, numeric) family
-   * but with arguments (op1, op2) of types (varchar(20), boolean), try to 
coerce op1
-   * to numeric and op2 to numeric if the type coercion rules allow it, or 
else try to coerce
-   * op2 to numeric and keep op1 the type as it is.
+   * <p>If the {@link org.apache.calcite.sql.type.FamilyOperandTypeChecker}s 
are
+   * subsumed in a
+   * {@link org.apache.calcite.sql.type.CompositeOperandTypeChecker}, check 
them
+   * based on their combination order. i.e. If we allows a (numeric, numeric) 
OR
+   * (string, numeric) family but with arguments (op1, op2) of types
+   * (varchar(20), boolean), try to coerce op1 to numeric and op2 to numeric if
+   * the type coercion rules allow it, or else try to coerce op2 to numeric and
+   * keep op1 the type as it is.
    *
-   * <p>This is also very interrelated to the
-   * composition predicate for the checkers, if the predicate is AND, we would 
fail fast
-   * if the first family type coercion fails.
-   * @param binding          call binding.
-   * @param operandTypes     Types of the operands passed in.
-   * @param expectedFamilies Expected SqlTypeFamily list by user specified.
-   * @return true if we successfully do any implicit cast.
+   * <p>This is also very interrelated to the composition predicate for the
+   * checkers: if the predicate is AND, we would fail fast if the first family
+   * type coercion fails.
+   *
+   * @param binding          Call binding
+   * @param operandTypes     Types of the operands passed in
+   * @param expectedFamilies Expected SqlTypeFamily list by user specified
+   * @return true if we successfully do any implicit cast
    */
   boolean builtinFunctionCoercion(
       SqlCallBinding binding,
@@ -152,18 +158,20 @@ public interface TypeCoercion {
       List<SqlTypeFamily> expectedFamilies);
 
   /**
-   * Non builtin functions(UDFs) type coercion, compare the types of arguments 
with
-   * rules:
+   * Non built-in functions (UDFs) type coercion, compare the types of 
arguments
+   * with rules:
+   *
    * <ol>
-   * <li>named param: find the desired type by the passed in operand's 
name.</li>
-   * <li>non-named param: find the desired type by formal parameter 
ordinal.</li>
+   * <li>named param: find the desired type by the passed in operand's name
+   * <li>non-named param: find the desired type by formal parameter ordinal
    * </ol>
    *
    * <p>Try to make type coercion only of the desired type is found.
    *
-   * @return true if any operands is coerced.
+   * @return true if any operands is coerced
    */
-  boolean userDefinedFunctionCoercion(SqlValidatorScope scope, SqlCall call, 
SqlFunction function);
+  boolean userDefinedFunctionCoercion(SqlValidatorScope scope, SqlCall call,
+      SqlFunction function);
 }
 
 // End TypeCoercion.java
diff --git 
a/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java
 
b/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java
index 0a2a5d7..cfc8cca 100644
--- 
a/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java
+++ 
b/core/src/main/java/org/apache/calcite/sql/validate/implicit/TypeCoercionImpl.java
@@ -346,21 +346,28 @@ public class TypeCoercionImpl extends 
AbstractTypeCoercion {
   /**
    * STRATEGIES
    *
-   * <p>with/Without subquery:</p>
+   * <p>with/Without sub-query:
+   *
    * <ul>
-   * <li>With subquery: find the common type through comparing the left hand 
side (LHS)
-   * expression types with corresponding right hand side (RHS) expression 
derived
-   * from the subquery expression's row type. Wrap the fields of the
-   * LHS and RHS in CAST operators if it is needed.</li>
-   * <li>Without subquery: convert the nodes of the RHS to the
-   * common type by checking all the argument types and find out
-   * the minimum common type that all the arguments can be cast to.</li>
+   *
+   * <li>With sub-query: find the common type through comparing the left hand
+   * side (LHS) expression types with corresponding right hand side (RHS)
+   * expression derived from the sub-query expression's row type. Wrap the
+   * fields of the LHS and RHS in CAST operators if it is needed.
+   *
+   * <li>Without sub-query: convert the nodes of the RHS to the common type by
+   * checking all the argument types and find out the minimum common type that
+   * all the arguments can be cast to.
+   *
    * </ul>
    *
-   * How to find the common type:
+   * <p>How to find the common type:
+   *
    * <ul>
-   *   <li>For both struct sql types(LHS and RHS), find the common type of 
every LHS and RHS
-   *   fields pair:
+   *
+   * <li>For both struct sql types (LHS and RHS), find the common type of every
+   * LHS and RHS fields pair:
+   *
    *<pre>
    * (field1, field2, field3)    (field4, field5, field6)
    *    |        |       |          |       |       |
@@ -435,7 +442,7 @@ public class TypeCoercionImpl extends AbstractTypeCoercion {
           coerced = coerceOperandType(scope, binding.getCall(), 0, desired)
               || coerced;
         }
-        // RSH may be a row values expression or subquery.
+        // RHS may be a row values expression or sub-query.
         if (node2 instanceof SqlNodeList) {
           final SqlNodeList node3 = (SqlNodeList) node2;
           boolean listCoerced = false;
@@ -456,7 +463,7 @@ public class TypeCoercionImpl extends AbstractTypeCoercion {
             }
           }
         } else {
-          // Another subquery.
+          // Another sub-query.
           SqlValidatorScope scope1 = node2 instanceof SqlSelect
               ? validator.getSelectScope((SqlSelect) node2)
               : scope;
diff --git 
a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java 
b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index 9da2c35..aeaf99e 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -1102,13 +1102,14 @@ public class SqlToRelConverter {
       //   where emp.deptno <> null
       //         and q.indicator <> TRUE"
       //
-      // Note:
-      // Subquery can be used as SqlUpdate#condition like below:
-      // "update emp
-      //  set empno = 1 where emp.empno in (
-      //   select emp.empno from emp where emp.empno=2)"
+      // Note: Sub-query can be used as SqlUpdate#condition like below:
+      //
+      //   UPDATE emp
+      //   SET empno = 1 WHERE emp.empno IN (
+      //     SELECT emp.empno FROM emp WHERE emp.empno = 2)
+      //
       // In such case, when converting SqlUpdate#condition, bb.root is null
-      // and it makes no sense to do the subquery substituion.
+      // and it makes no sense to do the sub-query substitution.
       if (bb.root == null) {
         return;
       }
diff --git a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java 
b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
index 690c372..60af563 100644
--- a/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
+++ b/core/src/test/java/org/apache/calcite/plan/RelWriterTest.java
@@ -620,8 +620,7 @@ public class RelWriterTest {
         + "    LogicalProject(JOB=[$2], SAL=[$5])\n"
         + "      LogicalTableScan(table=[[scott, EMP]])\n";
 
-    assertThat(s, isLinux(expected)
-    );
+    assertThat(s, isLinux(expected));
   }
 
   @Test public void testAggregateWithoutAlias() {
@@ -661,8 +660,7 @@ public class RelWriterTest {
         + "    LogicalProject(JOB=[$2], SAL=[$5])\n"
         + "      LogicalTableScan(table=[[scott, EMP]])\n";
 
-    assertThat(s, isLinux(expected)
-    );
+    assertThat(s, isLinux(expected));
   }
 
   /** Returns the schema of a {@link org.apache.calcite.rel.core.TableScan}
diff --git a/core/src/test/java/org/apache/calcite/runtime/EnumerablesTest.java 
b/core/src/test/java/org/apache/calcite/runtime/EnumerablesTest.java
index 8c7f427..690cdaa 100644
--- a/core/src/test/java/org/apache/calcite/runtime/EnumerablesTest.java
+++ b/core/src/test/java/org/apache/calcite/runtime/EnumerablesTest.java
@@ -297,8 +297,7 @@ public class EnumerablesTest {
             e -> e.deptno,
             d -> d.deptno,
             (v0, v1) -> v0 + ", " + v1, null, false, true,
-            (v0, v1) -> v0.deptno < 30
-        )
+            (v0, v1) -> v0.deptno < 30)
             .toList()
             .toString(),
         equalTo("[Emp(10, Fred), null,"
@@ -326,8 +325,7 @@ public class EnumerablesTest {
             e -> e.deptno,
             d -> d.deptno,
             (v0, v1) -> v0 + ", " + v1, null, true, false,
-            (v0, v1) -> v0.deptno < 30
-        )
+            (v0, v1) -> v0.deptno < 30)
             .toList()
             .toString(),
         equalTo("[Emp(20, Theodore), Dept(20, Sales),"
diff --git a/core/src/test/java/org/apache/calcite/util/Smalls.java 
b/core/src/test/java/org/apache/calcite/util/Smalls.java
index 991090f..9c437e2 100644
--- a/core/src/test/java/org/apache/calcite/util/Smalls.java
+++ b/core/src/test/java/org/apache/calcite/util/Smalls.java
@@ -371,8 +371,8 @@ public class Smalls {
   /** Example of a UDF with a non-static {@code eval} method,
    * and named parameters. */
   public static class MyPlusFunction {
-    public static final ThreadLocal<AtomicInteger> INSTANCE_COUNT
-        = new ThreadLocal<>().withInitial(() -> new AtomicInteger(0));
+    public static final ThreadLocal<AtomicInteger> INSTANCE_COUNT =
+        new ThreadLocal<>().withInitial(() -> new AtomicInteger(0));
 
     // Note: Not marked @Deterministic
     public MyPlusFunction() {
@@ -387,8 +387,8 @@ public class Smalls {
 
   /** As {@link MyPlusFunction} but declared to be deterministic. */
   public static class MyDeterministicPlusFunction {
-    public static final ThreadLocal<AtomicInteger> INSTANCE_COUNT
-        = new ThreadLocal<>().withInitial(() -> new AtomicInteger(0));
+    public static final ThreadLocal<AtomicInteger> INSTANCE_COUNT =
+        new ThreadLocal<>().withInitial(() -> new AtomicInteger(0));
 
     @Deterministic public MyDeterministicPlusFunction() {
       INSTANCE_COUNT.get().incrementAndGet();
diff --git a/site/_docs/adapter.md b/site/_docs/adapter.md
index 3c6f5a5..feb357b 100644
--- a/site/_docs/adapter.md
+++ b/site/_docs/adapter.md
@@ -107,14 +107,14 @@ as implemented by Avatica's
 To make a connection to a single schema based on a built-in schema type, you 
don't need to specify
 a model. For example,
 
-  jdbc:calcite:schemaType=JDBC; schema.jdbcUser=SCOTT; 
schema.jdbcPassword=TIGER; schema.jdbcUrl=jdbc:hsqldb:res:foodmart
+  `jdbc:calcite:schemaType=JDBC; schema.jdbcUser=SCOTT; 
schema.jdbcPassword=TIGER; schema.jdbcUrl=jdbc:hsqldb:res:foodmart`
 
 creates a connection with a schema mapped via the JDBC schema adapter to the 
foodmart database.
 
 Similarly, you can connect to a single schema based on a user-defined schema 
adapter.
 For example,
 
-  
jdbc:calcite:schemaFactory=org.apache.calcite.adapter.cassandra.CassandraSchemaFactory;
 schema.host=localhost; schema.keyspace=twissandra
+  
`jdbc:calcite:schemaFactory=org.apache.calcite.adapter.cassandra.CassandraSchemaFactory;
 schema.host=localhost; schema.keyspace=twissandra`
 
 makes a connection to the Cassandra adapter, equivalent to writing the 
following model file:
 
@@ -156,6 +156,8 @@ adding some DDL commands:
 * `CREATE` and `DROP TABLE` (including `CREATE TABLE ... AS SELECT`)
 * `CREATE` and `DROP MATERIALIZED VIEW`
 * `CREATE` and `DROP VIEW`
+* `CREATE` and `DROP FUNCTION`
+* `CREATE` and `DROP TYPE`
 
 Commands are described in the [SQL reference](reference.html#ddl-extensions).
 
diff --git a/site/_docs/reference.md b/site/_docs/reference.md
index b2590c7..b85bd7a 100644
--- a/site/_docs/reference.md
+++ b/site/_docs/reference.md
@@ -1371,9 +1371,9 @@ collectionsTypeName:
 
 rowTypeName:
       ROW '('
-        fieldName1 fieldType1 [ [ NULL | NOT NULL ] ]
-        [ , fieldName2 fieldType2 [ [ NULL | NOT NULL ] ] ]*
-        ')'
+      fieldName1 fieldType1 [ NULL | NOT NULL ]
+      [ , fieldName2 fieldType2 [ NULL | NOT NULL ] ]*
+      ')'
 
 char:
       CHARACTER | CHAR
@@ -1408,47 +1408,71 @@ timeZone:
 {% endhighlight %}
 
 #### Implicit Type Conversion
-Calcite automatically converts a value from one datatype to another when such 
a conversion makes sense. The table below is a matrix of Calcite type 
conversions. The table shows all possible conversions, without regard to the 
context in which it is made. The rules governing these details follow the table.
-
-| FROM-TO     | NULL | BOOLEAN | TINYINT | SMALLINT | INT | BIGINT | DECIMAL | 
FLOAT/REAL | DOUBLE | INTERVAL | DATE | TIME | TIMESTAMP | (VAR)CHAR | 
(VAR)BINARY
-|:----------- |:---- |:------- |:------- |:-------- |:--- |:------ |:------- 
|:---------- |:------ |:-------- |:---- |:---- |:--------- |:--------- 
|:-----------
-| NULL        | i    | i       | i       | i        | i   | i      | i       | 
i          | i      | i        | i    | i    | i         | i         | i
-| BOOLEAN     | x    | i       | e       | e        | e   | e      | e       | 
e          | e      | x        | x    | x    | x         | i         | x
-| TINYINT     | x    | e       | i       | i        | i   | i      | i       | 
i          | i      | e        | x    | x    | e         | i         | x
-| SMALLINT    | x    | e       | i       | i        | i   | i      | i       | 
i          | i      | e        | x    | x    | e         | i         | x
-| INT         | x    | e       | i       | i        | i   | i      | i       | 
i          | i      | e        | x    | x    | e         | i         | x
-| BIGINT      | x    | e       | i       | i        | i   | i      | i       | 
i          | i      | e        | x    | x    | e         | i         | x
-| DECIMAL     | x    | e       | i       | i        | i   | i      | i       | 
i          | i      | e        | x    | x    | e         | i         | x
-| FLOAT/REAL  | x    | e       | i       | i        | i   | i      | i       | 
i          | i      | x        | x    | x    | e         | i         | x
-| DOUBLE      | x    | e       | i       | i        | i   | i      | i       | 
i          | i      | x        | x    | x    | e         | i         | x
-| INTERVAL    | x    | x       | e       | e        | e   | e      | e       | 
x          | x      | i        | x    | x    | x         | e         | x
-| DATE        | x    | x       | x       | x        | x   | x      | x       | 
x          | x      | x        | i    | x    | i         | i         | x
-| TIME        | x    | x       | x       | x        | x   | x      | x       | 
x          | x      | x        | x    | i    | e         | i         | x
-| TIMESTAMP   | x    | x       | e       | e        | e   | e      | e       | 
e          | e      | x        | i    | e    | i         | i         | x
-| (VAR)CHAR   | x    | e       | i       | i        | i   | i      | i       | 
i          | i      | i        | i    | i    | i         | i         | i
-| (VAR)BINARY | x    | x       | x       | x        | x   | x      | x       | 
x          | x      | x        | e    | e    | e         | i         | i
+
+Calcite automatically converts a value from one datatype to another
+when such a conversion makes sense. The table below is a matrix of
+Calcite type conversions. The table shows all possible conversions,
+without regard to the context in which it is made. The rules governing
+these details follow the table.
+
+| FROM - TO           | NULL | BOOLEAN | TINYINT | SMALLINT | INT | BIGINT | 
DECIMAL | FLOAT or REAL | DOUBLE | INTERVAL | DATE | TIME | TIMESTAMP | CHAR or 
VARCHAR | BINARY or VARBINARY
+|:------------------- |:---- |:------- |:------- |:-------- |:--- |:------ 
|:------- |:------------- |:------ |:-------- |:---- |:---- |:--------- 
|:--------------- |:-----------
+| NULL                | i    | i       | i       | i        | i   | i      | i 
      | i             | i      | i        | i    | i    | i         | i         
      | i
+| BOOLEAN             | x    | i       | e       | e        | e   | e      | e 
      | e             | e      | x        | x    | x    | x         | i         
      | x
+| TINYINT             | x    | e       | i       | i        | i   | i      | i 
      | i             | i      | e        | x    | x    | e         | i         
      | x
+| SMALLINT            | x    | e       | i       | i        | i   | i      | i 
      | i             | i      | e        | x    | x    | e         | i         
      | x
+| INT                 | x    | e       | i       | i        | i   | i      | i 
      | i             | i      | e        | x    | x    | e         | i         
      | x
+| BIGINT              | x    | e       | i       | i        | i   | i      | i 
      | i             | i      | e        | x    | x    | e         | i         
      | x
+| DECIMAL             | x    | e       | i       | i        | i   | i      | i 
      | i             | i      | e        | x    | x    | e         | i         
      | x
+| FLOAT/REAL          | x    | e       | i       | i        | i   | i      | i 
      | i             | i      | x        | x    | x    | e         | i         
      | x
+| DOUBLE              | x    | e       | i       | i        | i   | i      | i 
      | i             | i      | x        | x    | x    | e         | i         
      | x
+| INTERVAL            | x    | x       | e       | e        | e   | e      | e 
      | x             | x      | i        | x    | x    | x         | e         
      | x
+| DATE                | x    | x       | x       | x        | x   | x      | x 
      | x             | x      | x        | i    | x    | i         | i         
      | x
+| TIME                | x    | x       | x       | x        | x   | x      | x 
      | x             | x      | x        | x    | i    | e         | i         
      | x
+| TIMESTAMP           | x    | x       | e       | e        | e   | e      | e 
      | e             | e      | x        | i    | e    | i         | i         
      | x
+| CHAR or VARCHAR     | x    | e       | i       | i        | i   | i      | i 
      | i             | i      | i        | i    | i    | i         | i         
      | i
+| BINARY or VARBINARY | x    | x       | x       | x        | x   | x      | x 
      | x             | x      | x        | e    | e    | e         | i         
      | i
 
 i: implicit cast / e: explicit cast / x: not allowed
 
 ##### Conversion Contexts and Strategies
-* Set Operation(UNION/EXCEPT/INTERSECT): Compare every branch row data type 
and find the common type of each fields pair;
-* Arithmetic Expression: For binary arithmetic(`+`, `-`, `&`, `^`, `/`, `%`), 
promote string operand to data type of the other numeric operand;
-For binary comparison(`=`, `<`, `<=`, `<>`, `>`, `>=`),  
-  - If operands are STRING and TIMESTAMP, promotes to TIMESTAMP
-  - Make `1=true` and `0=false` always evaluates true
-  - Find common type for both operands if there is NUMERIC type operand
-* IN Expression: If with subquery, compare type of LHS and RHS, find the 
common type, if it is struct type, find wider type for every field;
-If without subquery and RHS is a node list, compare every node to find the 
common type;
-* CASE WHEN Expression(or COALESCE): Find then and else operands common wider 
type;
-* Datetime String +/- INTERVAL: Promote string to timestamp;
-* Builtin Function: Look up the families registered in the checker, find the 
family default type if checker rules allow it;
-* User Defined Function: Try to coerce based on the declared argument types of 
the `eval()` method.
+
+* Set operation (`UNION`, `EXCEPT`, `INTERSECT`): Compare every branch
+  row data type and find the common type of each fields pair;
+* Binary arithmetic expression (`+`, `-`, `&`, `^`, `/`, `%`): promote
+  string operand to data type of the other numeric operand;
+* Binary comparison (`=`, `<`, `<=`, `<>`, `>`, `>=`):
+  if operands are `STRING` and `TIMESTAMP`, promote to `TIMESTAMP`;
+  make `1 = true` and `0 = false` always evaluate to `TRUE`;
+  if there is numeric type operand, find common type for both operands.
+* `IN` sub-query: compare type of LHS and RHS, and find the common type;
+  if it is struct type, find wider type for every field;
+* `IN` expression list: compare every expression to find the common type;
+* `CASE WHEN` expression or `COALESCE`: find the common wider type of the 
`THEN`
+  and `ELSE` operands;
+* Character + `INTERVAL` or character - `INTERVAL`: Promote character to
+  `TIMESTAMP`;
+* Built-in function: Look up the type families registered in the checker,
+  find the family default type if checker rules allow it;
+* User-defined function (UDF): Coerce based on the declared argument types
+  of the `eval()` method.
 
 ##### Strategies for Finding Common Type
-- If the operator has expected data types, just take them as the desired one. 
(e.g. the UDF would have `eval()` method which has reflection argument types);
-- If there is no expected data type but the data type families are registered, 
try to coerce the arguments to the family's default data type, i.e. the String 
family will have a VARCHAR type;
-- If neither expected data type nor families are specified, try to find the 
tightest common type of the node types, i.e. INT and DOUBLE will return DOUBLE, 
the numeric precision does not lose for this case;
-- If no tightest common type is found, try to find a wider type, i.e. STRING 
and INT will return INT, we allow some precision loss when widening decimal to 
fractional, or promote to STRING type.
+
+* If the operator has expected data types, just take them as the
+  desired one. (e.g. the UDF would have `eval()` method which has
+  reflection argument types);
+* If there is no expected data type but the data type families are
+  registered, try to coerce the arguments to the family's default data
+  type, i.e. the String family will have a `VARCHAR` type;
+* If neither expected data type nor families are specified, try to
+  find the tightest common type of the node types, i.e. `INTEGER` and
+  `DOUBLE` will return `DOUBLE`, the numeric precision does not lose
+  for this case;
+* If no tightest common type is found, try to find a wider type,
+  i.e. `VARCHAR` and `INTEGER` will return `INTEGER`,
+  we allow some precision loss when widening decimal to fractional,
+  or promote to `VARCHAR` type.
 
 ### Value constructors
 

Reply via email to