|
56 | 56 | * analyzing to the operands of a {@link SqlCall} with a {@link SqlValidator}.
|
57 | 57 | */
|
58 | 58 | public class SqlCallBinding extends SqlOperatorBinding {
|
59 |
| - private static final SqlCall DEFAULT_CALL = |
60 |
| - SqlStdOperatorTable.DEFAULT.createCall(SqlParserPos.ZERO); |
| 59 | + |
| 60 | + /** Static nested class required due to |
| 61 | + * <a href="https://issues.apache.org/jira/browse/CALCITE-4393">[CALCITE-4393] |
| 62 | + * ExceptionInInitializerError due to NPE in SqlCallBinding caused by circular dependency</a>. |
| 63 | + * The static field inside it cannot be part of the outer class: it must be defined |
| 64 | + * within a nested class in order to break the cycle during class loading. */ |
| 65 | + private static class DefaultCallHolder { |
| 66 | + private static final SqlCall DEFAULT_CALL = |
| 67 | + SqlStdOperatorTable.DEFAULT.createCall(SqlParserPos.ZERO); |
| 68 | + } |
| 69 | + |
61 | 70 | //~ Instance fields --------------------------------------------------------
|
62 | 71 |
|
63 | 72 | private final SqlValidator validator;
|
@@ -148,7 +157,7 @@ public List<SqlNode> operands() {
|
148 | 157 | while (list.size() < range.getMax()
|
149 | 158 | && checker.isOptional(list.size())
|
150 | 159 | && checker.isFixedParameters()) {
|
151 |
| - list.add(DEFAULT_CALL); |
| 160 | + list.add(DefaultCallHolder.DEFAULT_CALL); |
152 | 161 | }
|
153 | 162 | return list;
|
154 | 163 | }
|
@@ -201,7 +210,7 @@ private List<SqlNode> permutedOperands(final SqlCall call) {
|
201 | 210 | // with DEFAULT and then convert to nulls during sql-to-rel conversion.
|
202 | 211 | // Thus, there is no need to show the optional operands in the plan and
|
203 | 212 | // decide if the optional operand is null when code generation.
|
204 |
| - permuted.add(DEFAULT_CALL); |
| 213 | + permuted.add(DefaultCallHolder.DEFAULT_CALL); |
205 | 214 | }
|
206 | 215 | }
|
207 | 216 | }
|
|
0 commit comments