001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.compile.LengthOperatorNode
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.compile;
023:
024: import org.apache.derby.iapi.services.sanity.SanityManager;
025:
026: import org.apache.derby.iapi.sql.compile.C_NodeTypes;
027:
028: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
029: import org.apache.derby.iapi.types.TypeId;
030: import org.apache.derby.iapi.types.DataTypeDescriptor;
031: import org.apache.derby.iapi.types.ConcatableDataValue;
032: import org.apache.derby.iapi.sql.compile.TypeCompiler;
033: import org.apache.derby.iapi.reference.SQLState;
034: import org.apache.derby.iapi.error.StandardException;
035: import org.apache.derby.iapi.reference.ClassName;
036: import org.apache.derby.iapi.reference.JDBC20Translation;
037:
038: import java.sql.Types;
039:
040: import java.util.Vector;
041:
042: /**
043: * This node represents a unary XXX_length operator
044: *
045: * @author Jeff Lichtman
046: */
047:
048: public final class LengthOperatorNode extends UnaryOperatorNode {
049: private int parameterType;
050: private int parameterWidth;
051:
052: public void setNodeType(int nodeType) {
053: String operator = null;
054: String methodName = null;
055:
056: if (nodeType == C_NodeTypes.CHAR_LENGTH_OPERATOR_NODE) {
057: operator = "char_length";
058: methodName = "charLength";
059: parameterType = Types.VARCHAR;
060: parameterWidth = TypeId.VARCHAR_MAXWIDTH;
061: } else {
062: if (SanityManager.DEBUG) {
063: SanityManager.THROWASSERT("Unexpected nodeType = "
064: + nodeType);
065: }
066: }
067: setOperator(operator);
068: setMethodName(methodName);
069: super .setNodeType(nodeType);
070: }
071:
072: /**
073: * Bind this operator
074: *
075: * @param fromList The query's FROM list
076: * @param subqueryList The subquery list being built as we find SubqueryNodes
077: * @param aggregateVector The aggregate vector being built as we find AggregateNodes
078: *
079: * @return The new top of the expression tree.
080: *
081: * @exception StandardException Thrown on error
082: */
083:
084: public ValueNode bindExpression(FromList fromList,
085: SubqueryList subqueryList, Vector aggregateVector)
086: throws StandardException {
087: TypeId operandType;
088:
089: super .bindExpression(fromList, subqueryList, aggregateVector);
090:
091: /*
092: ** Check the type of the operand - this function is allowed only on
093: ** string value types.
094: */
095: operandType = operand.getTypeId();
096: switch (operandType.getJDBCTypeId()) {
097: case Types.CHAR:
098: case Types.VARCHAR:
099: case Types.BINARY:
100: case Types.VARBINARY:
101: case Types.LONGVARBINARY:
102: case Types.LONGVARCHAR:
103: case JDBC20Translation.SQL_TYPES_BLOB:
104: case JDBC20Translation.SQL_TYPES_CLOB:
105: break;
106:
107: default:
108: throw StandardException.newException(
109: SQLState.LANG_UNARY_FUNCTION_BAD_TYPE,
110: getOperatorString(), operandType.getSQLTypeName());
111: }
112:
113: /*
114: ** The result type of XXX_length is int.
115: */
116: setType(new DataTypeDescriptor(TypeId.INTEGER_ID, operand
117: .getTypeServices().isNullable()));
118: return this ;
119: }
120:
121: /**
122: * Bind a ? parameter operand of the XXX_length function.
123: *
124: * @exception StandardException Thrown on error
125: */
126:
127: void bindParameter() throws StandardException {
128: /*
129: ** According to the SQL standard, if XXX_length has a ? operand,
130: ** its type is varchar with the implementation-defined maximum length
131: ** for a varchar.
132: */
133:
134: operand.setType(DataTypeDescriptor
135: .getBuiltInDataTypeDescriptor(parameterType, true,
136: parameterWidth));
137: }
138:
139: /**
140: * This is a length operator node. Overrides this method
141: * in UnaryOperatorNode for code generation purposes.
142: */
143: public String getReceiverInterfaceName() {
144: return ClassName.ConcatableDataValue;
145: }
146: }
|