--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.sql.compile.LengthOperatorNode\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.sql.compile;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.types.StringDataValue;\r
+import org.apache.derby.iapi.types.TypeId;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+import org.apache.derby.iapi.types.ConcatableDataValue;\r
+import org.apache.derby.iapi.sql.compile.TypeCompiler;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.reference.ClassName;\r
+import org.apache.derby.iapi.reference.JDBC20Translation;\r
+\r
+import java.sql.Types;\r
+\r
+import java.util.Vector;\r
+\r
+/**\r
+ * This node represents a unary XXX_length operator\r
+ *\r
+ */\r
+\r
+public final class LengthOperatorNode extends UnaryOperatorNode\r
+{\r
+ private int parameterType;\r
+ private int parameterWidth;\r
+\r
+ public void setNodeType(int nodeType)\r
+ {\r
+ String operator = null;\r
+ String methodName = null;\r
+\r
+ if (nodeType == C_NodeTypes.CHAR_LENGTH_OPERATOR_NODE)\r
+ {\r
+ operator = "char_length";\r
+ methodName = "charLength";\r
+ parameterType = Types.VARCHAR;\r
+ parameterWidth = TypeId.VARCHAR_MAXWIDTH;\r
+ }\r
+ else\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.THROWASSERT(\r
+ "Unexpected nodeType = " + nodeType);\r
+ }\r
+ }\r
+ setOperator(operator);\r
+ setMethodName(methodName);\r
+ super.setNodeType(nodeType);\r
+ }\r
+\r
+ /**\r
+ * Bind this operator\r
+ *\r
+ * @param fromList The query's FROM list\r
+ * @param subqueryList The subquery list being built as we find SubqueryNodes\r
+ * @param aggregateVector The aggregate vector being built as we find AggregateNodes\r
+ *\r
+ * @return The new top of the expression tree.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+\r
+ public ValueNode bindExpression(\r
+ FromList fromList, SubqueryList subqueryList,\r
+ Vector aggregateVector)\r
+ throws StandardException\r
+ {\r
+ TypeId operandType;\r
+\r
+ bindOperand(fromList, subqueryList,\r
+ aggregateVector);\r
+\r
+ /*\r
+ ** Check the type of the operand - this function is allowed only on\r
+ ** string value types. \r
+ */\r
+ operandType = operand.getTypeId();\r
+ switch (operandType.getJDBCTypeId())\r
+ {\r
+ case Types.CHAR:\r
+ case Types.VARCHAR:\r
+ case Types.BINARY:\r
+ case Types.VARBINARY:\r
+ case Types.LONGVARBINARY:\r
+ case Types.LONGVARCHAR:\r
+ case JDBC20Translation.SQL_TYPES_BLOB:\r
+ case JDBC20Translation.SQL_TYPES_CLOB:\r
+ break;\r
+ \r
+ default:\r
+ throw StandardException.newException(SQLState.LANG_UNARY_FUNCTION_BAD_TYPE,\r
+ getOperatorString(),\r
+ operandType.getSQLTypeName());\r
+ }\r
+\r
+ /*\r
+ ** The result type of XXX_length is int.\r
+ */\r
+ setType(new DataTypeDescriptor(\r
+ TypeId.INTEGER_ID,\r
+ operand.getTypeServices().isNullable()\r
+ )\r
+ );\r
+ return this;\r
+ }\r
+\r
+ /**\r
+ * Bind a ? parameter operand of the XXX_length function.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+\r
+ void bindParameter()\r
+ throws StandardException\r
+ {\r
+ /*\r
+ ** According to the SQL standard, if XXX_length has a ? operand,\r
+ ** its type is varchar with the implementation-defined maximum length\r
+ ** for a varchar.\r
+ ** Also, for XXX_length, it doesn't matter what is VARCHAR's collation \r
+ ** (since for XXX_length, no collation sensitive processing is \r
+ ** is required) and hence we will not worry about the collation setting\r
+ */\r
+\r
+ operand.setType(DataTypeDescriptor.getBuiltInDataTypeDescriptor(parameterType, true, \r
+ parameterWidth));\r
+ }\r
+\r
+ /**\r
+ * This is a length operator node. Overrides this method\r
+ * in UnaryOperatorNode for code generation purposes.\r
+ */\r
+ public String getReceiverInterfaceName() {\r
+ return ClassName.ConcatableDataValue;\r
+ }\r
+}\r