com.hazelcast.org.apache.calcite.sql.util.SqlShuttle Maven / Gradle / Ivy
/*
* 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 com.hazelcast.org.apache.calcite.sql.util;
import com.hazelcast.org.apache.calcite.sql.SqlCall;
import com.hazelcast.org.apache.calcite.sql.SqlDataTypeSpec;
import com.hazelcast.org.apache.calcite.sql.SqlDynamicParam;
import com.hazelcast.org.apache.calcite.sql.SqlIdentifier;
import com.hazelcast.org.apache.calcite.sql.SqlIntervalQualifier;
import com.hazelcast.org.apache.calcite.sql.SqlLiteral;
import com.hazelcast.org.apache.calcite.sql.SqlNode;
import com.hazelcast.org.apache.calcite.sql.SqlNodeList;
import java.util.ArrayList;
import java.util.List;
/**
* Basic implementation of {@link SqlVisitor} which returns each leaf node
* unchanged.
*
* This class is useful as a base class for classes which implement the
* {@link SqlVisitor} interface and have {@link SqlNode} as the return type. The
* derived class can override whichever methods it chooses.
*/
public class SqlShuttle extends SqlBasicVisitor {
//~ Methods ----------------------------------------------------------------
public SqlNode visit(SqlLiteral literal) {
return literal;
}
public SqlNode visit(SqlIdentifier id) {
return id;
}
public SqlNode visit(SqlDataTypeSpec type) {
return type;
}
public SqlNode visit(SqlDynamicParam param) {
return param;
}
public SqlNode visit(SqlIntervalQualifier intervalQualifier) {
return intervalQualifier;
}
public SqlNode visit(final SqlCall call) {
// Handler creates a new copy of 'call' only if one or more operands
// change.
ArgHandler argHandler = new CallCopyingArgHandler(call, false);
call.getOperator().acceptCall(this, call, false, argHandler);
return argHandler.result();
}
public SqlNode visit(SqlNodeList nodeList) {
boolean update = false;
List exprs = nodeList.getList();
int exprCount = exprs.size();
List newList = new ArrayList<>(exprCount);
for (SqlNode operand : exprs) {
SqlNode clonedOperand;
if (operand == null) {
clonedOperand = null;
} else {
clonedOperand = operand.accept(this);
if (clonedOperand != operand) {
update = true;
}
}
newList.add(clonedOperand);
}
if (update) {
return new SqlNodeList(newList, nodeList.getParserPosition());
} else {
return nodeList;
}
}
//~ Inner Classes ----------------------------------------------------------
/**
* Implementation of
* {@link com.hazelcast.org.apache.calcite.sql.util.SqlBasicVisitor.ArgHandler}
* that deep-copies {@link SqlCall}s and their operands.
*/
protected class CallCopyingArgHandler implements ArgHandler {
boolean update;
SqlNode[] clonedOperands;
private final SqlCall call;
private final boolean alwaysCopy;
public CallCopyingArgHandler(SqlCall call, boolean alwaysCopy) {
this.call = call;
this.update = false;
final List operands = call.getOperandList();
this.clonedOperands = operands.toArray(new SqlNode[0]);
this.alwaysCopy = alwaysCopy;
}
public SqlNode result() {
if (update || alwaysCopy) {
return call.getOperator().createCall(
call.getFunctionQuantifier(),
call.getParserPosition(),
clonedOperands);
} else {
return call;
}
}
public SqlNode visitChild(
SqlVisitor visitor,
SqlNode expr,
int i,
SqlNode operand) {
if (operand == null) {
return null;
}
SqlNode newOperand = operand.accept(SqlShuttle.this);
if (newOperand != operand) {
update = true;
}
clonedOperands[i] = newOperand;
return newOperand;
}
}
}