blob: 19a7c9d3f248010de54de49d1c0a1dc16e655a2c [file] [log] [blame]
/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde 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 org.eigenbase.sql;
import java.util.*;
import org.eigenbase.reltype.*;
import org.eigenbase.resource.*;
import org.eigenbase.sql.fun.*;
import org.eigenbase.sql.validate.*;
import org.eigenbase.util.*;
/**
* <code>SqlCallBinding</code> implements {@link SqlOperatorBinding} by
* analyzing to the operands of a {@link SqlCall} with a {@link SqlValidator}.
*
* @author Wael Chatila
* @version $Id$
*/
public class SqlCallBinding
extends SqlOperatorBinding
{
//~ Instance fields --------------------------------------------------------
private final SqlValidator validator;
private final SqlValidatorScope scope;
private final SqlCall call;
//~ Constructors -----------------------------------------------------------
/**
* Creates a call binding.
*
* @param validator Validator
* @param scope Scope of call
* @param call Call node
*/
public SqlCallBinding(
SqlValidator validator,
SqlValidatorScope scope,
SqlCall call)
{
super(
validator.getTypeFactory(),
call.getOperator());
this.validator = validator;
this.scope = scope;
this.call = call;
}
//~ Methods ----------------------------------------------------------------
/**
* Returns the validator.
*/
public SqlValidator getValidator()
{
return validator;
}
/**
* Returns the scope of the call.
*/
public SqlValidatorScope getScope()
{
return scope;
}
/**
* Returns the call node.
*/
public SqlCall getCall()
{
return call;
}
// implement SqlOperatorBinding
public String getStringLiteralOperand(int ordinal)
{
SqlNode node = call.operands[ordinal];
return SqlLiteral.stringValue(node);
}
// implement SqlOperatorBinding
public int getIntLiteralOperand(int ordinal)
{
//todo: move this to SqlTypeUtil
SqlNode node = call.operands[ordinal];
if (node instanceof SqlLiteral) {
SqlLiteral sqlLiteral = (SqlLiteral) node;
return sqlLiteral.intValue(true);
} else if (node instanceof SqlCall) {
final SqlCall c = (SqlCall) node;
if (c.getKind() == SqlKind.MINUS_PREFIX) {
SqlNode child = c.operands[0];
if (child instanceof SqlLiteral) {
return -((SqlLiteral) child).intValue(true);
}
}
}
throw Util.newInternal("should never come here");
}
// implement SqlOperatorBinding
public boolean isOperandNull(int ordinal, boolean allowCast)
{
return SqlUtil.isNullLiteral(call.operands[ordinal], allowCast);
}
// implement SqlOperatorBinding
public int getOperandCount()
{
return call.operands.length;
}
// implement SqlOperatorBinding
public RelDataType getOperandType(int ordinal)
{
final SqlNode operand = call.operands[ordinal];
final RelDataType type = validator.deriveType(scope, operand);
final SqlValidatorNamespace namespace = validator.getNamespace(operand);
if (namespace != null) {
return namespace.getRowTypeSansSystemColumns();
}
return type;
}
public RelDataType getCursorOperand(int ordinal)
{
final SqlNode operand = call.operands[ordinal];
if (!SqlUtil.isCallTo(operand, SqlStdOperatorTable.cursorConstructor)) {
return null;
}
final SqlCall cursorCall = (SqlCall) operand;
final SqlNode query = cursorCall.operands[0];
return validator.deriveType(scope, query);
}
// implement SqlOperatorBinding
public String getColumnListParamInfo(
int ordinal,
String paramName,
List<String> columnList)
{
final SqlNode operand = call.operands[ordinal];
if (!SqlUtil.isCallTo(operand, SqlStdOperatorTable.rowConstructor)) {
return null;
}
SqlNode [] operands = ((SqlCall) operand).getOperands();
for (int i = 0; i < operands.length; i++) {
SqlIdentifier id = (SqlIdentifier) operands[i];
columnList.add(id.getSimple());
}
return validator.getParentCursor(paramName);
}
public EigenbaseException newError(
SqlValidatorException e)
{
return validator.newValidationError(call, e);
}
/**
* Constructs a new validation signature error for the call.
*
* @return signature exception
*/
public EigenbaseException newValidationSignatureError()
{
return validator.newValidationError(
call,
EigenbaseResource.instance().CanNotApplyOp2Type.ex(
getOperator().getName(),
call.getCallSignature(validator, scope),
getOperator().getAllowedSignatures()));
}
/**
* Constructs a new validation error for the call. (Do not use this to
* construct a validation error for other nodes such as an operands.)
*
* @param ex underlying exception
*
* @return wrapped exception
*/
public EigenbaseException newValidationError(
SqlValidatorException ex)
{
return validator.newValidationError(call, ex);
}
}
// End SqlCallBinding.java