This is an automated email from the ASF dual-hosted git repository.
jhyde pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
The following commit(s) were added to refs/heads/master by this push:
new 77bb696 [CALCITE-4795] In class SqlBasicCall, make the "operands"
field private (part 2)
77bb696 is described below
commit 77bb696d020bea4467151109ffed4ced53ff0c2d
Author: Julian Hyde <[email protected]>
AuthorDate: Thu Sep 23 00:33:47 2021 -0700
[CALCITE-4795] In class SqlBasicCall, make the "operands" field private
(part 2)
This commit is part 2 of 2, after release 1.28, and removes
APIs marked 'deprecated to be removed before 1.29'.
The 'operands' field is now an immutable list (that may
contain null values). If a user calls setOperand, a new list
is created. Therefore operands do not need to be cloned when
the call is cloned.
The 'expanded' field has been removed, because it is typically
false. There is a sub-class where isExpanded() returns true.
---
.../calcite/rel/rel2sql/RelToSqlConverter.java | 14 +--
.../calcite/rex/RexSqlStandardConvertletTable.java | 39 +++----
.../java/org/apache/calcite/sql/SqlBasicCall.java | 118 ++++++++++++---------
.../calcite/sql/SqlNullTreatmentOperator.java | 4 +-
.../java/org/apache/calcite/sql/SqlOperator.java | 4 +-
.../calcite/sql/fun/SqlStdOperatorTable.java | 3 +-
.../calcite/sql/validate/SqlValidatorImpl.java | 11 +-
.../calcite/sql2rel/StandardConvertletTable.java | 3 +-
.../apache/calcite/util/ImmutableNullableList.java | 4 +-
9 files changed, 105 insertions(+), 95 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
b/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
index a8173fd..3dec153 100644
--- a/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
+++ b/core/src/main/java/org/apache/calcite/rel/rel2sql/RelToSqlConverter.java
@@ -1139,13 +1139,13 @@ public class RelToSqlConverter extends SqlImplementor
final Context context = tableFunctionScanContext(inputSqlNodes);
SqlNode callNode = context.toSql(null, e.getCall());
// Convert to table function call, "TABLE($function_name(xxx))"
- SqlNode tableCall = new SqlBasicCall(
- SqlStdOperatorTable.COLLECTION_TABLE,
- new SqlNode[] {callNode},
- SqlParserPos.ZERO);
- SqlNode select = new SqlSelect(
- SqlParserPos.ZERO, null, SqlNodeList.SINGLETON_STAR, tableCall,
- null, null, null, null, null, null, null, SqlNodeList.EMPTY);
+ SqlNode tableCall =
+ new SqlBasicCall(SqlStdOperatorTable.COLLECTION_TABLE,
+ ImmutableList.of(callNode), SqlParserPos.ZERO);
+ SqlNode select =
+ new SqlSelect(SqlParserPos.ZERO, null, SqlNodeList.SINGLETON_STAR,
+ tableCall, null, null, null, null, null, null, null,
+ SqlNodeList.EMPTY);
return result(select, ImmutableList.of(Clause.SELECT), e, null);
}
diff --git
a/core/src/main/java/org/apache/calcite/rex/RexSqlStandardConvertletTable.java
b/core/src/main/java/org/apache/calcite/rex/RexSqlStandardConvertletTable.java
index a828867..18b3c9d 100644
---
a/core/src/main/java/org/apache/calcite/rex/RexSqlStandardConvertletTable.java
+++
b/core/src/main/java/org/apache/calcite/rex/RexSqlStandardConvertletTable.java
@@ -31,7 +31,6 @@ import org.apache.calcite.sql.type.SqlTypeUtil;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
/**
@@ -153,7 +152,8 @@ public class RexSqlStandardConvertletTable
final SqlOperator op = call.getOperator();
final List<RexNode> operands = call.getOperands();
- final SqlNode[] exprs = convertExpressionList(converter, operands);
+ final @Nullable List<@Nullable SqlNode> exprs =
+ convertExpressionList(converter, operands);
if (exprs == null) {
return null;
}
@@ -163,17 +163,16 @@ public class RexSqlStandardConvertletTable
SqlParserPos.ZERO);
}
- private static SqlNode @Nullable [] convertExpressionList(
+ private static @Nullable List<@Nullable SqlNode> convertExpressionList(
RexToSqlNodeConverter converter,
List<RexNode> nodes) {
- final SqlNode[] exprs = new SqlNode[nodes.size()];
- for (int i = 0; i < nodes.size(); i++) {
- RexNode node = nodes.get(i);
- SqlNode converted = converter.convertNode(node);
+ final List<@Nullable SqlNode> exprs = new ArrayList<>();
+ for (RexNode node : nodes) {
+ @Nullable SqlNode converted = converter.convertNode(node);
if (converted == null) {
return null;
}
- exprs[i] = converted;
+ exprs.add(converted);
}
return exprs;
}
@@ -198,20 +197,15 @@ public class RexSqlStandardConvertletTable
private void registerTypeAppendOp(final SqlOperator op) {
registerOp(
op, (converter, call) -> {
- SqlNode[] operands =
+ @Nullable List<@Nullable SqlNode> operandList =
convertExpressionList(converter, call.operands);
- if (operands == null) {
+ if (operandList == null) {
return null;
}
- List<SqlNode> operandList =
- new ArrayList<>(Arrays.asList(operands));
SqlDataTypeSpec typeSpec =
SqlTypeUtil.convertTypeToSpec(call.getType());
operandList.add(typeSpec);
- return new SqlBasicCall(
- op,
- operandList.toArray(new SqlNode[0]),
- SqlParserPos.ZERO);
+ return new SqlBasicCall(op, operandList, SqlParserPos.ZERO);
});
}
@@ -225,7 +219,7 @@ public class RexSqlStandardConvertletTable
registerOp(
op, (converter, call) -> {
assert op instanceof SqlCaseOperator;
- SqlNode[] operands =
+ @Nullable List<@Nullable SqlNode> operands =
convertExpressionList(converter, call.operands);
if (operands == null) {
return null;
@@ -233,13 +227,13 @@ public class RexSqlStandardConvertletTable
SqlNodeList whenList = new SqlNodeList(SqlParserPos.ZERO);
SqlNodeList thenList = new SqlNodeList(SqlParserPos.ZERO);
int i = 0;
- while (i < operands.length - 1) {
- whenList.add(operands[i]);
+ while (i < operands.size() - 1) {
+ whenList.add(operands.get(i));
++i;
- thenList.add(operands[i]);
+ thenList.add(operands.get(i));
++i;
}
- SqlNode elseExpr = operands[i];
+ SqlNode elseExpr = operands.get(i);
return op.createCall(null, SqlParserPos.ZERO, null, whenList,
thenList, elseExpr);
});
}
@@ -254,7 +248,8 @@ public class RexSqlStandardConvertletTable
}
@Override public @Nullable SqlNode convertCall(RexToSqlNodeConverter
converter, RexCall call) {
- SqlNode[] operands = convertExpressionList(converter, call.operands);
+ @Nullable List<@Nullable SqlNode> operands =
+ convertExpressionList(converter, call.operands);
if (operands == null) {
return null;
}
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlBasicCall.java
b/core/src/main/java/org/apache/calcite/sql/SqlBasicCall.java
index 246748f..a3bb120 100755
--- a/core/src/main/java/org/apache/calcite/sql/SqlBasicCall.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlBasicCall.java
@@ -21,7 +21,6 @@ import org.apache.calcite.util.ImmutableNullableList;
import org.checkerframework.checker.nullness.qual.Nullable;
-import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -32,63 +31,50 @@ import static
org.apache.calcite.linq4j.Nullness.castNonNull;
*/
public class SqlBasicCall extends SqlCall {
private SqlOperator operator;
-
- /** Array of operands.
- *
- * @deprecated Use the methods {@link #getOperandList()} and
- * {@link #setOperand(int, SqlNode)}. To be removed before 1.29.
- */
- @Deprecated // to be removed before 1.29
- public final @Nullable SqlNode[] operands;
-
- private final List<@Nullable SqlNode> operandList;
+ private List<@Nullable SqlNode> operandList;
private final @Nullable SqlLiteral functionQuantifier;
- private final boolean expanded;
+ @Deprecated // to be removed before 2.0
public SqlBasicCall(
SqlOperator operator,
@Nullable SqlNode[] operands,
SqlParserPos pos) {
- this(operator, operands, pos, null, false);
+ this(operator, ImmutableNullableList.copyOf(operands), pos, null);
}
/** Creates a SqlBasicCall.
*
- * @deprecated Use
- * {@link #SqlBasicCall(SqlOperator, SqlNode[], SqlParserPos, SqlLiteral)}
- * followed by {@link #withExpanded(boolean)}. To be removed before 1.29.
- */
- @Deprecated // to be removed before 1.29
+ * <p>It is not expanded; call {@link #withExpanded withExpanded(true)}
+ * to expand. */
public SqlBasicCall(
SqlOperator operator,
- @Nullable SqlNode[] operands,
- SqlParserPos pos,
- boolean expanded,
- @Nullable SqlLiteral functionQualifier) {
- this(operator, operands, pos, functionQualifier, expanded);
+ List<? extends @Nullable SqlNode> operandList,
+ SqlParserPos pos) {
+ this(operator, operandList, pos, null);
}
- /** Creates an unexpanded SqlBasicCall. */
+ @Deprecated // to be removed before 2.0
public SqlBasicCall(
SqlOperator operator,
@Nullable SqlNode[] operands,
SqlParserPos pos,
@Nullable SqlLiteral functionQualifier) {
- this(operator, operands, pos, functionQualifier, false);
+ this(operator, ImmutableNullableList.copyOf(operands), pos,
+ functionQualifier);
}
- /** Private constructor. */
- private SqlBasicCall(
+ /** Creates a SqlBasicCall with an optional function qualifier.
+ *
+ * <p>It is not expanded; call {@link #withExpanded withExpanded(true)}
+ * to expand. */
+ public SqlBasicCall(
SqlOperator operator,
- @Nullable SqlNode[] operands,
+ List<? extends @Nullable SqlNode> operandList,
SqlParserPos pos,
- @Nullable SqlLiteral functionQualifier,
- boolean expanded) {
+ @Nullable SqlLiteral functionQualifier) {
super(pos);
this.operator = Objects.requireNonNull(operator, "operator");
- this.operands = operands;
- this.operandList = Arrays.asList(operands);
- this.expanded = expanded;
+ this.operandList = ImmutableNullableList.copyOf(operandList);
this.functionQuantifier = functionQualifier;
}
@@ -96,20 +82,25 @@ public class SqlBasicCall extends SqlCall {
return operator.getKind();
}
- @Override public boolean isExpanded() {
- return expanded;
- }
-
+ /** Sets whether this call is expanded.
+ *
+ * @see #isExpanded() */
public SqlCall withExpanded(boolean expanded) {
- return expanded == this.expanded ? this
- : new SqlBasicCall(operator, operandList.toArray(new SqlNode[0]), pos,
- functionQuantifier, expanded);
+ return !expanded
+ ? this
+ : new ExpandedBasicCall(operator, operandList, pos,
+ functionQuantifier);
}
@Override public void setOperand(int i, @Nullable SqlNode operand) {
- operandList.set(i, operand);
+ operandList = set(operandList, i, operand);
}
+ /** Sets the operator (or function) that is being called.
+ *
+ * <p>This method is used by the validator to set a more refined version of
+ * the same operator (for instance, a version where overloading has been
+ * resolved); use with care. */
public void setOperator(SqlOperator operator) {
this.operator = Objects.requireNonNull(operator, "operator");
}
@@ -118,19 +109,9 @@ public class SqlBasicCall extends SqlCall {
return operator;
}
- /** Returns the array of operands.
- *
- * @deprecated Use the methods {@link #getOperandList()} and
- * {@link #setOperand(int, SqlNode)}. To be removed before 1.29.
- */
- @Deprecated // to be removed before 1.29
- public @Nullable SqlNode[] getOperands() {
- return operands;
- }
-
@SuppressWarnings("nullness")
@Override public List<SqlNode> getOperandList() {
- return ImmutableNullableList.copyOf(operandList);
+ return operandList;
}
@SuppressWarnings("unchecked")
@@ -150,4 +131,37 @@ public class SqlBasicCall extends SqlCall {
return getOperator().createCall(getFunctionQuantifier(), pos, operandList);
}
+ /** Sets the {@code i}th element of {@code list} to value {@code e}, creating
+ * an immutable copy of the list. */
+ private static <E> List<@Nullable E> set(List<E> list, int i, @Nullable E e)
{
+ if (i == 0 && list.size() == 1) {
+ // short-cut case where the contents of the previous list can be ignored
+ return ImmutableNullableList.of(e);
+ }
+ //noinspection unchecked
+ @Nullable E[] objects = (E[]) list.toArray();
+ objects[i] = e;
+ return ImmutableNullableList.copyOf(objects);
+ }
+
+ /** Sub-class of {@link org.apache.calcite.sql.SqlBasicCall}
+ * for which {@link #isExpanded()} returns true. */
+ private static class ExpandedBasicCall extends SqlBasicCall {
+ ExpandedBasicCall(SqlOperator operator,
+ List<? extends @Nullable SqlNode> operandList, SqlParserPos pos,
+ @Nullable SqlLiteral functionQualifier) {
+ super(operator, operandList, pos, functionQualifier);
+ }
+
+ @Override public boolean isExpanded() {
+ return true;
+ }
+
+ @Override public SqlCall withExpanded(boolean expanded) {
+ return expanded
+ ? this
+ : new SqlBasicCall(getOperator(), getOperandList(), pos,
+ getFunctionQuantifier());
+ }
+ }
}
diff --git
a/core/src/main/java/org/apache/calcite/sql/SqlNullTreatmentOperator.java
b/core/src/main/java/org/apache/calcite/sql/SqlNullTreatmentOperator.java
index d70046f..590aac2 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlNullTreatmentOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlNullTreatmentOperator.java
@@ -21,6 +21,7 @@ import org.apache.calcite.sql.type.OperandTypes;
import org.apache.calcite.sql.type.ReturnTypes;
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorScope;
+import org.apache.calcite.util.ImmutableNullableList;
import com.google.common.base.Preconditions;
@@ -47,7 +48,8 @@ public class SqlNullTreatmentOperator extends
SqlSpecialOperator {
@Override public SqlCall createCall(@Nullable SqlLiteral functionQualifier,
SqlParserPos pos, @Nullable SqlNode... operands) {
// As super.createCall, but don't union the positions
- return new SqlBasicCall(this, operands, pos, functionQualifier);
+ return new SqlBasicCall(this, ImmutableNullableList.copyOf(operands), pos,
+ functionQualifier);
}
@Override public void unparse(SqlWriter writer, SqlCall call, int leftPrec,
diff --git a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
index 4d89a12..3dd7105 100644
--- a/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
+++ b/core/src/main/java/org/apache/calcite/sql/SqlOperator.java
@@ -33,6 +33,7 @@ import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorImpl;
import org.apache.calcite.sql.validate.SqlValidatorScope;
import org.apache.calcite.sql.validate.SqlValidatorUtil;
+import org.apache.calcite.util.ImmutableNullableList;
import org.apache.calcite.util.Litmus;
import org.apache.calcite.util.Util;
@@ -274,7 +275,8 @@ public abstract class SqlOperator {
SqlParserPos pos,
@Nullable SqlNode... operands) {
pos = pos.plusAll(operands);
- return new SqlBasicCall(this, operands, pos, functionQualifier);
+ return new SqlBasicCall(this, ImmutableNullableList.copyOf(operands), pos,
+ functionQualifier);
}
/** Not supported. Choose between
diff --git
a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
index 3385743..342719f 100644
--- a/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
+++ b/core/src/main/java/org/apache/calcite/sql/fun/SqlStdOperatorTable.java
@@ -2622,8 +2622,7 @@ public class SqlStdOperatorTable extends
ReflectiveSqlOperatorTable {
/** Creates a copy of a call with a new operator. */
private static SqlCall copy(SqlCall call, SqlOperator operator) {
- final List<SqlNode> list = call.getOperandList();
- return new SqlBasicCall(operator, list.toArray(new SqlNode[0]),
+ return new SqlBasicCall(operator, call.getOperandList(),
call.getParserPosition());
}
diff --git
a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
index 0f607d9..99eb9f9 100644
--- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
+++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java
@@ -1821,7 +1821,7 @@ public class SqlValidatorImpl implements
SqlValidatorWithHints {
// actually a call to a function. Construct a fake
// call to this function, so we can use the regular
// operator validation.
- return new SqlBasicCall(operator, SqlNode.EMPTY_ARRAY,
+ return new SqlBasicCall(operator, ImmutableList.of(),
id.getParserPosition(), null).withExpanded(true);
}
}
@@ -6443,14 +6443,11 @@ public class SqlValidatorImpl implements
SqlValidatorWithHints {
&& !DynamicRecordType.isDynamicStarColName(Util.last(id.names))) {
// Convert a column ref into ITEM(*, 'col_name')
// for a dynamic star field in dynTable's rowType.
- SqlNode[] inputs = new SqlNode[2];
- inputs[0] = fqId;
- inputs[1] = SqlLiteral.createCharString(
- Util.last(id.names),
- id.getParserPosition());
return new SqlBasicCall(
SqlStdOperatorTable.ITEM,
- inputs,
+ ImmutableList.of(fqId,
+ SqlLiteral.createCharString(Util.last(id.names),
+ id.getParserPosition())),
id.getParserPosition());
}
return fqId;
diff --git
a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
index 9e0bc9e..f02a986 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/StandardConvertletTable.java
@@ -1152,8 +1152,7 @@ public class StandardConvertletTable extends
ReflectiveConvertletTable {
private RexNode toRex(SqlRexContext cx, SqlBasicCall call, SqlFunction f) {
final SqlCall call2 =
- new SqlBasicCall(f, call.getOperandList().toArray(new SqlNode[0]),
- call.getParserPosition());
+ new SqlBasicCall(f, call.getOperandList(), call.getParserPosition());
final SqlRexConvertlet convertlet = requireNonNull(get(call2));
return convertlet.convertCall(cx, call2);
}
diff --git
a/core/src/main/java/org/apache/calcite/util/ImmutableNullableList.java
b/core/src/main/java/org/apache/calcite/util/ImmutableNullableList.java
index 45fa177..2d88c11 100644
--- a/core/src/main/java/org/apache/calcite/util/ImmutableNullableList.java
+++ b/core/src/main/java/org/apache/calcite/util/ImmutableNullableList.java
@@ -20,6 +20,8 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
import java.util.AbstractList;
import java.util.ArrayList;
import java.util.Collection;
@@ -120,7 +122,7 @@ public class ImmutableNullableList<E> extends
AbstractList<E> {
}
/** Creates an immutable list of 1 element. */
- public static <E> List<E> of(E e1) {
+ public static <E> List<E> of(@Nullable E e1) {
//noinspection unchecked
return e1 == null ? (List<E>) SINGLETON_NULL : ImmutableList.of(e1);
}