Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / sql / compile / sqlgrammar.jj
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
new file mode 100644 (file)
index 0000000..f80c6a1
--- /dev/null
@@ -0,0 +1,13154 @@
+options\r
+{\r
+       STATIC = false;\r
+       LOOKAHEAD = 1;\r
+       DEBUG_PARSER = false;\r
+       DEBUG_LOOKAHEAD = false;\r
+       DEBUG_TOKEN_MANAGER = false;\r
+       ERROR_REPORTING = true;\r
+       USER_TOKEN_MANAGER = false;\r
+       USER_CHAR_STREAM = true;\r
+       COMMON_TOKEN_ACTION = true;\r
+       CACHE_TOKENS = true;\r
+       UNICODE_INPUT = true;\r
+}\r
+\r
+PARSER_BEGIN(SQLParser)\r
+\r
+/*\r
+\r
+   Derby - File org.apache.derby.impl.sql.compile.sqlgrammar.jj\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.sql.Statement;\r
+import org.apache.derby.iapi.sql.StatementType;\r
+\r
+/* aggregates */\r
+import org.apache.derby.impl.sql.compile.CountAggregateDefinition;\r
+import org.apache.derby.impl.sql.compile.MaxMinAggregateDefinition;\r
+import org.apache.derby.impl.sql.compile.SumAvgAggregateDefinition;\r
+\r
+import org.apache.derby.impl.sql.compile.AggregateNode;\r
+import org.apache.derby.impl.sql.compile.BinaryOperatorNode;\r
+import org.apache.derby.impl.sql.compile.CallStatementNode;\r
+import org.apache.derby.impl.sql.compile.CharConstantNode;\r
+import org.apache.derby.impl.sql.compile.CastNode;\r
+import org.apache.derby.impl.sql.compile.ColumnDefinitionNode;\r
+import org.apache.derby.impl.sql.compile.ColumnReference;\r
+import org.apache.derby.impl.sql.compile.CursorNode;\r
+import org.apache.derby.impl.sql.compile.FromBaseTable;\r
+import org.apache.derby.impl.sql.compile.FromList;\r
+import org.apache.derby.impl.sql.compile.FromSubquery;\r
+import org.apache.derby.impl.sql.compile.FromTable;\r
+import org.apache.derby.impl.sql.compile.GroupByList;\r
+import org.apache.derby.impl.sql.compile.HasNodeVisitor;\r
+import org.apache.derby.impl.sql.compile.JavaToSQLValueNode;\r
+import org.apache.derby.impl.sql.compile.JoinNode;\r
+import org.apache.derby.impl.sql.compile.MethodCallNode;\r
+import org.apache.derby.impl.sql.compile.QueryTreeNode;\r
+import org.apache.derby.impl.sql.compile.ReplaceAggregatesWithCRVisitor;\r
+import org.apache.derby.impl.sql.compile.ResultColumnList;\r
+import org.apache.derby.impl.sql.compile.ResultColumn;\r
+import org.apache.derby.impl.sql.compile.OrderByList;\r
+import org.apache.derby.impl.sql.compile.OrderByColumn;\r
+import org.apache.derby.impl.sql.compile.ResultSetNode;\r
+import org.apache.derby.impl.sql.compile.SelectNode;\r
+import org.apache.derby.impl.sql.compile.SubqueryNode;\r
+import org.apache.derby.impl.sql.compile.TableName;\r
+import org.apache.derby.impl.sql.compile.TernaryOperatorNode;\r
+import org.apache.derby.impl.sql.compile.ParameterNode;\r
+import org.apache.derby.impl.sql.compile.PrivilegeNode;\r
+import org.apache.derby.impl.sql.compile.ConstraintDefinitionNode;\r
+import org.apache.derby.impl.sql.compile.DMLModStatementNode;\r
+import org.apache.derby.impl.sql.compile.RoutineDesignator;\r
+import org.apache.derby.impl.sql.compile.StatementNode;\r
+import org.apache.derby.impl.sql.compile.TableElementList;\r
+import org.apache.derby.impl.sql.compile.TableElementNode;\r
+import org.apache.derby.impl.sql.compile.TableOperatorNode;\r
+import org.apache.derby.impl.sql.compile.TablePrivilegesNode;\r
+import org.apache.derby.impl.sql.compile.TransactionStatementNode;\r
+import org.apache.derby.impl.sql.compile.TriggerReferencingStruct;\r
+import org.apache.derby.impl.sql.compile.UnionNode;\r
+import org.apache.derby.impl.sql.compile.IntersectOrExceptNode;\r
+import org.apache.derby.impl.sql.compile.UnaryOperatorNode;\r
+import org.apache.derby.impl.sql.compile.UntypedNullConstantNode;\r
+import org.apache.derby.impl.sql.compile.UpdateNode;\r
+import org.apache.derby.impl.sql.compile.UserTypeConstantNode;\r
+import org.apache.derby.impl.sql.compile.ValueNode;\r
+import org.apache.derby.impl.sql.compile.ValueNodeList;\r
+import org.apache.derby.impl.sql.compile.GroupByColumn;\r
+import org.apache.derby.impl.sql.compile.CurrentDatetimeOperatorNode;\r
+import org.apache.derby.impl.sql.compile.DDLStatementNode;\r
+import org.apache.derby.impl.sql.compile.AlterTableNode;\r
+\r
+import org.apache.derby.impl.sql.compile.ParseException;\r
+import org.apache.derby.impl.sql.compile.Token;\r
+import org.apache.derby.impl.sql.compile.TokenMgrError;\r
+import org.apache.derby.impl.sql.compile.SQLParserConstants;\r
+import org.apache.derby.impl.sql.compile.CharStream;\r
+import org.apache.derby.impl.sql.execute.TablePrivilegeInfo;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TriggerDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.ViewDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;\r
+\r
+import org.apache.derby.iapi.sql.conn.Authorizer;\r
+import org.apache.derby.iapi.sql.execute.ConstantAction;\r
+import org.apache.derby.iapi.sql.execute.ExecutionContext;\r
+\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+import org.apache.derby.iapi.types.TypeId;\r
+import org.apache.derby.iapi.sql.compile.TypeCompiler;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+\r
+import org.apache.derby.iapi.types.DateTimeDataValue;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+import org.apache.derby.iapi.types.DataTypeUtilities;\r
+import org.apache.derby.iapi.types.StringDataValue;\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.reference.Property;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.reference.JDBC30Translation;\r
+import org.apache.derby.iapi.reference.Limits;\r
+\r
+import org.apache.derby.iapi.sql.compile.CompilerContext;\r
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;\r
+\r
+import org.apache.derby.iapi.services.context.ContextManager;\r
+\r
+import org.apache.derby.iapi.sql.compile.NodeFactory;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.catalog.AliasInfo;\r
+import org.apache.derby.catalog.TypeDescriptor;\r
+import org.apache.derby.catalog.types.RoutineAliasInfo;\r
+\r
+import org.apache.derby.iapi.services.io.FormatableProperties;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+import org.apache.derby.iapi.util.ReuseFactory;\r
+import org.apache.derby.iapi.services.io.FormatableBitSet;\r
+import org.apache.derby.iapi.util.StringUtil;\r
+\r
+import java.sql.Types;\r
+import java.util.List;\r
+import java.util.ArrayList;\r
+import java.util.Hashtable;\r
+import java.util.Properties;\r
+import java.util.StringTokenizer;\r
+import java.util.Vector;\r
+import java.lang.Character;\r
+\r
+public class SQLParser\r
+{\r
+       private static final String[] SAVEPOINT_CLAUSE_NAMES = {"UNIQUE", "ON ROLLBACK RETAIN LOCKS", "ON ROLLBACK RETAIN CURSORS"};\r
+       private static final String[] ROUTINE_CLAUSE_NAMES =\r
+               {null, "SPECIFIC", "RESULT SET", "LANGUAGE", "EXTERNAL NAME", "PARAMETER STYLE", "SQL", "ON NULL INPUT"};\r
+       /**\r
+          Clauses required for Java routines. Numbers correspond\r
+          to offsets in ROUTINE_CLAUSE_NAMES.\r
+          3 - "LANGUAGE"\r
+          4 - "EXTERNAL NAME"\r
+          5 - "PARAMETER STYLE"\r
+       */\r
+       private static final int[] JAVA_ROUTINE_CLAUSES = {3,4,5};\r
+       private static final String[] TEMPORARY_TABLE_CLAUSE_NAMES = {"NOT LOGGED", "ON COMMIT", "ON ROLLBACK"};\r
+       /* The default length of a char or bit if the length is omitted */\r
+       private static final int        DEFAULT_STRING_COLUMN_LENGTH = 1;\r
+\r
+       // Defines for ON or USING clauses\r
+       private static final int        ON_OR_USING_CLAUSE_SIZE = 2;\r
+       private static final int        ON_CLAUSE = 0;\r
+       private static final int        USING_CLAUSE = 1;\r
+\r
+       // Defines for optional table clauses\r
+       private static final int        OPTIONAL_TABLE_CLAUSES_SIZE = 3;\r
+       private static final int        OPTIONAL_TABLE_CLAUSES_TABLE_PROPERTIES = 0;\r
+       private static final int        OPTIONAL_TABLE_CLAUSES_DERIVED_RCL = 1;\r
+       private static final int        OPTIONAL_TABLE_CLAUSES_CORRELATION_NAME = 2;\r
+\r
+       // Define for UTF8 max\r
+       private static final int        MAX_UTF8_LENGTH = 65535;\r
+\r
+    // Constants for set operator types\r
+    private static final int NO_SET_OP = 0;\r
+    private static final int UNION_OP = 1;\r
+    private static final int UNION_ALL_OP = 2;\r
+    private static final int EXCEPT_OP = 3;\r
+    private static final int EXCEPT_ALL_OP = 4;\r
+    private static final int INTERSECT_OP = 5;\r
+    private static final int INTERSECT_ALL_OP = 6;\r
+\r
+       private Object[]                                        paramDefaults;\r
+       private String                                          statementSQLText;\r
+       private NodeFactory                                     nodeFactory;\r
+       private ContextManager                          cm;\r
+       private CompilerContext                         compilerContext;\r
+\r
+       /* The number of the next ? parameter */\r
+       private int                     parameterNumber;\r
+\r
+       /* The list of ? parameters */\r
+       private Vector                  parameterList;\r
+\r
+       /* Remember if the last identifier or keyword was a\r
+        * delimited identifier.  This is used for remembering\r
+        * if the xxx in SERIALIZE(xxx) was a delimited identifier\r
+        * because we need to know whether or not we can convert\r
+        * xxx to upper case if we try to resolve it as a class\r
+        * alias at bind time.\r
+        */\r
+       private Boolean lastTokenDelimitedIdentifier = Boolean.FALSE;\r
+       private Boolean nextToLastTokenDelimitedIdentifier = Boolean.FALSE;\r
+\r
+\r
+       /*\r
+       ** Remember the last token we got that was an identifier\r
+       */      \r
+       private Token   lastIdentifierToken;\r
+       private Token   nextToLastIdentifierToken;\r
+\r
+       static final String SINGLEQUOTES = "\'\'";\r
+       static final String DOUBLEQUOTES = "\"\"";\r
+\r
+       static final String DEFAULT_INDEX_TYPE = "BTREE";\r
+\r
+       //the following 2 booleans are used to make sure only null or not null is\r
+       //defined for a column while creating a table or altering a table. Defining\r
+       //both at the same time will be an error case.\r
+        boolean explicitNotNull = false;\r
+        boolean explicitNull = false;\r
+\r
+       //this vector keeps a list of explicitly nullable columns, so that if they\r
+       //get used in the table level primary key constraint, it will result in an\r
+       //exception.    \r
+        Vector explicitlyNullableColumnsList = new Vector();\r
+\r
+\r
+       final void setCompilerContext(CompilerContext cc) {\r
+               this.compilerContext = cc;\r
+               this.cm = cc.getContextManager();\r
+       }\r
+\r
+       /**\r
+         *     Get the NodeFactory for this database.\r
+         *\r
+         *     @return The NodeFactory for this database.\r
+         * @exception StandardException                Thrown on error\r
+         */\r
+       private final NodeFactory       getNodeFactory()        throws StandardException\r
+       {\r
+               if ( nodeFactory == null )\r
+               {\r
+                       nodeFactory = getCompilerContext().getNodeFactory();\r
+               }\r
+\r
+               return  nodeFactory;\r
+       }\r
+\r
+       private final CompilerContext getCompilerContext()\r
+       {               \r
+               return compilerContext;                 \r
+       }\r
+\r
+       private DataTypeDescriptor getDataTypeServices(int type, int precision, int scale,\r
+                       int length)\r
+       {\r
+               return new DataTypeDescriptor(\r
+                                       TypeId.getBuiltInTypeId(type),\r
+                                       precision,\r
+                                       scale,\r
+                                       true, /* assume nullable for now, change it if not nullable */\r
+                                       length\r
+                               );\r
+       }\r
+\r
+       private DataTypeDescriptor getJavaClassDataTypeDescriptor(String javaClassName) \r
+       {\r
+               return new DataTypeDescriptor(\r
+                                       TypeId.getUserDefinedTypeId(\r
+                                                               javaClassName, \r
+                                                               lastTokenDelimitedIdentifier.booleanValue()),\r
+                                       true);\r
+       }\r
+       private LanguageConnectionContext getLanguageConnectionContext()\r
+       {\r
+               return (LanguageConnectionContext) getContextManager().getContext(\r
+                                                                               LanguageConnectionContext.CONTEXT_ID);\r
+       }\r
+\r
+       /**\r
+               Utility method for checking that the underlying database has been\r
+               upgraded to the required level to use this functionality. Used to\r
+               disallow SQL statements that would leave on-disk formats that would\r
+               not be understood by a engine that matches the current upgrade level\r
+               of the database. Throws an exception if the database is not a the required level.\r
+               <P>\r
+               Typically used for CREATE statements at the parser level. Called usually just\r
+               before the node is created, or can be called in just a partial syntax fragment\r
+               \r
+               @param version Data Dictionary major version (DataDictionary.DD_ constant)\r
+               @param feature SQL Feature name, for error text.\r
+       */\r
+       private void checkVersion(int version, String feature) throws StandardException\r
+       {\r
+               getLanguageConnectionContext().getDataDictionary().checkVersion(\r
+                               version, feature);\r
+       }\r
+\r
+    /**\r
+               Utility method for checking that the underlying database uses SQL standard\r
+               permission checking (GRANT/REVOKE).\r
+\r
+               @param command "GRANT" or "REVOKE"\r
+    */\r
+       private void checkSqlStandardAccess( String command) throws StandardException\r
+       {\r
+               if( getLanguageConnectionContext().usesSqlAuthorization())\r
+                       return;\r
+\r
+               throw StandardException.newException(SQLState.LANG_GRANT_REVOKE_WITH_LEGACY_ACCESS,\r
+                                                                                       command,\r
+                                                                                       Property.SQL_AUTHORIZATION_PROPERTY,\r
+                                                                                       "TRUE");\r
+       }\r
+\r
+\r
+       /**\r
+               Check that the current mode supports internal extensions.\r
+\r
+               @param feature Description of feature for exception.\r
+\r
+               @exception StandardException current mode does not support statement\r
+       */\r
+       private void checkInternalFeature(String feature) throws StandardException\r
+       {\r
+               CompilerContext cc = getCompilerContext();\r
+               if ((cc.getReliability() & CompilerContext.INTERNAL_SQL_ILLEGAL) != 0)\r
+                       throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, feature);\r
+       }\r
+\r
+       /**\r
+        * check if the type length is ok for the given type.\r
+        */\r
+       private void checkTypeLimits(int type, int length)\r
+               throws StandardException\r
+       {       \r
+       boolean valid = true;\r
+\r
+               \r
+       switch (type) {\r
+               case Types.BINARY:\r
+               case Types.CHAR:\r
+                       if (length  > Limits.DB2_CHAR_MAXWIDTH)\r
+                               valid = false;\r
+                       break;\r
+                       \r
+               case Types.VARBINARY:\r
+               case Types.VARCHAR:\r
+                       if (length  > Limits.DB2_VARCHAR_MAXWIDTH)\r
+                               valid = false;\r
+\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+       if (!valid)  // If these limits are too big \r
+               {\r
+                       DataTypeDescriptor charDTD = \r
+                               DataTypeDescriptor.getBuiltInDataTypeDescriptor(type, length);\r
+       \r
+                       throw StandardException.newException(SQLState.LANG_DB2_LENGTH_PRECISION_SCALE_VIOLATION, charDTD.getSQLstring());\r
+               }       \r
+       }\r
+       \r
+       \r
+\r
+       // Get the current ContextManager\r
+       private final ContextManager getContextManager()\r
+       {\r
+               return cm;\r
+       }\r
+\r
+       /*\r
+       ** Compress 2 adjacent (single or double) quotes into a single (s or d) quote when\r
+       ** found in the middle of a String.\r
+       ** NOTE:  """" or '''' will be compressed into "" or ''.\r
+       **                This function assumes that the leading and trailing quote from a\r
+       **                string or delimited identifier have already been removed.\r
+       */\r
+       private static String compressQuotes(String source, String quotes)\r
+       {\r
+               String  result = source;\r
+               int             index;\r
+       \r
+               /* Find the first occurrence of adjacent quotes. */\r
+               index = result.indexOf(quotes);\r
+\r
+               /* Replace each occurrence with a single quote and begin the\r
+                * search for the next occurrence from where we left off.\r
+                */\r
+               while (index != -1)\r
+               {\r
+                       result = result.substring(0, index + 1) + result.substring(index + 2);\r
+\r
+                       index = result.indexOf(quotes, index + 1);\r
+               }\r
+\r
+               return result;\r
+       }\r
+       \r
+       private static void verifyImageLength(String image) throws StandardException\r
+               {\r
+               // beetle 2758.  For right now throw an error for literals > 64K\r
+               if (image.length() > MAX_UTF8_LENGTH)\r
+                       {\r
+               throw StandardException.newException(SQLState.LANG_INVALID_LITERAL_LENGTH);\r
+                       }       \r
+               }\r
+\r
+       /*\r
+       ** Converts a delimited id to a canonical form.\r
+       ** Post process delimited identifiers to eliminate leading and\r
+       ** trailing " and convert all occurrences of "" to ".\r
+       */\r
+       private static String normalizeDelimitedID(String str)\r
+       {\r
+               str = compressQuotes(str, DOUBLEQUOTES);\r
+               return str;\r
+       }\r
+       private static boolean isDATETIME(int val)\r
+       {\r
+               if (val == DATE || val == TIME || val == TIMESTAMP)\r
+                       return true;\r
+               else\r
+                       return false;\r
+       }\r
+\r
+       /*\r
+        * Generate a multiplicative operator node, if necessary.\r
+        *\r
+        * If there are two operands, generate the multiplicative operator\r
+        * that corresponds to the multiplicativeOperator parameter.  If there\r
+        * is no left operand, just return the right operand.\r
+        *\r
+        * @param leftOperand   The left operand, null if no operator\r
+        * @param rightOperand  The right operand\r
+        * @param multiplicativeOperator        An identifier from BinaryOperatorNode\r
+        *                                                                      telling what operator to generate.\r
+        *\r
+        * @return      The multiplicative operator, or the right operand if there is\r
+        *                      no operator.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       ValueNode multOp(ValueNode leftOperand,\r
+                                                       ValueNode rightOperand,\r
+                                                       int multiplicativeOperator)\r
+                                       throws StandardException\r
+       {\r
+               if (leftOperand == null)\r
+               {\r
+                       return rightOperand;\r
+               }\r
+\r
+               switch (multiplicativeOperator)\r
+               {\r
+                 case BinaryOperatorNode.TIMES:\r
+                       return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.BINARY_TIMES_OPERATOR_NODE,\r
+                                                                       leftOperand,\r
+                                                                       rightOperand, \r
+                                                                       getContextManager());\r
+\r
+                 case BinaryOperatorNode.DIVIDE:\r
+                       return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.BINARY_DIVIDE_OPERATOR_NODE,\r
+                                                                       leftOperand,\r
+                                                                       rightOperand,\r
+                                                                       getContextManager());\r
+                 case BinaryOperatorNode.CONCATENATE:\r
+                       return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.CONCATENATION_OPERATOR_NODE,\r
+                                                                       leftOperand,\r
+                                                                       rightOperand,\r
+                                                                       getContextManager());\r
+\r
+                 default:\r
+                       if (SanityManager.DEBUG)\r
+                       SanityManager.THROWASSERT("Unexpected multiplicative operator " + \r
+                                                                               multiplicativeOperator);\r
+                       return null;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Set up and like the parameters to the descriptors.\r
+        * Set all the ParameterNodes to point to the array of\r
+        * parameter descriptors.\r
+        * \r
+        *      @exception      StandardException\r
+        */\r
+        private void setUpAndLinkParameters()\r
+                       throws StandardException\r
+        {\r
+               CompilerContext cc = getCompilerContext();\r
+               cc.setParameterList(parameterList);\r
+               /* Link the untyped parameters to the array of parameter descriptors */\r
+               \r
+               DataTypeDescriptor[] descriptors = cc.getParameterTypes();\r
+\r
+               ParameterNode                           newNode;\r
+               ParameterNode                           oldNode;\r
+               int                                                     paramCount;\r
+\r
+               /*\r
+               ** Iterate through the list of untyped parameter nodes, set each one\r
+               ** to point to the array of parameter descriptors.\r
+               */\r
+               paramCount = -1;\r
+               int plSize = parameterList.size();\r
+               for (int index = 0; index < plSize; index++)\r
+               {\r
+                       paramCount++;\r
+\r
+                       newNode = (ParameterNode) parameterList.elementAt(index);\r
+                       newNode.setDescriptors(descriptors );\r
+               }\r
+       }\r
+\r
+       /**\r
+        *  Initializes the list of unnamed parameters, i.e., "?" parameters\r
+        *\r
+        *      Usually, this routine just gets an empty list for the unnamed parameters.\r
+        *\r
+        *\r
+        */\r
+       void    initUnnamedParameterList()\r
+       {\r
+               parameterList = new Vector();\r
+       }\r
+\r
+       /**\r
+        * Makes a new unnamed ParameterNode and chains it onto parameterList.\r
+        *\r
+        *      @return new unnamed parameter.\r
+        *\r
+        *      @exception      StandardException\r
+        */\r
+       ParameterNode   makeParameterNode(  )\r
+                                       throws StandardException\r
+       {\r
+               ParameterNode   parm;\r
+               DataValueDescriptor sdv = null;\r
+\r
+               if ((paramDefaults != null) && (parameterNumber < paramDefaults.length))\r
+               {\r
+                       sdv = (DataValueDescriptor) paramDefaults[parameterNumber];\r
+               }\r
+\r
+               parm = (ParameterNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.PARAMETER_NODE,\r
+                                                               ReuseFactory.getInteger(parameterNumber),\r
+                                                               sdv,\r
+                                                               getContextManager());\r
+\r
+               parameterNumber++;\r
+               parameterList.addElement(parm);\r
+\r
+               return parm;\r
+       }\r
+\r
+       /**\r
+        * Looks up an unnamed parameter given its parameter number.\r
+        *\r
+        *      @param  paramNumber             Number of parameter in unnamed\r
+        *                                                      parameter list.\r
+        *\r
+        *      @return corresponding unnamed parameter.\r
+        *\r
+        */\r
+       ParameterNode   lookupUnnamedParameter( int paramNumber )\r
+       {\r
+               ParameterNode           unnamedParameter;\r
+\r
+               unnamedParameter = (ParameterNode) parameterList.elementAt( paramNumber );\r
+               return unnamedParameter;\r
+       }\r
+\r
+       /**\r
+        * Translate a String containing a number into the appropriate type\r
+        * of Numeric node.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       ValueNode getNumericNode(String num) throws StandardException\r
+       {\r
+               ContextManager cm = getContextManager();\r
+\r
+               // first, see if it might be an integer\r
+               try\r
+               {\r
+                       return (ValueNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.INT_CONSTANT_NODE,\r
+                                                                               new Integer(num),\r
+                                                                               cm);\r
+               }\r
+               catch (NumberFormatException nfe)\r
+               {\r
+                       // we catch because we want to continue on below\r
+               }\r
+\r
+               // next, see if it might be a long\r
+               try\r
+               {\r
+                       return (ValueNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.LONGINT_CONSTANT_NODE,\r
+                                                                               new Long(num),\r
+                                                                               cm);\r
+               }\r
+               catch (NumberFormatException nfe)\r
+               {\r
+                       // we catch because we want to continue on below\r
+               }\r
+\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.DECIMAL_CONSTANT_NODE,\r
+                                                                       num,\r
+                                                                       cm);\r
+       }\r
+       /**\r
+        * Determine whether the current token represents one of\r
+        * the built-in aliases.\r
+        *\r
+        * @return      TRUE iff the current token names a built-in alias\r
+        */\r
+       private boolean isBuiltInAlias()\r
+       {\r
+               boolean retval = false;\r
+\r
+               switch (token.kind)\r
+               {\r
+                 case UCASE:\r
+                 case LCASE:\r
+                 case SQRT:\r
+                 case LOCATE:\r
+                 case ABS:\r
+                 case ABSVAL:\r
+                 case SUBSTR:\r
+                 case MOD:\r
+                       retval = true;\r
+                       break;\r
+\r
+                 default:\r
+                       retval = false;\r
+                       break;\r
+               }\r
+\r
+\r
+               return retval;\r
+       }\r
+\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens represents one of\r
+        * the common (built-in) datatypes.\r
+        *\r
+        * @param checkFollowingToken true if additonal token for NATIONAL\r
+        *        or LONG should be checked\r
+        * @return      TRUE iff the next set of tokens names a common datatype\r
+        */\r
+       boolean commonDatatypeName(boolean checkFollowingToken)\r
+       {\r
+           return commonDatatypeName(1, checkFollowingToken);\r
+       }\r
+\r
+       /**\r
+        * Determine whether a sequence of tokens represents one of\r
+        * the common (built-in) datatypes.\r
+        *\r
+        * @param checkFollowingToken true if additonal token for NATIONAL\r
+        *        or LONG should be checked\r
+        * @param start starting token index of the sequence\r
+        * @return      TRUE iff the next set of tokens names a common datatype\r
+        */\r
+       boolean commonDatatypeName(int start, boolean checkFollowingToken)\r
+       {\r
+               boolean retval = false;\r
+\r
+               switch (getToken(start).kind)\r
+               {\r
+                 case CHARACTER:\r
+                 case CHAR:\r
+                 case VARCHAR:\r
+                 case NVARCHAR:\r
+                 case NCHAR:\r
+                 case BIT:\r
+                 case NUMERIC:\r
+                 case DECIMAL:\r
+                 case DEC:\r
+                 case INTEGER:\r
+                 case INT:\r
+                 case SMALLINT:\r
+                 case LONGINT:\r
+                 case FLOAT:\r
+                 case REAL:\r
+                 case DATE:\r
+                 case TIME:\r
+                 case TIMESTAMP:\r
+                 case BOOLEAN:\r
+                 case DOUBLE:\r
+                 case BLOB:\r
+                 case CLOB:\r
+                 case NCLOB:\r
+                 case BINARY: // LARGE OBJECT\r
+                 case XML:\r
+                       retval = true;\r
+                       break;\r
+\r
+                 case LONG:\r
+                       if (checkFollowingToken == true)\r
+                       {\r
+                               switch (getToken(start+1).kind)\r
+                               {\r
+                                 case VARCHAR:\r
+                                 case NVARCHAR:\r
+                                 case BINARY:\r
+                                 case VARBINARY:\r
+                                 case BIT:\r
+                                       retval = true;\r
+                                       break;\r
+                               }\r
+                               break;\r
+                       }\r
+                       else\r
+                       {\r
+                               retval = true;\r
+                               break;\r
+                       }\r
+\r
+                 case NATIONAL:\r
+                       if (checkFollowingToken == true)\r
+                       {\r
+                               switch (getToken(start+1).kind)\r
+                               {\r
+                                 case CHAR:\r
+                                 case CHARACTER:\r
+                                       retval = true;\r
+                                       break;\r
+                               }\r
+                               break;\r
+                       }\r
+                       else\r
+                       {\r
+                               retval = true;\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Get a DELETE node given the pieces.\r
+        *\r
+        *\r
+        *      @exception      StandardException\r
+        */\r
+        private StatementNode getDeleteNode(FromTable fromTable,\r
+                                                                                TableName tableName,\r
+                                                                                ValueNode whereClause)\r
+               throws StandardException\r
+       {\r
+               FromList   fromList = (FromList) nodeFactory.getNode(\r
+                                                               C_NodeTypes.FROM_LIST,\r
+                                                               getContextManager());\r
+\r
+               fromList.addFromTable(fromTable);\r
+\r
+               SelectNode resultSet = (SelectNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.SELECT_NODE,\r
+                                                                               null,\r
+                                                                               null,   /* AGGREGATE list */\r
+                                                                               fromList, /* FROM list */\r
+                                                                               whereClause, /* WHERE clause */\r
+                                                                               null, /* GROUP BY list */\r
+                                                                               null, /* having clause */\r
+                                                                               getContextManager());\r
+\r
+               StatementNode retval =\r
+                       (StatementNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.DELETE_NODE,\r
+                                                       tableName,\r
+                                                       resultSet,\r
+                                                       getContextManager());\r
+\r
+               setUpAndLinkParameters();\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Get an UPDATE node given the pieces.\r
+        *\r
+        *\r
+        *      @exception      StandardException\r
+        */\r
+        private StatementNode getUpdateNode(FromTable fromTable,\r
+                                                                                TableName tableName,\r
+                                                                                ResultColumnList setClause,\r
+                                                                                ValueNode whereClause)\r
+               throws StandardException\r
+       {\r
+               FromList   fromList = (FromList) nodeFactory.getNode(\r
+                                                               C_NodeTypes.FROM_LIST,\r
+                                                               getContextManager());\r
+\r
+               fromList.addFromTable(fromTable);\r
+\r
+               SelectNode resultSet = (SelectNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.SELECT_NODE,\r
+                                                                               setClause,\r
+                                                                               null,   /* AGGREGATE list */\r
+                                                                               fromList, /* FROM list */\r
+                                                                               whereClause, /* WHERE clause */\r
+                                                                               null, /* GROUP BY list */\r
+                                                                               null, /* having clause */\r
+                                                                               getContextManager());\r
+\r
+               StatementNode retval =\r
+                       (StatementNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.UPDATE_NODE,\r
+                                                       tableName,\r
+                                                       resultSet,\r
+                                                       getContextManager());\r
+\r
+               setUpAndLinkParameters();\r
+\r
+               return retval;\r
+       }\r
+\r
+    /**\r
+     * Generate a trim operator node\r
+     * @param trimSpec one of Leading, Trailing or Both.\r
+     * @param trimChar the character to trim. Can be null in which case it defaults\r
+     * to ' '.\r
+     * @param trimSource expression to be trimmed.\r
+     */\r
+    private ValueNode getTrimOperatorNode(Integer trimSpec, ValueNode trimChar,\r
+        ValueNode trimSource, ContextManager cm) throws StandardException\r
+    {\r
+        if (trimChar == null)\r
+        {\r
+               trimChar = (CharConstantNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.CHAR_CONSTANT_NODE,\r
+                                                       " ",\r
+                                                       getContextManager());\r
+        }\r
+        return (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.TRIM_OPERATOR_NODE,\r
+                                                       trimSource, // receiver\r
+                                                       trimChar,   // leftOperand.\r
+                                                       null,\r
+                                                       ReuseFactory.getInteger(TernaryOperatorNode.TRIM),\r
+                                                       trimSpec,\r
+                                                       cm == null ? getContextManager() : cm);\r
+    }\r
+\r
+    private boolean ansiTrimSpecFollows()\r
+    {\r
+        return (getToken(2).kind == LEADING || getToken(2).kind == TRAILING\r
+                || getToken(2).kind == BOTH);\r
+    }\r
+    \r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of a remainingPredicate() rule.\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      remainingPredicate()\r
+        */\r
+       private boolean remainingPredicateFollows()\r
+       {\r
+               boolean retval = false;\r
+\r
+               switch (getToken(1).kind)\r
+               {\r
+                 case EQUALS_OPERATOR:\r
+                 case NOT_EQUALS_OPERATOR:\r
+                 case NOT_EQUALS_OPERATOR2: // !=\r
+                 case LESS_THAN_OPERATOR:\r
+                 case GREATER_THAN_OPERATOR:\r
+                 case LESS_THAN_OR_EQUALS_OPERATOR:\r
+                 case GREATER_THAN_OR_EQUALS_OPERATOR:\r
+                 case IN:\r
+                 case LIKE:\r
+                 case BETWEEN:\r
+                       retval = true;\r
+                       break;\r
+\r
+                 case NOT:\r
+                       switch (getToken(2).kind)\r
+                       {\r
+                         case IN:\r
+                         case LIKE:\r
+                         case BETWEEN:\r
+                               retval = true;\r
+                       }\r
+                       break;\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+\r
+       /**\r
+        * Determine whether the next token is a DROP\r
+        *\r
+        * @return      TRUE iff the next token is DROP\r
+        */\r
+       private boolean dropFollows()\r
+       {\r
+               if (getToken(1).kind == DROP)\r
+               { return true; }\r
+               else { return false; }\r
+       }\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of a escapedValueFunction().\r
+        *\r
+        * We check only for the punctuation here, because identifiers are\r
+        * very hard to check for in semantic lookahead.\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      escapedValueFunction()\r
+        */\r
+       private boolean escapedValueFunctionFollows()\r
+       {\r
+               if (getToken(1).kind != LEFT_BRACE)\r
+               {\r
+                       return false;\r
+               }\r
+\r
+               return getToken(2).kind == FN;\r
+       }\r
+       \r
+\r
+    /**\r
+       List of JDBC escape functions that map directly onto\r
+       a function in the SYSFUN schema.\r
+    */\r
+       private static final String[] ESCAPED_SYSFUN_FUNCTIONS =\r
+        {"ACOS", "ASIN", "ATAN", "COS", "SIN", "TAN", "PI",\r
+         "DEGREES", "RADIANS", "EXP", "LOG", "LOG10", "CEILING", "FLOOR",\r
+         "SIGN", "RAND", "COT" };\r
+       \r
+    /**\r
+       Convert a JDBC escaped function name to a function\r
+       name in the SYSFUC schema. Returns null if no such\r
+       function exists.\r
+    */  \r
+       private String getEscapedSYSFUN(String name)\r
+       {\r
+           name = StringUtil.SQLToUpperCase(name);\r
+           \r
+           for (int i = 0; i < ESCAPED_SYSFUN_FUNCTIONS.length; i++)\r
+           {\r
+               if (ESCAPED_SYSFUN_FUNCTIONS[i].equals(name))\r
+                   return name;\r
+           }\r
+           return null;\r
+       }\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of a columnInvocation() rule.  columnInvocations start with\r
+        * [ [ id . ] id . ] id . id (\r
+        *\r
+        * We check only for the punctuation here, because identifiers are\r
+        * very hard to check for in semantic lookahead.\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      columnInvocation()\r
+        */\r
+       private boolean columnMethodInvocationFollows()\r
+       {\r
+               int tokKind;\r
+\r
+               // First token must not be a built-in function name that can be\r
+               // followed immediately by a PERIOD. There are only a few of\r
+               // these - most built-in functions have a LEFT_PAREN following\r
+               // the function name.\r
+\r
+               // if we run out of token, it's probably a syntax error,  \r
+               // in fact\r
+               tokKind = getToken(1).kind;\r
+               if ( tokKind == EOF ) { return false; }                \r
+               \r
+               // disambiguate from named parameter reference\r
+               if ( getToken(1).image.charAt(0) == '?' ) { return false; }\r
+\r
+               if (tokKind == CURRENT_DATE ||\r
+                       tokKind == CURRENT_TIME ||\r
+                       tokKind == CURRENT_TIMESTAMP ||\r
+                       tokKind == CURRENT && (isDATETIME(getToken(2).kind)) )\r
+               {\r
+                       return false;\r
+               }\r
+\r
+               // Second token must be a PERIOD\r
+               if (getToken(2).kind != PERIOD)\r
+               {\r
+                       return false;\r
+               }\r
+\r
+               // We have established that we start with " id . "\r
+               tokKind = getToken(4).kind;\r
+               if (tokKind == LEFT_PAREN)\r
+               {\r
+                       // id.id(\r
+                       return true;\r
+               }\r
+\r
+               // Not id.id(, so 4th token must be PERIOD\r
+               if (tokKind != PERIOD)\r
+               {\r
+                       return false;\r
+               }\r
+\r
+               tokKind = getToken(6).kind;\r
+               if (tokKind == LEFT_PAREN)\r
+               {\r
+                       // id.id.id(\r
+                       return true;\r
+               }\r
+\r
+               // Not id.id.id(, so 6th token must be PERIOD\r
+               if (tokKind != PERIOD)\r
+               {\r
+                       return false;\r
+               }\r
+\r
+               tokKind = getToken(8).kind;\r
+               if (tokKind == LEFT_PAREN)\r
+               {\r
+                       // id.id.id.id(\r
+                       return true;\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of an aggregateNode()() rule.  aggregateNodes() start with one\r
+        * of the built-in aggregate names, or with an identifier followed\r
+        * by "( DISTINCT". A non-distinct user-defined aggregate invocation\r
+        * is treated as a staticMethodInvocationAlias() by the parser,\r
+        * and the binding phase figures out what it really is by looking\r
+        * at the data dictionary.\r
+        *\r
+        * We check only for the punctuation here, because identifiers are\r
+        * very hard to check for in semantic lookahead.\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      aggregateNode()\r
+        */\r
+       private boolean aggregateFollows()\r
+       {\r
+               boolean retval = false;\r
+\r
+               switch (getToken(1).kind)\r
+               {\r
+                 case MAX:\r
+                 case AVG:\r
+                 case MIN:\r
+                 case SUM:\r
+                       // This is a built-in aggregate\r
+                       retval = true;\r
+                       break;\r
+\r
+                 case COUNT:\r
+                       // COUNT is not a reserved word\r
+                       // This may eclipse use of COUNT as a function or a procedure that is probably what we want\r
+                       if (getToken(2).kind == LEFT_PAREN)\r
+                               retval = true;\r
+                 default:\r
+                       // Not a built-in aggregate - assume the first token is an\r
+                       // identifier, and see whether it is followed by " ( DISTINCT "\r
+                       if (getToken(2).kind == LEFT_PAREN && getToken(3).kind == DISTINCT)\r
+                               retval = true;\r
+                       break;\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of a miscBuiltins().\r
+        *\r
+        * We check only for the punctuation here, because identifiers are\r
+        * very hard to check for in semantic lookahead.\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      aggregateNode()\r
+        */\r
+       private boolean miscBuiltinFollows()\r
+       {\r
+               boolean retval = false;\r
+               int tokKind = getToken(1).kind;\r
+               \r
+               if (getToken(0).kind == CALL) \r
+                       retval = true;\r
+\r
+               switch (tokKind)\r
+               {\r
+                 case GET_CURRENT_CONNECTION:\r
+                 case CURRENT_DATE:\r
+                 case CURRENT_TIME:\r
+                 case CURRENT_TIMESTAMP:\r
+                       retval = true;\r
+                       break;\r
+\r
+                 case CURRENT:\r
+                       if (isDATETIME(getToken(2).kind)) \r
+                               retval = true;\r
+                       break;\r
+       \r
+                 case CAST:\r
+                 case LEFT_PAREN:\r
+                       retval = false;\r
+                       break;\r
+\r
+                 default:\r
+                   if (getToken(2).kind == LEFT_PAREN)\r
+                               retval = true;\r
+                       break;\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of a subquery. A subquery can begin with an arbitrary number of\r
+        * left parentheses, followed by either SELECT or VALUES.\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      subquery.\r
+        */\r
+       private boolean subqueryFollows()\r
+       {\r
+               int tokKind;\r
+               boolean retval = false;\r
+\r
+               for (int i = 1; true; i++)\r
+               {\r
+                       tokKind = getToken(i).kind;\r
+                       if (tokKind == LEFT_PAREN)\r
+                       {\r
+                               // A subquery can start with an arbitrary number of left\r
+                               // parentheses.\r
+                               continue;\r
+                       }\r
+                       else if (tokKind == SELECT || tokKind == VALUES)\r
+                       {\r
+                               // If the first token we find after all the left parentheses\r
+                               // is SELECT or VALUES, it's a subquery.\r
+                               retval = true;\r
+                               break;\r
+                       }\r
+                       else\r
+                       {\r
+                               // If the first token we find after all the left parentheses\r
+                               // is neither SELECT nor VALUES, it's not a subquery.\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of a rowValueConstructorList. A rowValueConstructorList is a comma-\r
+        * separated list of expressions enclosed in parentheses. This presents\r
+        * special problems, because an expression be nested within an\r
+        * arbitrary number of parentheses. To determine whether a left\r
+        * parenthesis introduces a rowValueConstructorList or an expression,\r
+        * we need to find the closing parenthesis, and determine whether\r
+        * the next token is a comma.\r
+        *\r
+        * For example, the following is a rowValueConstructorList:\r
+        *\r
+        *              (((1)), 2)\r
+        *\r
+        * and the following is just an expression:\r
+        *\r
+        *              (((1)))\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      subquery.\r
+        */\r
+       private boolean rowValueConstructorListFollows()\r
+       {\r
+               int nesting;\r
+               boolean retval = false;\r
+\r
+               // A rowValueConstructorList starts with a left parenthesis\r
+               if (getToken(1).kind == LEFT_PAREN)\r
+               {\r
+                       // Keep track of the nesting of parens while looking ahead\r
+                       nesting = 1;\r
+                       for (int i = 2; true; i++)\r
+                       {\r
+                               int tokKind = getToken(i).kind;\r
+\r
+                               // Special case for NULL/DEFAULT because they are not allowed in\r
+                               // a parenthesized expression, so (null)/(default) must be seen\r
+                               // as a rowValueConstructorList with one element.\r
+                               if (i == 2 && (tokKind == NULL || tokKind == _DEFAULT))\r
+                               {\r
+                                       retval = true;\r
+                                       break;\r
+                               }\r
+\r
+                               // There must be a COMMA at nesting level 1 (i.e. outside of\r
+                               // the first expression) for it to be a rowValueConstructorList\r
+                               if (nesting == 1 && tokKind == COMMA)\r
+                               {\r
+                                       retval = true;\r
+                                       break;\r
+                               }\r
+\r
+                               // If we run out of tokens before finding the last closing\r
+                               // parenthesis, it's not a rowValueConstructorList (it's\r
+                               // probably a syntax error, in fact)\r
+                               if (tokKind == EOF)\r
+                               {\r
+                                       break;\r
+                               }\r
+\r
+                               // Increase the nesting for each (, and decrease it for each )\r
+                               if (tokKind == LEFT_PAREN)\r
+                               {\r
+                                       nesting++;\r
+                               }\r
+                               else if (tokKind == RIGHT_PAREN)\r
+                               {\r
+                                       nesting--;\r
+                               }\r
+\r
+                               // Don't look any farther than the last closing parenthesis\r
+                               if (nesting == 0)\r
+                               {\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Determine whether the next token is the beginning of a propertyList(). \r
+        * A properties list is the comment "--derby-properties" followed by a \r
+        * dot-separated list, followed by an =, followed by a value all on that \r
+        * comment line. This means that the comment should start with the word\r
+        * "derby-properties".\r
+        *\r
+        * @return      TRUE iff the next token is derby-properties \r
+        */\r
+       private boolean derbyPropertiesListFollows()\r
+       {\r
+               return \r
+                       getToken(1).kind == DERBYDASHPROPERTIES;\r
+       }\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of a newInvocation(). A newInvocation() begins with the word "new"\r
+        * followed by a dot-separated list of identifiers, followed\r
+        * by a left parenthesis.\r
+        *\r
+        * @param startToken    Token to look for new at\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      newInvocation().\r
+        */\r
+       private boolean newInvocationFollows(int startToken)\r
+       {\r
+               boolean retval = false;\r
+\r
+               // newInvocation() starts with the word "new"\r
+               if (getToken(startToken).kind == NEW)\r
+               {\r
+                       // Look at every other token. Ignore the identifiers, because\r
+                       // they are hard to test for.\r
+                       for (int i = 2 + startToken; true; i += 2)\r
+                       {\r
+                               int tokKind = getToken(i).kind;\r
+\r
+                               // If we find a left parenthesis without any intervening\r
+                               // cruft, we have found a newInvocation()\r
+                               if (tokKind == LEFT_PAREN)\r
+                               {\r
+                                       retval = true;\r
+                                       break;\r
+                               }\r
+                               else if (tokKind != PERIOD)\r
+                               {\r
+                                       // Anything other than a PERIOD is "cruft"\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return retval;\r
+       }\r
+       /**\r
+        * Determine whether the next sequence of tokens is a class name\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the java class name\r
+        */\r
+       boolean javaClassFollows()\r
+       {\r
+               boolean retval = false;\r
+\r
+               // Look at every other token. Ignore the identifiers, because\r
+               // they are hard to test for.\r
+               for (int i = 2; true; i += 2)\r
+               {\r
+                       int tokKind = getToken(i).kind;\r
+\r
+                       // If we find a '::' without any intervening\r
+                       // cruft, we have found a javaClass\r
+                       if (tokKind == DOUBLE_COLON)\r
+                       {\r
+                               retval = true;\r
+                               break;\r
+                       }\r
+                       else if (tokKind != PERIOD)\r
+                       {\r
+                               // Anything other than a PERIOD is "cruft"\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of a FROM newInvocation(). A FROM newInvocation() begins with the words "from new"\r
+        * followed by a dot-separated list of identifiers, followed\r
+        * by a left parenthesis.\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      FROM newInvocation().\r
+        */\r
+       private boolean fromNewInvocationFollows()\r
+       {\r
+               boolean retval = false;\r
+\r
+               // FROM newInvocation() starts with the words "from new"\r
+               return (getToken(1).kind == FROM && newInvocationFollows(2));\r
+       }\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of a joinedTableExpression(). A joinedTableExpression() begins\r
+        * with one of:\r
+        *\r
+        *      JOIN\r
+        *      INNER JOIN\r
+        *      LEFT OUTER JOIN\r
+        *      RIGHT OUTER JOIN\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      joinedTableExpression().\r
+        */\r
+       private boolean joinedTableExpressionFollows()\r
+       {\r
+               boolean retval = false;\r
+\r
+               int tokKind1 = getToken(1).kind;\r
+               int tokKind2 = getToken(2).kind;\r
+\r
+               if (tokKind1 == JOIN)\r
+               {\r
+                       retval = true;\r
+               }\r
+               else if (tokKind1 == INNER && tokKind2 == JOIN)\r
+               {\r
+                       retval = true;\r
+               }\r
+               else if ((tokKind1 == LEFT || tokKind1 == RIGHT) && tokKind2 == OUTER)\r
+               {\r
+                       if (getToken(3).kind == JOIN)\r
+                       {\r
+                               retval = true;\r
+                       }\r
+               }\r
+               else if ((tokKind1 == LEFT || tokKind1 == RIGHT) && tokKind2 == JOIN)\r
+               {\r
+                       retval = true;\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Translate a token for the name of a built-in aggregate to a String\r
+        * containing an aggregate name.\r
+        */\r
+       private static String aggName(Token token)\r
+       {\r
+               String  retval = null;\r
+\r
+               switch (token.kind)\r
+               {\r
+                 case MAX:\r
+                       retval = "MAX";\r
+                       break;\r
+\r
+                 case AVG:\r
+                   retval = "AVG";\r
+                       break;\r
+\r
+                 case MIN:\r
+                   retval = "MIN";\r
+                       break;\r
+\r
+                 case SUM:\r
+                   retval = "SUM";\r
+                       break;\r
+\r
+                 case COUNT:\r
+                   retval = "COUNT";\r
+                       break;\r
+\r
+                 default:\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               SanityManager.THROWASSERT("Unexpected token type in aggName: " +\r
+                                                                                       token.kind);\r
+                       }\r
+                       break;\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Translate a token for the name of a built-in aggregate to an\r
+        * aggregate definition class.\r
+        */\r
+       private static Class aggClass(Token token)\r
+       {\r
+               Class   retval = null;\r
+\r
+               switch (token.kind)\r
+               {\r
+                 case MAX:\r
+                 case MIN:\r
+                       retval = MaxMinAggregateDefinition.class;\r
+                       break;\r
+\r
+                 case AVG:\r
+                 case SUM:\r
+                       retval = SumAvgAggregateDefinition.class;\r
+                       break;\r
+\r
+                 case COUNT:\r
+                   retval = CountAggregateDefinition.class;\r
+                       break;\r
+\r
+                 default:\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               SanityManager.THROWASSERT("Unexpected token type in aggClass: "\r
+                                                                                       + token.kind);\r
+                       }\r
+                       break;\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Determine whether the next sequence of tokens can be the beginning\r
+        * of another element in a PROPERTY list. These elements are of the\r
+        * form:\r
+        *\r
+        *              COMMA dot.separated.list = ...\r
+        *\r
+        * Look for the COMMA, the dots in the dot-separated list, and the =\r
+        *\r
+        * @return      TRUE iff the next set of tokens is the beginning of a\r
+        *                      another element in a PROPERTY list.\r
+        */\r
+       private boolean anotherPropertyFollows()\r
+       {\r
+               boolean retval = false;\r
+\r
+               // Element must start with COMMA\r
+               if (getToken(1).kind == COMMA)\r
+               {\r
+                       // Rest of element is dot-separated list with = at end\r
+                       int i = 3;\r
+                       int tokKind;\r
+                       do\r
+                       {\r
+                               tokKind = getToken(i).kind;\r
+\r
+                               // If we've found nothing but PERIODs until the EQUALS_OPERATOR\r
+                               // it is the beginning of another property list element.\r
+                               if (tokKind == EQUALS_OPERATOR)\r
+                               {\r
+                                       retval = true;\r
+                                       break;\r
+                               }\r
+\r
+                               i += 2;\r
+                       } while (tokKind == PERIOD);\r
+               }\r
+\r
+               return retval;\r
+       }\r
+\r
+       /**\r
+        * Get one of the several types of create alias nodes.\r
+        *\r
+        * @param aliasName     The name of the alias\r
+        * @param fullStaticMethodName  The full path/method name\r
+        * @param aliasSpecificInfo      Information specific to the type of alias being created.\r
+        * @param aliasType     The type of alias to create\r
+        * @param delimitedIdentifier   Whether or not to treat the class name\r
+        *                                                              as a delimited identifier if trying to\r
+        *                                                              resolve it as a class alias.\r
+        *\r
+        * @return      A CreateAliasNode matching the given parameters\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       StatementNode\r
+       getCreateAliasNode(\r
+               Object aliasName,\r
+               String fullStaticMethodName,\r
+               Object aliasSpecificInfo,\r
+               char aliasType,\r
+               Boolean delimitedIdentifier)\r
+               throws StandardException\r
+       {\r
+\r
+               StatementNode aliasNode = (StatementNode) getNodeFactory().getCreateAliasNode\r
+                       (\r
+                               aliasName,\r
+                               fullStaticMethodName,\r
+                               aliasSpecificInfo,\r
+                               aliasType,\r
+                               delimitedIdentifier,\r
+                               getContextManager()\r
+                       );\r
+\r
+               return aliasNode;\r
+       }\r
+\r
+       /**\r
+               Create a node for the drop alias/procedure call.\r
+       */\r
+       StatementNode\r
+       dropAliasNode(Object aliasName, char type) throws StandardException\r
+       {\r
+\r
+               StatementNode stmt = (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.DROP_ALIAS_NODE,\r
+                                                               aliasName,\r
+                                                               new Character(type),\r
+                                                               getContextManager());\r
+\r
+               return stmt;\r
+       }\r
+\r
+    /**\r
+     * Get a substring node from\r
+     *      - the string\r
+     *      - the start position\r
+     *      - the length\r
+     *      - a boolean values for specifying the kind of substring function\r
+     * @exception StandardException  Thrown on error\r
+     */\r
+    ValueNode getSubstringNode( ValueNode stringValue, ValueNode startPosition, \r
+                         ValueNode length, Boolean boolVal ) throws StandardException\r
+    {\r
+        return (ValueNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.SUBSTRING_OPERATOR_NODE,\r
+                                               stringValue,\r
+                                               startPosition,\r
+                                               length,\r
+                                               ReuseFactory.getInteger(TernaryOperatorNode.SUBSTRING),\r
+                                               null,\r
+                                                   getContextManager());\r
+    }\r
+\r
+    final public TableName\r
+    qualifiedName(int id_length_limit) throws ParseException, StandardException\r
+    {\r
+       return qualifiedName( C_NodeTypes.TABLE_NAME, id_length_limit);\r
+    }\r
+\r
+    private void initStatement( String statementSQLText, Object[] paramDefaults)\r
+        throws StandardException\r
+    {\r
+        /* Do per-statement initialization here */\r
+        parameterNumber = 0;\r
+       this.statementSQLText = statementSQLText;\r
+        this.paramDefaults = paramDefaults;\r
+        nodeFactory = getNodeFactory();\r
+        initUnnamedParameterList();\r
+    } // End of initStatement\r
+\r
+    private void checkIdentifierLengthLimit( String identifier, int identifier_length_limit) \r
+        throws StandardException\r
+    {\r
+       if (identifier.length() > identifier_length_limit)\r
+               throw StandardException.newException(SQLState.LANG_IDENTIFIER_TOO_LONG, identifier, String.valueOf(identifier_length_limit));\r
+    }\r
+\r
+    private ValueNode getJdbcIntervalNode( int intervalType) throws StandardException\r
+    {\r
+        return (ValueNode) nodeFactory.getNode( C_NodeTypes.INT_CONSTANT_NODE,\r
+                                                ReuseFactory.getInteger( intervalType),\r
+                                                getContextManager());\r
+    }\r
+    \r
+       private void checkAuthorizationLength( String authorization)\r
+               throws StandardException\r
+       {\r
+               checkIdentifierLengthLimit( authorization, Limits.DB2_MAX_USERID_LENGTH);\r
+       }\r
+\r
+    /**\r
+        Check to see if the required claues have been added\r
+        to a procedure or function defintion.\r
+        \r
+        @param required int array of require clauses\r
+        @param  clauses the array of declared clauses.\r
+    */\r
+    void checkRequiredRoutineClause(int[] required, Object[] clauses)\r
+        throws StandardException\r
+    {\r
+        for (int i = 0; i < required.length; i++)\r
+        {\r
+            int re = required[i];\r
+            if (clauses[re] == null)\r
+            {\r
+                throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR,\r
+                                ROUTINE_CLAUSE_NAMES[re]);\r
+                   }\r
+               }\r
+    }\r
+}\r
+\r
+PARSER_END(SQLParser)\r
+\r
+TOKEN_MGR_DECLS :\r
+{\r
+       void    CommonTokenAction(Token t)\r
+       {\r
+               t.beginOffset = input_stream.getBeginOffset();\r
+               t.endOffset = input_stream.getEndOffset();\r
+       }\r
+}\r
+\r
+SKIP :\r
+{      /* white space */\r
+         " "\r
+       | "\t"\r
+       | "\n"\r
+       | "\r"\r
+}\r
+\r
+SKIP :\r
+{      /* comments */\r
+       "--" : IN_COMMENT\r
+}\r
+\r
+<IN_COMMENT> SKIP :\r
+{      /* white space */\r
+         " "\r
+       | "\t"\r
+}\r
+\r
+/*\r
+       Check if the comment characters -- are followed by DERBY-PROPERTIES\r
+       token. \r
+\r
+       If yes, then this comment is providing user-supplied optimizer \r
+       overrides. There should be keyname=value [,keyname=value] pairs\r
+       after -- DERBY-PROPERTIES otherwise throw an exception. These\r
+       optimier overrides should be used in correct context only, \r
+       otherwise, the parser will throw an exception.\r
+\r
+       If this comment does not start with DERBY-PROPERTOIES, then it is \r
+       just a regular comment. Skip the comment and move on to the next line.\r
+ */\r
+<IN_COMMENT> MORE [IGNORE_CASE]:\r
+{\r
+"D" : LOOKFOR_DE\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_D : (~["D"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DE> MORE [IGNORE_CASE]:\r
+{\r
+"E" : LOOKFOR_DER\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DE : (~["E"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DER> MORE [IGNORE_CASE]:\r
+{\r
+"R" : LOOKFOR_DERB\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DER : (~["R"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERB> MORE [IGNORE_CASE]:\r
+{\r
+"B" : LOOKFOR_DERBY\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERB : (~["B"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBY> MORE [IGNORE_CASE]:\r
+{\r
+"Y" : LOOKFOR_DERBYDASH\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBY : (~["Y"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASH> MORE [IGNORE_CASE]:\r
+{\r
+"-" : LOOKFOR_DERBYDASHP\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBYDASH : (~["-"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASHP> MORE [IGNORE_CASE]:\r
+{\r
+"P" : LOOKFOR_DERBYDASHPR\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBYDASHP : (~["P"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASHPR> MORE [IGNORE_CASE]:\r
+{\r
+"R" : LOOKFOR_DERBYDASHPRO\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBYDASHPR : (~["R"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASHPRO> MORE [IGNORE_CASE]:\r
+{\r
+"O" : LOOKFOR_DERBYDASHPROP\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBYDASHPRO : (~["O"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASHPROP> MORE [IGNORE_CASE]:\r
+{\r
+"P" : LOOKFOR_DERBYDASHPROPE\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBYDASHPROP : (~["P"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASHPROPE> MORE [IGNORE_CASE]:\r
+{\r
+"E" : LOOKFOR_DERBYDASHPROPER\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBYDASHPROPE : (~["E"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASHPROPER> MORE [IGNORE_CASE]:\r
+{\r
+"R" : LOOKFOR_DERBYDASHPROPERT\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBYDASHPROPER : (~["R"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASHPROPERT> MORE [IGNORE_CASE]:\r
+{\r
+"T" : LOOKFOR_DERBYDASHPROPERTI\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBYDASHPROPERT : (~["T"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASHPROPERTI> MORE [IGNORE_CASE]:\r
+{\r
+"I" : LOOKFOR_DERBYDASHPROPERTIE\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBYDASHPROPERTI : (~["I"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASHPROPERTIE> MORE [IGNORE_CASE]:\r
+{\r
+"E" : LOOKFOR_DERBYDASHPROPERTIES\r
+|\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_DERBYDASHPROPERTIE : (~["E"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<LOOKFOR_DERBYDASHPROPERTIES> TOKEN [IGNORE_CASE] :\r
+{      \r
+       <DERBYDASHPROPERTIES : "DERBYDASHPROPERTIES"> \r
+}\r
+\r
+//once we find comment starting with -- DERBY-PROPERTIES, we want to switch \r
+//from SKIP mode to the TOKEN mode in the parser so the rest of the characters \r
+//on the comment line can be treated as part of one big token so we can get \r
+//keyname=value pairs from that token. The reason for treating them as one big\r
+//token is that the existing code in parser allows newline characters between\r
+//individual token but with optimizer overrides, all the properties have to\r
+//be specified on the -- DERBY-PROPERTIES comment line. \r
+<LOOKFOR_DERBYDASHPROPERTIES> TOKEN [IGNORE_CASE]:\r
+{\r
+"S" { matchedToken.kind = DERBYDASHPROPERTIES; } : PROPERTIES_LIST\r
+}\r
+\r
+//We found -- DERBY-PROPERTIE? where ? is a character other than S\r
+//and hence we should the rest of the characters on this line as \r
+//a regular comment\r
+<LOOKFOR_DERBYDASHPROPERTIES> SKIP :\r
+{\r
+<("\n"|"\r"|"\r\n")?> : DEFAULT\r
+|\r
+<NOT_PROPERTIES : (~["S","s"])> : IT_IS_NOT_DERBYPROPERTIES_COMMENT\r
+}\r
+\r
+<IT_IS_NOT_DERBYPROPERTIES_COMMENT> SKIP :\r
+{\r
+       <SINGLE_LINE_SQLCOMMENT: (~["\n","\r"])* ("\n"|"\r"|"\r\n")?> : DEFAULT\r
+}\r
+\r
+//found -- DERBY-PROPERTIES. Treat rest of the characters on the line\r
+//as one big token and then fetch keyname=value pairs from that token.\r
+<PROPERTIES_LIST> TOKEN :\r
+{\r
+       <CHECK_PROPERTIES: (~["\n","\r"])* ("\n"|"\r"|"\r\n")?> : DEFAULT\r
+}\r
+\r
+/*\r
+       This list should contain only and all SQL92 keywords that are reserved.\r
+       Reserved keywords can be used as identifiers in the language only\r
+       as delimited identifiers.\r
+ */\r
+/* NOTE - If you add a keyword, then you must add it to reservedKeyword()\r
+ *           or nonReservedKeyword() as well!\r
+ */\r
+TOKEN [IGNORE_CASE] :\r
+{      /* SQL92 reserved Keywords */\r
+       <ADD: "add">\r
+|      <ALL: "all">\r
+|      <ALLOCATE: "allocate">\r
+|      <ALTER: "alter">\r
+|      <AND: "and">\r
+|      <ANY: "any">\r
+|      <ARE: "are">\r
+|      <AS: "as">\r
+|      <ASC: "asc">\r
+|      <ASSERTION: "assertion">\r
+|      <AT: "at">\r
+|      <AUTHORIZATION: "authorization">\r
+|      <AVG: "avg">\r
+|      <BEGIN: "begin">\r
+|      <BETWEEN: "between">\r
+|      <BINARY: "binary">\r
+|      <BIT: "bit">\r
+|      <BOTH: "both">\r
+|      <BY: "by">\r
+|      <CASCADE: "cascade">\r
+|      <CASCADED: "cascaded">\r
+|      <CASE: "case">\r
+|      <CAST: "cast">\r
+|      <CHAR: "char">\r
+|      <CHARACTER: "character">\r
+|      <CHARACTER_LENGTH: "character_length">\r
+|      <CHECK: "check">\r
+|      <CLOSE: "close">\r
+|      <COALESCE: "coalesce">\r
+|      <COLLATE: "collate">\r
+|      <COLLATION: "collation">\r
+|      <COLUMN: "column">\r
+|      <COMMIT: "commit">\r
+|      <CONNECT: "connect">\r
+|      <CONNECTION: "connection">\r
+|      <CONSTRAINT: "constraint">\r
+|      <CONSTRAINTS: "constraints">\r
+|      <CONTINUE: "continue">\r
+|      <CONVERT: "convert">\r
+|      <CORRESPONDING: "corresponding">\r
+|      <COUNT: "count">\r
+|      <CREATE: "create">\r
+|      <CURRENT: "current">\r
+|      <CURRENT_DATE: "current_date">\r
+|      <CURRENT_TIME: "current_time">\r
+|      <CURRENT_TIMESTAMP: "current_timestamp">\r
+|      <CURRENT_USER: "current_user">\r
+|      <CURSOR: "cursor">\r
+|      <D: "d">\r
+|      <DEALLOCATE: "deallocate">\r
+|      <DEC: "dec">\r
+|      <DECIMAL: "decimal">\r
+|      <DECLARE: "declare">\r
+|      <_DEFAULT: "default">\r
+|      <DEFERRABLE: "deferrable">\r
+|      <DEFERRED: "deferred">\r
+|      <DELETE: "delete">\r
+|      <DESC: "desc">\r
+|      <DESCRIBE: "describe">\r
+|      <DIAGNOSTICS: "diagnostics">\r
+|      <DISCONNECT: "disconnect">\r
+|      <DISTINCT: "distinct">\r
+|      <DOUBLE: "double">\r
+|      <DROP: "drop">\r
+|      <ELSE: "else">\r
+|      <END: "end">\r
+|      <ENDEXEC: "end-exec">\r
+|      <ESCAPE: "escape">\r
+|      <EXCEPT: "except">\r
+|      <EXCEPTION: "exception">\r
+|      <EXEC: "exec">\r
+|      <EXECUTE: "execute">\r
+|      <EXISTS: "exists">\r
+|      <EXTERNAL: "external">\r
+|      <FALSE: "false">\r
+|      <FETCH: "fetch">\r
+|      <FIRST: "first">\r
+|      <FLOAT: "float">\r
+|      <FOR: "for">\r
+|      <FOREIGN: "foreign">\r
+|      <FOUND: "found">\r
+|      <FROM: "from">\r
+|      <FULL: "full">\r
+|      <FUNCTION: "function">\r
+|      <GET: "get">\r
+|      <GLOBAL: "global">\r
+|      <GO: "go">\r
+|      <GOTO: "goto">\r
+|      <GRANT: "grant">\r
+|      <GROUP: "group">\r
+|      <HAVING: "having">\r
+|      <HOUR: "hour">\r
+|      <IDENTITY: "identity">\r
+|      <IMMEDIATE: "immediate">\r
+|      <IN: "in">\r
+|      <INDICATOR: "indicator">\r
+|      <INITIALLY: "initially">\r
+|      <INNER: "inner">\r
+|      <INPUT: "input">\r
+|      <INSENSITIVE: "insensitive">\r
+|      <INSERT: "insert">\r
+|      <INT: "int">\r
+|      <INTEGER: "integer">\r
+|      <INTERSECT: "intersect">\r
+|      <INTO: "into">\r
+|      <IS: "is">\r
+|      <ISOLATION: "isolation">\r
+|      <JOIN: "join">\r
+|      <KEY: "key">\r
+|      <LAST: "last">\r
+|      <LEADING: "leading">\r
+|      <LEFT: "left">\r
+|      <LIKE: "like">\r
+|      <LOWER: "lower">\r
+|      <MATCH: "match">\r
+|      <MAX: "max">\r
+|      <MIN: "min">\r
+|      <MINUTE: "minute">\r
+|      <MODULE: "module">\r
+|      <NATIONAL: "national">\r
+|      <NATURAL: "natural">\r
+|      <NCHAR: "nchar">\r
+|      <NEXT: "next">\r
+|      <NO: "no">\r
+|      <NOT: "not">\r
+|      <NULL: "null">\r
+|      <NULLIF: "nullif">\r
+|      <NUMERIC: "numeric">\r
+|      <OF: "of">\r
+|      <ON: "on">\r
+|      <ONLY: "only">\r
+|      <OPEN: "open">\r
+|      <OPTION: "option">\r
+|      <OR: "or">\r
+|      <ORDER: "order">\r
+|      <OUTER: "outer">\r
+|      <OUTPUT: "output">\r
+|      <OVERLAPS: "overlaps">\r
+|      <PAD: "pad">\r
+|      <PARTIAL: "partial">\r
+|      <PREPARE: "prepare">\r
+|      <PRESERVE: "preserve">\r
+|      <PRIMARY: "primary">\r
+|      <PRIOR: "prior">\r
+|      <PRIVILEGES: "privileges">\r
+|      <PROCEDURE: "procedure">\r
+|      <PUBLIC: "public">\r
+|      <READ: "read">\r
+|      <REAL: "real">\r
+|      <REFERENCES: "references">\r
+|      <RELATIVE: "relative">\r
+|      <RESTRICT: "restrict">\r
+|      <REVOKE: "revoke">\r
+|      <RIGHT: "right">\r
+|      <ROLLBACK: "rollback">\r
+|      <ROWS: "rows">\r
+|      <SCHEMA: "schema">\r
+|      <SCROLL: "scroll">\r
+|      <SECOND: "second">\r
+|      <SELECT: "select">\r
+|      <SESSION_USER: "session_user">\r
+|      <SET: "set">\r
+|      <SMALLINT: "smallint">\r
+|      <SOME: "some">\r
+|      <SPACE: "space">\r
+|      <SQL: "sql">\r
+|      <SQLCODE: "sqlcode">\r
+|      <SQLERROR: "sqlerror">\r
+|      <SQLSTATE: "sqlstate">\r
+|      <SUBSTRING: "substring">\r
+|      <SUM: "sum">\r
+|      <SYSTEM_USER: "system_user">\r
+|      <T: "t">\r
+|      <TABLE: "table">\r
+|      <TEMPORARY: "temporary">\r
+|      <TIMEZONE_HOUR: "timezone_hour">\r
+|      <TIMEZONE_MINUTE: "timezone_minute">\r
+|      <TO: "to">\r
+|      <TRANSACTION: "transaction">\r
+|      <TRANSLATE: "translate">\r
+|      <TRANSLATION: "translation">\r
+|      <TRAILING: "trailing">\r
+|      <TRIM: "trim">\r
+|      <TRUE: "true">\r
+|      <TS: "ts">\r
+|      <UNION: "union">\r
+|      <UNIQUE: "unique">\r
+|      <UNKNOWN: "unknown">\r
+|      <UPDATE: "update">\r
+|      <UPPER: "upper">\r
+|      <USER: "user">\r
+|      <USING: "using">\r
+|      <VALUE: "value">\r
+|      <VALUES: "values">\r
+|      <VARBINARY: "varbinary">\r
+|      <VARCHAR: "varchar">\r
+|      <VARYING: "varying">\r
+|      <VIEW: "view">\r
+|      <WHENEVER: "whenever">\r
+|      <WHERE: "where">\r
+|      <WITH: "with">\r
+|      <WORK: "work">\r
+|      <WRITE: "write">\r
+|      <YEAR: "year">\r
+}\r
+\r
+/*\r
+       This list should contain only and all SQL92 keywords that are non-reserved.\r
+       Non-reserved keywords can be used as identifiers in the language.\r
+       To make that happen, the individual tokens have to be repeated in\r
+       the nonReservedKeyword() rule -- unless there's some other JavaCC shorthand?\r
+\r
+       NOTE: I've commented out most of these because we won't be using them\r
+       right away and the grammar is taking forever to process.\r
+ */\r
+/* NOTE - If you add a keyword, then you must add it to reservedKeyword()\r
+ *           or nonReservedKeyword() as well!\r
+ */\r
+TOKEN [IGNORE_CASE] :\r
+{      /* SQL92 non-reserved Keywords */\r
+    <ABS: "abs">\r
+|    <ABSVAL: "absval">\r
+|      <ACTION: "action">\r
+|      <ALWAYS: "always">\r
+|      <BLOB: "blob">\r
+  |    <C: "c">\r
+  | <CALLED: "called">\r
+|      <CLOB: "clob">\r
+  |    <COBOL: "cobol">\r
+|      <COMMITTED: "committed">\r
+|   <CONCAT: "concat">\r
+|      <CONTAINS: "contains">\r
+|      <DATA: "data">\r
+|      <DATE: "date">\r
+|      <DAY: "day">\r
+|      <DEFINER: "definer">\r
+|   <DYNAMIC: "dynamic">\r
+|      <FORTRAN: "fortran">\r
+|   <GENERATED: "generated">\r
+|      <IDENTITY_VAL_LOCAL: "identity_val_local">\r
+|      <INCREMENT: "increment">\r
+|      <INITIAL: "initial">\r
+|   <INOUT: "inout">\r
+|      <INTERVAL: "interval">\r
+|      <INVOKER: "invoker">\r
+|      <LANGUAGE: "language">\r
+|      <LARGE: "large">\r
+|      <LENGTH: "length">\r
+|      <LEVEL: "level">\r
+|      <LOCKS: "locks">\r
+|      <LOCKSIZE: "locksize">\r
+|      <LOGGED: "logged">\r
+|       <MOD: "mod">\r
+|      <MODIFIES: "modifies">\r
+|      <MODIFY: "modify">\r
+|      <MONTH: "month">\r
+|      <_MORE: "more">\r
+|      <MUMPS: "mumps">\r
+|      <NAME: "name">\r
+|      <NCLOB: "nclob">\r
+|      <NULLABLE: "nullable">\r
+|      <NUMBER: "number">\r
+|      <OBJECT: "object">\r
+|      <PASCAL: "pascal">\r
+|      <PLI: "pli">\r
+|      <PRECISION: "precision">\r
+|      <RELEASE: "release">\r
+|      <REPEATABLE: "repeatable">\r
+|      <RESTART: "restart">\r
+|      <RETURNS: "returns">\r
+|      <ROW: "row">\r
+|      <SAVEPOINT: "savepoint">\r
+|      <SCALE: "scale">\r
+|      <SECURITY: "security">\r
+|      <SERIALIZABLE: "serializable">\r
+|      <SQL_TSI_FRAC_SECOND: "sql_tsi_frac_second">\r
+|      <SQL_TSI_SECOND: "sql_tsi_second">\r
+|      <SQL_TSI_MINUTE: "sql_tsi_minute">\r
+|      <SQL_TSI_HOUR: "sql_tsi_hour">\r
+|      <SQL_TSI_DAY: "sql_tsi_day">\r
+|      <SQL_TSI_WEEK: "sql_tsi_week">\r
+|      <SQL_TSI_MONTH: "sql_tsi_month">\r
+|      <SQL_TSI_QUARTER: "sql_tsi_quarter">\r
+|      <SQL_TSI_YEAR: "sql_tsi_year">\r
+|      <START: "start">\r
+|      <STATEMENT: "statement">\r
+|      <SYNONYM: "synonym">\r
+|      <THEN: "then">\r
+|      <TIME: "time">\r
+|      <TIMESTAMP: "timestamp">\r
+|      <TIMESTAMPADD: "timestampadd">\r
+|      <TIMESTAMPDIFF: "timestampdiff">\r
+|      <TRUNCATE: "truncate">\r
+|      <TYPE: "type">\r
+|      <UNCOMMITTED: "uncommitted">\r
+|      <USAGE: "usage">\r
+|      <WHEN: "when">\r
+}\r
+\r
+/*\r
+       The next lists should contain non-SQL92 keywords, and should\r
+       specify whether their keywords are reserved or non-reserved.\r
+       If they are non-reserved, they need to be added to the identifier() rule.\r
+\r
+       NOTE: XML, XMLPARSE, XMLSERIALIZE, and XMLEXISTS are considered reserved\r
+       words to comply with the SQL/XML (2003) standard, section 5.1.  Similarly,\r
+       XMLQUERY is a reserved word per SQL/XML (2006).\r
+ */\r
+\r
+/* NOTE - If you add a keyword, then you must add it to reservedKeyword()\r
+ *           or nonReservedKeyword() as well!\r
+ */\r
+TOKEN [IGNORE_CASE] :\r
+{      /* Additional JSQL reserved keywords -- non-SQL92 reserved Keywords */\r
+       <BOOLEAN: "boolean">\r
+|      <CALL: "call">\r
+|      <CURDATE: "curdate">\r
+|      <CURTIME: "curtime">\r
+|   <DATABASE: "database">\r
+|      <GET_CURRENT_CONNECTION: "getCurrentConnection">\r
+|      <EXPLAIN: "explain">\r
+|      <LONGINT: "bigint">\r
+|      <LONG: "long">\r
+|      <LTRIM: "ltrim">\r
+|      <RTRIM: "rtrim">\r
+|      <SUBSTR:        "substr">\r
+|      <XML:   "xml">\r
+|      <XMLEXISTS:     "xmlexists">\r
+|      <XMLPARSE:      "xmlparse">\r
+|      <XMLQUERY:      "xmlquery">\r
+|      <XMLSERIALIZE:  "xmlserialize">\r
+}\r
+\r
+/* NOTE - If you add a keyword, then you must add it to reservedKeyword()\r
+ *           or nonReservedKeyword() as well!\r
+ *\r
+ * NOTE: CONTENT, DOCUMENT, STRIP, WHITESPACE and PASSING are considered NON-\r
+ * reserved words to comply with the SQL/XML (2003) standard, section 5.1.\r
+ * Similarly, EMPTY, RETURNING, and SEQUENCE are all considered NON-reserved\r
+ * words per SQL/XML (2006).  PRESERVE is also listed as non-reserved in the\r
+ * SQL/XML spec, but since that word is already reserved, we leave it alone.\r
+ */\r
+TOKEN [IGNORE_CASE] :\r
+{      /* Additional JSQL keywords -- non-SQL92 non-reserved Keywords */\r
+       <AFTER: "after">\r
+|      <BEFORE: "before">\r
+|      <CLASS: "class">\r
+|      <COMPRESS: "compress">\r
+|      <CONTENT: "content">\r
+|   <CS: "cs">\r
+|      <CURSORS: "cursors">\r
+|      <DB2SQL: "db2sql">\r
+|       <DIRTY: "dirty">\r
+|      <DOCUMENT: "document">\r
+|      <EACH: "each">\r
+|      <EMPTY: "empty">\r
+|      <EXCLUSIVE: "exclusive">\r
+|      <FN: "fn">\r
+|      <INDEX: "index">\r
+|      <JAVA: "java">\r
+|   <LCASE: "lcase">\r
+|   <LOCATE: "locate">\r
+|      <LOCK: "lock">\r
+|      <MESSAGE_LOCALE: "message_locale">\r
+|      <METHOD: "method">\r
+|      <MODE: "mode">\r
+|      <NEW: "new">\r
+|   <NEW_TABLE: "new_table">\r
+|      <NVARCHAR: "nvarchar"> \r
+|      <OJ: "oj">\r
+|      <OFF: "off">\r
+|      <OLD: "old">\r
+|   <OLD_TABLE: "old_table">\r
+|   <OUT: "out">\r
+|      <PARAMETER: "parameter">\r
+|      <PASSING: "passing">\r
+|      <PROPERTIES: "properties">\r
+|      <READS: "reads">\r
+|      <REF: "ref">\r
+|      <REFERENCING: "referencing">\r
+|      <RENAME: "rename">\r
+|       <RESET: "reset">\r
+|      <RESULT: "result">\r
+|      <RETAIN: "retain">\r
+|      <RETURNING: "returning">\r
+|   <RR: "rr">\r
+|   <RS: "rs">\r
+|      <SEQUENCE: "sequence">\r
+|      <SEQUENTIAL: "sequential">\r
+|      <SETS: "sets">\r
+|      <SHARE: "share">\r
+|      <SQLID: "sqlid">\r
+|      <SPECIFIC: "specific">\r
+|   <SQRT: "sqrt">\r
+|       <STABILITY: "stability">\r
+|   <STRIP: "strip">\r
+|   <STYLE: "style">\r
+|      <TRIGGER: "trigger">\r
+|   <UCASE: "ucase">\r
+|   <UR: "ur">\r
+|   <WHITESPACE: "whitespace">\r
+}\r
+\r
+TOKEN :\r
+{      /* Operators and punctuation */\r
+       <DOUBLE_QUOTE: "\"">\r
+|      <PERCENT: "%">\r
+|      <AMPERSAND: "&">\r
+|      <QUOTE: "'">\r
+|      <LEFT_BRACE: "{">\r
+|      <RIGHT_BRACE: "}">\r
+|      <LEFT_PAREN: "(">\r
+|      <RIGHT_PAREN: ")">\r
+|      <ASTERISK: "*">\r
+|      <PLUS_SIGN: "+">\r
+|      <COMMA: ",">\r
+|      <MINUS_SIGN: "-">\r
+|      <PERIOD: ".">\r
+|      <SOLIDUS: "/">\r
+|      <COLON: ":">\r
+|      <DOUBLE_COLON: "::">\r
+|      <SEMICOLON: ";">\r
+|      <LESS_THAN_OPERATOR: "<">\r
+|      <LESS_THAN_OR_EQUALS_OPERATOR: "<=">\r
+|      <EQUALS_OPERATOR: "=">\r
+|      <NOT_EQUALS_OPERATOR: "<>">\r
+|      <NOT_EQUALS_OPERATOR2: "!=">\r
+|      <GREATER_THAN_OPERATOR: ">">\r
+|      <GREATER_THAN_OR_EQUALS_OPERATOR: ">=">\r
+|      <QUESTION_MARK: "?">\r
+|      <UNDERSCORE: "_">\r
+|      <VERTICAL_BAR: "|">\r
+|      <LEFT_BRACKET: "[">\r
+|      <RIGHT_BRACKET: "]">\r
+|      <CONCATENATION_OPERATOR: "||">\r
+|      <FIELD_REFERENCE: "->">\r
+}\r
+\r
+TOKEN :\r
+{      /* Identifiers */\r
+       <IDENTIFIER: ( <LETTER> ) (<LETTER> | "_" | <DIGIT>)* >\r
+}\r
+\r
+TOKEN: {       <K: "K" >        }\r
+TOKEN: {       <M: "M" >        }\r
+TOKEN: {       <G: "G" >        }\r
+\r
+TOKEN:\r
+{\r
+       <#LETTER: [\r
+                               "a"-"z",\r
+                               "A"-"Z",\r
+                               "\u00aa",\r
+                               "\u00b5",\r
+                               "\u00ba",\r
+                               "\u00c0" - "\u00d6",\r
+                               "\u00d8" - "\u00f6",\r
+                               "\u00f8" - "\u01f5",\r
+                               "\u01fa" - "\u0217",\r
+                               "\u0250" - "\u02a8",\r
+                               "\u02b0" - "\u02b8",\r
+                               "\u02bb" - "\u02c1",\r
+                               "\u02d0" - "\u02d1",\r
+                               "\u02e0" - "\u02e4",\r
+                               "\u037a",\r
+                               "\u0386",\r
+                               "\u0388" - "\u038a",\r
+                               "\u038c",\r
+                               "\u038e" - "\u03a1",\r
+                               "\u03a3" - "\u03ce",\r
+                               "\u03d0" - "\u03d6",\r
+                               "\u03da",\r
+                               "\u03dc",\r
+                               "\u03de",\r
+                               "\u03e0",\r
+                               "\u03e2" - "\u03f3",\r
+                               "\u0401" - "\u040c",\r
+                               "\u040e" - "\u044f",\r
+                               "\u0451" - "\u045c",\r
+                               "\u045e" - "\u0481",\r
+                               "\u0490" - "\u04c4",\r
+                               "\u04c7" - "\u04c8",\r
+                               "\u04cb" - "\u04cc",\r
+                               "\u04d0" - "\u04eb",\r
+                               "\u04ee" - "\u04f5",\r
+                               "\u04f8" - "\u04f9",\r
+                               "\u0531" - "\u0556",\r
+                               "\u0559",\r
+                               "\u0561" - "\u0587",\r
+                               "\u05d0" - "\u05ea",\r
+                               "\u05f0" - "\u05f2",\r
+                               "\u0621" - "\u063a",\r
+                               "\u0640" - "\u064a",\r
+                               "\u0671" - "\u06b7",\r
+                               "\u06ba" - "\u06be",\r
+                               "\u06c0" - "\u06ce",\r
+                               "\u06d0" - "\u06d3",\r
+                               "\u06d5",\r
+                               "\u06e5" - "\u06e6",\r
+                               "\u0905" - "\u0939",\r
+                               "\u093d",\r
+                               "\u0958" - "\u0961",\r
+                               "\u0985" - "\u098c",\r
+                               "\u098f" - "\u0990",\r
+                               "\u0993" - "\u09a8",\r
+                               "\u09aa" - "\u09b0",\r
+                               "\u09b2",\r
+                               "\u09b6" - "\u09b9",\r
+                               "\u09dc" - "\u09dd",\r
+                               "\u09df" - "\u09e1",\r
+                               "\u09f0" - "\u09f1",\r
+                               "\u0a05" - "\u0a0a",\r
+                               "\u0a0f" - "\u0a10",\r
+                               "\u0a13" - "\u0a28",\r
+                               "\u0a2a" - "\u0a30",\r
+                               "\u0a32" - "\u0a33",\r
+                               "\u0a35" - "\u0a36",\r
+                               "\u0a38" - "\u0a39",\r
+                               "\u0a59" - "\u0a5c",\r
+                               "\u0a5e",\r
+                               "\u0a72" - "\u0a74",\r
+                               "\u0a85" - "\u0a8b",\r
+                               "\u0a8d",\r
+                               "\u0a8f" - "\u0a91",\r
+                               "\u0a93" - "\u0aa8",\r
+                               "\u0aaa" - "\u0ab0",\r
+                               "\u0ab2" - "\u0ab3",\r
+                               "\u0ab5" - "\u0ab9",\r
+                               "\u0abd",\r
+                               "\u0ae0",\r
+                               "\u0b05" - "\u0b0c",\r
+                               "\u0b0f" - "\u0b10",\r
+                               "\u0b13" - "\u0b28",\r
+                               "\u0b2a" - "\u0b30",\r
+                               "\u0b32" - "\u0b33",\r
+                               "\u0b36" - "\u0b39",\r
+                               "\u0b3d",\r
+                               "\u0b5c" - "\u0b5d",\r
+                               "\u0b5f" - "\u0b61",\r
+                               "\u0b85" - "\u0b8a",\r
+                               "\u0b8e" - "\u0b90",\r
+                               "\u0b92" - "\u0b95",\r
+                               "\u0b99" - "\u0b9a",\r
+                               "\u0b9c",\r
+                               "\u0b9e" - "\u0b9f",\r
+                               "\u0ba3" - "\u0ba4",\r
+                               "\u0ba8" - "\u0baa",\r
+                               "\u0bae" - "\u0bb5",\r
+                               "\u0bb7" - "\u0bb9",\r
+                               "\u0c05" - "\u0c0c",\r
+                               "\u0c0e" - "\u0c10",\r
+                               "\u0c12" - "\u0c28",\r
+                               "\u0c2a" - "\u0c33",\r
+                               "\u0c35" - "\u0c39",\r
+                               "\u0c60" - "\u0c61",\r
+                               "\u0c85" - "\u0c8c",\r
+                               "\u0c8e" - "\u0c90",\r
+                               "\u0c92" - "\u0ca8",\r
+                               "\u0caa" - "\u0cb3",\r
+                               "\u0cb5" - "\u0cb9",\r
+                               "\u0cde",\r
+                               "\u0ce0" - "\u0ce1",\r
+                               "\u0d05" - "\u0d0c",\r
+                               "\u0d0e" - "\u0d10",\r
+                               "\u0d12" - "\u0d28",\r
+                               "\u0d2a" - "\u0d39",\r
+                               "\u0d60" - "\u0d61",\r
+                               "\u0e01" - "\u0e2e",\r
+                               "\u0e30",\r
+                               "\u0e32" - "\u0e33",\r
+                               "\u0e40" - "\u0e46",\r
+                               "\u0e81" - "\u0e82",\r
+                               "\u0e84",\r
+                               "\u0e87" - "\u0e88",\r
+                               "\u0e8a",\r
+                               "\u0e8d",\r
+                               "\u0e94" - "\u0e97",\r
+                               "\u0e99" - "\u0e9f",\r
+                               "\u0ea1" - "\u0ea3",\r
+                               "\u0ea5",\r
+                               "\u0ea7",\r
+                               "\u0eaa" - "\u0eab",\r
+                               "\u0ead" - "\u0eae",\r
+                               "\u0eb0",\r
+                               "\u0eb2" - "\u0eb3",\r
+                               "\u0ebd",\r
+                               "\u0ec0" - "\u0ec4",\r
+                               "\u0ec6",\r
+                               "\u0edc" - "\u0edd",\r
+                               "\u0f40" - "\u0f47",\r
+                               "\u0f49" - "\u0f69",\r
+                               "\u10a0" - "\u10c5",\r
+                               "\u10d0" - "\u10f6",\r
+                               "\u1100" - "\u1159",\r
+                               "\u115f" - "\u11a2",\r
+                               "\u11a8" - "\u11f9",\r
+                               "\u1e00" - "\u1e9b",\r
+                               "\u1ea0" - "\u1ef9",\r
+                               "\u1f00" - "\u1f15",\r
+                               "\u1f18" - "\u1f1d",\r
+                               "\u1f20" - "\u1f45",\r
+                               "\u1f48" - "\u1f4d",\r
+                               "\u1f50" - "\u1f57",\r
+                               "\u1f59",\r
+                               "\u1f5b",\r
+                               "\u1f5d",\r
+                               "\u1f5f" - "\u1f7d",\r
+                               "\u1f80" - "\u1fb4",\r
+                               "\u1fb6" - "\u1fbc",\r
+                               "\u1fbe",\r
+                               "\u1fc2" - "\u1fc4",\r
+                               "\u1fc6" - "\u1fcc",\r
+                               "\u1fd0" - "\u1fd3",\r
+                               "\u1fd6" - "\u1fdb",\r
+                               "\u1fe0" - "\u1fec",\r
+                               "\u1ff2" - "\u1ff4",\r
+                               "\u1ff6" - "\u1ffc",\r
+                               "\u207f",\r
+                               "\u2102",\r
+                               "\u2107",\r
+                               "\u210a" - "\u2113",\r
+                               "\u2115",\r
+                               "\u2118" - "\u211d",\r
+                               "\u2124",\r
+                               "\u2126",\r
+                               "\u2128",\r
+                               "\u212a" - "\u2131",\r
+                               "\u2133" - "\u2138",\r
+                               "\u3005",\r
+                               "\u3031" - "\u3035",\r
+                               "\u3041" - "\u3094",\r
+                               "\u309b" - "\u309e",\r
+                               "\u30a1" - "\u30fa",\r
+                               "\u30fc" - "\u30fe",\r
+                               "\u3105" - "\u312c",\r
+                               "\u3131" - "\u318e",\r
+                               "\u4e00" - "\u9fa5",\r
+                               "\uac00" - "\ud7a3",\r
+                               "\uf900" - "\ufa2d",\r
+                               "\ufb00" - "\ufb06",\r
+                               "\ufb13" - "\ufb17",\r
+                               "\ufb1f" - "\ufb28",\r
+                               "\ufb2a" - "\ufb36",\r
+                               "\ufb38" - "\ufb3c",\r
+                               "\ufb3e",\r
+                               "\ufb40" - "\ufb41",\r
+                               "\ufb43" - "\ufb44",\r
+                               "\ufb46" - "\ufbb1",\r
+                               "\ufbd3" - "\ufd3d",\r
+                               "\ufd50" - "\ufd8f",\r
+                               "\ufd92" - "\ufdc7",\r
+                               "\ufdf0" - "\ufdfb",\r
+                               "\ufe70" - "\ufe72",\r
+                               "\ufe74",\r
+                               "\ufe76" - "\ufefc",\r
+                               "\uff21" - "\uff3a",\r
+                               "\uff41" - "\uff5a",\r
+                               "\uff66" - "\uffbe",\r
+                               "\uffc2" - "\uffc7",\r
+                               "\uffca" - "\uffcf",\r
+                               "\uffd2" - "\uffd7",\r
+                               "\uffda" - "\uffdc"\r
+                       ]>\r
+}\r
+\r
+TOKEN :\r
+{\r
+       <#DIGIT: [\r
+                               "0" - "9",\r
+                               "\u0660" - "\u0669",\r
+                               "\u06f0" - "\u06f9",\r
+                               "\u0966" - "\u096f",\r
+                               "\u09e6" - "\u09ef",\r
+                               "\u0a66" - "\u0a6f",\r
+                               "\u0ae6" - "\u0aef",\r
+                               "\u0b66" - "\u0b6f",\r
+                               "\u0be7" - "\u0bef",\r
+                               "\u0c66" - "\u0c6f",\r
+                               "\u0ce6" - "\u0cef",\r
+                               "\u0d66" - "\u0d6f",\r
+                               "\u0e50" - "\u0e59",\r
+                               "\u0ed0" - "\u0ed9",\r
+                               "\u0f20" - "\u0f29",\r
+                               "\uff10" - "\uff19"\r
+                       ]>\r
+}\r
+\r
+TOKEN :\r
+{      /* Delimited Identifiers - NOTE: this does not allow zero-length identifiers */\r
+       <DELIMITED_IDENTIFIER: "\""\r
+               (\r
+                       ("\"\"") |\r
+                       (~["\""])\r
+               ) +\r
+               "\"">\r
+}\r
+\r
+TOKEN :\r
+{      /* Literals */\r
+       <EXACT_NUMERIC: ( <UINT> ( "." ( <UINT> )? )? | "." <UINT> )>\r
+|      <UINT: (["0" - "9"])+ >/* This is for an unsigned exact numeric */\r
+|      <LENGTH_MODIFIER: ( <UINT> ["K","M","G","k","m","g"] )>\r
+|      <STRING: "'"\r
+               (\r
+                       "''" |\r
+                       ~["'"]\r
+               ) *\r
+               "'">\r
+|      <HEX_STRING: ["X","x"] "'" (["0"-"9","a"-"f","A"-"F"])*"'"> /* RESOLVE: does not allow separators */\r
+|      <APPROXIMATE_NUMERIC: <EXACT_NUMERIC> ["e","E"] ( ("+" | "-") )? ( ["0" - "9"] )+ >\r
+/*****\r
+       The tokenizer can't handle the date/time literals because\r
+       they are constructed of two tokens with arbitrary whitespace between them.\r
+       INTERVAL_LITERAL will also have to be upgraded at some point.\r
+|      <DATE_LITERAL: "DATE" "'" <DATE_VALUE> "'" >\r
+|      <#DATE_VALUE: <UINT> "-" <UINT> "-" <UINT> >\r
+|      <TIME_LITERAL: "TIME" "'" <TIME_VALUE> ( <TIMEZONE_INTERVAL> ) ? "'" >\r
+|      <#TIME_VALUE: <UINT> ":" <UINT> ":" <SECONDS_VALUE> >\r
+|      <#TIMEZONE_INTERVAL: ("+" | "-") <UINT> ":" <UINT> >\r
+|      <TIMESTAMP_LITERAL: "TIMESTAMP" "'" <DATE_VALUE> " " <TIME_VALUE> ( <TIMEZONE_INTERVAL> ) ? "'" >\r
+*****/\r
+|      <INTERVAL_LITERAL: "INTERVAL" "'" (["+","-"])? <INTERVAL_STRING> <INTERVAL_QUALIFIER> >\r
+|      <#INTERVAL_STRING: "'" ( <YEAR_MONTH_LITERAL> | <DAY_TIME_LITERAL> ) "'" >\r
+|      <#INTERVAL_QUALIFIER: <SINGLE_DATETIME_FIELD> | ( <START_FIELD> <TO> <END_FIELD> ) >\r
+|      <#SINGLE_DATETIME_FIELD: <NON_SECOND_DATETIME_FIELD> ( <LEFT_PAREN> <UINT> <RIGHT_PAREN> ) ? >\r
+|      <#START_FIELD: <NON_SECOND_DATETIME_FIELD> ( <LEFT_PAREN> <UINT> <RIGHT_PAREN> ) ? >\r
+|      <#END_FIELD: <NON_SECOND_DATETIME_FIELD> >\r
+|      <#NON_SECOND_DATETIME_FIELD: <YEAR> | <MONTH> | <DAY> | <HOUR> | <MINUTE> >\r
+|      <#YEAR_MONTH_LITERAL: (<UINT> | ( <UINT> "-" ) )? <UINT> >\r
+|      <#DAY_TIME_LITERAL:  ( <DAY_TIME_INTERVAL> | <TIME_INTERVAL> ) >\r
+|      <#DAY_TIME_INTERVAL: <UINT> ( " " <UINT> ( ":" <UINT> ( ":" <SECONDS_VALUE> ) ? ) ? ) ? >\r
+|      <#SECONDS_VALUE: <UINT> ( "." ( <UINT> ) ? ) ? >\r
+|      <#TIME_INTERVAL: <UINT> ( ":" <UINT> ( ":" <SECONDS_VALUE> ) ? ) ?\r
+               |        <UINT> ( ":" <SECONDS_VALUE> ) ?\r
+               |       <SECONDS_VALUE> >\r
+}\r
+\r
+\r
+\r
+/*\r
+ * <A NAME="Statement">Statement</A>\r
+ */\r
+StatementNode\r
+Statement( String statementSQLText, Object[] paramDefaults) throws StandardException :\r
+{\r
+       StatementNode   statementNode;\r
+\r
+        initStatement(statementSQLText, paramDefaults);\r
+}\r
+{\r
+       statementNode = StatementPart(null) <EOF>\r
+       {\r
+               return statementNode;\r
+       }\r
+}\r
+\r
+StatementNode \r
+proceduralStatement(Token[] tokenHolder) throws StandardException : \r
+{\r
+       StatementNode statementNode;\r
+       tokenHolder[0] = getToken(1);\r
+}   \r
+{      \r
+(\r
+       statementNode = insertStatement()\r
+|      \r
+       statementNode = preparableUpdateStatement()\r
+|\r
+       statementNode = preparableDeleteStatement()\r
+|\r
+       statementNode =  preparableSelectStatement(true)        \r
+|\r
+       statementNode =  callStatement()        \r
+)\r
+       {\r
+               return statementNode;\r
+       }               \r
+}\r
+\r
+/*\r
+ * <A NAME="StatementPart">StatementPart</A>\r
+ * \r
+ * @param tokenHolder returns the token that starts\r
+ * the statement.  If null, ignored.\r
+ */\r
+StatementNode\r
+StatementPart(Token[] tokenHolder) throws StandardException :\r
+{\r
+       StatementNode   statementNode;\r
+       //before starting new statements, initialize this variables. Otherwise, the left\r
+       //over values from previously failed sql will affect the next sql. \r
+        explicitNotNull = false;\r
+        explicitNull = false;\r
+       explicitlyNullableColumnsList = new Vector();\r
+\r
+       /*\r
+       ** Grab the token preceding this production\r
+       */\r
+       if (tokenHolder != null) \r
+       {\r
+               tokenHolder[0] = getToken(1);\r
+       }\r
+}\r
+{\r
+       /*\r
+        * The present method of invoking the parser is\r
+        * via JDBC, which uses preparable SQL statements only.\r
+        * the only place this makes a difference from other\r
+        * flavors of SQL (direct SQL, embedded SQL, dynamic SQL)\r
+        * is in the select and positioned update/delete statements,\r
+        * and in whether transaction and connection statements are\r
+        * allowed.\r
+        *\r
+        * When it becomes necessary to differentiate, we should\r
+        * define a way to put the parser into different modes\r
+        * (preparable SQL, dynamic SQL, direct SQL, embedded SQL, etc.)\r
+        * and have it accept/reject statements based on the mode\r
+        * it is in.\r
+        */\r
+    (\r
+        statementNode = spsRenameStatement() |\r
+        // statementNode = SQLTransactionStatement() |\r
+        statementNode = lockStatement()\r
+    )\r
+    {\r
+        return statementNode;\r
+    }\r
+|   (\r
+        statementNode = createStatements() |\r
+        statementNode = dropStatements() |\r
+        statementNode = spsAlterStatement() |\r
+        statementNode = globalTemporaryTableDeclaration() |\r
+        statementNode = preparableSQLDataStatement() |\r
+        statementNode = spsSetStatement() |\r
+               statementNode = truncateTableStatement() |\r
+               statementNode = grantStatement() |\r
+               statementNode = revokeStatement() |\r
+               statementNode = execStatement()\r
+        // statementNode = SQLTransactionStatement()\r
+    )\r
+    {\r
+        return statementNode;\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="createStatements">spsCreateStatement</A>\r
+ */\r
+StatementNode\r
+createStatements() throws StandardException :\r
+{\r
+       StatementNode statementNode;\r
+       Token beginToken;\r
+       int tokKind;\r
+}\r
+{\r
+       beginToken = <CREATE> (\r
+               (\r
+            statementNode = schemaDefinition() |\r
+            statementNode = viewDefinition(beginToken) |\r
+            statementNode = triggerDefinition() |\r
+            statementNode = synonymDefinition()\r
+        )\r
+        {\r
+        }\r
+|       statementNode = tableDefinition()\r
+        {\r
+        }\r
+|              statementNode = procedureDefinition()\r
+|              statementNode = functionDefinition()\r
+|\r
+               statementNode = indexDefinition()\r
+        {\r
+        }\r
+               )\r
+       {\r
+               return statementNode;\r
+       }\r
+\r
+}\r
+\r
+/*\r
+ * <A NAME="dropStatements">spsDropStatement</A>\r
+ */\r
+StatementNode\r
+dropStatements() throws StandardException :\r
+{\r
+       StatementNode statementNode;\r
+}\r
+{\r
+       <DROP>\r
+        (\r
+            statementNode = dropSchemaStatement() |\r
+            statementNode = dropTableStatement() |\r
+            statementNode = dropIndexStatement() |\r
+            statementNode = dropAliasStatement() |\r
+            statementNode = dropViewStatement() |\r
+            statementNode = dropTriggerStatement() \r
+        )\r
+       {\r
+               return statementNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="spsAlterStatement">spsAlterStatement</A>\r
+ */\r
+StatementNode\r
+spsAlterStatement() throws StandardException :\r
+{\r
+       StatementNode statementNode;\r
+}\r
+{\r
+       <ALTER>\r
+        (\r
+                   statementNode = alterTableStatement()\r
+        )\r
+       {\r
+               return statementNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="spsSetStatement">spsSetStatement</A>\r
+ */\r
+StatementNode\r
+spsSetStatement() throws StandardException :\r
+{\r
+       StatementNode statementNode;\r
+}\r
+{\r
+        LOOKAHEAD ( { getToken(1).kind == SET && getToken(2).kind != CURRENT } )\r
+       <SET>\r
+        (\r
+                statementNode = setIsolationStatement() |\r
+               statementNode = setSchemaStatement() |\r
+               statementNode = setMessageLocaleStatement()\r
+        )\r
+       {\r
+               return statementNode;\r
+       }\r
+|\r
+        LOOKAHEAD ( { getToken(1).kind == SET && getToken(2).kind == CURRENT } )\r
+       <SET>\r
+        (\r
+               statementNode = setSchemaStatement() |\r
+                statementNode = setIsolationStatement()\r
+\r
+        )\r
+       {\r
+               return statementNode;\r
+       }\r
+}\r
+               \r
+/*\r
+ * <A NAME="preparableSQLDataStatement">preparableSQLDataStatement</A>\r
+ *\r
+ * preparableSQLDataStatement differs from\r
+ * directSQLDataStatement in that it\r
+ * supports positioned update and delete\r
+ * and a preparable select (with FOR UPDATE)\r
+ * instead of a direct select (without FOR UPDATE)\r
+ */\r
+StatementNode\r
+preparableSQLDataStatement() throws StandardException :\r
+{\r
+       StatementNode   dmlStatement;\r
+}\r
+{\r
+       /*\r
+       ** RESOLVE: Ignoring temporary table declarations for now.\r
+       */\r
+       dmlStatement = preparableDeleteStatement()\r
+       {\r
+               return dmlStatement;\r
+       }\r
+|\r
+       dmlStatement = preparableSelectStatement(true)\r
+       {\r
+               return dmlStatement;\r
+       }\r
+|\r
+       dmlStatement = insertStatement()\r
+       {\r
+               return dmlStatement;\r
+       }\r
+|\r
+       dmlStatement = preparableUpdateStatement()\r
+       {\r
+               return dmlStatement;\r
+       }\r
+|\r
+       dmlStatement = callStatement()\r
+       {\r
+               return dmlStatement;\r
+       }\r
+|\r
+       dmlStatement = savepointStatement()\r
+       {\r
+               return dmlStatement;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="preparableDeleteStatement">preparableDeleteStatement</A>\r
+ *\r
+ *     This may be a search or positioned delete statement.\r
+ */\r
+StatementNode\r
+preparableDeleteStatement() throws StandardException :\r
+{\r
+       StatementNode qtn;\r
+}\r
+{\r
+       <DELETE> qtn = deleteBody()\r
+       {\r
+               return qtn;\r
+       }\r
+}\r
+\r
+StatementNode\r
+deleteBody() throws StandardException :\r
+{\r
+       JavaToSQLValueNode      javaToSQLNode = null;\r
+       String                          correlationName = null;\r
+       TableName  tableName = null;\r
+       ValueNode  whereClause = null;\r
+       FromTable  fromTable = null;\r
+       QueryTreeNode retval;\r
+       Properties targetProperties = null;\r
+       Token      whereToken = null;\r
+}\r
+{\r
+       LOOKAHEAD( { fromNewInvocationFollows() } ) \r
+       <FROM> javaToSQLNode = newInvocation()\r
+       [ whereToken = <WHERE> whereClause = whereClause(whereToken) ]\r
+       {\r
+               fromTable =  (FromTable) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.FROM_VTI,\r
+                                                                       javaToSQLNode.getJavaValueNode(), \r
+                                                                       (String) null,\r
+                                                                       null, \r
+                                                                       (Properties) null,\r
+                                                                       getContextManager()); \r
+\r
+               return getDeleteNode(fromTable, tableName, whereClause);\r
+       }\r
+|\r
+       <FROM> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+               [ \r
+                       LOOKAHEAD\r
+                       ( { (getToken(1).kind != EOF) && (getToken(1).kind != WHERE) && !derbyPropertiesListFollows() } )\r
+                       [ <AS> ] correlationName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) \r
+               ]\r
+               [targetProperties = propertyList(false) <CHECK_PROPERTIES>] \r
+               [ \r
+                       whereToken = <WHERE>\r
+                   (\r
+                               //need LOOKAHEAD here to decide between CURRENT in class name\r
+                               //and CURRENT in CURRENT OF\r
+                               LOOKAHEAD ( \r
+                       {\r
+                                (getToken(1).kind == CURRENT) &&\r
+                                        (getToken(2).kind == OF) \r
+                                       }\r
+                               )       \r
+                               fromTable = currentOfClause( correlationName ) |\r
+                               whereClause = whereClause(whereToken)\r
+                       )\r
+               ]\r
+       {\r
+               /* Fabricate a ResultSetNode (SelectNode) under the DeleteNode.\r
+                * For a searched delete,\r
+                * The FromList is simply the table that we are deleting from.\r
+                * (NOTE - we mark the table as the one that we are deleting from.)\r
+                * For a positioned delete,\r
+                * the FromList is a CurrentOfNode holding the cursor name.\r
+                * The select list will be null for now.  We will generate it at\r
+                * bind time, in keeping with the design decision that the parser's\r
+                * output should look like the language.\r
+                */\r
+               if (fromTable == null)\r
+                       fromTable = (FromTable) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.FROM_BASE_TABLE,\r
+                                                                               tableName,\r
+                                                                               correlationName,\r
+                                                                               ReuseFactory.getInteger(\r
+                                                                                               FromBaseTable.DELETE),\r
+                                                                               null,\r
+                                                                               getContextManager());\r
+\r
+               /* Update the FromTable with any properties, if non-null */\r
+               if (targetProperties != null)\r
+               {\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               if (((FromBaseTable) fromTable).getProperties() != null)\r
+                               {\r
+                                       SanityManager.THROWASSERT(\r
+                                               "Overwriting existing properties");\r
+                               }\r
+                       }\r
+                       ((FromBaseTable) fromTable).setTableProperties(targetProperties);\r
+               }\r
+\r
+               return getDeleteNode(fromTable, tableName, whereClause);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="currentOfClause">currentOfClause</A>\r
+ */\r
+FromTable\r
+currentOfClause( String correlationName ) throws StandardException :\r
+{\r
+       String cursorName = null;\r
+}\r
+{\r
+       <CURRENT> <OF> cursorName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       { \r
+               return (FromTable) nodeFactory.getNode(\r
+                                                               C_NodeTypes.CURRENT_OF_NODE,\r
+                                                               correlationName,\r
+                                                               cursorName,\r
+                                                               null,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="preparableSelectStatement">preparableSelectStatement</A>\r
+ *\r
+ *\r
+ *     The preparable select statement is a superset of\r
+ *     the directSelectStatementMultipleRows in that it\r
+ *     allows both the preparable single row select statement\r
+ *     (a query expression that returns one row, although it\r
+ *     is also handled like a cursor) and the preparable\r
+ *     multiple row select statement, which allows not only\r
+ *     an order by clause but also a for update clause.\r
+ */\r
+CursorNode\r
+preparableSelectStatement(boolean checkParams) throws StandardException :\r
+{\r
+       ResultSetNode     queryExpression;\r
+       Vector  updateColumns = new Vector();\r
+       int               forUpdateState = CursorNode.UNSPECIFIED;\r
+       int                               isolationLevel = ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL;\r
+       CursorNode                retval;\r
+       OrderByList orderCols = null;\r
+}\r
+{\r
+       queryExpression = queryExpression(null, NO_SET_OP) \r
+               [ orderCols = orderByClause() ]\r
+               [ <FOR> forUpdateState = forUpdateClause(updateColumns) ]\r
+               [ isolationLevel = atIsolationLevel() ]\r
+       {\r
+               // Note: if order by is specified, the for update clause\r
+               // must be READ ONLY or empty, and the cursor\r
+               // is implicitly READ_ONLY.\r
+\r
+               retval = (CursorNode) nodeFactory.getNode(\r
+                               C_NodeTypes.CURSOR_NODE,\r
+                               "SELECT",\r
+                               queryExpression,\r
+                               null,\r
+                               orderCols,\r
+                               ReuseFactory.getInteger(forUpdateState),\r
+                               (forUpdateState == CursorNode.READ_ONLY ? null : updateColumns ),\r
+                               getContextManager());\r
+\r
+               if (checkParams)\r
+               {\r
+                       setUpAndLinkParameters();\r
+               }\r
+\r
+               /* Set the isolation levels for the scans if specified */\r
+               if (isolationLevel != ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL)\r
+               {\r
+                       getCompilerContext().setScanIsolationLevel(isolationLevel);\r
+               }\r
+\r
+               return retval;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="insertStatement">insertStatement</A>\r
+ */\r
+StatementNode\r
+insertStatement() throws StandardException :\r
+{\r
+       StatementNode   insertNode;\r
+       QueryTreeNode   targetTable;\r
+}\r
+{\r
+       <INSERT> <INTO> targetTable = targetTable()\r
+                       insertNode = insertColumnsAndSource(targetTable)\r
+       {\r
+               setUpAndLinkParameters();\r
+\r
+               return insertNode;\r
+       }\r
+}\r
+\r
+QueryTreeNode\r
+targetTable() throws StandardException :\r
+{\r
+       JavaToSQLValueNode      javaToSQLNode = null;\r
+       String                          correlationName = null;\r
+       TableName                       tableName;\r
+}\r
+{\r
+       /* NOTE: this rule has to come first in order to avoid making NEW\r
+        * a reserved word.\r
+        */\r
+       /* identifier() used to be correlationName() */\r
+       LOOKAHEAD( { newInvocationFollows(1) } )\r
+       javaToSQLNode = newInvocation()\r
+       {\r
+               return nodeFactory.getNode(\r
+                                                               C_NodeTypes.FROM_VTI,\r
+                                                               javaToSQLNode.getJavaValueNode(), \r
+                                                               correlationName,\r
+                                                               null, \r
+                                                               (Properties) null,\r
+                                                               getContextManager()); \r
+       }\r
+|\r
+       tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+       {\r
+               return tableName;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="preparableUpdateStatement">preparableUpdateStatement</A>\r
+ */\r
+StatementNode\r
+preparableUpdateStatement() throws StandardException :\r
+{\r
+       StatementNode qtn;\r
+}\r
+{\r
+       // NOTE: It only makes sense to have a property list if there is a\r
+       // table name, so I moved it into the [] for qualifiedName(). \r
+\r
+       <UPDATE> qtn = updateBody()\r
+       {\r
+               return qtn;\r
+       }\r
+\r
+}\r
+\r
+boolean\r
+tableOrIndex() :\r
+{\r
+}\r
+{\r
+       <TABLE>\r
+       {\r
+               return true;\r
+       }\r
+|\r
+       <INDEX>\r
+       {\r
+               return false;\r
+       }\r
+}\r
+\r
+StatementNode\r
+updateBody() throws StandardException :\r
+{\r
+       ResultColumnList        columnList;\r
+       String                          correlationName = null;\r
+       JavaToSQLValueNode      javaToSQLNode = null;\r
+       TableName  tableName = null;\r
+       ValueNode  whereClause = null;\r
+       FromTable  fromTable = null;\r
+       Properties targetProperties = null;\r
+       Token      whereToken = null;\r
+}\r
+{\r
+       LOOKAHEAD( { newInvocationFollows(1) } ) \r
+       javaToSQLNode = newInvocation()\r
+               <SET> columnList = setClauseList()\r
+       [ whereToken = <WHERE> whereClause = whereClause(whereToken) ]\r
+       {\r
+               fromTable =  (FromTable) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.FROM_VTI,\r
+                                                                       javaToSQLNode.getJavaValueNode(), \r
+                                                                       (String) null,\r
+                                                                       null, \r
+                                                                       (Properties) null,\r
+                                                                       getContextManager()); \r
+\r
+               return getUpdateNode(fromTable, tableName, columnList, whereClause);\r
+       }\r
+|\r
+               tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+               [\r
+                       LOOKAHEAD( { (getToken(1).kind != SET) && !derbyPropertiesListFollows() } )\r
+                       [ <AS> ] correlationName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) \r
+               ]\r
+               [\r
+                       targetProperties = propertyList(false) <CHECK_PROPERTIES>\r
+               ] \r
+               <SET> columnList = setClauseList()\r
+               [ \r
+                       whereToken = <WHERE>\r
+                   (\r
+                               whereClause = whereClause(whereToken) |\r
+                               fromTable = currentOfClause( correlationName )\r
+                       )\r
+               ]\r
+       {\r
+               /* Fabricate a ResultSetNode (SelectNode) under the UpdateNode.\r
+                * For a searched update,\r
+                * The FromList is simply the table that we are updating.\r
+                * For a positioned update,\r
+                * the FromList is a CurrentOfNode holding the cursor name.\r
+                * (NOTE - we mark the table as the one that we are updating.)\r
+                * The select list is the columns in the SET clause.  At bind time,\r
+                * we will prepend the CurrentRowLocation() in keeping with the design \r
+                * decision that the parser's output should look like the language.\r
+                */\r
+               if (fromTable == null)\r
+                       fromTable = (FromTable) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.FROM_BASE_TABLE,\r
+                                                                               tableName,\r
+                                                                               correlationName,\r
+                                                                               ReuseFactory.getInteger(\r
+                                                                                                               FromBaseTable.UPDATE),\r
+                                                                               null,\r
+                                                                               getContextManager());\r
+\r
+               /* Update the FromTable with any properties, if non-null */\r
+               if (targetProperties != null)\r
+               {\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               if (((FromBaseTable) fromTable).getProperties() != null)\r
+                               {\r
+                                       SanityManager.THROWASSERT(\r
+                                               "Overwriting existing properties");\r
+                               }\r
+                       }\r
+                       ((FromBaseTable) fromTable).setTableProperties(targetProperties);\r
+               }\r
+               return getUpdateNode(fromTable, tableName, columnList, whereClause);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="callStatement">callStatement</A>\r
+ */\r
+StatementNode\r
+callStatement() throws StandardException :\r
+{\r
+       StatementNode retval;\r
+}\r
+{\r
+       (\r
+               retval = bareCallStatement() |\r
+               <LEFT_BRACE> retval = bareCallStatement() <RIGHT_BRACE>\r
+       )\r
+       {\r
+               return retval;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="bareCallStatement">baseCallStatement</A>\r
+ */\r
+StatementNode\r
+bareCallStatement() throws StandardException :\r
+{\r
+       ParameterNode           returnParam;\r
+\r
+       ValueNode                       value;\r
+\r
+       ResultSetNode           resultSetNode;\r
+}\r
+{\r
+       <CALL> value = primaryExpression( true )\r
+       {\r
+               if (! (value instanceof JavaToSQLValueNode) ||\r
+                       ! (((JavaToSQLValueNode) value).getJavaValueNode() instanceof MethodCallNode))\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_INVALID_CALL_STATEMENT);\r
+               }\r
+\r
+               StatementNode callStatement =\r
+                                                                       (StatementNode) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.CALL_STATEMENT_NODE,\r
+                                                                                               value,\r
+                                                                                               getContextManager());\r
+\r
+               setUpAndLinkParameters();\r
+\r
+               return callStatement;\r
+       }\r
+\r
+       // ? = CALL method()\r
+|      returnParam = dynamicParameterSpecification()\r
+       {\r
+               getCompilerContext().setReturnParameterFlag(); //bug4450\r
+       }\r
+       <EQUALS_OPERATOR> <CALL> resultSetNode = rowValueConstructor(null)\r
+       {\r
+               // validate that we have something that is an appropriate call statement\r
+               ResultColumnList rcl = resultSetNode.getResultColumns();\r
+\r
+               // we can have only 1 return value/column\r
+               if (rcl == null || rcl.size() > 1)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_INVALID_CALL_STATEMENT);\r
+               }\r
+\r
+               // we must have a method call node\r
+               value = ((ResultColumn) rcl.elementAt(0)).getExpression();\r
+               if (! (value instanceof JavaToSQLValueNode) ||\r
+                       ! (((JavaToSQLValueNode) value).getJavaValueNode() instanceof MethodCallNode))\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_INVALID_CALL_STATEMENT);\r
+               }\r
+\r
+               // wrap the row result set in a cursor node\r
+               StatementNode cursorNode =\r
+                                       (StatementNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CURSOR_NODE,\r
+                                               "SELECT",\r
+                                               resultSetNode,\r
+                                               null,\r
+                                               null,\r
+                                               ReuseFactory.getInteger(CursorNode.READ_ONLY),\r
+                                               null,\r
+                                               getContextManager());\r
+\r
+               // set the 0th param to be a RETURN param\r
+               returnParam.setReturnOutputParam(value);\r
+\r
+               setUpAndLinkParameters();\r
+\r
+               return cursorNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="primaryExpression">primaryExpression</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode primaryExpression( boolean inSelectClause ) throws StandardException :\r
+{\r
+       ValueNode                       value = null;\r
+}\r
+{\r
+       LOOKAHEAD\r
+       ( {\r
+               getToken(2).kind == PERIOD &&\r
+               getToken(4).kind == LEFT_PAREN\r
+         }\r
+       )\r
+       value = routineInvocation()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       value = primaryExpressionXX( inSelectClause )\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+/* \r
+ * <A NAME="savepointStatement">savepointStatement</A>\r
+\r
+       savepointStatementClauses contains the UNIQUE, ON ROLLBACK RETAIN LOCKS, ON ROLLBACK RETAIN CURSORS clauses.\r
+\r
+       0 - Boolean - UNIQUE clause\r
+       1 - Boolean - ON ROLLBACK RETAIN LOCKS clause\r
+       2 - Boolean - ON ROLLBACK RETAIN CURSORS clause\r
+ */\r
+StatementNode\r
+savepointStatement() throws StandardException :\r
+{\r
+       String                  savepointName = null;\r
+       int                     savepointStatementType;\r
+       Object[] savepointStatementClauses = new Object[3];\r
+}\r
+{\r
+       (\r
+       <SAVEPOINT> savepointName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) (savepointStatementClause(savepointStatementClauses))+\r
+       {\r
+               //ON ROLLBACK RETAIN CURSORS is mandatory\r
+               if (savepointStatementClauses[2] == null)\r
+                               throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, "MISSING ON ROLLBACK RETAIN CURSORS");\r
+               savepointStatementType = 1;\r
+       }\r
+|      <ROLLBACK> [ <WORK> ] <TO> <SAVEPOINT> [ savepointName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) ]\r
+       {\r
+               savepointStatementType = 2;\r
+       }\r
+|      <RELEASE> [ <TO> ] <SAVEPOINT> savepointName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               savepointStatementType = 3;\r
+       }\r
+       )\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.SAVEPOINT_NODE,\r
+                                                               savepointName,\r
+                                                               ReuseFactory.getInteger(savepointStatementType),\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+void savepointStatementClause(Object[] savepointStatementClauses) throws StandardException :\r
+{\r
+       int clausePosition = -1;\r
+}\r
+{\r
+       (\r
+               <UNIQUE> {clausePosition = 0;}\r
+       |\r
+               <ON> <ROLLBACK> <RETAIN> (clausePosition = LocksOrCursors())\r
+       )\r
+       {\r
+               if (clausePosition != -1) {\r
+                       // check for repeated clause\r
+                       if (savepointStatementClauses[clausePosition] != null) {\r
+\r
+                               String which = SAVEPOINT_CLAUSE_NAMES[clausePosition];\r
+                               throw StandardException.newException(SQLState.LANG_DB2_MULTIPLE_ELEMENTS, which);\r
+                       }\r
+                               \r
+                       savepointStatementClauses[clausePosition] = Boolean.TRUE;\r
+               }\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="LocksOrCursors">LocksOrCursors</A>\r
+ */\r
+int\r
+LocksOrCursors() :\r
+{\r
+}\r
+{\r
+       <LOCKS>\r
+       {\r
+               return (1);\r
+       }\r
+|\r
+       <CURSORS>\r
+       {\r
+               return (2);\r
+       }\r
+}\r
+\r
+/* \r
+ * <A NAME="globalTemporaryTableDeclaration">globalTemporaryTableDeclaration</A>\r
+\r
+       declareTableClauses contains the NOT LOGGED, on commit and on rollback clauses.\r
+\r
+       0 - Boolean - NOT LOGGED clause\r
+       1 - Boolean - on commit behavior\r
+       2 - Boolean - on rollback behavior\r
+ */\r
+StatementNode\r
+globalTemporaryTableDeclaration() throws StandardException :\r
+{\r
+       TableName                       tableName;\r
+       TableElementList tableElementList;\r
+       Object[] declareTableClauses = new Object[3];\r
+}\r
+{ \r
+       <DECLARE> <GLOBAL> <TEMPORARY> <TABLE> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+               tableElementList = tableElementList()\r
+               ( declareTableClause(declareTableClauses) ) +\r
+       {\r
+               // NOT LOGGED is mandatory\r
+               if (declareTableClauses[0] == null)\r
+                               throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, "MISSING NOT LOGGED");\r
+               // if ON COMMIT behavior not explicitly specified in DECLARE command, resort to default ON COMMIT DELETE ROWS\r
+               if (declareTableClauses[1] == null)\r
+                               declareTableClauses[1] = Boolean.TRUE;\r
+               // if ON ROLLBACK behavior not explicitly specified in DECLARE command, resort to default ON ROLLBACK DELETE ROWS\r
+               if (declareTableClauses[2] == null)\r
+                               declareTableClauses[2] = Boolean.TRUE;\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.CREATE_TABLE_NODE,\r
+                                                               tableName,\r
+                                                               tableElementList,\r
+                                                               (Properties)null,\r
+                                                               (Boolean) declareTableClauses[1],\r
+                                                               (Boolean) declareTableClauses[2],\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+void declareTableClause(Object[] declareTableClauses) throws StandardException :\r
+{\r
+       int clausePosition = -1;\r
+       Object clauseValue = null;\r
+}\r
+{\r
+       (\r
+               <NOT> <LOGGED> {clauseValue = Boolean.TRUE; clausePosition = 0;}\r
+       |\r
+               LOOKAHEAD( {getToken(1).kind == ON && getToken(2).kind == COMMIT} )\r
+               <ON> <COMMIT> ( clauseValue = onCommit() ) <ROWS> { clausePosition = 1;} \r
+       |\r
+               LOOKAHEAD( {getToken(1).kind == ON && getToken(2).kind == ROLLBACK} )\r
+               <ON> <ROLLBACK> <DELETE> <ROWS> { clauseValue = Boolean.TRUE; clausePosition = 2;} \r
+       )\r
+\r
+\r
+       {\r
+               if (clausePosition != -1) {\r
+                       // check for repeated clause\r
+                       if (declareTableClauses[clausePosition] != null) {\r
+\r
+                               String which = TEMPORARY_TABLE_CLAUSE_NAMES[clausePosition];\r
+                               throw StandardException.newException(SQLState.LANG_DB2_MULTIPLE_ELEMENTS, which);\r
+                       }\r
+                               \r
+                       declareTableClauses[clausePosition] = clauseValue;\r
+               }\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="onCommit">onCommit</A>\r
+ */\r
+Boolean\r
+onCommit() :\r
+{\r
+}\r
+{\r
+       <PRESERVE>\r
+       {\r
+               return (Boolean.FALSE);\r
+       }\r
+|\r
+       <DELETE>\r
+       {\r
+               return (Boolean.TRUE);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="tableElementList">tableElementList</A>\r
+ */\r
+TableElementList\r
+tableElementList() throws StandardException :\r
+{\r
+       TableElementList        tableElementList =\r
+                                       (TableElementList) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.TABLE_ELEMENT_LIST,\r
+                                                                       getContextManager());\r
+}\r
+{\r
+       <LEFT_PAREN> tableElement(tableElementList)\r
+               ( <COMMA> tableElement(tableElementList) ) * <RIGHT_PAREN>\r
+       {\r
+               return tableElementList;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="tableElement">tableElement</A>\r
+ */\r
+void\r
+tableElement(TableElementList tableElementList) throws StandardException :\r
+{\r
+       TableElementNode        tableElement;\r
+       //initialize following two booleans for every new table element so that the\r
+       //values from previous tableElement doesn't impact the next tableElement\r
+       explicitNotNull = false;\r
+       explicitNull = false;\r
+\r
+}\r
+{\r
+       tableElement = columnDefinition(tableElementList)\r
+       {\r
+               tableElementList.addTableElement(tableElement);\r
+       }\r
+|\r
+       tableElement = tableConstraintDefinition()\r
+       {\r
+               tableElementList.addTableElement(tableElement);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="columnDefinition">columnDefinition</A>\r
+ */\r
+TableElementNode\r
+columnDefinition(TableElementList tableElementList) throws StandardException :\r
+{\r
+       DataTypeDescriptor      typeDescriptor = null;\r
+       ValueNode                       defaultNode = null;\r
+       String                          columnName;\r
+       long[]                          autoIncrementInfo = new long[4];\r
+}\r
+{\r
+       /*\r
+       ** RESOLVE: We are ignoring domains and collation.\r
+       */\r
+\r
+       /* identifier() used to be columnName() */\r
+       columnName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) \r
+               ( typeDescriptor = dataTypeDDL() \r
+               )\r
+       [ defaultNode = defaultAndConstraints(typeDescriptor, tableElementList, columnName, autoIncrementInfo) ]\r
+       {\r
+               // Only pass autoincrement info for autoincrement columns\r
+               if (autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_IS_AUTOINCREMENT_INDEX] == 0)\r
+               {\r
+                       autoIncrementInfo = null;\r
+               }\r
+\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.COLUMN_DEFINITION_NODE,\r
+                                                               columnName,\r
+                                                               defaultNode,\r
+                                                               typeDescriptor,\r
+                                                               autoIncrementInfo,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="defaultAndConstraints">defaultAndConstraints</A>\r
+ */\r
+ValueNode\r
+defaultAndConstraints(DataTypeDescriptor typeDescriptor,\r
+                                         TableElementList tableElementList,\r
+                                         String columnName,\r
+                                         long[] autoIncrementInfo) throws StandardException :\r
+{\r
+       ValueNode               defaultNode = null;\r
+}\r
+{      // compatible with db2 syntax\r
+       columnConstraintDefinition(typeDescriptor, tableElementList, columnName) ( columnConstraintDefinition(typeDescriptor, tableElementList, columnName)) *\r
+       [ defaultNode = defaultClause(autoIncrementInfo, columnName) ( columnConstraintDefinition(typeDescriptor, tableElementList, columnName) )* ]\r
+       {\r
+               return defaultNode;\r
+       }\r
+|\r
+       defaultNode = defaultClause(autoIncrementInfo, columnName)\r
+       ( columnConstraintDefinition(typeDescriptor, tableElementList, columnName) ) *\r
+       {\r
+               return defaultNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="dataTypeDDL">dataTypeDDL</A>\r
+ */\r
+DataTypeDescriptor\r
+dataTypeDDL() throws StandardException :\r
+{\r
+       DataTypeDescriptor      typeDescriptor;\r
+}\r
+{\r
+       LOOKAHEAD( { commonDatatypeName(false) } )\r
+       typeDescriptor = dataTypeCommon()\r
+       {\r
+               return typeDescriptor;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="dataTypeCast">dataTypeCast</A>\r
+ */\r
+DataTypeDescriptor\r
+dataTypeCast() throws StandardException :\r
+{\r
+       DataTypeDescriptor      typeDescriptor;\r
+}\r
+{\r
+       // This lookahead is required because the names of the built-in\r
+       // datatypes are not reserved words\r
+       LOOKAHEAD( { commonDatatypeName(true) } )\r
+       typeDescriptor = dataTypeCommon()\r
+       {\r
+               return typeDescriptor;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="dataTypeCommon">dataTypeCommon</A>\r
+ */\r
+DataTypeDescriptor\r
+dataTypeCommon() throws StandardException :\r
+{\r
+       DataTypeDescriptor      typeDescriptor;\r
+       boolean checkCS = false;\r
+}\r
+{\r
+(\r
+       /* RESOLVE: Ignoring decimal, numeric, long */\r
+\r
+       /*\r
+       ** We are not planning to support character sets, so I commented\r
+       ** out characterSetSpecification().\r
+       */\r
+       ( LOOKAHEAD({getToken(2).kind != LARGE})\r
+               typeDescriptor = characterStringType()\r
+       )\r
+               /* [ <CHARACTER> <SET> characterSetSpecification() ] */\r
+|\r
+       ( LOOKAHEAD({getToken(3).kind != LARGE})\r
+               typeDescriptor = nationalCharacterStringType()\r
+       )\r
+|\r
+       typeDescriptor = numericType()\r
+|\r
+       typeDescriptor = datetimeType()\r
+| <BOOLEAN>\r
+{\r
+       checkInternalFeature(TypeId.BOOLEAN_NAME);\r
+       typeDescriptor = new DataTypeDescriptor(TypeId.BOOLEAN_ID, true);\r
+}\r
+|\r
+       typeDescriptor = longType()\r
+|\r
+       typeDescriptor = LOBType()\r
+|\r
+       typeDescriptor = XMLType()\r
+       )\r
+       {\r
+               return typeDescriptor;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="characterStringType">characterStringType</A>\r
+ */\r
+DataTypeDescriptor\r
+characterStringType() throws StandardException :\r
+{\r
+       int                                     length = DEFAULT_STRING_COLUMN_LENGTH;\r
+       Token                           varyingToken = null;\r
+       int type;\r
+}\r
+{\r
+  (\r
+       (\r
+               <VARCHAR> length = charLength()\r
+       )\r
+       {\r
+               type = Types.VARCHAR;\r
+       }\r
+|\r
+       charOrCharacter()\r
+       (\r
+               // Length is optional for CHARACTER, not for plain CHARACTER VARYING\r
+               varyingToken = <VARYING> length = charLength() |\r
+               [ length = charLength() ]\r
+       )\r
+       {\r
+               // If the user says CHARACTER VARYING, it's really VARCHAR\r
+               type = (varyingToken == null ? Types.CHAR : Types.VARCHAR);\r
+       }\r
+  ) [ type = forBitData(type) ]\r
+\r
+       {\r
+               checkTypeLimits(type,length);\r
+               DataTypeDescriptor charDTD = DataTypeDescriptor.getBuiltInDataTypeDescriptor(type, length);\r
+               return charDTD;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="charOrCharacter">charOrCharacter</A>\r
+ */\r
+void\r
+charOrCharacter() :\r
+{\r
+}\r
+{\r
+       <CHAR> | <CHARACTER>\r
+}\r
+\r
+/*\r
+ * <A NAME="charType">charType</A>\r
+ */\r
+int\r
+charLength() throws StandardException :\r
+{\r
+       int length;\r
+}\r
+{\r
+       <LEFT_PAREN> length = length() <RIGHT_PAREN>\r
+       {\r
+               return length;\r
+       }\r
+}\r
+\r
+/*\r
+** <A NAME="forBitData">forBitData</A>\r
+*/\r
+\r
+int\r
+forBitData(int charType) :\r
+{\r
+}\r
+{\r
+       <FOR> <BIT> <DATA>\r
+       {\r
+               if (charType == Types.CHAR)\r
+                       charType = Types.BINARY;\r
+               else if (charType == Types.VARCHAR)\r
+                       charType = Types.VARBINARY;\r
+               else if (charType == Types.LONGVARCHAR)\r
+                       charType = Types.LONGVARBINARY;\r
+\r
+               return charType;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="nationalCharacterStringType">nationalCharacterStringType</A>\r
+ */\r
+DataTypeDescriptor\r
+nationalCharacterStringType() throws StandardException :\r
+{\r
+       DataTypeDescriptor      dataTypeDescriptor;\r
+       int                                     length = DEFAULT_STRING_COLUMN_LENGTH;\r
+       String                          type = null;\r
+       Token                           varyingToken = null;\r
+}\r
+{\r
+(\r
+       <NATIONAL> charOrCharacter() \r
+       (\r
+               // Length is optional for NATIONAL CHARACTER , not for NATIONAL CHARACTER VARYING\r
+               varyingToken = <VARYING> length = charLength() |\r
+               [ length = charLength() ]\r
+       )\r
+       {\r
+\r
+               // If the user says NATIONAL CHARACTER VARYING, it's really NATIONALVARCHAR\r
+               type = (varyingToken == null ? TypeId.NATIONAL_CHAR_NAME : \r
+                               TypeId.NATIONAL_VARCHAR_NAME);\r
+       }\r
+|\r
+       <NCHAR> \r
+       (\r
+               // Length is optional for NCHAR, not for NCHAR VARYING\r
+               varyingToken = <VARYING> length = charLength() |\r
+               [ length = charLength() ]\r
+       )\r
+       {\r
+               // If the user says NCHAR VARYING, it's really NATIONALVARCHAR\r
+               type = (varyingToken == null ? TypeId.NATIONAL_CHAR_NAME : \r
+                               TypeId.NATIONAL_VARCHAR_NAME);\r
+\r
+       }\r
+|\r
+       <NVARCHAR> \r
+       (\r
+               length = charLength()\r
+       )\r
+       {\r
+               type = TypeId.NATIONAL_VARCHAR_NAME;\r
+       }\r
+)\r
+\r
+       {\r
+               // need to re-enable according to SQL standard\r
+               throw StandardException.newException(SQLState.NOT_IMPLEMENTED, type);\r
+               // return DataTypeDescriptor.getBuiltInDataTypeDescriptor(type, length);\r
+       } \r
+}\r
+\r
+/*\r
+ * <A NAME="LOBType">lobType</A>\r
+ */\r
+DataTypeDescriptor\r
+LOBType() throws StandardException :\r
+{\r
+       int     length = 2147483647; // default to 2GB-1 if no length specified\r
+       String  type;\r
+}\r
+{\r
+       (\r
+               <BLOB> [ length = lengthAndModifier() ]\r
+               {\r
+                       type = TypeId.BLOB_NAME;\r
+               }\r
+       |\r
+               <CLOB> [ length = lengthAndModifier() ]\r
+               {\r
+                       type = TypeId.CLOB_NAME;\r
+               }\r
+       |\r
+               <NCLOB> length = lengthAndModifier()\r
+               {\r
+                       type = TypeId.NCLOB_NAME;\r
+                       // need to re-enable according to SQL standard\r
+                       throw StandardException.newException(SQLState.NOT_IMPLEMENTED, type);\r
+               }\r
+       |\r
+               <BINARY> <LARGE> <OBJECT> [ length = lengthAndModifier() ]\r
+               {\r
+                       type = TypeId.BLOB_NAME;\r
+               }\r
+       |\r
+               charOrCharacter() <LARGE> <OBJECT> [ length = lengthAndModifier() ]\r
+               {\r
+                       type = TypeId.CLOB_NAME;\r
+               }\r
+       |\r
+               <NATIONAL> <CHARACTER> <LARGE> <OBJECT> length = lengthAndModifier()\r
+               {\r
+                       type = TypeId.NCLOB_NAME;\r
+                       // need to re-enable according to SQL standard\r
+                       throw StandardException.newException(SQLState.NOT_IMPLEMENTED, type);\r
+               }\r
+       )\r
+       {\r
+               DataTypeDescriptor dtd = DataTypeDescriptor.getBuiltInDataTypeDescriptor(type, length);\r
+\r
+               return dtd;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="numericType">numericType</A>\r
+ */\r
+DataTypeDescriptor\r
+numericType() throws StandardException :\r
+{\r
+       DataTypeDescriptor      typeDescriptor;\r
+}\r
+{\r
+       typeDescriptor = exactNumericType()\r
+       {\r
+               return typeDescriptor;\r
+       }\r
+|\r
+       typeDescriptor = approximateNumericType()\r
+       {\r
+               return typeDescriptor;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="exactNumericType">exactNumericType</A>\r
+ */\r
+DataTypeDescriptor\r
+exactNumericType() throws StandardException :\r
+{\r
+       int precision = TypeCompiler.DEFAULT_DECIMAL_PRECISION;\r
+       int scale = TypeCompiler.DEFAULT_DECIMAL_SCALE;\r
+       int type = Types.DECIMAL;\r
+       String typeStr = "DECIMAL";\r
+       int maxWidth;\r
+       DataTypeDescriptor dtd =  null;\r
+}\r
+{\r
+       ( <NUMERIC> \r
+       {\r
+               type = Types.NUMERIC;\r
+               typeStr = "NUMERIC";\r
+       }\r
+       | <DECIMAL> | <DEC> )\r
+       [ <LEFT_PAREN> precision = precision() [ <COMMA> scale = scale() ] <RIGHT_PAREN> ]\r
+       {\r
+               if ((precision <= 0) || \r
+                       (precision > TypeCompiler.MAX_DECIMAL_PRECISION_SCALE))\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_INVALID_PRECISION, \r
+                               typeStr, String.valueOf(precision));\r
+               } \r
+               else if ((scale < 0) || \r
+                                (scale > TypeCompiler.MAX_DECIMAL_PRECISION_SCALE))\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_INVALID_DECIMAL_SCALE, \r
+                               typeStr, String.valueOf(scale));\r
+               }\r
+               else if (scale > precision)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_INVALID_DECIMAL_PRECISION_SCALE, \r
+                               String.valueOf(scale),\r
+                               String.valueOf(precision));\r
+               }\r
+               /*\r
+               ** If we have a decimal point, need to count it\r
+               ** towards maxwidth.  Max width needs to account\r
+               ** for the possible leading '0' and '-' and the\r
+               ** decimal point.  e.g., DEC(1,1) has a maxwidth\r
+               ** of 4 (to handle "-0.1").\r
+               */\r
+               maxWidth = DataTypeUtilities.computeMaxWidth( precision, scale);\r
+               return getDataTypeServices(type, precision, scale, maxWidth);\r
+       }\r
+       |\r
+               dtd = exactIntegerType()\r
+               {\r
+                       return dtd;\r
+               }\r
+}\r
+\r
+/*\r
+ * <A NAME="exactNumericType">exactNumericType</A>\r
+ */\r
+DataTypeDescriptor\r
+exactIntegerType() throws StandardException :\r
+{\r
+\r
+}\r
+{\r
+       (<INTEGER> | <INT>)\r
+       {\r
+               return DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.INTEGER);\r
+       }\r
+|\r
+       <SMALLINT>\r
+       {\r
+               return DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.SMALLINT);\r
+       }\r
+|\r
+       <LONGINT>\r
+       {\r
+               return DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.BIGINT);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="approximateNumericType">approximateNumericType</A>\r
+ */\r
+DataTypeDescriptor\r
+approximateNumericType() throws StandardException :\r
+{\r
+       int type = 0, scale = 0, width = 0;\r
+       int prec = -1;\r
+       DataTypeDescriptor dts = null;\r
+}\r
+{\r
+       <FLOAT> [ <LEFT_PAREN> prec = precision() <RIGHT_PAREN> ]\r
+       {\r
+               /*\r
+                       When not specified, default is DOUBLE_PRECISION\r
+                */\r
+               if (prec == -1)\r
+                       prec = TypeId.DOUBLE_PRECISION;\r
+\r
+               if (prec > 0 && prec <= TypeId.REAL_PRECISION)\r
+               {\r
+                       type = Types.REAL;\r
+                       prec = TypeId.REAL_PRECISION;\r
+                       scale = TypeId.REAL_SCALE;\r
+                       width = TypeId.REAL_MAXWIDTH;\r
+               }\r
+               else if (prec > TypeId.REAL_PRECISION &&\r
+                                prec <= TypeId.DOUBLE_PRECISION)\r
+               {\r
+                       type = Types.DOUBLE;\r
+                       prec = TypeId.DOUBLE_PRECISION;\r
+                       scale = TypeId.DOUBLE_SCALE;\r
+                       width = TypeId.DOUBLE_MAXWIDTH;\r
+               }\r
+               else\r
+                       throw StandardException.newException(SQLState.LANG_INVALID_PRECISION, "FLOAT", String.valueOf(prec));\r
+\r
+               /*\r
+                       REMIND: this is a slight hack, in that exacting reading of\r
+                       the InformationSchema requires that the type the user typed\r
+                       in be visible to them in the InformationSchema views. But\r
+                       most implementations use synonyms or mappings at some point,\r
+                       and this is one of those places, for us.\r
+                */\r
+               return getDataTypeServices(type, prec, scale, width);\r
+       }\r
+| \r
+       <REAL>\r
+       {\r
+               return DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.REAL);\r
+       }\r
+|\r
+               dts = doubleType()\r
+       {\r
+               return dts;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="doubleType">doubleType</A>\r
+ */\r
+DataTypeDescriptor\r
+doubleType() throws StandardException :\r
+\r
+{\r
+\r
+}\r
+{\r
+       ( LOOKAHEAD({getToken(2).kind == PRECISION}) <DOUBLE> <PRECISION> | <DOUBLE> )\r
+       {\r
+               return DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.DOUBLE);\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="longType">longType</A>\r
+ */\r
+DataTypeDescriptor\r
+longType() throws StandardException :\r
+{\r
+       DataTypeDescriptor      dataTypeDescriptor;\r
+}\r
+{\r
+       <LONG> dataTypeDescriptor = longSubType()\r
+       {\r
+               return dataTypeDescriptor;\r
+       }\r
+}\r
+\r
+\r
+DataTypeDescriptor\r
+longSubType() throws StandardException :\r
+{\r
+       int lvcType = Types.LONGVARCHAR;\r
+}\r
+{\r
+       <VARCHAR> [ lvcType = forBitData(lvcType) ]\r
+       {\r
+               return DataTypeDescriptor.getBuiltInDataTypeDescriptor(lvcType);\r
+       }\r
+|\r
+       <NVARCHAR> \r
+       {\r
+               // need to re-enable according to SQL standard\r
+               throw StandardException.newException(SQLState.NOT_IMPLEMENTED, TypeId.NATIONAL_LONGVARCHAR_NAME);\r
+               // return DataTypeDescriptor.getBuiltInDataTypeDescriptor(TypeId.NATIONAL_LONGVARCHAR_NAME);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="XMLType">XMLType</A>\r
+ */\r
+DataTypeDescriptor\r
+XMLType() throws StandardException :\r
+{\r
+       DataTypeDescriptor value;\r
+}\r
+{\r
+       <XML>\r
+       {\r
+               checkVersion(DataDictionary.DD_VERSION_DERBY_10_1, "XML");\r
+               return DataTypeDescriptor.getBuiltInDataTypeDescriptor(\r
+                       StoredFormatIds.XML_TYPE_ID);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="xmlDocOrContent">xmlDocOrContent</A>\r
+ *\r
+ * Parse the XML keywords DOCUMENT and CONTENT.  We don't\r
+ * support CONTENT yet, so we throw an appropriate error\r
+ * if we see it.\r
+ *\r
+ */\r
+void\r
+xmlDocOrContent() throws StandardException :\r
+{\r
+}\r
+{\r
+       LOOKAHEAD({ (getToken(1).kind != DOCUMENT) &&\r
+               (getToken(1).kind != CONTENT) })\r
+       {\r
+               throw StandardException.newException(\r
+                       SQLState.LANG_XML_KEYWORD_MISSING, "DOCUMENT",\r
+                       ReuseFactory.getInteger(getToken(1).beginLine),\r
+                       ReuseFactory.getInteger(getToken(1).beginColumn));\r
+       }\r
+|\r
+       LOOKAHEAD({ getToken(1).kind == CONTENT }) <CONTENT>\r
+       {\r
+               throw StandardException.newException(\r
+                       SQLState.LANG_UNSUPPORTED_XML_FEATURE, "CONTENT");\r
+       }\r
+|\r
+       LOOKAHEAD({ getToken(1).kind == DOCUMENT }) <DOCUMENT>\r
+       {\r
+               return;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="javaType">javaType</A>\r
+ */\r
+DataTypeDescriptor\r
+javaType() throws StandardException :\r
+{\r
+       String  javaClassName;\r
+}\r
+{\r
+       javaClassName = javaClassName() \r
+       {\r
+               return getJavaClassDataTypeDescriptor(javaClassName);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME = "javaDSL">javaDSL</A>\r
+ *\r
+ * A Java dot-separated list.\r
+ */\r
+String\r
+javaDSL() :\r
+{\r
+       String dotSeparatedList;\r
+}\r
+{\r
+       dotSeparatedList = caseSensitiveIdentifierPlusReservedWords()\r
+               ( dotSeparatedList = javaDSLNameExtender(dotSeparatedList) ) *\r
+       {\r
+               return dotSeparatedList;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="javaClassName">javaClassName</A>\r
+ */\r
+String\r
+javaClassName() :\r
+{\r
+       String javaClassName;\r
+}\r
+{\r
+       javaClassName = javaDSL()\r
+       {\r
+               return javaClassName;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="javaDSLNameExtender">javaDSLNameExtender</A>\r
+ */\r
+String\r
+javaDSLNameExtender(String dotSeparatedList)  :\r
+{\r
+       String  extender;\r
+}\r
+{\r
+       <PERIOD> extender = caseSensitiveIdentifierPlusReservedWords()\r
+       {\r
+               return dotSeparatedList + "." + extender;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="length">lengthAndModifier</A>\r
+ */\r
+int\r
+lengthAndModifier() throws StandardException :\r
+{\r
+       Token   tok;\r
+       Token   tokmod = null;\r
+}\r
+{\r
+       <LEFT_PAREN> \r
+       // we have essentially 3 different ways of specifying the length of a LOB\r
+       ( tok = <LENGTH_MODIFIER>                                       // LOB(33K)\r
+       | tok = <EXACT_NUMERIC> [ tokmod = <IDENTIFIER> ] )             // LOB(33) or LOB(33 K)\r
+       <RIGHT_PAREN>\r
+       {\r
+               String s = tok.image + (tokmod==null ? "" : tokmod.image); // colapse cases;\r
+               try\r
+               {\r
+                       char modifier = s.charAt(s.length()-1);\r
+                       String number = s.substring(0, s.length()-1); // in case of ending w. letter\r
+                       long mul;\r
+                       switch (modifier) {\r
+                       case 'G': \r
+                       case 'g':\r
+                               mul =1073741824L;       //1 Giga\r
+                               break;\r
+                       case 'M':\r
+                       case 'm':\r
+                               mul=1048576L;           // 1 Mega\r
+                               break;\r
+                       case 'K':\r
+                       case 'k':\r
+                               mul=1024L;              // 1 Kilo\r
+                               break;\r
+                       default:\r
+                               mul=1;\r
+                               number = s; // no letter in end, need whole string\r
+                               break;\r
+                       }\r
+                       long    specifiedLength = Long.parseLong(number) * mul;\r
+                       \r
+                       // match DB2 limits of 1 to 2147483647\r
+                       if ((specifiedLength > 0L) && \r
+                (specifiedLength <= Limits.DB2_LOB_MAXWIDTH))\r
+            {\r
+                               return (int)specifiedLength;\r
+            }\r
+\r
+                       // DB2 allows 2G or 2048M or 2097152k that calculate out to \r
+            // 2147483648, but sets the length to be one less.\r
+                       if (mul != 1 && specifiedLength == 2147483648L)\r
+                               return Limits.DB2_LOB_MAXWIDTH;\r
+                               \r
+               }\r
+               catch (NumberFormatException nfe)\r
+               {\r
+               }\r
+\r
+               throw StandardException.newException(\r
+            SQLState.LANG_INVALID_COLUMN_LENGTH, s);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="length">length</A>\r
+ */\r
+int\r
+length() throws StandardException :\r
+{\r
+       Token   tok;\r
+       int     retval;\r
+}\r
+{\r
+       tok = <EXACT_NUMERIC>\r
+       {\r
+               try\r
+               {\r
+                       retval = Integer.parseInt(tok.image);\r
+\r
+                       if (retval > 0)\r
+                               return retval;\r
+               }\r
+               catch (NumberFormatException nfe)\r
+               {\r
+               }\r
+               throw StandardException.newException(SQLState.LANG_INVALID_COLUMN_LENGTH, tok.image);\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="exactNumber">exactNumber</A>\r
+*/\r
+long\r
+exactNumber() throws StandardException :\r
+{\r
+       Token longToken;\r
+       String sign = "";\r
+}\r
+{\r
+       [ sign = sign() ] longToken = <EXACT_NUMERIC>\r
+       {\r
+               try \r
+               {\r
+                       /*\r
+                        * Note that it's important to re-concatenate\r
+                        * the - sign (if present) into the number\r
+                        * before converting it to a long value so\r
+                        * that we can successfully handle any value\r
+                        * in the range Long.MIN_VALUE ... Long.MAX_VALUE.\r
+                        * Unfortunately, we can't simply do:\r
+                        *     return Long.parseLong(sign+longToken.image);\r
+                        * because Long.parseLong() doesn't accept a\r
+                        * leading + sign.\r
+                        */\r
+\r
+                       if (sign.equals("-"))\r
+                       {\r
+                               return Long.parseLong("-"+longToken.image);\r
+                       }\r
+                       else\r
+                       {\r
+                               return Long.parseLong(longToken.image);\r
+                       }\r
+               }\r
+               catch (NumberFormatException nfe)\r
+               {\r
+                       throw\r
+                       StandardException.newException(\r
+                                  SQLState.LANG_INVALID_INTEGER_LITERAL, longToken.image);\r
+               }\r
+       }\r
+}\r
+/*\r
+ * <A NAME="precision">precision</A>\r
+ */\r
+int\r
+precision() throws StandardException :\r
+{\r
+       int uintValue;\r
+}\r
+{\r
+       uintValue = uint_value()\r
+       {\r
+               return uintValue;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="uint_value">uint_value</A>\r
+ */\r
+int \r
+uint_value() throws StandardException :\r
+{\r
+       Token uintToken;\r
+}\r
+{\r
+       /*\r
+               because the parser won't match to UINT, we use EXACT_NUMERIC.\r
+        */\r
+       uintToken = <EXACT_NUMERIC>\r
+       {\r
+               try {\r
+                       return Integer.parseInt(uintToken.image);\r
+               } catch (NumberFormatException nfe) {\r
+                       throw StandardException.newException(SQLState.LANG_INVALID_INTEGER_LITERAL, uintToken.image);\r
+               }\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="scale">scale</A>\r
+ */\r
+int\r
+scale() throws StandardException :\r
+{\r
+       int uintValue;\r
+}\r
+{\r
+       uintValue = uint_value()\r
+       {\r
+               return uintValue;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="datetimeType">datetimeType</A>\r
+ */\r
+DataTypeDescriptor\r
+datetimeType() throws StandardException :\r
+{\r
+       Token tzTok = null;\r
+       int prec = -1; // know the value back is positive and in range\r
+}\r
+{\r
+       <DATE> \r
+       {\r
+               return DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.DATE);\r
+       }\r
+|\r
+       <TIME> \r
+       {\r
+\r
+               /*\r
+                       We do not try to set up a precision for time/timestamp\r
+                       values because this field gets mapped to the precision\r
+                       field in the JDBC driver that is for the number of\r
+                       decimal digits in the value.  Precision for time is\r
+                       actually the scale of the seconds value.\r
+\r
+                       If/when precision for times is supported, we may need\r
+                       to migrate the system catalog information to fill in\r
+                       the default values appropriately (the default for\r
+                       time is 0, fortunately; but for timestamp it is\r
+                       actually 9 due to java.sql.Timestamp's precision).\r
+                */\r
+               return DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.TIME);\r
+       }\r
+|\r
+       <TIMESTAMP> \r
+       {\r
+\r
+               return DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.TIMESTAMP);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="timePrecision">timePrecision</A>\r
+ */\r
+\r
+void\r
+qualifiedNameList(Vector list, int id_length_limit) throws StandardException :\r
+{\r
+}\r
+{\r
+       qualifiedNameElement(list, id_length_limit) ( <COMMA> qualifiedNameElement(list, id_length_limit) ) *\r
+}\r
+\r
+void \r
+qualifiedNameElement(Vector list, int id_length_limit) throws StandardException :\r
+{\r
+       TableName qualifiedName = null;\r
+}\r
+{\r
+       qualifiedName = qualifiedName(id_length_limit)\r
+       {\r
+               list.addElement(qualifiedName);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="qualifiedName">qualifiedName</A>\r
+ */\r
+TableName\r
+qualifiedName( int nodeType, int id_length_limit) throws StandardException :\r
+{\r
+       //String        catalogName = null;\r
+       String  schemaName = null;\r
+       String  qualifiedId;\r
+       String  firstName = null;\r
+       String  secondName = null;\r
+}\r
+{\r
+       firstName = identifier(Limits.MAX_IDENTIFIER_LENGTH, false)\r
+                               [\r
+                                       // This LOOKAHEAD is necessary because a selectSublist()\r
+                                       // can be a qualifiedName.*. Make sure that the token after\r
+                                       // the PERIOD is not an ASTERISK before committing to this\r
+                                       // optional element.\r
+                                       LOOKAHEAD( {getToken(1).kind == PERIOD &&\r
+                                                               getToken(2).kind != ASTERISK} )\r
+                                       <PERIOD> secondName = identifier(Limits.MAX_IDENTIFIER_LENGTH, false)\r
+                               ]\r
+       {\r
+               if (secondName == null)\r
+               {\r
+                       qualifiedId = firstName;\r
+               }\r
+               else\r
+               {\r
+                       schemaName = firstName;\r
+                       qualifiedId = secondName;\r
+               }\r
+\r
+               //limit the qualifiedId to the id length limit passed to this method\r
+               checkIdentifierLengthLimit(qualifiedId, id_length_limit);\r
+               if (schemaName != null)\r
+                       checkIdentifierLengthLimit(schemaName, Limits.MAX_IDENTIFIER_LENGTH);\r
+\r
+               return (TableName) nodeFactory.getNode(\r
+                                                               nodeType,\r
+                                                               schemaName,\r
+                                                               qualifiedId,\r
+                                                               new Integer(lastIdentifierToken.beginOffset),\r
+                                                               new Integer(lastIdentifierToken.endOffset),\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="queryExpression">queryExpression</A>\r
+ *\r
+ * We have to be carefull to get the associativity correct. According to the SQL spec\r
+ *   <non-join query expression> ::=\r
+ *     <non-join query term>\r
+ *    | <query expression body> UNION [ ALL ] <query term>\r
+ *    | <query expression body> EXCEPT [ ALL ] <query term>\r
+ * Meaning that\r
+ *   t1 UNION ALL t2 UNION t3\r
+ * is equivalent to\r
+ *   (t1 UNION ALL t2) UNION t3\r
+ * However recursive descent parsers want recursion to be on the right, so this kind of associativity is unnatural\r
+ * for our parser. The queryExpression method must know whether it is being called as the right hand side of a\r
+ * set operator to produce a query tree with the correct associativity.\r
+ */\r
+ResultSetNode\r
+queryExpression(ResultSetNode leftSide, int operatorType) throws StandardException :\r
+{\r
+       ResultSetNode   term;\r
+}\r
+{\r
+       term = nonJoinQueryTerm(leftSide, operatorType) [ term = unionOrExcept(term) ]\r
+       {\r
+               return term;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="unionOrExcept">unionOrExcept</A>\r
+ */\r
+ResultSetNode\r
+unionOrExcept(ResultSetNode term) throws StandardException :\r
+{\r
+       ResultSetNode   expression;\r
+       Token                   tok = null;\r
+}\r
+{\r
+       <UNION> [ tok = <ALL> | <DISTINCT> ] expression =\r
+                               queryExpression(term,\r
+                                                               (tok != null) ? UNION_ALL_OP : UNION_OP)\r
+       {\r
+               return expression;\r
+       }\r
+|\r
+       <EXCEPT> [ tok = <ALL> | <DISTINCT> ] expression =\r
+                               queryExpression(term,\r
+                                                               (tok != null) ? EXCEPT_ALL_OP : EXCEPT_OP)\r
+       {\r
+               return expression;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="nonJoinQueryTerm">nonJoinQueryTerm</A>\r
+ *\r
+ * Be careful with the associativity of INTERSECT. According to the SQL spec\r
+ *   t1 INTERSECT t2 INTERSECT ALL t3\r
+ * is equivalent to\r
+ *   (t1 INTERSECT t2) INTERSECT ALL t3\r
+ * which is not the same as\r
+ *   t1 INTERSECT (t2 INTERSECT ALL t3)\r
+ * See the comment on queryExpression.\r
+ */\r
+ResultSetNode\r
+nonJoinQueryTerm(ResultSetNode leftSide, int operatorType) throws StandardException :\r
+{\r
+       ResultSetNode   term;\r
+}\r
+{\r
+       term = nonJoinQueryPrimary() [ term = intersect( term) ]\r
+       {\r
+        switch( operatorType)\r
+        {\r
+        case NO_SET_OP:\r
+            return term;\r
+\r
+        case UNION_OP:\r
+            return (ResultSetNode) nodeFactory.getNode(\r
+                C_NodeTypes.UNION_NODE,\r
+                leftSide,\r
+                term,\r
+                Boolean.FALSE,\r
+                Boolean.FALSE,\r
+                null,\r
+                getContextManager());\r
+\r
+        case UNION_ALL_OP:\r
+            return (ResultSetNode) nodeFactory.getNode(\r
+                C_NodeTypes.UNION_NODE,\r
+                leftSide,\r
+                term,\r
+                Boolean.TRUE,\r
+                Boolean.FALSE,\r
+                null,\r
+                getContextManager());\r
+\r
+        case EXCEPT_OP:\r
+            return (ResultSetNode) nodeFactory.getNode(\r
+                C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,\r
+                ReuseFactory.getInteger( IntersectOrExceptNode.EXCEPT_OP),\r
+                leftSide,\r
+                term,\r
+                Boolean.FALSE,\r
+                null,\r
+                getContextManager());\r
+\r
+        case EXCEPT_ALL_OP:\r
+            return (ResultSetNode) nodeFactory.getNode(\r
+                C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,\r
+                ReuseFactory.getInteger( IntersectOrExceptNode.EXCEPT_OP),\r
+                leftSide,\r
+                term,\r
+                Boolean.TRUE,\r
+                null,\r
+                getContextManager());\r
+\r
+        case INTERSECT_OP:\r
+            return (ResultSetNode) nodeFactory.getNode(\r
+                C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,\r
+                ReuseFactory.getInteger( IntersectOrExceptNode.INTERSECT_OP),\r
+                leftSide,\r
+                term,\r
+                Boolean.FALSE,\r
+                null,\r
+                getContextManager());\r
+\r
+        case INTERSECT_ALL_OP:\r
+            return (ResultSetNode) nodeFactory.getNode(\r
+                C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,\r
+                ReuseFactory.getInteger( IntersectOrExceptNode.INTERSECT_OP),\r
+                leftSide,\r
+                term,\r
+                Boolean.TRUE,\r
+                null,\r
+                getContextManager());\r
+\r
+\r
+        default:\r
+            if (SanityManager.DEBUG)\r
+            {\r
+                SanityManager.THROWASSERT( "Invalid set operator type: " + operatorType);\r
+            }\r
+            return null;\r
+        }\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="intersect">intersect</A>\r
+ */\r
+ResultSetNode\r
+intersect(ResultSetNode term) throws StandardException :\r
+{\r
+       ResultSetNode   expression;\r
+       Token                   tok = null;\r
+}\r
+{\r
+       <INTERSECT> [ tok = <ALL> | <DISTINCT> ] expression =\r
+                               nonJoinQueryTerm(term, (tok != null) ? INTERSECT_ALL_OP : INTERSECT_OP)\r
+       {\r
+               return expression;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="nonJoinQueryPrimary">nonJoinQueryPrimary</A>\r
+ */\r
+ResultSetNode\r
+nonJoinQueryPrimary() throws StandardException :\r
+{\r
+       ResultSetNode   primary;\r
+}\r
+{\r
+       primary = simpleTable()\r
+       {\r
+               return primary;\r
+       }\r
+|\r
+       <LEFT_PAREN> primary = queryExpression(null, NO_SET_OP) <RIGHT_PAREN>\r
+       {\r
+               return primary;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="simpleTable">simpleTable</A>\r
+ */\r
+ResultSetNode\r
+simpleTable() throws StandardException :\r
+{\r
+       ResultSetNode   resultSetNode;\r
+}\r
+{\r
+       resultSetNode = querySpecification()\r
+       {\r
+               return resultSetNode;\r
+       }\r
+|\r
+       resultSetNode = tableValueConstructor()\r
+       {\r
+               return resultSetNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="querySpecification">querySpecification</A>\r
+ */\r
+ResultSetNode\r
+querySpecification() throws StandardException :\r
+{\r
+       ResultColumnList        selectList;\r
+       SelectNode                      selectNode;\r
+       boolean isDistinct = false;\r
+}\r
+{\r
+       <SELECT> [ isDistinct = setQuantifier() ]\r
+               selectList = selectList()\r
+               selectNode = tableExpression(selectList)\r
+       {\r
+               if (isDistinct) selectNode.makeDistinct();\r
+               return selectNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="setQuantifier">setQuantifier</A>\r
+ */\r
+boolean\r
+setQuantifier() :\r
+{}\r
+{\r
+       // This lookahead is required to distinquish distinct from\r
+       // a class which starts with distinct (e.g., distinct::)\r
+       LOOKAHEAD\r
+       (\r
+               {\r
+                       getToken(1).kind == DISTINCT &&\r
+                       !(\r
+                               getToken(2).kind == PERIOD ||\r
+                               getToken(2).kind == DOUBLE_COLON\r
+                       )\r
+               }\r
+       )\r
+       <DISTINCT>\r
+       {\r
+               return true;\r
+       }\r
+|\r
+       // This lookahead is required to distinquish all from\r
+       // a class which starts with all (e.g., all::)\r
+       LOOKAHEAD\r
+       (\r
+               {\r
+                       getToken(1).kind == ALL &&\r
+                       !(\r
+                               getToken(2).kind == PERIOD ||\r
+                               getToken(2).kind == DOUBLE_COLON\r
+                       )\r
+               }\r
+       )\r
+       <ALL>\r
+       {\r
+               return false;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="selectList">selectList</A>\r
+ */\r
+ResultColumnList\r
+selectList() throws StandardException :\r
+{\r
+       ResultColumn    allResultColumn;\r
+       ResultColumnList        resultColumns = (ResultColumnList) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                       getContextManager());\r
+}\r
+{\r
+       <ASTERISK>\r
+       {\r
+               allResultColumn = (ResultColumn) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.ALL_RESULT_COLUMN,\r
+                                                                               null,\r
+                                                                               getContextManager());\r
+               /* Add the new AllResultColumn to the end of the list */\r
+               resultColumns.addResultColumn(allResultColumn);\r
+               return resultColumns;\r
+       }\r
+|\r
+       selectColumnList(resultColumns)\r
+       {\r
+               return resultColumns;\r
+       }\r
+}\r
+\r
+void\r
+selectColumnList(ResultColumnList resultColumns) throws StandardException :\r
+{\r
+}\r
+{\r
+       selectSublist(resultColumns) ( <COMMA> selectSublist(resultColumns) ) *\r
+}\r
+\r
+/*\r
+ * <A NAME="selectSublist">selectSublist</A>\r
+ */\r
+void\r
+selectSublist(ResultColumnList resultColumns) throws StandardException :\r
+{\r
+       ResultColumn    resultColumn;\r
+       ResultColumn    allResultColumn;\r
+       TableName       tableName;\r
+}\r
+{\r
+       // This LOOKAHEAD is required because both a qualifiedName() and a\r
+       // derivedColumn() can start with an identifier().  So, the two cases\r
+       // we check for are x.* and x.y.*\r
+       //\r
+       // NOTE: It is hard to check for an identifier() using semantic lookahead.\r
+       LOOKAHEAD\r
+       (\r
+               {\r
+                       getToken(2).kind == PERIOD &&\r
+                       (\r
+                               getToken(3).kind == ASTERISK ||\r
+                               (getToken(4).kind == PERIOD && getToken(5).kind == ASTERISK)\r
+                       )\r
+               }\r
+       )\r
+       tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) <PERIOD> <ASTERISK>\r
+       {\r
+               allResultColumn = (ResultColumn) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.ALL_RESULT_COLUMN,\r
+                                                                               tableName,\r
+                                                                               getContextManager());\r
+               /* Add the new AllResultColumn to the end of the list */\r
+               resultColumns.addResultColumn(allResultColumn);\r
+       }\r
+|\r
+       resultColumn = derivedColumn(resultColumns)\r
+       {\r
+               /* Add the new ResultColumn to the end of the list */\r
+               resultColumns.addResultColumn(resultColumn);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="derivedColumn">derivedColumn</A>\r
+ */\r
+ResultColumn\r
+derivedColumn(ResultColumnList resultColumns) throws StandardException :\r
+{\r
+       ValueNode       columnExpression;\r
+       String          columnName = null;\r
+}\r
+{\r
+       //true to additiveExpression ensures that for the derived columns, we will not allow boolean values inside (), \r
+       //eg (2 > 1) should be disallowed in the select clause\r
+       columnExpression = additiveExpression(null, 0, true) \r
+                       [ columnName = asClause() ]\r
+       { \r
+               /*\r
+               ** If there is no AS clause, and the expression is a simple\r
+               ** column, use the name of the column as the result column\r
+               ** name.\r
+               */\r
+               if ((columnName == null) && (columnExpression instanceof ColumnReference))\r
+               {\r
+                       columnName = ((ColumnReference) columnExpression).columnName;\r
+               }\r
+\r
+               return (ResultColumn) nodeFactory.getNode(\r
+                                               C_NodeTypes.RESULT_COLUMN,\r
+                                               columnName,\r
+                                               columnExpression,\r
+                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="asClause">asClause</A>\r
+ */\r
+String\r
+asClause() throws StandardException :\r
+{\r
+       String  columnName;\r
+}\r
+{\r
+       /* identifier() used to be columnName() */\r
+       [ <AS> ] columnName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               return columnName;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="valueExpression">valueExpression</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+valueExpression( boolean inSelectClause ) throws StandardException :\r
+{\r
+       ValueNode       leftOperand;\r
+}\r
+{\r
+       leftOperand = orExpression(null, inSelectClause)\r
+               (<OR> leftOperand = orExpression(leftOperand, inSelectClause) ) *\r
+       {\r
+\r
+               return leftOperand;\r
+       }\r
+}\r
+       \r
+/*\r
+ * <A NAME="orExpression">orExpression</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+orExpression(ValueNode farLeftOperand, boolean inSelectClause) throws StandardException :\r
+{\r
+       ValueNode       leftOperand;\r
+}\r
+{\r
+       leftOperand = andExpression(null, inSelectClause)\r
+               (<AND> leftOperand = andExpression(leftOperand, inSelectClause)) *\r
+       {\r
+               if (farLeftOperand == null)\r
+               {\r
+                       return leftOperand;\r
+               }\r
+               else\r
+               {\r
+                       return (ValueNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.OR_NODE,\r
+                                                                               farLeftOperand,\r
+                                                                               leftOperand,\r
+                                                                               getContextManager());\r
+               }\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="andExpression">andExpression</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+andExpression(ValueNode farLeftOperand, boolean inSelectClause) throws StandardException :\r
+{\r
+       Token           tok = null;\r
+       ValueNode       test;\r
+}\r
+{\r
+       //LOOKAHEAD required to tell that NOT is not part of a class name\r
+       [ LOOKAHEAD({getToken(1).kind == NOT && !(getToken(2).kind == PERIOD ||\r
+                       getToken(2).kind == DOUBLE_COLON)}) tok = <NOT> ] test = isSearchCondition(inSelectClause) \r
+       {\r
+               /* Put the NOT on top of test */\r
+               if (tok != null)\r
+               {\r
+                       test = (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.NOT_NODE,\r
+                                                                       test,\r
+                                                                       getContextManager());\r
+               }\r
+\r
+               if (farLeftOperand != null)\r
+               {\r
+                       test = (ValueNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.AND_NODE,\r
+                                                                               farLeftOperand,\r
+                                                                               test,\r
+                                                                               getContextManager());\r
+               }\r
+               return test;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="isSearchCondition">isSearchCondition</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+isSearchCondition( boolean inSelectClause ) throws StandardException :\r
+{\r
+       ValueNode       result;\r
+       ValueNode       booleanPrimary;\r
+       Token           isToken = null;\r
+       Token           notToken = null;\r
+       Token           truthValue = null;\r
+}\r
+{\r
+       booleanPrimary = booleanPrimary(inSelectClause)\r
+       [\r
+               isToken = <IS> [ notToken = <NOT> ] <NULL>\r
+       ]\r
+       {\r
+               if ( isToken != null )\r
+               {\r
+                               result = (ValueNode) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.IS_NULL_NODE,\r
+                                                                                       booleanPrimary,\r
+                                                                                       getContextManager());\r
+               \r
+                               /* Put the NOT on top of the tree */\r
+                               if (notToken != null)\r
+                               {\r
+                                       result = (ValueNode) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.NOT_NODE,\r
+                                                                                       result,\r
+                                                                                       getContextManager());\r
+                               }\r
+               }\r
+               else { result = booleanPrimary; }\r
+\r
+               return result;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="booleanPrimary">booleanPrimary</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+booleanPrimary(boolean inSelectClause) throws StandardException :\r
+{\r
+       ValueNode       primary;\r
+       ValueNode       searchCondition;\r
+}\r
+{\r
+       primary = predicate(inSelectClause)\r
+       {\r
+               return  primary;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="predicate">predicate</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+predicate( boolean inSelectClause ) throws StandardException :\r
+{\r
+       ValueNode       value;\r
+}\r
+{\r
+       (\r
+               value = additiveExpression(null, 0, inSelectClause) |\r
+               value = existsExpression()\r
+       )\r
+       (\r
+               // This LOOKAHEAD is necessary because remainingPredicate() can\r
+               // start with NOT, and what follows a predicate() can also start\r
+               // with NOT\r
+               LOOKAHEAD( { remainingPredicateFollows() } )\r
+               value = remainingPredicate(value, inSelectClause)\r
+       )*\r
+       {\r
+               return value;\r
+       }\r
+/*\r
+** RESOLVE: overlapsExpression commented out for the time being to avoid\r
+** a left recursion.  An OVERLAPS expression is defined as taking row\r
+** constructors as parameters.  A row constructor contains a valueExpression\r
+** as its first element, so it can't return be the first element in a\r
+** valueExpression.\r
+\r
+|\r
+       overlapsExpression()\r
+       {\r
+               return null;\r
+       }\r
+*/\r
+}\r
+\r
+/*\r
+ * <A NAME="remainingPredicates">remainingPredicates</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+remainingPredicate(ValueNode value, boolean inSelectClause) throws StandardException :\r
+{\r
+       Token tok = null;\r
+}\r
+{\r
+       value = remainingNonNegatablePredicate(value, inSelectClause)\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       [ tok = <NOT> ] value = remainingNegatablePredicate(value, inSelectClause)\r
+       {\r
+               /* Put the NOT on top of the tree */\r
+               if (tok != null)\r
+               {\r
+                       value = (ValueNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.NOT_NODE,\r
+                                                                               value,\r
+                                                                               getContextManager());\r
+               }\r
+\r
+               return value;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="remainingNonNegatablePredicate">remainingNonNegatablePredicate</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode \r
+remainingNonNegatablePredicate(ValueNode leftOperand, boolean inSelectClause) throws StandardException :\r
+{\r
+       int                     operator;\r
+       String          javaClassName;\r
+       Token           tok = null;\r
+       ValueNode       tree = null;\r
+       ValueNode       likePattern;\r
+       ValueNode       betweenLeft;\r
+       ValueNode       betweenRight;\r
+}\r
+{\r
+       operator = compOp()\r
+       (\r
+               // Lookahead required here to tell ALL, ANY or SOME from a \r
+               // class which starts with these words (e.g., ALL::)\r
+               LOOKAHEAD({(getToken(1).kind == ALL || getToken(1).kind == ANY || \r
+                       getToken(1).kind == SOME) && getToken(2).kind == LEFT_PAREN})\r
+               (\r
+                       operator = quantifier(operator)\r
+                       <LEFT_PAREN>\r
+                       leftOperand = tableSubquery(operator, leftOperand)\r
+                       <RIGHT_PAREN>\r
+               )\r
+               |\r
+               (\r
+                       leftOperand = additiveExpression(leftOperand, operator, inSelectClause)\r
+               )\r
+       )\r
+       {\r
+               return leftOperand;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="remainingNegatablePredicate">remainingNegatablePredicate</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode \r
+remainingNegatablePredicate(ValueNode leftOperand, boolean inSelectClause) throws StandardException :\r
+{\r
+       ValueNode       tree = null;\r
+       ValueNode       likePattern;\r
+       ValueNode       betweenLeft;\r
+       ValueNode       betweenRight;\r
+       ValueNode       escapeValue = null;\r
+}\r
+{\r
+       <IN> tree = inPredicateValue(leftOperand)\r
+       {\r
+               return tree;\r
+       }\r
+|\r
+       <LIKE> likePattern = additiveExpression(null, 0, inSelectClause)\r
+            [\r
+                <ESCAPE> escapeValue = additiveExpression(null, 0, inSelectClause) |\r
+                <LEFT_BRACE> <ESCAPE> escapeValue = additiveExpression(null, 0, inSelectClause) <RIGHT_BRACE>\r
+            ]\r
+       {\r
+               tree = (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.LIKE_OPERATOR_NODE,\r
+                                                               leftOperand,\r
+                                                               likePattern,\r
+                                                               escapeValue,\r
+                                                               getContextManager());\r
+               \r
+               return tree;\r
+       }\r
+|\r
+       <BETWEEN> betweenLeft = additiveExpression(null, 0, inSelectClause) <AND>\r
+                       betweenRight = additiveExpression(null, 0, inSelectClause)\r
+       {\r
+               ValueNodeList betweenList = (ValueNodeList) nodeFactory.getNode(\r
+                                                                                                       C_NodeTypes.VALUE_NODE_LIST,\r
+                                                                                                       getContextManager());\r
+               betweenList.addElement(betweenLeft);\r
+               betweenList.addElement(betweenRight);\r
+               tree = (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.BETWEEN_OPERATOR_NODE,\r
+                                                               leftOperand,\r
+                                                               betweenList,\r
+                                                               getContextManager());\r
+               \r
+               return tree;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="compOp">compOp</A>\r
+ */\r
+int\r
+compOp() throws StandardException :\r
+{}\r
+{\r
+       <EQUALS_OPERATOR>\r
+       {\r
+               return BinaryOperatorNode.EQ;\r
+       }\r
+|\r
+       <NOT_EQUALS_OPERATOR>\r
+       {\r
+               return BinaryOperatorNode.NE;\r
+       }\r
+|\r
+       <NOT_EQUALS_OPERATOR2>\r
+       {\r
+               return BinaryOperatorNode.NE;\r
+       }\r
+|\r
+       <LESS_THAN_OPERATOR>\r
+       {\r
+               return BinaryOperatorNode.LT;\r
+       }\r
+|\r
+       <GREATER_THAN_OPERATOR>\r
+       {\r
+               return BinaryOperatorNode.GT;\r
+       }\r
+|\r
+       <LESS_THAN_OR_EQUALS_OPERATOR>\r
+       {\r
+               return BinaryOperatorNode.LE;\r
+       }\r
+|\r
+       <GREATER_THAN_OR_EQUALS_OPERATOR>\r
+       {\r
+               return BinaryOperatorNode.GE;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="additiveExpression">additiveExpression</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+additiveExpression(ValueNode farLeftOperand, int compOp, boolean inSelectClause) throws StandardException :\r
+{\r
+       ValueNode       leftOperand;\r
+       int                     operator;\r
+       int                     nodeType;\r
+}\r
+{\r
+       leftOperand = multiplicativeExpression(null, 0, inSelectClause)                         \r
+                       (operator = additiveOperator()                   \r
+                               leftOperand = multiplicativeExpression(leftOperand, operator, inSelectClause) )*\r
+       {\r
+               if (farLeftOperand == null)\r
+                       return leftOperand;\r
+\r
+               switch (compOp)\r
+               {\r
+                 case BinaryOperatorNode.EQ:\r
+                       nodeType = C_NodeTypes.BINARY_EQUALS_OPERATOR_NODE;\r
+                       break;\r
+\r
+                 case BinaryOperatorNode.NE:\r
+                       nodeType = C_NodeTypes.BINARY_NOT_EQUALS_OPERATOR_NODE;\r
+                       break;\r
+\r
+                 case BinaryOperatorNode.LT:\r
+                       nodeType = C_NodeTypes.BINARY_LESS_THAN_OPERATOR_NODE;\r
+                       break;\r
+\r
+                 case BinaryOperatorNode.GT:\r
+                       nodeType = C_NodeTypes.BINARY_GREATER_THAN_OPERATOR_NODE;\r
+                       break;\r
+\r
+                 case BinaryOperatorNode.LE:\r
+                       nodeType = C_NodeTypes.BINARY_LESS_EQUALS_OPERATOR_NODE;\r
+                       break;\r
+\r
+                 case BinaryOperatorNode.GE:\r
+                       nodeType = C_NodeTypes.BINARY_GREATER_EQUALS_OPERATOR_NODE;\r
+                       break;\r
+\r
+                 default:\r
+                       if (SanityManager.DEBUG)\r
+                       SanityManager.THROWASSERT("Unknown comparison operator " + compOp);\r
+                       nodeType = 0;\r
+                       break;\r
+               }\r
+\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                       nodeType,\r
+                                                       farLeftOperand,\r
+                                                       leftOperand,\r
+                                                       getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="additiveOperator">additiveOperator</A>\r
+ */\r
+int\r
+additiveOperator() throws StandardException :\r
+{\r
+       Token tok;\r
+}\r
+{      tok = <PLUS_SIGN> \r
+       {\r
+               return BinaryOperatorNode.PLUS;\r
+       }\r
+|\r
+       tok = <MINUS_SIGN>\r
+       {\r
+               return BinaryOperatorNode.MINUS;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="multiplicativeExpression">multiplicativeExpression</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+multiplicativeExpression(ValueNode farLeftOperand, int additiveOperator, boolean inSelectClause) throws StandardException :\r
+{\r
+       ValueNode       leftOperand;\r
+       int                     multOp;\r
+}\r
+{\r
+       leftOperand = unaryExpression(null, 0, inSelectClause) \r
+                               (multOp = multiplicativeOperator() \r
+                                leftOperand = unaryExpression(leftOperand, multOp, inSelectClause) )*\r
+       {\r
+               if (farLeftOperand == null)\r
+                       return leftOperand;\r
+\r
+               switch (additiveOperator)\r
+               {\r
+                 case BinaryOperatorNode.PLUS:\r
+                       return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.BINARY_PLUS_OPERATOR_NODE,\r
+                                                                       farLeftOperand,\r
+                                                                       leftOperand,\r
+                                                                       getContextManager()\r
+                                                                       );\r
+\r
+                 case BinaryOperatorNode.MINUS:\r
+                       return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.BINARY_MINUS_OPERATOR_NODE,\r
+                                                                       farLeftOperand,\r
+                                                                       leftOperand,\r
+                                                                       getContextManager()\r
+                                                                       );\r
+\r
+                 default:\r
+                       if (SanityManager.DEBUG)\r
+                       SanityManager.THROWASSERT(\r
+                                       "Unexpected operator value of " + additiveOperator);\r
+                       return null;\r
+               }\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="multiplicativeOperator">multiplicativeOperator</A>\r
+ */\r
+int\r
+multiplicativeOperator() throws StandardException :\r
+{ }\r
+{      <ASTERISK> \r
+       {\r
+               return BinaryOperatorNode.TIMES;\r
+       }\r
+|\r
+       <SOLIDUS>\r
+       {\r
+               return BinaryOperatorNode.DIVIDE;\r
+       }\r
+|\r
+       <CONCATENATION_OPERATOR>\r
+       {\r
+               return BinaryOperatorNode.CONCATENATE;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="unaryExpression">unaryExpression</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+unaryExpression(ValueNode farLeftOperand, int multiplicativeOperator, boolean inSelectClause) throws StandardException :\r
+{\r
+       ValueNode       value;\r
+       String          sign = null;\r
+       int                     tokKind1;\r
+       int                     tokKind2;\r
+}\r
+{\r
+       [\r
+               // This LOOKAHEAD is required because a + or - sign can come before\r
+               // any expression, and also can be part of a literal. If it comes\r
+               // before a number, we want it to be considered part of the literal,\r
+               // because the literal() rule knows how to handle the minimum value\r
+               // for an int without changing it to a long.\r
+               LOOKAHEAD( {\r
+                                       ( (tokKind1 = getToken(1).kind) == PLUS_SIGN ||\r
+                                          tokKind1 == MINUS_SIGN )\r
+                                       &&\r
+                                       ( (tokKind2 = getToken(2).kind) != EXACT_NUMERIC &&\r
+                                          tokKind2 != APPROXIMATE_NUMERIC)\r
+                                  } )\r
+               sign = sign()\r
+       ]\r
+       value = primaryExpression(inSelectClause)\r
+       {\r
+               if ("-".equals(sign))\r
+               {\r
+                       value = (ValueNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.UNARY_MINUS_OPERATOR_NODE,\r
+                                                                               value,\r
+                                                                               getContextManager());\r
+               }\r
+               else if ("+".equals(sign))\r
+               {\r
+                       value = (ValueNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.UNARY_PLUS_OPERATOR_NODE,\r
+                                                                               value,\r
+                                                                               getContextManager());\r
+               }\r
+               else if (SanityManager.DEBUG)\r
+               {\r
+                       if (sign != null)\r
+                       {\r
+                               SanityManager.THROWASSERT("Unknown unary operator '"\r
+                                                                                       + sign\r
+                                                                                       + "'");\r
+                       }\r
+               }\r
+\r
+               return multOp(farLeftOperand, value, multiplicativeOperator);\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="sign">sign</A>\r
+ */\r
+String\r
+sign() :\r
+{\r
+       Token   s;\r
+}\r
+{\r
+       s = <PLUS_SIGN>\r
+       {\r
+               return s.image;\r
+       }\r
+|\r
+       s = <MINUS_SIGN>\r
+       {\r
+               return s.image;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="primaryExpressionXX">primaryExpressionXX</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+primaryExpressionXX( boolean inSelectClause ) throws StandardException :\r
+{\r
+       ValueNode       value;\r
+}\r
+{\r
+       value = primary(inSelectClause)\r
+         ( value = nonStaticMethodCallOrFieldAccess(value)) *  \r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+ValueNode\r
+nonStaticMethodCallOrFieldAccess(ValueNode receiver) throws StandardException :\r
+{\r
+       ValueNode value;\r
+}\r
+{\r
+       value = nonStaticMethodInvocation(receiver)\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="nonStaticMethodInvocation">nonStaticMethodInvocation</A>\r
+ */\r
+ValueNode\r
+nonStaticMethodInvocation(ValueNode receiver) throws StandardException :\r
+{\r
+       Vector                                  parameterList = new Vector();\r
+       MethodCallNode                  methodNode;\r
+       ParameterNode                   parameterNode;\r
+}\r
+{\r
+        LOOKAHEAD\r
+       ( {\r
+               getToken(3).kind == LEFT_PAREN\r
+         }\r
+       )\r
+\r
+       ( <FIELD_REFERENCE> | <PERIOD> )\r
+               methodNode = methodName(receiver) methodCallParameterList(parameterList)\r
+\r
+       {\r
+\r
+               /*\r
+               ** ? parameters are not allowed for the receiver --\r
+               ** unless the receiver is standing in for a named parameter,\r
+               ** whose type is therefore known.\r
+               */\r
+               if (receiver instanceof ParameterNode)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_PARAMETER_RECEIVER,\r
+                                                                                               methodNode.getMethodName());\r
+               }\r
+\r
+               methodNode.addParms(parameterList);\r
+\r
+               /*\r
+               ** Assume this is being returned to the SQL domain.  If it turns\r
+               ** out that this is being returned to the Java domain, we will\r
+               ** get rid of this node.\r
+               */\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,\r
+                                                               methodNode,\r
+                                                               getContextManager());\r
+       }\r
+|\r
+        <PERIOD> methodNode = methodName(receiver)\r
+       {\r
+               /*\r
+               ** ? parameters are not allowed for the receiver --\r
+               ** unless the receiver is standing in for a named parameter,\r
+               ** whose type is therefore known.\r
+               */\r
+               if (receiver instanceof ParameterNode)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_PARAMETER_RECEIVER,\r
+                                                                                               methodNode.getMethodName());\r
+               }\r
+\r
+               methodNode.addParms(parameterList);\r
+\r
+               /*\r
+               ** Assume this is being returned to the SQL domain.  If it turns\r
+               ** out that this is being returned to the Java domain, we will\r
+               ** get rid of this node.\r
+               */\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,\r
+                                                               methodNode,\r
+                                                               getContextManager());\r
+       }\r
+\r
+\r
+}\r
+\r
+/*\r
+ * <A NAME="methodName">methodName</A>\r
+ */\r
+MethodCallNode\r
+methodName(ValueNode receiver) throws StandardException :\r
+{\r
+       String  methodName;\r
+}\r
+{\r
+       /*\r
+       ** NOTE: allowing a delimited identifier as a method name is necessary,\r
+       ** because Java is case-sensitive.  But this also allows identifiers that\r
+       ** do not match Java syntax.  This will probably not cause a problem\r
+       ** in later phases, like binding and code generation.\r
+       */\r
+       methodName = caseSensitiveIdentifierPlusReservedWords()\r
+       {\r
+               return (MethodCallNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.NON_STATIC_METHOD_CALL_NODE,\r
+                                                                               methodName,\r
+                                                                               receiver,\r
+                                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="staticMethodName">staticMethodName</A>\r
+ */\r
+MethodCallNode\r
+staticMethodName(String javaClassName) throws StandardException :\r
+{\r
+       String  methodName;\r
+}\r
+{\r
+       /*\r
+       ** NOTE: allowing a delimited identifier as a method name is necessary,\r
+       ** because Java is case-sensitive.  But this also allows identifiers that\r
+       ** do not match Java syntax.  This will probably not cause a problem\r
+       ** in later phases, like binding and code generation.\r
+       */\r
+       methodName = caseSensitiveIdentifierPlusReservedWords()\r
+       {\r
+               return (MethodCallNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.STATIC_METHOD_CALL_NODE,\r
+                                                               methodName,\r
+                                                               javaClassName,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="methodParameter">methodParameter</A>\r
+ */\r
+void\r
+methodParameter(Vector parameterList) throws StandardException :\r
+{\r
+       ValueNode       parameter;\r
+}\r
+{\r
+       parameter = additiveExpression(null,0, false)\r
+       {\r
+               parameterList.addElement(parameter);\r
+       }\r
+|\r
+       parameter = nullSpecification()\r
+       {\r
+               parameterList.addElement(parameter);\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="primary">primary</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+primary(boolean inSelectClause) throws StandardException :\r
+{\r
+       String          javaClassName;\r
+       ValueNode       value;\r
+}\r
+{\r
+       \r
+       //Look ahead required here to tell a java class from a identifier\r
+       LOOKAHEAD( { javaClassFollows() } )\r
+       value = staticClassReference()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       value = valueExpressionPrimary(inSelectClause)\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="staticClassReference">staticClassReference</A>\r
+ */\r
+ValueNode\r
+staticClassReference() throws StandardException :\r
+{\r
+       String          javaClassName;\r
+       ValueNode value;\r
+}\r
+{\r
+       javaClassName = javaClass() <DOUBLE_COLON>  value = staticClassReferenceType(javaClassName)\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="staticClassReferenceType">staticClassReferenceType</A>\r
+ */\r
+ValueNode\r
+staticClassReferenceType(String javaClassName) throws StandardException :\r
+{\r
+       ValueNode value;\r
+}\r
+{\r
+       //Look ahead required here to tell method from field reference\r
+       LOOKAHEAD({(getToken(2).kind == LEFT_PAREN)})\r
+       value = staticMethodInvocation(javaClassName) \r
+       {\r
+               return value;\r
+       }\r
+|\r
+       value = staticClassFieldReference(javaClassName) \r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="staticClassFieldReference">staticClassFieldReference</A>\r
+ */\r
+ValueNode\r
+staticClassFieldReference(String javaClassName) throws StandardException :\r
+{\r
+       String          fieldName = null;\r
+}\r
+{\r
+       fieldName = caseSensitiveIdentifierPlusReservedWords() \r
+       {\r
+               return  (ValueNode) nodeFactory.getNode(\r
+                                       C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,\r
+                                       nodeFactory.getNode(\r
+                                                               C_NodeTypes.STATIC_CLASS_FIELD_REFERENCE_NODE,\r
+                                                               javaClassName,\r
+                                                               fieldName,\r
+                                                               nextToLastTokenDelimitedIdentifier,\r
+                                                               getContextManager()),\r
+                                       getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="nonSecondDatetimeField">nonSecondDatetimeField</A>\r
+ */\r
+int\r
+nonSecondDatetimeField() :\r
+{}\r
+{\r
+       <YEAR> \r
+       {\r
+               return DateTimeDataValue.YEAR_FIELD;\r
+       }\r
+|\r
+       <MONTH> \r
+       {\r
+               return DateTimeDataValue.MONTH_FIELD;\r
+       }\r
+|\r
+       <DAY> \r
+       {\r
+               return DateTimeDataValue.DAY_FIELD;\r
+       }\r
+|\r
+       <HOUR> \r
+       {\r
+               return DateTimeDataValue.HOUR_FIELD;\r
+       }\r
+|\r
+       <MINUTE>\r
+       {\r
+               return DateTimeDataValue.MINUTE_FIELD;\r
+       }\r
+}\r
+\r
+\r
+ValueNode\r
+escapedValueFunction() throws StandardException :\r
+{\r
+       ValueNode       value;\r
+    ValueNode   str1;\r
+    ValueNode   str2;\r
+       ValueNode       startPosition;\r
+    ValueNode  length = null;\r
+}\r
+{\r
+       value = miscBuiltinsCore( true /* is JDBC escape */)\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       /* Escaped function substring() */\r
+    <SUBSTRING> <LEFT_PAREN> value = additiveExpression(null, 0, false) <COMMA> startPosition = additiveExpression(null, 0, false) [ <COMMA> length = additiveExpression(null, 0, false) ] <RIGHT_PAREN>\r
+       {\r
+        return getSubstringNode(value, startPosition, length, Boolean.FALSE);\r
+       }\r
+|\r
+       /* CURDATE() is an escaped function supported by JCC 2.2 or higher */\r
+       <CURDATE> <LEFT_PAREN> <RIGHT_PAREN>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.CURRENT_DATETIME_OPERATOR_NODE,\r
+                                                               ReuseFactory.getInteger(\r
+                                                                       CurrentDatetimeOperatorNode.CURRENT_DATE),\r
+                                                               getContextManager());\r
+       }\r
+|\r
+       /* CURTIME() is an escaped function supported by JCC 2.2 or higher */\r
+       <CURTIME> <LEFT_PAREN> <RIGHT_PAREN>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.CURRENT_DATETIME_OPERATOR_NODE,\r
+                                                       ReuseFactory.getInteger(\r
+                                                               CurrentDatetimeOperatorNode.CURRENT_TIME),\r
+                                                       getContextManager());\r
+       }\r
+|\r
+    /* CONCAT( string1, string2 )\r
+     * CONCAT is not a reserved word.\r
+     */\r
+    <CONCAT> <LEFT_PAREN> str1 = additiveExpression(null,0, false) <COMMA> \r
+            str2 = additiveExpression(null,0, false) <RIGHT_PAREN>\r
+    {\r
+        return (ValueNode) nodeFactory.getNode(\r
+                            C_NodeTypes.CONCATENATION_OPERATOR_NODE,\r
+                            str1,\r
+                            str2,\r
+                            getContextManager());\r
+    }\r
+|\r
+       /* Method versions of USER special registers\r
+        * are ODBC remnants.  Only supported\r
+        * when escaped.\r
+        */\r
+       value = userNode() <LEFT_PAREN> <RIGHT_PAREN>\r
+       {\r
+               return value;\r
+       }\r
+|\r
+    value = timestampArithmeticFuncion()\r
+    {\r
+        return value;\r
+    }\r
\r
+|   \r
+    LOOKAHEAD({ getEscapedSYSFUN(getToken(1).image) != null }) \r
+    value = escapedSYSFUNFunction()\r
+    {\r
+        return value;\r
+    }\r
+\r
+    \r
+}\r
+\r
+/*\r
+ * <A NAME="numericValueFunction">numericValueFunction</A>\r
+ */\r
+ValueNode\r
+escapedSYSFUNFunction() throws StandardException :\r
+{\r
+    Vector      parameterList = new Vector();\r
+       Token tok;\r
+}\r
+{\r
+    tok = <IDENTIFIER> methodCallParameterList(parameterList)\r
+    {\r
+           String sysFunName = getEscapedSYSFUN(tok.image);\r
+           \r
+           TableName functionName = (TableName) nodeFactory.getNode(\r
+                                                               C_NodeTypes.TABLE_NAME,\r
+                                                               SchemaDescriptor.IBM_SYSTEM_FUN_SCHEMA_NAME,\r
+                                                               sysFunName,\r
+                                                               new Integer(0),\r
+                                                               new Integer(0),\r
+                                                               getContextManager());\r
+          \r
+               MethodCallNode methodNode = (MethodCallNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.STATIC_METHOD_CALL_NODE,\r
+                                                               functionName,\r
+                                                               null,\r
+                                                               getContextManager());\r
+\r
+               methodNode.addParms(parameterList);\r
+\r
+               /*\r
+               ** Assume this is being returned to the SQL domain.  If it turns\r
+               ** out that this is being returned to the Java domain, we will\r
+               ** get rid of this node.\r
+               */\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,\r
+                                                               methodNode,\r
+                                                               getContextManager());\r
+     }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="timestampArithmeticFuncion">timestampArithmeticFuncion</A>\r
+ */\r
+ValueNode\r
+timestampArithmeticFuncion() throws StandardException :\r
+{\r
+    ValueNode intervalType;\r
+    ValueNode tstamp1;\r
+    ValueNode tstamp2;\r
+    ValueNode count;\r
+}\r
+{\r
+    <TIMESTAMPADD> <LEFT_PAREN> intervalType = jdbcIntervalType() <COMMA>\r
+       count = additiveExpression(null,0,false) <COMMA>\r
+       tstamp1 = additiveExpression(null,0,false) <RIGHT_PAREN>\r
+    {\r
+        return (ValueNode) nodeFactory.getNode( C_NodeTypes.TIMESTAMP_ADD_FN_NODE,\r
+                                                tstamp1,\r
+                                                intervalType,\r
+                                                count,\r
+                                                ReuseFactory.getInteger( TernaryOperatorNode.TIMESTAMPADD),\r
+                                                null,\r
+                                                getContextManager());\r
+    }\r
+|\r
+    <TIMESTAMPDIFF> <LEFT_PAREN> intervalType = jdbcIntervalType() <COMMA>\r
+       tstamp1 = additiveExpression(null,0,false) <COMMA>\r
+       tstamp2 = additiveExpression(null,0,false) <RIGHT_PAREN>\r
+    {\r
+        return (ValueNode) nodeFactory.getNode( C_NodeTypes.TIMESTAMP_DIFF_FN_NODE,\r
+                                                tstamp2,\r
+                                                intervalType,\r
+                                                tstamp1,\r
+                                                ReuseFactory.getInteger( TernaryOperatorNode.TIMESTAMPDIFF),\r
+                                                null,\r
+                                                getContextManager());\r
+    }\r
+}       \r
+\r
+/*\r
+ * <A NAME="jdbcIntervalType">jdbcIntervalType</A>\r
+ */\r
+ValueNode jdbcIntervalType() throws StandardException :\r
+{\r
+}\r
+{\r
+    <SQL_TSI_FRAC_SECOND>\r
+    {\r
+        return getJdbcIntervalNode( DateTimeDataValue.FRAC_SECOND_INTERVAL);\r
+    }\r
+|\r
+    <SQL_TSI_SECOND>\r
+    {\r
+        return getJdbcIntervalNode( DateTimeDataValue.SECOND_INTERVAL);\r
+    }\r
+|\r
+    <SQL_TSI_MINUTE>\r
+    {\r
+        return getJdbcIntervalNode( DateTimeDataValue.MINUTE_INTERVAL);\r
+    }\r
+|\r
+    <SQL_TSI_HOUR>\r
+    {\r
+        return getJdbcIntervalNode( DateTimeDataValue.HOUR_INTERVAL);\r
+    }\r
+|\r
+    <SQL_TSI_DAY>\r
+    {\r
+        return getJdbcIntervalNode( DateTimeDataValue.DAY_INTERVAL);\r
+    }\r
+|\r
+    <SQL_TSI_WEEK>\r
+    {\r
+        return getJdbcIntervalNode( DateTimeDataValue.WEEK_INTERVAL);\r
+    }\r
+|\r
+    <SQL_TSI_MONTH>\r
+    {\r
+        return getJdbcIntervalNode( DateTimeDataValue.MONTH_INTERVAL);\r
+    }\r
+|\r
+    <SQL_TSI_QUARTER>\r
+    {\r
+        return getJdbcIntervalNode( DateTimeDataValue.QUARTER_INTERVAL);\r
+    }\r
+|\r
+    <SQL_TSI_YEAR>\r
+    {\r
+        return getJdbcIntervalNode( DateTimeDataValue.YEAR_INTERVAL);\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="numericValueFunction">numericValueFunction</A>\r
+ */\r
+ValueNode\r
+numericValueFunction() throws StandardException :\r
+{\r
+       ValueNode       value;\r
+       int                     field;\r
+}\r
+{\r
+    /*\r
+     * NOTE: If you add a new rule here, you must add the appropriate\r
+     *    LOOKAHEAD rule to miscBuiltins().\r
+     */\r
+\r
+    <ABS>  value = absFunction()\r
+    {\r
+               return value;\r
+    }\r
+|\r
+    <ABSVAL>  value = absFunction()\r
+    {\r
+               return value;\r
+    }\r
+|\r
+    <SQRT> <LEFT_PAREN> value = additiveExpression(null,0,false) <RIGHT_PAREN>\r
+    {\r
+        return (ValueNode)nodeFactory.getNode(\r
+                C_NodeTypes.SQRT_OPERATOR_NODE,\r
+                value,\r
+                getContextManager());\r
+    }\r
+|\r
+       /* MOD(int, int)\r
+       */\r
+       <MOD> value = modFunction()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       <IDENTITY_VAL_LOCAL> <LEFT_PAREN> <RIGHT_PAREN>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.IDENTITY_VAL_NODE,\r
+                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="coalesceFunction">coalesceFunction</A>\r
+ */\r
+ValueNode\r
+coalesceFunction(String coalesceOrValue) throws StandardException :\r
+{\r
+    ValueNodeList expressionList = (ValueNodeList) nodeFactory.getNode(\r
+       C_NodeTypes.VALUE_NODE_LIST,\r
+       getContextManager());\r
+}\r
+{\r
+    <LEFT_PAREN>\r
+        coalesceExpression(expressionList)\r
+               ( <COMMA> coalesceExpression(expressionList) )* \r
+    <RIGHT_PAREN>\r
+    {\r
+        return (ValueNode)nodeFactory.getNode(\r
+                C_NodeTypes.COALESCE_FUNCTION_NODE,\r
+                coalesceOrValue,\r
+                expressionList,\r
+                getContextManager());\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="coalesceExpression">coalesceExpression</A>\r
+ */\r
+void\r
+coalesceExpression(ValueNodeList expressionList) throws StandardException :\r
+{\r
+       ValueNode       expression;\r
+}\r
+{\r
+       expression = additiveExpression(null,0,false)\r
+       {\r
+               expressionList.addElement(expression);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="absFunction">absFunction</A>\r
+ */\r
+ValueNode\r
+absFunction() throws StandardException :\r
+{\r
+    ValueNode value;\r
+}\r
+{\r
+    <LEFT_PAREN> value = additiveExpression(null,0, false) <RIGHT_PAREN>\r
+    {\r
+        return (ValueNode)nodeFactory.getNode(\r
+                C_NodeTypes.ABSOLUTE_OPERATOR_NODE,\r
+                value,\r
+                getContextManager());\r
+    }\r
+}\r
+/*\r
+ * <A NAME="modFunction">modFunction</A>\r
+ */\r
+ValueNode\r
+modFunction() throws StandardException :\r
+{\r
+    ValueNode int1;\r
+       ValueNode int2;\r
+}\r
+{\r
+    <LEFT_PAREN> int1 = additiveExpression(null,0,false) <COMMA> \r
+            int2 = additiveExpression(null,0,false) <RIGHT_PAREN>\r
+    {\r
+        return (ValueNode)nodeFactory.getNode(\r
+                C_NodeTypes.MOD_OPERATOR_NODE,\r
+                int1, int2,\r
+                getContextManager());\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="datetimeField">datetimeField</A>\r
+ */\r
+int\r
+datetimeField() :\r
+{\r
+       int field;\r
+}\r
+{\r
+       field = nonSecondDatetimeField() \r
+       {\r
+               return field;\r
+       }\r
+|\r
+       <SECOND>\r
+       {\r
+               return DateTimeDataValue.SECOND_FIELD;\r
+       }\r
+}\r
+\r
+\r
+ValueNode\r
+characterValueFunction() throws StandardException :\r
+{\r
+       ValueNode       value = null;\r
+       ValueNode       str1;\r
+       ValueNode       str2;\r
+       Token           upperTok = null;\r
+       Token           lowerTok = null;\r
+       ValueNode       startPosition;\r
+    ValueNode  length = null;\r
+}\r
+{\r
+       <SUBSTR> <LEFT_PAREN> value = additiveExpression(null,0,false) <COMMA> startPosition = additiveExpression(null,0,false) [ <COMMA> length = additiveExpression(null,0,false) ] <RIGHT_PAREN>\r
+       {\r
+        return getSubstringNode( value, startPosition, length, Boolean.FALSE );\r
+       }\r
+|\r
+       ( upperTok = <UPPER> | lowerTok = <LOWER> ) <LEFT_PAREN> value = additiveExpression(null,0,false) <RIGHT_PAREN>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                       C_NodeTypes.SIMPLE_STRING_OPERATOR_NODE,\r
+                                       value,\r
+                                       (upperTok != null) ? "upper" : "lower",\r
+                                       getContextManager());\r
+       }\r
+|\r
+       ( upperTok = <UCASE> | lowerTok = <LCASE> ) <LEFT_PAREN> value = additiveExpression(null,0,false) <RIGHT_PAREN>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                       C_NodeTypes.SIMPLE_STRING_OPERATOR_NODE,\r
+                                       value,\r
+                                       (upperTok != null) ? "upper" : "lower",\r
+                                       getContextManager());\r
+       }\r
+|\r
+       value = trimFunction()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+    /* LOCATE( string1, string2[, start] )\r
+     * LOCATE is a SQLJ reserved word.\r
+     */\r
+    <LOCATE> <LEFT_PAREN> str1 = additiveExpression(null,0,false) <COMMA>\r
+            str2 = additiveExpression(null,0,false)\r
+            [ <COMMA> value = additiveExpression(null,0,false) ]\r
+            <RIGHT_PAREN>\r
+    {\r
+               // if start is missing, start is equal to 1\r
+        return (ValueNode) nodeFactory.getNode(\r
+                            C_NodeTypes.LOCATE_FUNCTION_NODE,\r
+                            str1,\r
+                            str2,\r
+                            (value == null) ? getNodeFactory().getNode(\r
+                                        C_NodeTypes.INT_CONSTANT_NODE, \r
+                                        ReuseFactory.getInteger(1), \r
+                                        getContextManager() )\r
+                                                                                       : value,\r
+                            ReuseFactory.getInteger(TernaryOperatorNode.LOCATE),\r
+                            null,\r
+                            getContextManager());\r
+    }\r
+}\r
+\r
+\r
+ValueNode\r
+trimFunction() throws StandardException :\r
+{\r
+       ValueNode       source;\r
+       Integer         trimType;\r
+       ValueNode       ansiTrimNode;\r
+}\r
+{\r
+       trimType = trimType() <LEFT_PAREN> source = additiveExpression(null,0,false) <RIGHT_PAREN>\r
+       {\r
+               return getTrimOperatorNode(trimType, null, source, null);\r
+       }\r
+|\r
+       <TRIM> ansiTrimNode = ansiTrim()\r
+       {\r
+               return ansiTrimNode;\r
+       }\r
+\r
+}\r
+\r
+\r
+ValueNode\r
+ansiTrim() throws StandardException  :\r
+{\r
+    Integer trimSpec = ReuseFactory.getInteger(StringDataValue.BOTH);\r
+    ValueNode trimChar = null;\r
+    ValueNode trimSource = null;\r
+}\r
+{\r
+    LOOKAHEAD ({ansiTrimSpecFollows()})\r
+    <LEFT_PAREN> trimSpec = ansiTrimSpec()\r
+    (\r
+         // LEADING FROM <source>\r
+         LOOKAHEAD(<FROM>)\r
+         <FROM> trimSource = additiveExpression(null,0,false) <RIGHT_PAREN>\r
+         {\r
+             return getTrimOperatorNode(trimSpec, trimChar, trimSource, null);\r
+         }\r
+     |\r
+         // LEADING <char> FROM <source>\r
+         trimChar = additiveExpression(null,0,false) <FROM> trimSource = additiveExpression(null,0,false) <RIGHT_PAREN>\r
+         {\r
+             return getTrimOperatorNode(trimSpec, trimChar, trimSource, null);\r
+         }\r
+    )\r
+|\r
+    LOOKAHEAD ({!ansiTrimSpecFollows()})\r
+    <LEFT_PAREN> trimChar = additiveExpression(null,0,false)\r
+    (\r
+        <FROM> trimSource = additiveExpression(null,0,false) <RIGHT_PAREN>\r
+        {\r
+            return getTrimOperatorNode(trimSpec, trimChar, trimSource, null);\r
+        }\r
+    |\r
+        <RIGHT_PAREN>\r
+        {\r
+            // expr was trim(e)-- we assigned e to trimChar but it is really the trimSource\r
+            return getTrimOperatorNode(trimSpec, null, trimChar, null);\r
+        }\r
+    )\r
+}\r
+\r
+Integer\r
+ansiTrimSpec() :\r
+{\r
+}\r
+{\r
+       <TRAILING>\r
+       {\r
+               return ReuseFactory.getInteger(StringDataValue.TRAILING);\r
+       }\r
+|\r
+       <LEADING>\r
+       {\r
+               return ReuseFactory.getInteger(StringDataValue.LEADING);\r
+       }\r
+|\r
+       <BOTH>\r
+       {\r
+               return ReuseFactory.getInteger(StringDataValue.BOTH);\r
+       }\r
+}\r
+\r
+\r
+Integer\r
+trimType() :\r
+{\r
+}\r
+{\r
+       <RTRIM>\r
+       {\r
+               return ReuseFactory.getInteger(StringDataValue.TRAILING);\r
+       }\r
+|\r
+       <LTRIM>\r
+       {\r
+               return ReuseFactory.getInteger(StringDataValue.LEADING);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="valueExpressionPrimary">valueExpressionPrimary</A>\r
+ * \r
+ * @param inSelectClause will be true if this method got called while parsing the select or values clause\r
+ * If in select or values clause, we do not want to allow boolean values.\r
+ */\r
+ValueNode\r
+valueExpressionPrimary(boolean inSelectClause) throws StandardException :\r
+{\r
+       ValueNode       value;\r
+       int                     tokKind;\r
+}\r
+{\r
+       /* This LOOKAHEAD is required to distinguish \r
+        * a escapedValueFunction() from other escaped \r
+        * clauses. The former always has an FN as its \r
+        * second token.\r
+        */\r
+       LOOKAHEAD( { escapedValueFunctionFollows() } )\r
+       <LEFT_BRACE> <FN> value = escapedValueFunction() <RIGHT_BRACE>\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       LOOKAHEAD({getToken(2).kind == SCHEMA || getToken(2).kind == SQLID}) \r
+       <CURRENT> (<SCHEMA> | <SQLID>)\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CURRENT_SCHEMA_NODE,\r
+                                               getContextManager());\r
+       }\r
+|\r
+       LOOKAHEAD({getToken(2).kind == ISOLATION}) \r
+       <CURRENT> <ISOLATION>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CURRENT_ISOLATION_NODE,\r
+                                               getContextManager());\r
+       }\r
+|\r
+       /* Omitted "case_expression" */\r
+       value = valueSpecification()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       // This LOOKAHEAD is required to distinguish a newInvocation() from\r
+       // an aggregateNode() and a columnReference(). It is necessary because\r
+       // NEW is not a reserved word.\r
+       LOOKAHEAD( { newInvocationFollows(1) } )\r
+       value = newInvocation()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       // This LOOKAHEAD is required to distinguish an aggregateNode from\r
+       // miscBuiltins(). Both can start with an identifier.\r
+       LOOKAHEAD( { aggregateFollows() } )\r
+       value = aggregateNode()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       // This LOOKAHEAD is required because both miscBuiltins() and\r
+       // columnReference can start with an identifier()\r
+       LOOKAHEAD( { miscBuiltinFollows() } )\r
+       value = miscBuiltins()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       value = columnReference()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       <LEFT_PAREN>\r
+       (\r
+               // This LOOKAHEAD is required because a subquery can have\r
+               // queryExpressions nested arbitrarily deep inside of parentheses,\r
+               // so both subquery() and valueExpression() can start with\r
+               // LEFT_PAREN. We disambiguate this case by only considering it\r
+               // to be a subquery if it starts with SELECT or VALUES, which\r
+               // are the first tokens to come after the LEFT_PAREN in a subquery.\r
+               LOOKAHEAD( {getToken(1).kind == SELECT || getToken(1).kind == VALUES} )\r
+               value = subquery(SubqueryNode.EXPRESSION_SUBQUERY, null)\r
+               |\r
+               /*\r
+               ** NOTE: The optional intervalQualfier() here makes sense only for\r
+               ** the MINUS operator.  We will have to add a semantic check that the\r
+               ** valueExpression() here is a MINUS operator if the intervalQualifier\r
+               ** is supplied.\r
+               */\r
+               // without the following check, select/values (c1>c2) will not be caught\r
+               LOOKAHEAD({inSelectClause})\r
+               value = additiveExpression(null,0, inSelectClause)\r
+               | //following will happen if we are not coming here for select/values clause\r
+               value = valueExpression(inSelectClause)\r
+       )\r
+       <RIGHT_PAREN>\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       value = castSpecification()\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="miscBuiltins">miscBuiltins</A>\r
+ */\r
+ValueNode\r
+miscBuiltins() throws StandardException :\r
+{\r
+       ValueNode value;\r
+}\r
+{\r
+    /*\r
+     * If you add rule to miscBuiltinsCore(), you must add the appropriate \r
+     *     LOOKAHEAD rule here.\r
+     * SQRT and LOCATE are non-reserved keywords, so we need to disambiguate\r
+     *     the grammar: "SQRT(" and "LOCATE(" introduce the SQRT and LOCATE\r
+     *     built-in functions, not a static method invocation alias.\r
+     */\r
+    LOOKAHEAD( {\r
+             ( (getToken(1).kind == GET_CURRENT_CONNECTION ||\r
+                getToken(1).kind == ABS ||\r
+                getToken(1).kind == ABSVAL ||\r
+                getToken(1).kind == SQRT ||\r
+                getToken(1).kind == MOD ||\r
+                getToken(1).kind == COALESCE ||\r
+                getToken(1).kind == VALUE ||\r
+                getToken(1).kind == IDENTITY_VAL_LOCAL ||\r
+                getToken(1).kind == SUBSTRING ||\r
+                getToken(1).kind == SUBSTR ||\r
+                getToken(1).kind == UPPER ||\r
+                getToken(1).kind == LOWER ||\r
+                getToken(1).kind == UCASE ||\r
+                getToken(1).kind == LCASE ||\r
+                getToken(1).kind == LTRIM ||\r
+                getToken(1).kind == RTRIM ||\r
+                getToken(1).kind == TRIM ||\r
+                getToken(1).kind == DATE ||\r
+                getToken(1).kind == TIME ||\r
+                getToken(1).kind == TIMESTAMP ||\r
+               getToken(1).kind == DOUBLE ||\r
+               getToken(1).kind == CHAR ||\r
+               getToken(1).kind == VARCHAR ||\r
+               getToken(1).kind == INTEGER ||\r
+               getToken(1).kind == INT || \r
+               getToken(1).kind == SMALLINT ||\r
+               getToken(1).kind == LONGINT ||\r
+                getToken(1).kind == YEAR ||\r
+                getToken(1).kind == MONTH ||\r
+                getToken(1).kind == DAY ||\r
+                getToken(1).kind == HOUR ||\r
+                getToken(1).kind == MINUTE ||\r
+                getToken(1).kind == SECOND ||\r
+                getToken(1).kind == LENGTH ||\r
+                getToken(1).kind == LOCATE ||\r
+                getToken(1).kind == XMLPARSE ||\r
+                getToken(1).kind == XMLSERIALIZE ||\r
+                getToken(1).kind == XMLEXISTS ||\r
+                getToken(1).kind == XMLQUERY ) &&\r
+              getToken(2).kind == LEFT_PAREN\r
+              )\r
+    } )\r
+       /* miscBuiltins() are composed of the core\r
+        * system, string and numeric functions,\r
+        * date functions\r
+        * and static method calls.\r
+        */\r
+       value = miscBuiltinsCore( false /* not JDBC escape */)\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       value = datetimeValueFunction()\r
+       {\r
+               return value;\r
+       }\r
+|      \r
+       /* This is where we build a node for static method aliases */\r
+       value = routineInvocation()\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+ValueNode\r
+miscBuiltinsCore( boolean isJDBCEscape) throws StandardException :\r
+{\r
+       ValueNode value;\r
+}\r
+{\r
+       /* miscBuiltinsCore() are the core\r
+        * system, string and numeric functions.\r
+        * NOTE: date functions not currently considered\r
+        * core for purposes of the grammar since\r
+        * they can only be escaped when they appear\r
+        * as functions (not special registers).\r
+     *\r
+     * NOTE: If you add a new rule here, you must add the appropriate\r
+     *    LOOKAHEAD rule to miscBuiltins().\r
+        */\r
+\r
+       <GET_CURRENT_CONNECTION> <LEFT_PAREN> <RIGHT_PAREN>\r
+       {\r
+               checkInternalFeature("GETCURRENTCONNECTION()");\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,\r
+                                                               nodeFactory.getNode(\r
+                                                                       C_NodeTypes.GET_CURRENT_CONNECTION_NODE,\r
+                                                                       getContextManager()),\r
+                                                               getContextManager());\r
+       }\r
+|\r
+       value = numericValueFunction() \r
+       {\r
+               return value;\r
+       }\r
+|\r
+       value = characterValueFunction()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       value = dataTypeScalarFunction()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       <COALESCE>  value = coalesceFunction("COALESCE")\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       <VALUE>  value = coalesceFunction("VALUE")\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       <LENGTH> <LEFT_PAREN> value = additiveExpression(null,0, false) <RIGHT_PAREN>\r
+       {\r
+               ContextManager  localCM = getContextManager();\r
+                if( isJDBCEscape)\r
+                        return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.CHAR_LENGTH_OPERATOR_NODE,\r
+                                                               getTrimOperatorNode(\r
+                                                                       ReuseFactory.getInteger(StringDataValue.TRAILING),\r
+                                                                       null,\r
+                                                                       value,\r
+                                                                       localCM),\r
+                                                               localCM);\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.DB2_LENGTH_OPERATOR_NODE,\r
+                                                        value,\r
+                                                        localCM);\r
+       }\r
+|\r
+       value = xmlFunction()\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="dataTypeScalarFunction">dataTypeScalarFunction</A>\r
+ */\r
+ValueNode\r
+       dataTypeScalarFunction() throws StandardException :\r
+{\r
+       DataTypeDescriptor dts;\r
+       ValueNode value;           //converted result\r
+       ValueNode operand;\r
+       int charType;\r
+       int length = -1;\r
+}\r
+{\r
+       //Note: When you add a new data type function, in addition to adding it \r
+       // here, you need to add it to miscBuiltins()\r
+       value = dateTimeScalarFunction()\r
+       {\r
+               return value;\r
+       }\r
+       |\r
+        dts = numericFunctionType() <LEFT_PAREN> operand = additiveExpression(null,0, false) <RIGHT_PAREN>\r
+         {\r
+                       value = (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.CAST_NODE,\r
+                                                                       operand,\r
+                                                                       dts,\r
+                                                                       getContextManager());\r
+                       ((CastNode) value).setForDataTypeFunction(true);\r
+                       ((CastNode) value).setForExternallyGeneratedCASTnode();\r
+\r
+                       return value;\r
+         }\r
+        | charType = charOrVarchar() <LEFT_PAREN> operand = additiveExpression(null,0, false) [ <COMMA> length = length() ] <RIGHT_PAREN>\r
+       {\r
+               // Always check db2 limits for this function. It's new\r
+               checkTypeLimits(charType,length);\r
+               value = (ValueNode) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.CAST_NODE,\r
+                                                                                               operand,\r
+                                                                                               new Integer(charType),\r
+                                                                                               new Integer(length),\r
+                                                                                               getContextManager());\r
+\r
+               ((CastNode) value).setForDataTypeFunction(true);\r
+               ((CastNode) value).setForExternallyGeneratedCASTnode();\r
+               return value;\r
+       }\r
+}\r
+        \r
+/*\r
+ * <A NAME="xmlFunction">xmlFunction</A>\r
+ *\r
+ * This method parses the built-in functions used with\r
+ * the XML datatype.\r
+ *\r
+ */\r
+ValueNode\r
+       xmlFunction() throws StandardException :\r
+{\r
+       ValueNode value;\r
+       checkVersion(DataDictionary.DD_VERSION_DERBY_10_1, "XML");\r
+\r
+       // We only allow XML operations if the classpath has all\r
+       // of the required external classes (namley, JAXP and Xalan).\r
+       org.apache.derby.iapi.types.XML.checkXMLRequirements();\r
+}\r
+{\r
+       <XMLPARSE> <LEFT_PAREN>\r
+               xmlDocOrContent() value = xmlParseValue() <RIGHT_PAREN>\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       <XMLSERIALIZE> <LEFT_PAREN> value = xmlSerializeValue() <RIGHT_PAREN>\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       <XMLEXISTS> <LEFT_PAREN> value = xmlQueryValue(true) <RIGHT_PAREN>\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       <XMLQUERY> <LEFT_PAREN> value = xmlQueryValue(false) <RIGHT_PAREN>\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="xmlParseValue">xmlParseValue</A>\r
+ *\r
+ * Syntax is as follows:\r
+ *\r
+ *     XMLPARSE( DOCUMENT <string-value-expression> PRESERVE WHITESPACE )\r
+ *\r
+ * The result of this operation will be an XML value, which can either\r
+ * be used transiently or else can be stored persistently in a table that\r
+ * has an XML column.  For example:\r
+ *\r
+ * ij> CREATE TABLE x_table (id INT, xdoc XML);\r
+ * 0 rows inserted/updated/deleted\r
+ * ij> INSERT INTO x_table VALUES (1, XMLPARSE(DOCUMENT '<simp> doc </simp>'\r
+ * PRESERVE WHITESPACE));\r
+ * 1 row inserted/updated/deleted\r
+ *\r
+ * We only allow XML documents (as opposed to XML content) to be\r
+ * parsed into XML values.  Note that we require the "PRESERVE WHITESPACE"\r
+ * keyword to be explicit; this is because the SQL/XML (2003) spec says that\r
+ * if no whitespace option is given, the default is "STRIP WHITESPACE", which\r
+ * we don't support (yet).\r
+ *\r
+ * By the time we get to this method, the "DOCUMENT" keyword has already\r
+ * been parsed.\r
+ *\r
+ */\r
+ValueNode\r
+       xmlParseValue() throws StandardException :\r
+{\r
+       ValueNode value;\r
+       boolean wsOption;\r
+}\r
+{\r
+       value = additiveExpression(null,0,false) wsOption = xmlPreserveWhitespace() {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                       C_NodeTypes.XML_PARSE_OPERATOR_NODE,\r
+                                       value,\r
+                                       ReuseFactory.getInteger(UnaryOperatorNode.XMLPARSE_OP),\r
+                                       new Object[] {(wsOption ? Boolean.TRUE : Boolean.FALSE)},\r
+                                       getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="xmlPreserveWhitespace">xmlPreserveWhitespace</A>\r
+ *\r
+ * For now, we only support the PRESERVE WHITESPACE option.\r
+ *\r
+ */\r
+boolean\r
+       xmlPreserveWhitespace() throws StandardException :\r
+{\r
+}\r
+{\r
+       LOOKAHEAD({ (getToken(1).kind != STRIP) &&\r
+               (getToken(1).kind != PRESERVE) })\r
+       {\r
+               throw StandardException.newException(\r
+                       SQLState.LANG_XML_KEYWORD_MISSING, "PRESERVE WHITESPACE",\r
+                       ReuseFactory.getInteger(getToken(1).beginLine),\r
+                       ReuseFactory.getInteger(getToken(1).beginColumn));\r
+       }\r
+|\r
+       <STRIP> <WHITESPACE>\r
+       { // don't preserve whitespace.\r
+               throw StandardException.newException(\r
+                       SQLState.LANG_UNSUPPORTED_XML_FEATURE, "STRIP WHITESPACE");\r
+       }\r
+|\r
+       <PRESERVE> <WHITESPACE>\r
+       { // must preserve whitespace.\r
+               return true;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="xmlSerializeValue">xmlSerializeValue</A>\r
+ *\r
+ * Syntax is as follows:\r
+ *\r
+ *   XMLSERIALIZE( <xml-value-expression> AS <string-data-type> )\r
+ *\r
+ * The result of this operation will be a string value with the type specified\r
+ * by the user.  For example:\r
+ *\r
+ * ij> SELECT id, XMLSERIALIZE(xdoc AS varchar(30)) FROM x_table;\r
+ * ID         |2\r
+ * ------------------------------------------\r
+ * 1          |<simp> doc </simp>\r
+ *\r
+ */\r
+ValueNode\r
+       xmlSerializeValue() throws StandardException :\r
+{\r
+       ValueNode value;\r
+       DataTypeDescriptor targetType;\r
+}\r
+{\r
+       value = additiveExpression(null,0,false)\r
+               targetType = xmlSerializeTargetType()\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                       C_NodeTypes.XML_SERIALIZE_OPERATOR_NODE,\r
+                                       value,\r
+                                       ReuseFactory.getInteger(UnaryOperatorNode.XMLSERIALIZE_OP),\r
+                                       new Object[] {targetType},\r
+                                       getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="xmlSerializeTargetType">xmlSerializeTargetType</A>\r
+ *\r
+ * Parse the target type of an XMLSERIALIZE operation.\r
+ *\r
+ */\r
+DataTypeDescriptor xmlSerializeTargetType() throws StandardException :\r
+{\r
+       DataTypeDescriptor targetType;\r
+}\r
+{\r
+       LOOKAHEAD({ (getToken(1).kind != AS) })\r
+       {\r
+               throw StandardException.newException(\r
+                       SQLState.LANG_XML_KEYWORD_MISSING, "AS",\r
+                       ReuseFactory.getInteger(getToken(1).beginLine),\r
+                       ReuseFactory.getInteger(getToken(1).beginColumn));\r
+       }\r
+|\r
+       <AS> targetType = dataTypeDDL()\r
+       {\r
+               return targetType;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="xmlQueryValue">xmlQueryValue</A>\r
+ *\r
+ * This method is used for parsing the XMLEXISTS and XMLQUERY operators\r
+ * (which operator depends on the received boolean parameter).\r
+ *\r
+ * For XMLEXISTS, the syntax is as follows:\r
+ *\r
+ *   XMLEXISTS( <xpath-expression> PASSING BY REF <xml-value-expression> )\r
+ *\r
+ * The result of this operation will be a boolean true/false/unknown value:\r
+ *   -- Unknown if either <xquery-expression> or <xml-value-expression> is null;\r
+ *   -- True if evaluation of the given query expression against the\r
+ *      given xml-value returns at least one node.\r
+ *   -- False otherwise.\r
+ *\r
+ * For example:\r
+ *\r
+ * ij> SELECT id FROM x_table WHERE XMLEXISTS('/simple' PASSING BY REF xdoc);\r
+ * ID\r
+ * -----------\r
+ * 1\r
+ *\r
+ * ====\r
+ *\r
+ * For XMLQUERY, the syntax is as follows:\r
+ *\r
+ *   XMLQUERY( <xquery-expression>\r
+ *      PASSING BY REF <xml-value-expression>\r
+ *      [ RETURNING SEQUENCE [ BY REF ] ]\r
+ *      EMPTY ON EMPTY\r
+ *   )\r
+ *\r
+ * The result of this operation will be an XMLDataValue.\r
+ *\r
+ * For example:\r
+ *\r
+ * ij> SELECT XMLSERIALIZE(\r
+ *       XMLQUERY('/simple' PASSING BY REF xdoc EMPTY ON EMPTY) AS CHAR(100));\r
+ * ID\r
+ * -----------\r
+ * <simp> doc </simp>\r
+ *\r
+ */\r
+ValueNode\r
+       xmlQueryValue(boolean existsOnly) throws StandardException :\r
+{\r
+       // The query expression (currently must be an expression\r
+       // supported by Xalan--i.e. XPath only).\r
+       ValueNode xqueryExpr = null;\r
+\r
+       // Context item for the query; not required by SQL/XML spec,\r
+       // but required by Derby for now.\r
+       ValueNode xmlValue = null;\r
+\r
+       // User-specified default passing mechanism.  Since Derby only\r
+       // supports one type of passing mechanism--BY REF--this value\r
+       // isn't currently used.\r
+       short defaultPassingMech = -1;\r
+}\r
+{\r
+       xqueryExpr = additiveExpression(null, 0, false)\r
+       <PASSING> defaultPassingMech = xmlPassingMechanism()\r
+               xmlValue = xqVarList()\r
+       (\r
+               LOOKAHEAD( { !existsOnly } )\r
+               [ xqReturningClause() [ xmlPassingMechanism() ] ]\r
+                       xqEmptyHandlingClause()\r
+               { /* Right now, we only support one kind of returning clause\r
+                  * (RETURNING SEQUENCE) and one kind of handling clause\r
+                  * (EMPTY ON EMPTY), so there's nothing more to do here--\r
+                  * we just needed to check the syntax.  In the future\r
+                  * we may need to add more logic here to support the\r
+                  * other options.  Note: if no returning clause is\r
+                  * specified, RETURNING SEQUENCE is implied (because\r
+                  * that's all we support).\r
+                  */\r
+               }\r
+       |\r
+               LOOKAHEAD( { existsOnly } )\r
+               { /* For XMLEXISTS there's nothing more to parse.  We need\r
+                  * this LOOKAHEAD in order to tell the parser that we're\r
+                  * done parsing and thus it shouldn't look for (nor allow)\r
+                  * any more tokens (neither xqReturningClause() nor\r
+                  * xqEmptyHandlingClause() is allowed for the XMLEXISTS\r
+                  * operator).\r
+                  */\r
+               }\r
+       )\r
+       {\r
+               ValueNode vNode = (ValueNode) nodeFactory.getNode(\r
+                       (existsOnly\r
+                               ? C_NodeTypes.XML_EXISTS_OPERATOR_NODE\r
+                               : C_NodeTypes.XML_QUERY_OPERATOR_NODE),\r
+                       xqueryExpr,\r
+                       xmlValue,\r
+                       (existsOnly\r
+                               ? ReuseFactory.getInteger(BinaryOperatorNode.XMLEXISTS_OP)\r
+                               : ReuseFactory.getInteger(BinaryOperatorNode.XMLQUERY_OP)),\r
+                       getContextManager());\r
+\r
+               return vNode;\r
+       }\r
+}\r
+\r
+/**\r
+ * <A NAME="xqVarList">xqVarList</A>\r
+ *\r
+ * Parse a list of XML query variables, which can include at most one\r
+ * XML value to be used as the "context item" for the query.  If\r
+ * such a context item was found, return that item; for all other\r
+ * variable declarations we currently throw a "not supported" error\r
+ * because Xalan doesn't allowing binding of variables.\r
+ */\r
+\r
+ValueNode xqVarList()\r
+       throws StandardException :\r
+{\r
+       // Placeholder for the XML context item as we parse the\r
+       // argument list.\r
+       ValueNode [] xmlValue = new ValueNode [] { (ValueNode)null };\r
+}\r
+{\r
+       xqVariable(xmlValue)\r
+               ( <COMMA> xqVariable(xmlValue) )*\r
+       {\r
+               return xmlValue[0];\r
+       }\r
+}\r
+\r
+/**\r
+ * <A NAME="xqVariable">xqVariable</A>\r
+ *\r
+ * Parse an XML query variable.  If the argument is an XML value\r
+ * to be used as the "context item" for a query, then store the\r
+ * value in the first slot of the received ValueNode array;\r
+ * otherwise, throw a "not supported" errror (for now).\r
+ */\r
+\r
+void xqVariable(ValueNode [] xmlVal) throws StandardException :\r
+{\r
+       ValueNode curVal;\r
+       String varName = null;\r
+       short passingMech = -1;\r
+}\r
+{\r
+       curVal = additiveExpression(null,0, false)\r
+       [\r
+               LOOKAHEAD( { getToken(1).kind == AS } )\r
+               <AS> varName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+               {\r
+                       /* From XQuery 1.0: "The <identifier> I contained in XQV\r
+                        * shall be an XML 1.1 NCName."  From XML 1.1:\r
+                        *\r
+                        *   [4] NCName ::= (Letter | '_') (NCNameChar)*\r
+                        *   [5] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |\r
+                        *                    CombiningChar | Extender\r
+                        *\r
+                        * Since Derby's definition of an "identifier" is a subset\r
+                        * of NCName, we just use Derby's definition.  This means\r
+                        * that some valid NCNames won't be recognized by Derby--\r
+                        * but since the ones we _do_ recognize are all still valid\r
+                        * NCNames, we're not breaking any rules.\r
+                        */\r
+\r
+                       /* All of that said, since we use Xalan as the underlying\r
+                        * query engine and Xalan doesn't support variable binding,\r
+                        * there's no point in letting the user specify variables\r
+                        * right now.  So we disallow it.  In the future we'll have\r
+                        * to add logic here to store the variables and pass them\r
+                        * to the correct operator for binding/execution.\r
+                        */\r
+                       throw StandardException.newException(\r
+                               SQLState.LANG_UNSUPPORTED_XML_FEATURE, "PASSING ... AS");\r
+               }\r
+       ] \r
+       (\r
+               [ passingMech = xmlPassingMechanism() ]\r
+               {\r
+                       if (varName == null)\r
+                       {\r
+                               /* We get here if we just parsed an XML context item.\r
+                                * That said, if we already have one (xmlVal[0] is not\r
+                                * null) then we can't allow second one, per SQL/XML[2006]\r
+                                * (6.17: Syntax Rules:5.b.i): "XMQ shall contain exactly\r
+                                * one <XML query context item> XQCI."\r
+                                */\r
+                               if (xmlVal[0] != null)\r
+                               {\r
+                                       throw StandardException.newException(\r
+                                               SQLState.LANG_MULTIPLE_XML_CONTEXT_ITEMS);\r
+                               }\r
+\r
+                               xmlVal[0] = curVal;\r
+\r
+                               /* Note: It's possible that a passing mechanism was\r
+                                * specified for the context item; if so its value is\r
+                                * stored in passingMech.  However, we don't actually\r
+                                * store that passing mechanism anywhere because we\r
+                                * (currently) only support BY REF, so we know what\r
+                                * it has to be.  If we add support for other passing\r
+                                * mechanisms (namely, BY VALUE) in the future, we'll\r
+                                * have to store the passing mechanism provided by\r
+                                * the user and process it at compilation/execution\r
+                                * time.\r
+                                */\r
+                       }\r
+               }\r
+       )\r
+       { // By this time we've parsed everything we need so there's nothing\r
+         // more to do.  The reason we're left with this empty block is\r
+         // is that most of the syntax is optional.  We end up here if\r
+         // none of the optional syntax was given, in which case all we\r
+         // need to do is store curVal--and we already did that.\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="xmlPassingMechanism">xmlPassingMechanism</A>\r
+ *\r
+ * For now, we only support the BY REF option because\r
+ * that gives us better performance (allows us to avoid\r
+ * performing potentially deep copies of XML nodes).  This\r
+ * means that if the same XML value is passed BY REF into\r
+ * two different XML arguments for a single operator, then\r
+ * every node in the first XML argument must have an\r
+ * identical node in the second XML argument, and the\r
+ * ids for both nodes must be the same.  That said,\r
+ * since we don't support variable binding yet, this\r
+ * becomes a non-issue because we can't pass XML values.\r
+ * In the future, though, we may choose to support the\r
+ * passing/binding of variables (the only reason we\r
+ * don't now is because Xalan doesn't support it) and\r
+ * if we do, BY REF should provide better performance\r
+ * due to lack of deep copying.\r
+ */\r
+short\r
+       xmlPassingMechanism() throws StandardException :\r
+{\r
+}\r
+{\r
+       LOOKAHEAD( { getToken(2).kind == REF })\r
+       <BY> <REF>\r
+       { // pass the XML value by reference\r
+               return org.apache.derby.iapi.types.XML.XQ_PASS_BY_REF;\r
+       }\r
+|\r
+       <BY> <VALUE>\r
+       { // pass a 'copy' of the XML value.\r
+               throw StandardException.newException(\r
+                       SQLState.LANG_UNSUPPORTED_XML_FEATURE, "BY VALUE");\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="xqReturningClause">xqReturningClause</A>\r
+ *\r
+ * For now we only support "RETURNING SEQUENCE".  The reason\r
+ * is that this applies to the XMLQUERY operator and the\r
+ * results of evaluating a query expression in Xalan against\r
+ * an XML value can be an arbritary sequence of items--including\r
+ * atomic values.  For simplicity we just return the values\r
+ * as they are, without doing any further work.  SQL/XML[2006]\r
+ * says that if we supported RETURNING CONTENT then we'd have\r
+ * to construct an XQuery document from the results--but we don't\r
+ * do that extra work for now, so we just say that we return\r
+ * SEQUENCE.\r
+ *\r
+ * NOTE: This means that we may not be able to store the results\r
+ * of an XMLQUERY operation into a Derby XML column.  Right now\r
+ * an XML column can only hold valid DOCUMENT nodes, which we\r
+ * we define as an XML value whose serialized form can be parsed\r
+ * by a JAXP DocumentBuilder (because that's what Derby's XMLPARSE\r
+ * operator uses and the result is always a Document node).\r
+ * Internally this means that we can only store a sequence if it\r
+ * contains exactly one org.w3c.dom.Node that is an instance of\r
+ * org.w3c.dom.Document.  If the result of an XMLQUERY operation\r
+ * does not fit this criteria then it will *not* be storable into\r
+ * Derby XML columns.\r
+ */\r
+short\r
+       xqReturningClause() throws StandardException :\r
+{\r
+}\r
+{\r
+       LOOKAHEAD( { getToken(2).kind == SEQUENCE } )\r
+       <RETURNING> <SEQUENCE>\r
+       { // XMLQUERY should return result as a sequence.\r
+         // NOTE: since Derby XML columns only allow DOCUMENT(UNTYPED),\r
+         // the result of an XMLQUERY operator that returns SEQUENCE\r
+         // might not be storable into an XML column.\r
+               return org.apache.derby.iapi.types.XML.XQ_RETURN_SEQUENCE;\r
+       }\r
+|\r
+       <RETURNING> <CONTENT>\r
+       { // XMLQUERY should return 'content'.\r
+               throw StandardException.newException(\r
+                       SQLState.LANG_UNSUPPORTED_XML_FEATURE, "RETURNING CONTENT");\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="xqEmptyHandlingClause">xqEmptyHandlingClause</A>\r
+ *\r
+ * Defines what the behavior should be when an XMLQUERY operator\r
+ * results in an empty sequence.  For now we just return the\r
+ * empty sequence.\r
+ */\r
+short\r
+       xqEmptyHandlingClause() throws StandardException :\r
+{\r
+}\r
+{\r
+       LOOKAHEAD( { getToken(1).kind == EMPTY })\r
+       <EMPTY> <ON> <EMPTY>\r
+       { // XMLQUERY should return an empty sequence when result of\r
+         // the query is an empty sequence (i.e. when there are no\r
+         // results).\r
+               return org.apache.derby.iapi.types.XML.XQ_EMPTY_ON_EMPTY;\r
+       }\r
+|\r
+       <NULL> <ON> <EMPTY>\r
+       { // XMLQUERY should return a null XML value when result of\r
+         // the query is an empty sequence (i.e. when there are no\r
+         // results).\r
+               throw StandardException.newException(\r
+                       SQLState.LANG_UNSUPPORTED_XML_FEATURE, "NULL ON EMPTY");\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="numericFunctionType">numericFunctionType</A>\r
+ */\r
+DataTypeDescriptor\r
+numericFunctionType() throws StandardException :\r
+\r
+{\r
+       DataTypeDescriptor dts;\r
+}\r
+{\r
+       dts = doubleType()\r
+       {\r
+               return dts;\r
+       }\r
+       |\r
+       dts = exactIntegerType()\r
+       {\r
+               return dts;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="dateTimeScalarFunction">dateTimeScalarFunction</A>\r
+ */\r
+ValueNode\r
+dateTimeScalarFunction() throws StandardException :\r
+{\r
+       ValueNode       value;\r
+       ValueNode       timestampNode;\r
+        int             field;\r
+}\r
+{\r
+    /*\r
+     * NOTE: If you add a new rule here, you must add the appropriate\r
+     *    LOOKAHEAD rule to miscBuiltins().\r
+     */\r
+        <TIME> <LEFT_PAREN> value = additiveExpression(null,0, false) <RIGHT_PAREN>\r
+       {\r
+               ValueNode castValue = (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.CAST_NODE,\r
+                                                        value,\r
+                                                        DataTypeDescriptor.getBuiltInDataTypeDescriptor( Types.TIME),\r
+                                                        getContextManager());\r
+               ((CastNode) castValue).setForExternallyGeneratedCASTnode();\r
+               return castValue;\r
+        }\r
+|\r
+        <DATE> <LEFT_PAREN> value = additiveExpression(null,0, false) <RIGHT_PAREN>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.UNARY_DATE_TIMESTAMP_OPERATOR_NODE,\r
+                                                        value,\r
+                                                        DataTypeDescriptor.getBuiltInDataTypeDescriptor( Types.DATE),\r
+                                                        getContextManager());\r
+        }\r
+|\r
+        <TIMESTAMP> <LEFT_PAREN> value = additiveExpression(null,0, false) timestampNode = timestampFunctionCompletion( value)\r
+       {\r
+                return timestampNode;\r
+        }\r
+|\r
+        field = datetimeField() <LEFT_PAREN> value = additiveExpression(null,0, false) <RIGHT_PAREN>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.EXTRACT_OPERATOR_NODE,\r
+                                                               ReuseFactory.getInteger(field),\r
+                                                               value,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="timestampFunctionCompletion">timestampFunctionCompletion</A>\r
+ */\r
+ValueNode\r
+timestampFunctionCompletion( ValueNode firstArg) throws StandardException :\r
+{\r
+        ValueNode timeValue;\r
+}\r
+{\r
+        <RIGHT_PAREN>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.UNARY_DATE_TIMESTAMP_OPERATOR_NODE,\r
+                                                        firstArg,\r
+                                                        DataTypeDescriptor.getBuiltInDataTypeDescriptor( Types.TIMESTAMP),\r
+                                                        getContextManager());\r
+        }\r
+|\r
+        <COMMA> timeValue = additiveExpression(null,0, false) <RIGHT_PAREN>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.TIMESTAMP_OPERATOR_NODE,\r
+                                                        firstArg,\r
+                                                        timeValue,\r
+                                                        getContextManager());\r
+        }\r
+}\r
+\r
+/*\r
+ * <A NAME="booleanLiteral">booleanLiteral</A>\r
+ */\r
+Token\r
+booleanLiteral() :\r
+{\r
+       Token tok;\r
+}\r
+{\r
+       tok = <TRUE>\r
+       {\r
+               return tok;\r
+       }\r
+|\r
+       tok = <FALSE>\r
+       {\r
+               return tok;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="generalValueSpecification">generalValueSpecification</A>\r
+ */\r
+ValueNode\r
+generalValueSpecification() throws StandardException :\r
+{\r
+               ValueNode       parm;\r
+}\r
+{\r
+       parm = dynamicParameterSpecification()\r
+       {\r
+               return parm;\r
+       }\r
+|\r
+       parm = userNode()\r
+       {\r
+               return parm;\r
+       }\r
+}\r
+\r
+ValueNode\r
+userNode() throws StandardException :\r
+{\r
+}\r
+{\r
+       <USER>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.USER_NODE,\r
+                                                               getContextManager());\r
+       }\r
+|\r
+       <CURRENT_USER>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CURRENT_USER_NODE,\r
+                                               getContextManager());\r
+       }\r
+|\r
+       <SESSION_USER>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.SESSION_USER_NODE,\r
+                                               getContextManager());\r
+       }\r
+}\r
+\r
+\r
+\r
+\r
+/*\r
+ * <A NAME="newInvocation">newInvocation</A>\r
+ */\r
+JavaToSQLValueNode\r
+newInvocation() throws StandardException :\r
+{\r
+       QueryTreeNode   newNode;\r
+       Vector  parameterList = new Vector();\r
+       String  javaClassName;\r
+}\r
+{\r
+       <NEW> javaClassName = javaClassName() methodCallParameterList(parameterList)\r
+       {                       \r
+               if (!javaClassName.startsWith("org.apache.derby.diag.") && !javaClassName.startsWith("org.apache.derby.catalog.") && !javaClassName.startsWith("com.ibm.db2j."))\r
+               {\r
+                       checkInternalFeature(javaClassName);\r
+               }\r
+               newNode =  nodeFactory.getNode(C_NodeTypes.NEW_INVOCATION_NODE,\r
+                                                                          javaClassName,\r
+                                                                          parameterList, \r
+                                                                          lastTokenDelimitedIdentifier,\r
+                                                                          getContextManager());\r
+\r
+               /*\r
+               ** Assume this is being returned to the SQL domain.  If it turns\r
+               ** out that this is being returned to the Java domain, we will\r
+               ** get rid of this node.\r
+               */\r
+               return (JavaToSQLValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,\r
+                                                               newNode,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="vtiTableConstruct">vtiTableConstruct</A>\r
+ *\r
+ * Parse a TABLE() constructor that corresponds to an internal\r
+ * VTI invocation.  For example:\r
+ *\r
+ *    TABLE ( <qualifiedName> (arg1, arg2, ...) )\r
+ *\r
+ * where <qualifiedName> is a table name that Derby will map internally\r
+ * to a VTI (ex. "SYSCS_DIAG.SPACE_TABLE").  The list of arguments\r
+ * will then be passed to the VTI when it is invoked (DERBY-2152).\r
+ *\r
+ * An example query where this might occur is as follows:\r
+ *\r
+ *   SELECT * FROM TABLE(SYSCS_DIAG.SPACE_TABLE('APP', 'T1')) x\r
+ *\r
+ * in which case SYSCS_DIAG.SPACE_TABLE will be mapped (internally)\r
+ * to the "org.apache.derby.diag.SpaceTable" diagnostic VTI.  Thus\r
+ * the equivalent call prior to DERBY-2152 would have been:\r
+ *\r
+ *   SELECT * FROM NEW org.apache.derby.diag.SpaceTable('APP', 'T1')) x\r
+ *\r
+ * Note that this latter syntax is still supported.\r
+ */\r
+JavaToSQLValueNode\r
+vtiTableConstruct() throws StandardException :\r
+{\r
+    QueryTreeNode newNode = null;\r
+    Vector parameterList = new Vector();\r
+    TableName vtiTableName = null;\r
+}\r
+{\r
+    <TABLE> <LEFT_PAREN>\r
+        vtiTableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+        methodCallParameterList(parameterList)\r
+    <RIGHT_PAREN>\r
+    {\r
+               /* The fact that we pass a NULL table descriptor to the\r
+                * following call is an indication that we are mapping to a\r
+                * VTI table function (i.e. one that accepts arguments).\r
+                * Since we have the table name we do not need to pass in a\r
+                * TableDescriptor--we'll just create one from the table\r
+                * name. See NewInvocationNode for more.\r
+                */\r
+        newNode = nodeFactory.getNode(C_NodeTypes.NEW_INVOCATION_NODE,\r
+                    vtiTableName,  // TableName\r
+                    null,          // TableDescriptor\r
+                    parameterList, \r
+                    lastTokenDelimitedIdentifier,\r
+                    getContextManager());\r
+\r
+        /*\r
+        ** Assume this is being returned to the SQL domain.  If it turns\r
+        ** out that this is being returned to the Java domain, we will\r
+        ** get rid of this node.\r
+        */\r
+        return (JavaToSQLValueNode) nodeFactory.getNode(\r
+                    C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,\r
+                    newNode,\r
+                    getContextManager());\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="staticMethodInvocation">staticMethodInvocation</A>\r
+ */\r
+ValueNode\r
+staticMethodInvocation(String javaClassName) throws StandardException :\r
+{\r
+       Vector  parameterList = new Vector();\r
+       MethodCallNode  methodNode;\r
+}\r
+{\r
+       methodNode = staticMethodName(javaClassName) methodCallParameterList(parameterList)\r
+       {\r
+               methodNode.addParms(parameterList);\r
+\r
+               /*\r
+               ** Assume this is being returned to the SQL domain.  If it turns\r
+               ** out that this is being returned to the Java domain, we will\r
+               ** get rid of this node.\r
+               */\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,\r
+                                                               methodNode,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/**\r
+ * <A NAME="methodCallParameterList">methodCallParameterList</A>\r
+*/\r
+\r
+void methodCallParameterList(Vector parameterList) throws StandardException :\r
+{\r
+}\r
+{\r
+       <LEFT_PAREN>\r
+               [ methodParameter(parameterList)\r
+                       ( <COMMA> methodParameter(parameterList) )* ]\r
+       <RIGHT_PAREN>\r
+}\r
+\r
+/*\r
+ * <A NAME="routineInvocation">routineInvocation</A>\r
+ */\r
+ValueNode\r
+routineInvocation() throws StandardException :\r
+{\r
+       Vector  parameterList = new Vector();\r
+       TableName       routineName;\r
+       MethodCallNode  methodNode;\r
+}\r
+{\r
+       routineName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+               methodCallParameterList(parameterList)\r
+       {\r
+\r
+               methodNode = (MethodCallNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.STATIC_METHOD_CALL_NODE,\r
+                                                               routineName,\r
+                                                               null,\r
+                                                               getContextManager());\r
+\r
+               methodNode.addParms(parameterList);\r
+\r
+               /*\r
+               ** Assume this is being returned to the SQL domain.  If it turns\r
+               ** out that this is being returned to the Java domain, we will\r
+               ** get rid of this node.\r
+               */\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,\r
+                                                               methodNode,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="javaClass">javaClass</A>\r
+ */\r
+\r
+String\r
+javaClass() throws StandardException :\r
+{\r
+       String javaClassName;\r
+}\r
+{\r
+       javaClassName = javaClassName() \r
+       {\r
+               return javaClassName;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="columnMethodInvocation">columnMethodInvocation</A>\r
+ */\r
+ValueNode\r
+columnMethodInvocation() throws StandardException :\r
+{\r
+       ValueNode       columnReference;\r
+       ValueNode       methodNode;\r
+}\r
+{\r
+       columnReference = columnNameForInvocation()\r
+       methodNode = nonStaticMethodInvocation(columnReference)\r
+       {\r
+               return methodNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="columnNameForInvocation">columnNameForInvocation</A>\r
+ */\r
+ValueNode\r
+columnNameForInvocation() throws StandardException :\r
+{\r
+       String firstName;\r
+       String secondName = null;\r
+       String thirdName = null;\r
+       String          columnName = null;\r
+       String          tableName = null;\r
+       String          schemaName = null;\r
+       TableName       tabName = null;\r
+       ValueNode       retval;\r
+}\r
+{\r
+       firstName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       [\r
+               // This LOOKAHEAD is required because we have the following cases:\r
+               // schema.table.column.method()\r
+               // table.column.method()\r
+               // column.method()\r
+               //\r
+               // We have to look ahead to ensure that there is at least one more\r
+               // PERIOD after the current one, so that we don't consider the\r
+               // method name to be a table or column name\r
+               LOOKAHEAD( {\r
+                                       getToken(1).kind == PERIOD &&\r
+                                       getToken(3).kind == PERIOD\r
+                               } )\r
+               <PERIOD> secondName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+               [\r
+                       // See above: we don't want to mistake the method name for a\r
+                       // column name.\r
+                       LOOKAHEAD( {\r
+                                               getToken(1).kind == PERIOD &&\r
+                                               getToken(3).kind == PERIOD\r
+                                       } )\r
+                       <PERIOD> thirdName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+               ]\r
+       ]\r
+       {\r
+               // Figure out what each identifier stands for\r
+               if (thirdName == null)\r
+               {\r
+                       if (secondName == null)\r
+                       {\r
+                               // There's only one identifier, so it must be a column name\r
+                               columnName = firstName;\r
+                       }\r
+                       else\r
+                       {\r
+                               // There are two identifiers, so they are table and column names\r
+                               tableName = firstName;\r
+                               columnName = secondName;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       // There are three identifiers,\r
+                       // so they are schema, table, and column names\r
+                       schemaName = firstName;\r
+                       tableName = secondName;\r
+                       columnName = thirdName;\r
+               }\r
+\r
+               if (tableName != null)\r
+               {\r
+                       // There is a table name, so get a TableName node\r
+                       tabName =\r
+                               (TableName) nodeFactory.getNode(\r
+                                                       C_NodeTypes.TABLE_NAME,\r
+                                                       schemaName,\r
+                                                       tableName,\r
+                                                       new Integer(nextToLastIdentifierToken.beginOffset),\r
+                                                       new Integer(nextToLastIdentifierToken.endOffset),\r
+                                                       getContextManager());\r
+               }\r
+\r
+               // Get the column reference\r
+               retval = (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.COLUMN_REFERENCE,\r
+                                                                       columnName,\r
+                                                                       tabName,\r
+                                                                       new Integer(lastIdentifierToken.beginOffset),\r
+                                                                       new Integer(lastIdentifierToken.endOffset),\r
+                                                                       getContextManager());\r
+\r
+               return retval;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="columnReference">columnReference</A>\r
+ */\r
+ColumnReference\r
+columnReference() throws StandardException :\r
+{\r
+       String          firstName;\r
+       String          secondName = null;\r
+       String          thirdName = null;\r
+       String          columnName = null;\r
+       String          tableName = null;\r
+       String          schemaName = null;\r
+       TableName       tabName = null;\r
+}\r
+{\r
+       firstName = identifier(Limits.MAX_IDENTIFIER_LENGTH, false)\r
+       [\r
+               // This LOOKAHEAD is needed to ensure that, if the identifier\r
+               // after the PERIOD is a method name , we\r
+               // don't treat it as part of the column reference.\r
+               LOOKAHEAD( {\r
+                                       getToken(1).kind == PERIOD &&\r
+                                       getToken(3).kind != LEFT_PAREN\r
+                               } )\r
+               <PERIOD> secondName = identifier(Limits.MAX_IDENTIFIER_LENGTH, false)\r
+               [\r
+                       // This LOOKAHEAD is needed to ensure that, if the identifier\r
+                       // after the PERIOD is a method name , we\r
+                       // don't treat it as part of the column reference.\r
+                       LOOKAHEAD( {\r
+                                               getToken(1).kind == PERIOD &&\r
+                                               getToken(3).kind != LEFT_PAREN\r
+                                       } )\r
+                       <PERIOD> thirdName = identifier(Limits.MAX_IDENTIFIER_LENGTH, false)\r
+               ]\r
+       ]\r
+       {\r
+               // Figure out what each name stands for\r
+               if (thirdName == null)\r
+               {\r
+                       if (secondName == null)\r
+                       {\r
+                               // Only one name, must be column name\r
+                               columnName = firstName;\r
+                       }\r
+                       else\r
+                       {\r
+                               // Two names: table.column\r
+                               tableName = firstName;\r
+                               columnName = secondName;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       // Three names: schema.table.column\r
+                       schemaName = firstName;\r
+                       tableName = secondName;\r
+                       columnName = thirdName;\r
+               }\r
+\r
+               checkIdentifierLengthLimit(columnName, Limits.MAX_IDENTIFIER_LENGTH);\r
+               if (schemaName != null)\r
+                       checkIdentifierLengthLimit(schemaName, Limits.MAX_IDENTIFIER_LENGTH);\r
+               if (tableName != null)\r
+                       checkIdentifierLengthLimit(tableName, Limits.MAX_IDENTIFIER_LENGTH);\r
+\r
+               if (tableName != null)\r
+               {\r
+                       tabName = (TableName) nodeFactory.getNode(\r
+                                                       C_NodeTypes.TABLE_NAME,\r
+                                                       schemaName,\r
+                                                       tableName,\r
+                                                       new Integer(nextToLastIdentifierToken.beginOffset),\r
+                                                       new Integer(nextToLastIdentifierToken.endOffset),\r
+                                                       getContextManager());\r
+               }\r
+\r
+               return (ColumnReference) nodeFactory.getNode(\r
+                                                               C_NodeTypes.COLUMN_REFERENCE,\r
+                                                               columnName,\r
+                                                               tabName,\r
+                                                               new Integer(lastIdentifierToken.beginOffset),\r
+                                                               new Integer(lastIdentifierToken.endOffset),\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+void\r
+columnReference() throws StandardException :\r
+{}\r
+{\r
+       /*\r
+       **\r
+       ** I re-wrote the above rule because it caused a grammar ambiguitity.\r
+       ** The problem is that we are parsing a dot-separated list of identifiers,\r
+       ** and the grammar doesn't know what the identifiers stand for, but the\r
+       ** syntax assumed that it did.  For example, in schema.table.column,\r
+       ** the grammar doesn't know when it parses the first identifier whether\r
+       ** it will be a catalog name, schema name, table name, or column name.\r
+       **\r
+       ** I think this problem could be solved by increasing the lookahead.\r
+       ** I will try that solution next.  I like that solution better because,\r
+       ** if it works, it will be easier for the grammar to figure out what\r
+       ** each identifier stands for.\r
+       **\r
+\r
+       [ <MODULE> <PERIOD> <IDENTIFIER> |\r
+         [ [ [ <IDENTIFIER> <PERIOD> ] <IDENTIFIER> <PERIOD> ] <IDENTIFIER> <PERIOD> ]\r
+       ]\r
+       <IDENTIFIER>\r
+}\r
+*/\r
+\r
+OrderByList\r
+orderByClause() throws StandardException :\r
+{\r
+       OrderByList orderCols;\r
+}\r
+{\r
+       <ORDER> <BY> orderCols = sortSpecificationList()\r
+       {\r
+               return orderCols;\r
+       }\r
+}\r
+\r
+int\r
+atIsolationLevel() throws StandardException :\r
+{\r
+       int isolationLevel;\r
+}\r
+{\r
+       <WITH> isolationLevel = isolationLevelDB2Abbrev()\r
+       {\r
+               return isolationLevel;\r
+       }\r
+\r
+}\r
+\r
+OrderByList\r
+sortSpecificationList() throws StandardException :\r
+{ \r
+       OrderByList orderCols = (OrderByList) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.ORDER_BY_LIST,\r
+                                                                                       getContextManager()); \r
+}\r
+{\r
+       sortSpecification(orderCols) ( <COMMA> sortSpecification(orderCols) ) *\r
+       {\r
+               return orderCols;\r
+       }\r
+}\r
+\r
+void\r
+sortSpecification(OrderByList orderCols) throws StandardException :\r
+{      OrderByColumn orderCol; }\r
+{\r
+       orderCol = sortKey() /* [ collateClause() ] */ [ orderingSpecification(orderCol) ]\r
+       {\r
+               orderCols.addOrderByColumn(orderCol);\r
+       } \r
+}\r
+\r
+OrderByColumn\r
+sortKey() throws StandardException :\r
+{\r
+       ValueNode columnExpression;\r
+} \r
+{\r
+       columnExpression = additiveExpression(null,0,true)\r
+       {\r
+               return (OrderByColumn) nodeFactory.getNode(\r
+                                                               C_NodeTypes.ORDER_BY_COLUMN,\r
+                                                               columnExpression,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+\r
+\r
+void\r
+orderingSpecification(OrderByColumn orderCol) :\r
+{}\r
+{\r
+       <ASC> \r
+|\r
+       <DESC>\r
+       {\r
+               orderCol.setDescending();\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="forUpdateClause">forUpdateClause</A>\r
+ */\r
+int\r
+forUpdateClause(Vector columnList) throws StandardException :\r
+{\r
+       int     retval;\r
+}\r
+{\r
+       <UPDATE> [ <OF> forUpdateColumnList(columnList) ]\r
+       {\r
+               return CursorNode.UPDATE;\r
+       }\r
+|\r
+       <READ> <ONLY>\r
+       {\r
+               return CursorNode.READ_ONLY;\r
+       }\r
+|\r
+       <FETCH> <ONLY>\r
+       {\r
+               return CursorNode.READ_ONLY;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="forUpdateColumnList">forUpdateColumnList</A>\r
+ */\r
+void\r
+forUpdateColumnList(Vector columnList) throws StandardException :\r
+{\r
+}\r
+{\r
+       forUpdateColumn(columnList) ( <COMMA> forUpdateColumn(columnList) ) *\r
+}\r
+\r
+/*\r
+ * <A NAME="forUpdateColumn">forUpdateColumn</A>\r
+ */\r
+void\r
+forUpdateColumn(Vector columnList) throws StandardException :\r
+{\r
+       String           columnName;\r
+}\r
+{\r
+       /* identifier() used to be columnName() */\r
+       columnName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               columnList.addElement(columnName);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="setClauseList">setClauseList</A>\r
+ */\r
+ResultColumnList\r
+setClauseList() throws StandardException :\r
+{\r
+       ResultColumnList        columnList = (ResultColumnList) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                               getContextManager());\r
+}\r
+{\r
+       setClause(columnList) ( <COMMA> setClause(columnList) ) *\r
+       {\r
+               return columnList;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="setClause">setClause</A>\r
+ */\r
+void\r
+setClause(ResultColumnList columnList) throws StandardException :\r
+{\r
+       ResultColumn resultColumn;\r
+       ColumnReference  columnName;\r
+       ValueNode        valueNode;\r
+}\r
+{\r
+       /* identifier() used to be objectColumn() */\r
+       /*\r
+               SQL92 only wants identifiers here (column names)\r
+               but JBuilder expects table.column, so we allow the\r
+               general form.\r
+        */\r
+       columnName = columnReference() <EQUALS_OPERATOR> valueNode = updateSource(columnName.getColumnName())\r
+       {\r
+               resultColumn = (ResultColumn) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.RESULT_COLUMN,\r
+                                                                               columnName,\r
+                                                                               valueNode,\r
+                                                                               getContextManager());\r
+               columnList.addResultColumn(resultColumn);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="updateSource">updateSource</A>\r
+ */\r
+ValueNode\r
+updateSource(String columnName) throws StandardException :\r
+{\r
+       ValueNode       valueNode;\r
+}\r
+{\r
+       valueNode = additiveExpression(null,0, false) \r
+       {\r
+               return valueNode;\r
+       }\r
+|\r
+       valueNode = nullSpecification() \r
+       {\r
+               return valueNode;\r
+       }\r
+|\r
+       <_DEFAULT>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.DEFAULT_NODE,\r
+                                                               columnName,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="nullSpecification">nullSpecification</A>\r
+ */\r
+ValueNode\r
+nullSpecification() throws StandardException :\r
+{}\r
+{\r
+       <NULL>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,\r
+                                                                       getContextManager());\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="insertColumnsAndSource">insertColumnsAndSource</A>\r
+ */\r
+StatementNode\r
+insertColumnsAndSource(QueryTreeNode targetTable) \r
+       throws StandardException :\r
+{\r
+       Properties                      targetProperties = null;\r
+       ResultSetNode   queryExpression;\r
+       ResultColumnList        columnList = null;\r
+}\r
+{\r
+       [\r
+               // This LOOKAHEAD is required because a query expression can\r
+               // be a SELECT or VALUES nested arbitrarily deep in parentheses\r
+               // (which looks like a subquery). So, to be sure that a left\r
+               // parenthesis introduces an insertColumnList(), we have to\r
+               // be sure it doesn't introduce a subquery.\r
+               LOOKAHEAD( { getToken(1).kind == LEFT_PAREN && ! subqueryFollows() } )\r
+               <LEFT_PAREN> columnList = insertColumnList() <RIGHT_PAREN>\r
+       ]\r
+       [ targetProperties = propertyList(false) <CHECK_PROPERTIES>]\r
+       queryExpression = queryExpression(null, NO_SET_OP)\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.INSERT_NODE,\r
+                                                       targetTable,\r
+                                                       columnList,\r
+                                                       queryExpression,\r
+                                                       targetProperties,\r
+                                                       getContextManager());\r
+       }\r
+       /* RESOLVE: Ignoring default values for now\r
+|\r
+       [ targetProperties = propertyList(false) <CHECK_PROPERTIES>]\r
+       <_DEFAULT> <VALUES>\r
+       {\r
+               return null;\r
+       }\r
+       */\r
+}\r
+\r
+/*\r
+ * <A NAME="insertColumnList">insertColumnList</A>\r
+ */\r
+ResultColumnList\r
+insertColumnList() throws StandardException :\r
+{\r
+       ResultColumnList        columnList = (ResultColumnList) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                               getContextManager());\r
+}\r
+{\r
+       columnQualifiedNameList(columnList)\r
+       {\r
+               return columnList;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="columnQualifiedNameList">columnQualifiedNameList</A>\r
+ */\r
+void\r
+columnQualifiedNameList(ResultColumnList columnList) throws StandardException :\r
+{}\r
+{\r
+       columnQualifiedNameItem(columnList) ( <COMMA> columnQualifiedNameItem(columnList) ) *\r
+}\r
+\r
+/*\r
+ * <A NAME="columnQualifiedNameItem">columnQualifiedNameItem</A>\r
+ */\r
+void\r
+columnQualifiedNameItem(ResultColumnList columnList) throws StandardException :\r
+{\r
+       ColumnReference         columnRef;\r
+       ResultColumn    resultColumn;\r
+}\r
+{\r
+       /*\r
+               SQL92 only wants identifiers here (column names)\r
+               but JBuilder expects table.column, so we allow the\r
+               general form.\r
+        */\r
+       columnRef = columnReference()\r
+       {\r
+               /*\r
+               ** Store the column names for the result columns in the\r
+               ** result column list.  We don't know yet what valueNodes\r
+               ** should be hooked up to each result column, so set that\r
+               ** to null for now.\r
+               */\r
+               resultColumn = (ResultColumn) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.RESULT_COLUMN,\r
+                                                                               columnRef,\r
+                                                                               null,\r
+                                                                               getContextManager());\r
+               columnList.addResultColumn(resultColumn);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="rowValueConstructor">rowValueConstructor</A>\r
+ */\r
+ResultSetNode\r
+rowValueConstructor(ResultSetNode leftRSN) throws StandardException :\r
+{\r
+       ResultColumnList        resultColumns = (ResultColumnList) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                               getContextManager());\r
+       ResultSetNode           newRSN;\r
+}\r
+{\r
+       // This LOOKAHEAD is required because a rowValueConstructorList is\r
+       // nested in parentheses, and each element of the list can also be\r
+       // nested in an arbitrary number of parentheses.\r
+       LOOKAHEAD( { rowValueConstructorListFollows() } )\r
+       <LEFT_PAREN> rowValueConstructorList(resultColumns) <RIGHT_PAREN>\r
+       {\r
+               /* If leftRSN is null, simply return the newRSN, else generate and\r
+                * return a UNION ALL above the 2 RSNs, after verifying that the size()\r
+                * of both RSNs RCLs is the same.\r
+                */\r
+               newRSN = (ResultSetNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.ROW_RESULT_SET_NODE,\r
+                                                               resultColumns,\r
+                                                               null,\r
+                                                               getContextManager());\r
+               if (leftRSN != null)\r
+               {\r
+                       if (leftRSN.getResultColumns().size() !=\r
+                               newRSN.getResultColumns().size())\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_ROW_VALUE_CONSTRUCTOR_UNMATCHED_COLUMNS);\r
+                       }\r
+\r
+                       newRSN = (ResultSetNode) nodeFactory.getNode(   \r
+                                                                       C_NodeTypes.UNION_NODE,\r
+                                                                       leftRSN,\r
+                                                                       newRSN,\r
+                                                                       Boolean.TRUE,\r
+                                                                       Boolean.TRUE,\r
+                                                                       null,\r
+                                                                       getContextManager());\r
+               }\r
+               return newRSN;\r
+               \r
+       }\r
+|\r
+       rowValueConstructorElement(resultColumns)\r
+       {\r
+               /* If leftRSN is null, simply return the newRSN, else generate and\r
+                * return a UNION ALL above the 2 RSNs, after verifying that the size()\r
+                * of both RSNs RCLs is the same.\r
+                */\r
+               newRSN = (ResultSetNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.ROW_RESULT_SET_NODE,\r
+                                                               resultColumns,\r
+                                                               null,\r
+                                                               getContextManager());\r
+               if (leftRSN != null)\r
+               {\r
+                       if (leftRSN.getResultColumns().size() !=\r
+                               newRSN.getResultColumns().size())\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_ROW_VALUE_CONSTRUCTOR_UNMATCHED_COLUMNS);\r
+                       }\r
+\r
+                       newRSN = (ResultSetNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.UNION_NODE,\r
+                                                                       leftRSN,\r
+                                                                       newRSN,\r
+                                                                       Boolean.TRUE,\r
+                                                                       Boolean.TRUE,\r
+                                                                       null,\r
+                                                                       getContextManager());\r
+               }\r
+               return newRSN;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="rowValueConstructorElement">rowValueConstructorElement</A>\r
+ */\r
+void\r
+rowValueConstructorElement(ResultColumnList resultColumns) throws StandardException :\r
+{\r
+       ValueNode       value;\r
+}\r
+{\r
+       value = additiveExpression(null, 0, true)\r
+       {\r
+               resultColumns.addResultColumn(\r
+                       (ResultColumn) nodeFactory.getNode(\r
+                                                       C_NodeTypes.RESULT_COLUMN,\r
+                                                       null,\r
+                                                       value,\r
+                                                       getContextManager())\r
+                               );\r
+       }\r
+|\r
+       value = nullSpecification()\r
+       {\r
+               resultColumns.addResultColumn(\r
+                       (ResultColumn) nodeFactory.getNode(\r
+                                                       C_NodeTypes.RESULT_COLUMN,\r
+                                                       null,\r
+                                                       value,\r
+                                                       getContextManager())\r
+                               );\r
+       }\r
+|\r
+       <_DEFAULT>\r
+       {\r
+               resultColumns.addResultColumn(\r
+                       (ResultColumn) nodeFactory.getNode(\r
+                                                       C_NodeTypes.RESULT_COLUMN,\r
+                                                       null,\r
+                                                       (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.DEFAULT_NODE,\r
+                                                               null,\r
+                                                               getContextManager()),\r
+                                                       getContextManager())\r
+                               );\r
+       }\r
+|\r
+       {\r
+               throw StandardException.newException(SQLState.LANG_EMPTY_VALUES_CLAUSE);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="rowValueConstructorList">rowValueConstructorList</A>\r
+ */\r
+void\r
+rowValueConstructorList(ResultColumnList resultColumns) throws StandardException :\r
+{}\r
+{\r
+       rowValueConstructorElement(resultColumns)\r
+               ( <COMMA> rowValueConstructorElement(resultColumns) ) *\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="tableSubquery">tableSubquery</A>\r
+ */\r
+SubqueryNode\r
+tableSubquery(int subqueryType, ValueNode leftOperand) throws StandardException :\r
+{\r
+       SubqueryNode    subqueryNode;\r
+}\r
+{\r
+       subqueryNode = subquery(subqueryType, leftOperand)\r
+       {\r
+               return subqueryNode;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="subquery">subquery</A>\r
+ */\r
+SubqueryNode\r
+subquery(int subqueryType, ValueNode leftOperand) throws StandardException :\r
+{\r
+       ResultSetNode   queryExpression;\r
+       SubqueryNode    subqueryNode;\r
+}\r
+{\r
+       queryExpression = queryExpression(null, NO_SET_OP)\r
+       {\r
+               subqueryNode = (SubqueryNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.SUBQUERY_NODE,\r
+                                                                               queryExpression, \r
+                                                                               ReuseFactory.getInteger(subqueryType),\r
+                                                                               leftOperand,\r
+                                                                               getContextManager());\r
+               return subqueryNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="inPredicateValue">inPredicateValue</A>\r
+ */\r
+ValueNode\r
+inPredicateValue(ValueNode leftOperand) throws StandardException :\r
+{\r
+       ValueNode               retval;\r
+       int                             tokKind;\r
+}\r
+{\r
+       <LEFT_PAREN>\r
+       (\r
+               // This LOOKAHEAD is necessary because both a subquery and an\r
+               // inValueList can be nested arbitrarily deep in parentheses,\r
+               // so both can start with LEFT_PAREN. To disambiguate, we only\r
+               // consider it a subquery if the first token that comes after\r
+               // all the LEFT_PARENS is either a SELECT or a VALUES.\r
+               LOOKAHEAD( { subqueryFollows() } )\r
+               retval = tableSubquery(SubqueryNode.IN_SUBQUERY, leftOperand)\r
+       |\r
+               retval = inValueList(leftOperand)\r
+       )\r
+       <RIGHT_PAREN>\r
+       {\r
+               return retval;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="inValueList">inValueList</A>\r
+ */\r
+ValueNode\r
+inValueList(ValueNode leftOperand) throws StandardException:\r
+{\r
+       ValueNodeList   inList = (ValueNodeList) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.VALUE_NODE_LIST,\r
+                                                                                       getContextManager());\r
+}\r
+{\r
+       inElement(inList) ( <COMMA> inElement(inList) ) *\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.IN_LIST_OPERATOR_NODE,\r
+                                                               leftOperand,\r
+                                                               inList,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="inElement">inElement</A>\r
+ */\r
+void\r
+inElement(ValueNodeList inList) throws StandardException :\r
+{\r
+       ValueNode valueNode;\r
+}\r
+{\r
+       valueNode = additiveExpression(null, 0, false)\r
+       {\r
+               inList.addElement(valueNode);\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="quantifier">quantifier</A>\r
+ */\r
+int\r
+quantifier(int opType) throws StandardException :\r
+{\r
+       int retval = 0;\r
+}\r
+{\r
+       <ALL> \r
+       {\r
+               switch (opType)\r
+               {\r
+                       case BinaryOperatorNode.EQ:\r
+                               retval = SubqueryNode.EQ_ALL_SUBQUERY;\r
+                               break;\r
+\r
+                       case BinaryOperatorNode.NE:\r
+                               retval = SubqueryNode.NE_ALL_SUBQUERY;\r
+                               break;\r
+\r
+                       case BinaryOperatorNode.LE:\r
+                               retval = SubqueryNode.LE_ALL_SUBQUERY;\r
+                               break;\r
+\r
+                       case BinaryOperatorNode.LT:\r
+                               retval = SubqueryNode.LT_ALL_SUBQUERY;\r
+                               break;\r
+\r
+                       case BinaryOperatorNode.GE:\r
+                               retval = SubqueryNode.GE_ALL_SUBQUERY;\r
+                               break;\r
+\r
+                       case BinaryOperatorNode.GT:\r
+                               retval = SubqueryNode.GT_ALL_SUBQUERY;\r
+                               break;\r
+\r
+                       default:\r
+                               if (SanityManager.DEBUG)\r
+                               SanityManager.THROWASSERT(\r
+                                               "Invalid value for opType (" + opType +\r
+                                               ") passed to quantifier()");\r
+               }\r
+               return retval;\r
+       }\r
+|\r
+       some()\r
+       {\r
+               switch (opType)\r
+               {\r
+                       case BinaryOperatorNode.EQ:\r
+                               retval = SubqueryNode.EQ_ANY_SUBQUERY;\r
+                               break;\r
+\r
+                       case BinaryOperatorNode.NE:\r
+                               retval = SubqueryNode.NE_ANY_SUBQUERY;\r
+                               break;\r
+\r
+                       case BinaryOperatorNode.LE:\r
+                               retval = SubqueryNode.LE_ANY_SUBQUERY;\r
+                               break;\r
+\r
+                       case BinaryOperatorNode.LT:\r
+                               retval = SubqueryNode.LT_ANY_SUBQUERY;\r
+                               break;\r
+\r
+                       case BinaryOperatorNode.GE:\r
+                               retval = SubqueryNode.GE_ANY_SUBQUERY;\r
+                               break;\r
+\r
+                       case BinaryOperatorNode.GT:\r
+                               retval = SubqueryNode.GT_ANY_SUBQUERY;\r
+                               break;\r
+\r
+                       default:\r
+                               if (SanityManager.DEBUG)\r
+                               SanityManager.THROWASSERT(\r
+                                               "Invalid value for opType (" + opType +\r
+                                               ") passed to quantifier()");\r
+               }\r
+               return retval;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="some">some</A>\r
+ */\r
+void\r
+some() throws StandardException :\r
+{}\r
+{\r
+       <SOME> |\r
+       <ANY>\r
+}\r
+\r
+/*\r
+ * <A NAME="existsExpression">existsExpression</A>\r
+ */\r
+SubqueryNode\r
+existsExpression() throws StandardException :\r
+{\r
+       SubqueryNode    subqueryNode;\r
+}\r
+{\r
+       <EXISTS> <LEFT_PAREN>\r
+       subqueryNode = tableSubquery(SubqueryNode.EXISTS_SUBQUERY, null)\r
+       <RIGHT_PAREN>\r
+       {\r
+               return subqueryNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="tableExpression">tableExpression</A>\r
+ */\r
+SelectNode\r
+tableExpression(ResultColumnList selectList) throws StandardException :\r
+{\r
+       SelectNode      selectNode;\r
+       FromList        fromList;\r
+       ValueNode       whereClause = null;\r
+       GroupByList     groupByList = null;\r
+       ValueNode       havingClause = null;\r
+       Token           whereToken;\r
+}\r
+{\r
+       fromList = fromClause()\r
+       [ whereToken = <WHERE> whereClause = whereClause(whereToken) ]\r
+       [ groupByList = groupByClause() ]\r
+       [ havingClause = havingClause() ]\r
+       {\r
\r
+               // fix for HAVING without GROUP BY, makes sure we get one\r
+               // aggregate operator by adding a count(*), this fixes beetle 5853, 5890\r
+               if (havingClause != null && groupByList == null) {\r
+                       ValueNode vn = (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.AGGREGATE_NODE,\r
+                                                               null,\r
+                                                               org.apache.derby.impl.sql.compile.CountAggregateDefinition.class,\r
+                                                               Boolean.FALSE, // distinct Boolean.TRUE?\r
+                                                               "COUNT(*)",\r
+                                                               getContextManager());\r
+                       AggregateNode n = (AggregateNode) vn;\r
+                       n.replaceAggregatesWithColumnReferences(selectList, 0);                 \r
+               }\r
+               \r
+               selectNode = (SelectNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.SELECT_NODE,\r
+                                                       selectList,\r
+                                                       null,           /* AGGREGATE list */\r
+                                                       fromList,\r
+                                                       whereClause,\r
+                                                       groupByList,\r
+                                                       havingClause,\r
+                                                       getContextManager());\r
+\r
+               return selectNode;\r
+       }\r
+}\r
+\r
+\r
+\r
+/*\r
+ * <A NAME="fromClause">fromClause</A>\r
+ */\r
+FromList\r
+fromClause() throws StandardException :\r
+{\r
+       FromList fromList = (FromList) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.FROM_LIST,\r
+                                                                       getNodeFactory().doJoinOrderOptimization(),\r
+                                                                       getContextManager());\r
+       int     tokKind;\r
+        Token   beginToken;\r
+        Token   endToken;\r
+}\r
+{\r
+       <FROM> {beginToken = getToken(1);}\r
+       [\r
+               fromListProperties(fromList)\r
+       ]\r
+       dummyTableReferenceRule(fromList)\r
+                       ( <COMMA> dummyTableReferenceRule(fromList) ) * {endToken = getToken(0);}\r
+\r
+       {\r
+                fromList.setBeginOffset( beginToken.beginOffset);\r
+                fromList.setEndOffset( endToken.endOffset);\r
+               return fromList;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="fromListProperties">fromListProperties</A>\r
+ */\r
+void\r
+fromListProperties(FromList fromList) throws StandardException :\r
+{\r
+       Properties properties;\r
+}\r
+{\r
+       properties = propertyList(true) <CHECK_PROPERTIES>\r
+       {\r
+               fromList.setProperties(properties);\r
+       }\r
+}\r
+\r
+/* This rule created simply as a way to add the result of tableReference()\r
+ * to the fromList.\r
+ */\r
+void\r
+dummyTableReferenceRule(FromList fromList) throws StandardException :\r
+{\r
+       FromTable tableReference;\r
+}\r
+{\r
+       /* If we have a table constructor and the expression is a SELECT\r
+        * query or a VALUES query then we read the <TABLE> keyword;\r
+        * otherwise we leave the <TABLE> token in the queue and let\r
+        * other types of expressions (namely, vtiTableConstruct())\r
+        * deal with it accordingly.  DERBY-2152.\r
+        */\r
+       LOOKAHEAD({ getToken(1).kind == TABLE &&\r
+                               getToken(2).kind == LEFT_PAREN &&\r
+                               (\r
+                                       getToken(3).kind == SELECT ||\r
+                                       getToken(3).kind == VALUES\r
+                               )\r
+                       }) <TABLE>\r
+       tableReference = tableReferenceTypes(false)\r
+       {\r
+               fromList.addFromTable(tableReference);\r
+       }\r
+|\r
+       tableReference = tableReferenceTypes(false)\r
+       {\r
+               fromList.addFromTable(tableReference);\r
+       }\r
+}\r
+\r
+FromTable\r
+tableReferenceTypes(boolean nestedInParens) throws StandardException :\r
+{\r
+       FromTable tableReference;\r
+}\r
+{\r
+       tableReference = tableReference(nestedInParens)\r
+       {\r
+               return tableReference ;\r
+       }\r
+|\r
+       <LEFT_BRACE> <OJ> tableReference = tableReference(nestedInParens) <RIGHT_BRACE>\r
+       {\r
+               return tableReference;\r
+       }\r
+}\r
+\r
+Object[]\r
+optionalTableClauses() throws StandardException :\r
+{\r
+       Object[]                         otc = null;\r
+       Properties                      tableProperties = null;\r
+       ResultColumnList        derivedRCL = null;\r
+       String                          correlationName = null;\r
+}\r
+{\r
+       otc = optionalTableProperties() \r
+       {\r
+               otc[OPTIONAL_TABLE_CLAUSES_DERIVED_RCL] = derivedRCL;\r
+               otc[OPTIONAL_TABLE_CLAUSES_CORRELATION_NAME] = correlationName;\r
+               return otc;\r
+       }\r
+|\r
+       [ [ <AS> ] \r
+               correlationName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+               [ <LEFT_PAREN> derivedRCL = derivedColumnList() <RIGHT_PAREN> ] \r
+           [tableProperties = propertyList(true) <CHECK_PROPERTIES>] ]\r
+       {\r
+               otc = new Object[OPTIONAL_TABLE_CLAUSES_SIZE];\r
+               otc[OPTIONAL_TABLE_CLAUSES_TABLE_PROPERTIES] = tableProperties;\r
+               otc[OPTIONAL_TABLE_CLAUSES_DERIVED_RCL] = derivedRCL;\r
+               otc[OPTIONAL_TABLE_CLAUSES_CORRELATION_NAME] = correlationName;\r
+               return otc;\r
+       }\r
+}\r
+\r
+Object[]\r
+optionalTableProperties() throws StandardException :\r
+{\r
+       Object[]                        otc = null;\r
+       Properties                      tableProperties = null;\r
+}\r
+{\r
+       tableProperties = propertyList(true) <CHECK_PROPERTIES> \r
+       {\r
+               otc = new Object[OPTIONAL_TABLE_CLAUSES_SIZE];\r
+               otc[OPTIONAL_TABLE_CLAUSES_TABLE_PROPERTIES] = tableProperties;\r
+               return otc;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="tableReference">tableReference</A>\r
+ */\r
+FromTable\r
+tableReference(boolean nestedInParens) throws StandardException :\r
+{\r
+       JavaToSQLValueNode      javaToSQLNode = null;\r
+       TableName                       tableName;\r
+       String                          correlationName = null;\r
+       ResultColumnList        derivedRCL = null;\r
+       FromTable                       fromTable;\r
+       TableOperatorNode       joinTable = null;\r
+       FromTable                       tableReference;\r
+       Object[]                        optionalTableClauses = new Object[OPTIONAL_TABLE_CLAUSES_SIZE];\r
+       Properties                      tableProperties = null;\r
+       ResultSetNode           derivedTable;\r
+}\r
+{\r
+       /* NOTE: this rule has to come first in order to avoid making NEW\r
+        * a reserved word.\r
+        */\r
+       /* identifier() used to be correlationName() */\r
+       (LOOKAHEAD({ newInvocationFollows(1) }) javaToSQLNode = newInvocation()\r
+       | javaToSQLNode = vtiTableConstruct()\r
+       )\r
+               [ <AS> ] correlationName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+               [ <LEFT_PAREN> derivedRCL = derivedColumnList() <RIGHT_PAREN> ]\r
+               [ optionalTableClauses = optionalTableProperties() ]\r
+               (LOOKAHEAD( { joinedTableExpressionFollows() } )\r
+                joinTable = joinedTableExpression(\r
+                                                                       (joinTable != null) ?\r
+                                                                               joinTable :\r
+                                                                               (FromTable) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.FROM_VTI,\r
+                                                                                       javaToSQLNode.getJavaValueNode(), \r
+                                                                                       correlationName,\r
+                                                                                       derivedRCL, \r
+                                                                                       ((optionalTableClauses != null) ? \r
+                                                                                               (Properties) optionalTableClauses[OPTIONAL_TABLE_CLAUSES_TABLE_PROPERTIES] :\r
+                                                                                               (Properties) null),\r
+                                                                                       getContextManager()),\r
+                                                                       nestedInParens)) *\r
+       {\r
+               /* Build a derived table if not a join expression */\r
+               if (joinTable == null)\r
+               {\r
+                       fromTable = (FromTable) nodeFactory.getNode(\r
+                                                               C_NodeTypes.FROM_VTI,\r
+                                                               javaToSQLNode.getJavaValueNode(), \r
+                                                               correlationName,\r
+                                                               derivedRCL, \r
+                                                               ((optionalTableClauses != null) ? \r
+                                                                       (Properties) optionalTableClauses[OPTIONAL_TABLE_CLAUSES_TABLE_PROPERTIES] :\r
+                                                                       (Properties) null),\r
+                                                               getContextManager()); \r
+               }\r
+               else\r
+               {\r
+                       fromTable = joinTable;\r
+               }\r
+\r
+               return fromTable;\r
+       }\r
+|\r
+       /* identifier() used to be correlationName() */\r
+       tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+               optionalTableClauses = optionalTableClauses()\r
+               (LOOKAHEAD( { joinedTableExpressionFollows() } )\r
+                joinTable = joinedTableExpression(\r
+                                                                       (joinTable != null) ?\r
+                                                                               joinTable :\r
+                                                                               (FromTable) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.FROM_BASE_TABLE,\r
+                                                                                               tableName,\r
+                                                                                               (String) optionalTableClauses[OPTIONAL_TABLE_CLAUSES_CORRELATION_NAME],\r
+                                                                                               (ResultColumnList) optionalTableClauses[OPTIONAL_TABLE_CLAUSES_DERIVED_RCL],\r
+                                                                                               (Properties) optionalTableClauses[OPTIONAL_TABLE_CLAUSES_TABLE_PROPERTIES],\r
+                                                                                               getContextManager()), \r
+                                                                       nestedInParens)) *\r
+       {\r
+               /* Build a from table if not a join expression */\r
+               if (joinTable == null)\r
+               {\r
+                       fromTable = (FromTable) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.FROM_BASE_TABLE,\r
+                                                                                       tableName,\r
+                                                                                               (String) optionalTableClauses[OPTIONAL_TABLE_CLAUSES_CORRELATION_NAME],\r
+                                                                                               (ResultColumnList) optionalTableClauses[OPTIONAL_TABLE_CLAUSES_DERIVED_RCL],\r
+                                                                                               (Properties) optionalTableClauses[OPTIONAL_TABLE_CLAUSES_TABLE_PROPERTIES],\r
+                                                                                       getContextManager());\r
+               }\r
+               else\r
+               {                  \r
+                       fromTable = joinTable;\r
+               }\r
+               return fromTable;\r
+       }\r
+|\r
+       // There is a grammar ambiguity with nested parentheses here.\r
+       // A series of left parentheses could introduce either a table\r
+       // reference or a derived table.  For example:\r
+       //\r
+       //              (((select c from t) a inner join (select d from s) b ))\r
+       //\r
+       // and:\r
+       //\r
+       //              (((select c from t) a)))\r
+       //\r
+       // To distinguish these two cases, we consider anything that starts\r
+       // with a single parenthesis and either SELECT or VALUES to be\r
+       // a derived table, and anything else to be a table reference.\r
+       // Note that we can't use the subqueryFollows() lookahead method,\r
+       // because it skips over all leading left parentheses to decide\r
+       // whether a subquery follows.\r
+       LOOKAHEAD( {\r
+                               getToken(1).kind == LEFT_PAREN &&\r
+                               (\r
+                                       getToken(2).kind == SELECT ||\r
+                                       getToken(2).kind == VALUES\r
+                               )\r
+                       } )\r
+       derivedTable = derivedTable() [ <AS> ] correlationName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+               [ <LEFT_PAREN> derivedRCL = derivedColumnList() <RIGHT_PAREN> ]\r
+               [ optionalTableClauses = optionalTableProperties() ]\r
+               ( LOOKAHEAD( { joinedTableExpressionFollows() } )\r
+                 joinTable = joinedTableExpression(\r
+                                                                       (joinTable != null) ?\r
+                                                                               joinTable :\r
+                                                                               (FromTable) nodeFactory.getNode(\r
+                                                                                                       C_NodeTypes.FROM_SUBQUERY,\r
+                                                                                                       derivedTable, \r
+                                                                                                       correlationName,\r
+                                                                                                       derivedRCL,\r
+                                                                                                       ((optionalTableClauses != null) ?\r
+                                                                                                               (Properties) optionalTableClauses[OPTIONAL_TABLE_CLAUSES_TABLE_PROPERTIES] :\r
+                                                                                                               (Properties) null),\r
+                                                                                                       getContextManager()),\r
+                                                                       nestedInParens)) *\r
+       {\r
+               /* Build a derived table if not a join expression */\r
+               if (joinTable == null)\r
+               {\r
+                       fromTable = (FromTable) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.FROM_SUBQUERY,\r
+                                                                                       derivedTable, \r
+                                                                                       correlationName,\r
+                                                                                       derivedRCL,\r
+                                                                                       ((optionalTableClauses != null) ?\r
+                                                                                               (Properties) optionalTableClauses[OPTIONAL_TABLE_CLAUSES_TABLE_PROPERTIES] :\r
+                                                                                               (Properties) null),\r
+                                                                                       getContextManager()); \r
+               }\r
+               else\r
+               {\r
+                       fromTable = joinTable;\r
+               }\r
+\r
+               return fromTable;\r
+       }\r
+|\r
+       <LEFT_PAREN> tableReference = tableReferenceTypes(true) <RIGHT_PAREN>\r
+               ( LOOKAHEAD( { joinedTableExpressionFollows() } )\r
+                 joinTable = joinedTableExpression(\r
+                                                                       (joinTable != null) ?\r
+                                                                               joinTable :\r
+                                                                               tableReference,\r
+                                                                       nestedInParens)) *\r
+       {\r
+               if (joinTable == null)\r
+               {\r
+                       fromTable = tableReference; \r
+               }\r
+               else\r
+               {\r
+                       fromTable = joinTable;\r
+               }\r
+\r
+               return fromTable;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="derivedColumnList">derivedColumnList</A>\r
+ */\r
+ResultColumnList\r
+derivedColumnList() throws StandardException :\r
+{\r
+       ResultColumnList        resultColumns =\r
+                                                                       (ResultColumnList) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                       getContextManager());\r
+}\r
+{\r
+       columnNameList(resultColumns)\r
+       {\r
+               return resultColumns;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="columnNameList">columnNameList</A>\r
+ */\r
+void\r
+columnNameList(ResultColumnList columnList) throws StandardException :\r
+{}\r
+{\r
+       columnNameItem(columnList) ( <COMMA> columnNameItem(columnList) ) *\r
+}\r
+\r
+/*\r
+ * <A NAME="columnNameItem">columnNameItem</A>\r
+ */\r
+void\r
+columnNameItem(ResultColumnList columnList) throws StandardException :\r
+{\r
+       String          columnName;\r
+       ResultColumn    resultColumn;\r
+}\r
+{\r
+       /* identifier() used to be columnName() */\r
+       columnName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               /*\r
+               ** Store the column names for the result columns in the\r
+               ** result column list.  We don't know yet what valueNodes\r
+               ** should be hooked up to each result column, so set that\r
+               ** to null for now.\r
+               */\r
+               resultColumn = (ResultColumn) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.RESULT_COLUMN,\r
+                                                                       columnName,\r
+                                                                       null,\r
+                                                                       getContextManager());\r
+               columnList.addResultColumn(resultColumn);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="indexColumnList">indexColumnList</A>\r
+ */\r
+void\r
+indexColumnList(Vector columnList) throws StandardException :\r
+{}\r
+{\r
+       indexColumnItem(columnList) ( <COMMA> indexColumnItem(columnList) ) *\r
+}\r
+\r
+/*\r
+ * <A NAME="indexColumnItem">indexColumnItem</A>\r
+ */\r
+void\r
+indexColumnItem(Vector columnList) throws StandardException :\r
+{\r
+       String          columnName;\r
+}\r
+{\r
+       /* identifier never ends with a space; appending a space meaning desc */\r
+       columnName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) [<ASC> | <DESC> {columnName = columnName + ' ';}]\r
+       {\r
+               /*\r
+               ** Store the column names for the index columns in the\r
+               ** index column list.\r
+               */\r
+               columnList.addElement(columnName);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="derivedTable">derivedTable</A>\r
+ */\r
+ResultSetNode\r
+derivedTable() throws StandardException :\r
+{\r
+       SubqueryNode tableSubquery;\r
+}\r
+{\r
+       <LEFT_PAREN>\r
+       tableSubquery = tableSubquery(SubqueryNode.FROM_SUBQUERY, null)\r
+       <RIGHT_PAREN>\r
+       {\r
+               return tableSubquery.getResultSet();\r
+       }\r
+}\r
+\r
+TableOperatorNode\r
+joinedTableExpression(ResultSetNode leftRSN, boolean nestedInParens) throws StandardException :\r
+{\r
+       TableOperatorNode joinNode;\r
+}\r
+{\r
+       joinNode = qualifiedJoin(leftRSN, nestedInParens) \r
+       {\r
+               return joinNode;\r
+       }\r
+}\r
+\r
+TableOperatorNode\r
+qualifiedJoin(ResultSetNode leftRSN, boolean nestedInParens) throws StandardException :\r
+{\r
+       int                                     joinType = JoinNode.INNERJOIN;\r
+       ResultSetNode           rightRSN;\r
+       TableOperatorNode       ton = null;\r
+       Object[]                        onOrUsingClause = null;\r
+       ResultColumnList        usingClause = null;\r
+       ValueNode                       onClause;\r
+}\r
+{\r
+       /* RESOLVE - If we ever support NATURAL JOIN then we will need to break up\r
+        * this rule.  Right now the joinSpecification() is non-optional.  This\r
+        * allows us to build the Join tree from left to right. With NATURAL JOINS\r
+        * there is no joinSpecification() and we would want to build the tree from\r
+        * right to left.\r
+        */\r
+       //[ <NATURAL> ] \r
+               [ joinType = joinType() ] <JOIN>\r
+               rightRSN = tableReferenceTypes(nestedInParens) \r
+               onOrUsingClause = joinSpecification(leftRSN, rightRSN)\r
+       {\r
+               /* If NATURAL OR UNION is specified, then no joinSpecification()\r
+                * is required, otherwise it is required.\r
+                */\r
+\r
+               /* RESOLVE - Since we don't support NATURAL or UNION joins yet,\r
+                * onOrUsingClause must be non-null.  (Change error message if and\r
+                * when grammar changes.)\r
+                */\r
+\r
+               /* Figure out whether an ON or USING clause was used */\r
+               onClause = (ValueNode) onOrUsingClause[ON_CLAUSE];\r
+               usingClause = (ResultColumnList) onOrUsingClause[USING_CLAUSE];\r
+\r
+               if (onClause == null && usingClause == null)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_MISSING_JOIN_SPECIFICATION, \r
+                                                       JoinNode.joinTypeToString(joinType));\r
+               }\r
+\r
+               switch(joinType)\r
+               {\r
+                       case JoinNode.INNERJOIN:\r
+                               ton = (TableOperatorNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.JOIN_NODE,\r
+                                                                       leftRSN,\r
+                                                                       rightRSN,\r
+                                                                       onClause,\r
+                                                                       usingClause,\r
+                                                                       null,\r
+                                                                       null,\r
+                                                                       null,\r
+                                                                       getContextManager());\r
+                               break;\r
+\r
+                       case JoinNode.LEFTOUTERJOIN:\r
+                               ton = (TableOperatorNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.HALF_OUTER_JOIN_NODE,\r
+                                                                               leftRSN,\r
+                                                                               rightRSN,\r
+                                                                               onClause,\r
+                                                                               usingClause,\r
+                                                                               Boolean.FALSE,\r
+                                                                               null,\r
+                                                                               getContextManager());\r
+                               break;\r
+\r
+                       case JoinNode.RIGHTOUTERJOIN:\r
+                               ton = (TableOperatorNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.HALF_OUTER_JOIN_NODE,\r
+                                                                               leftRSN,\r
+                                                                               rightRSN,\r
+                                                                               onClause,\r
+                                                                               usingClause,\r
+                                                                               Boolean.TRUE,\r
+                                                                               null,\r
+                                                                               getContextManager());\r
+                               break;\r
+\r
+\r
+                       default:\r
+                               if (SanityManager.DEBUG)\r
+                               {\r
+                                       SanityManager.ASSERT(false, "Unexpected joinType");\r
+                               }\r
+                               return null;\r
+               }\r
+\r
+               /* Mark whether or not we are nested within parens */\r
+               ton.setNestedInParens(nestedInParens);\r
+               return ton;\r
+       }\r
+}\r
+\r
+int\r
+joinType() throws StandardException :\r
+{\r
+       int joinType;\r
+}\r
+{\r
+       <INNER> \r
+       {\r
+               return JoinNode.INNERJOIN;\r
+       }\r
+|\r
+       joinType = outerJoinType() [<OUTER>]\r
+       {\r
+               return joinType;\r
+       }\r
+}\r
+\r
+int\r
+outerJoinType() throws StandardException :\r
+{}\r
+{\r
+       <LEFT> \r
+       {\r
+               return JoinNode.LEFTOUTERJOIN;\r
+       }\r
+|\r
+       <RIGHT> \r
+       {\r
+               return JoinNode.RIGHTOUTERJOIN;\r
+       }\r
+}\r
+\r
+Object[]\r
+joinSpecification(ResultSetNode leftRSN, ResultSetNode rightRSN) \r
+               throws StandardException :\r
+{\r
+       Object[]                        onOrUsingClause = new Object[ON_OR_USING_CLAUSE_SIZE];\r
+       ResultColumnList        usingClause = null;\r
+       ValueNode                       joinClause = null;\r
+}\r
+{\r
+       joinClause = joinCondition() \r
+       {\r
+               onOrUsingClause[ON_CLAUSE] = joinClause;\r
+               onOrUsingClause[USING_CLAUSE] = usingClause;\r
+               return onOrUsingClause;\r
+       }\r
+}\r
+\r
+ValueNode\r
+joinCondition() throws StandardException :\r
+{\r
+       ValueNode joinClause;\r
+}\r
+{\r
+       /* valueExpression() was searchCondition() */\r
+       <ON> joinClause = valueExpression(false)\r
+       {\r
+               return joinClause;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="tableValueConstructor">tableValueConstructor</A>\r
+ */\r
+ResultSetNode\r
+tableValueConstructor() throws StandardException :\r
+{\r
+       ResultSetNode   resultSetNode;\r
+}\r
+{\r
+       <VALUES> resultSetNode = tableValueConstructorList()\r
+       {\r
+               return resultSetNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="tableValueConstructorList">tableValueConstructorList</A>\r
+ */\r
+ResultSetNode\r
+tableValueConstructorList() throws StandardException :\r
+{\r
+       ResultSetNode   resultSetNode;\r
+}\r
+{\r
+       resultSetNode = rowValueConstructor(null) \r
+               ( <COMMA> resultSetNode = rowValueConstructor(resultSetNode) ) *\r
+       {\r
+               if (resultSetNode instanceof UnionNode)\r
+               {\r
+                       ((UnionNode) resultSetNode).markTopTableConstructor();\r
+               }\r
+\r
+               return resultSetNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="explicitTable">explicitTable</A>\r
+ */\r
+\r
+/*\r
+ * <A NAME="datetimeValueFunction">datetimeValueFunction</A>\r
+ */\r
+ValueNode\r
+datetimeValueFunction() throws StandardException :\r
+{\r
+       int prec = -1; // can't be negative, if used\r
+}\r
+{\r
+       LOOKAHEAD({(getToken(1).kind == CURRENT && getToken(2).kind == DATE)}) <CURRENT> <DATE> \r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.CURRENT_DATETIME_OPERATOR_NODE,\r
+                                                               ReuseFactory.getInteger(\r
+                                                                       CurrentDatetimeOperatorNode.CURRENT_DATE),\r
+                                                               getContextManager());\r
+       }\r
+       | <CURRENT_DATE>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.CURRENT_DATETIME_OPERATOR_NODE,\r
+                                                               ReuseFactory.getInteger(\r
+                                                                       CurrentDatetimeOperatorNode.CURRENT_DATE),\r
+                                                               getContextManager());\r
+       }\r
+|\r
+       LOOKAHEAD({(getToken(1).kind == CURRENT && getToken(2).kind == TIME)}) <CURRENT> <TIME> \r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.CURRENT_DATETIME_OPERATOR_NODE,\r
+                                                       ReuseFactory.getInteger(\r
+                                                               CurrentDatetimeOperatorNode.CURRENT_TIME),\r
+                                                       getContextManager());\r
+       }\r
+       | <CURRENT_TIME> \r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.CURRENT_DATETIME_OPERATOR_NODE,\r
+                                                       ReuseFactory.getInteger(\r
+                                                               CurrentDatetimeOperatorNode.CURRENT_TIME),\r
+                                                       getContextManager());\r
+       }\r
+|\r
+       LOOKAHEAD({(getToken(1).kind == CURRENT && getToken(2).kind == TIMESTAMP)}) <CURRENT> <TIMESTAMP> \r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.CURRENT_DATETIME_OPERATOR_NODE,\r
+                                                       ReuseFactory.getInteger(\r
+                                                               CurrentDatetimeOperatorNode.CURRENT_TIMESTAMP),\r
+                                                       getContextManager());\r
+       }\r
+       | <CURRENT_TIMESTAMP> \r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.CURRENT_DATETIME_OPERATOR_NODE,\r
+                                                       ReuseFactory.getInteger(\r
+                                                               CurrentDatetimeOperatorNode.CURRENT_TIMESTAMP),\r
+                                                       getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+** Note that set function and aggregate are used\r
+** interchangeably in the parser.  The tree has\r
+** aggregate nodes.\r
+*/\r
+ValueNode\r
+aggregateNode() throws StandardException :\r
+{\r
+       ValueNode agg;\r
+}\r
+{\r
+       <COUNT> <LEFT_PAREN>\r
+       ( <ASTERISK>\r
+       {\r
+                       agg = (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.AGGREGATE_NODE,\r
+                                                               null,\r
+                                                               CountAggregateDefinition.class, \r
+                                                               Boolean.FALSE,\r
+                                                               "COUNT(*)",\r
+                                                               getContextManager());\r
+       }\r
+       |\r
+               agg = aggregateExpression("COUNT", CountAggregateDefinition.class)\r
+       )\r
+       <RIGHT_PAREN>\r
+       {\r
+               return agg;\r
+       }\r
+|\r
+       agg = generalAggregate()\r
+       {\r
+               return agg;\r
+       }\r
+}\r
+\r
+\r
+\r
+ValueNode\r
+aggregateExpression(String aggName, Class aggClass) throws StandardException :\r
+{\r
+       boolean         distinct = false;\r
+       ValueNode       value;\r
+}\r
+{\r
+       [ distinct = setQuantifier() ] value = additiveExpression(null, 0, false)\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.AGGREGATE_NODE,\r
+                                                               value,\r
+                                                               aggClass, \r
+                                                               distinct ? Boolean.TRUE : Boolean.FALSE,\r
+                                                               aggName,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+ValueNode\r
+generalAggregate() throws StandardException :\r
+{\r
+       Token                   aggToken;\r
+       String                  methodAliasString;\r
+       ValueNode       aggExpr;\r
+       ValueNode               value;\r
+}\r
+{\r
+       aggToken = builtInAggregateType()\r
+       <LEFT_PAREN>\r
+               aggExpr = aggregateExpression(aggName(aggToken), aggClass(aggToken))\r
+       <RIGHT_PAREN>\r
+       {\r
+               return aggExpr;\r
+       }\r
+}\r
+\r
+/*\r
+** All built in aggregates are pretty similar to user\r
+** defined aggregates, except we know what to map to\r
+** without looking up the class name.\r
+**\r
+** NOTE: COUNT is omitted here because the COUNT aggregate is\r
+** factored into a different rule, to distinguish between\r
+** COUNT(*) and COUNT(<expression>).\r
+*/\r
+Token\r
+builtInAggregateType() throws StandardException :\r
+{\r
+       Token   retval;\r
+}\r
+{\r
+       (\r
+               retval = <MAX> |\r
+               retval = <AVG> |\r
+               retval = <MIN> |\r
+               retval = <SUM>\r
+       )\r
+       {\r
+               return retval;\r
+       }\r
+}\r
+\r
+ValueNode\r
+castSpecification() throws StandardException :\r
+{\r
+       DataTypeDescriptor dts;\r
+       ValueNode                treeTop;\r
+       ValueNode                value;\r
+       int                              charType;\r
+       int                              length = -1;\r
+}\r
+{\r
+       <CAST> <LEFT_PAREN> value = castOperand() <AS> dts = dataTypeCast() <RIGHT_PAREN>\r
+       {\r
+               treeTop = (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.CAST_NODE,\r
+                                                                       value,\r
+                                                                       dts,\r
+                                                                       getContextManager());\r
+               ((CastNode) treeTop).setForExternallyGeneratedCASTnode();\r
+\r
+               /* We need to generate a SQL->Java conversion tree above us if\r
+                * the dataTypeCast is a user type.\r
+                */\r
+               if (dts.getTypeId().userType())\r
+               {\r
+                       treeTop = (ValueNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.JAVA_TO_SQL_VALUE_NODE,\r
+                                                       nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.SQL_TO_JAVA_VALUE_NODE,\r
+                                                                                       treeTop,\r
+                                                                                       getContextManager()),\r
+                                                       getContextManager());\r
+               }\r
+\r
+               return treeTop;\r
+       }\r
+               \r
+}\r
+\r
+/*\r
+ * <A NAME="charOrVarchar">charOrVarchar</A>\r
+ */\r
+int\r
+charOrVarchar() :\r
+{\r
+}\r
+{\r
+       <CHAR>\r
+       {\r
+               return Types.CHAR;\r
+       }\r
+|\r
+       <VARCHAR>\r
+       {\r
+               return Types.VARCHAR;\r
+       }\r
+}\r
+\r
+ValueNode\r
+castOperand() throws StandardException :\r
+{\r
+       ValueNode value;\r
+}\r
+{\r
+       value = additiveExpression(null, 0, false)\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       <NULL>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,\r
+                                                                       getContextManager());\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="dynamicParameterSpecification">dynamicParameterSpecification</A>\r
+ */\r
+ParameterNode\r
+dynamicParameterSpecification() throws StandardException :\r
+{}\r
+{\r
+       <QUESTION_MARK>\r
+       {\r
+               return makeParameterNode( );\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="whereClause">whereClause</A>\r
+ */\r
+ValueNode\r
+whereClause(Token beginToken) throws StandardException :\r
+{\r
+       ValueNode       value;\r
+       Token           endToken;\r
+}\r
+{\r
+       /* valueExpression() was searchCondition() */\r
+       value = valueExpression(false)\r
+       {\r
+               endToken = getToken(0);\r
+\r
+               value.setBeginOffset( beginToken.endOffset + 1 );\r
+               value.setEndOffset( endToken.endOffset );\r
+\r
+               return value;\r
+       }\r
+}\r
+\r
+GroupByList\r
+groupByClause() throws StandardException :\r
+{\r
+       GroupByList groupingCols;\r
+}\r
+{\r
+       <GROUP> <BY> groupingCols = groupingColumnReferenceList()\r
+       {\r
+               return groupingCols;\r
+       }\r
+}\r
+\r
+GroupByList\r
+groupingColumnReferenceList() throws StandardException :\r
+{\r
+       GroupByList groupingCols = (GroupByList) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.GROUP_BY_LIST,\r
+                                                                       getContextManager());\r
+}\r
+{\r
+       groupingColumnReference(groupingCols) ( <COMMA> groupingColumnReference(groupingCols) ) *\r
+       {\r
+               return groupingCols;\r
+       }\r
+}\r
+\r
+void\r
+groupingColumnReference(GroupByList groupingCols) throws StandardException :\r
+{\r
+        ValueNode columnExpression;\r
+}\r
+{\r
+       columnExpression = additiveExpression(null, 0, false)\r
+       {\r
+               if (columnExpression.isParameterNode()) \r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, "?");\r
+               }\r
+               if (columnExpression instanceof AggregateNode)\r
+               {\r
+                       AggregateNode agNode = (AggregateNode)columnExpression;\r
+                       throw StandardException.newException(\r
+                               SQLState.LANG_AGGREGATE_IN_GROUPBY_LIST, \r
+                               agNode.getAggregateName());\r
+               }        \r
+               groupingCols.addGroupByColumn(\r
+                       (GroupByColumn) nodeFactory.getNode(\r
+                                                       C_NodeTypes.GROUP_BY_COLUMN,\r
+                                                       columnExpression,\r
+                                                       getContextManager()));\r
+       }\r
+}\r
+\r
+ValueNode\r
+havingClause() throws StandardException :\r
+{\r
+       ValueNode value;\r
+}\r
+{\r
+       /* valueExpression() was searchCondition() */\r
+       <HAVING> value = valueExpression(false)\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+StatementNode\r
+schemaDefinition() throws StandardException :\r
+{\r
+       String  schemaName = null;\r
+       String  authName = null;\r
+}\r
+{\r
+       /*\r
+       ** CREATE SCHEMA:\r
+       ** We are not currently handling character set\r
+       ** specifications for schema, or schema bodies.\r
+       */\r
+       <SCHEMA>\r
+       (       schemaName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) [ <AUTHORIZATION> authName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) ]\r
+               {\r
+                       if (authName != null)\r
+                               checkVersion( DataDictionary.DD_VERSION_DERBY_10_2, "AUTHORIZATION");\r
+\r
+                       if (schemaName.startsWith("SYS"))\r
+                               throw StandardException.newException(SQLState.INVALID_SCHEMA_SYS, schemaName);\r
\r
+                       return (StatementNode) nodeFactory.getNode(\r
+                                       C_NodeTypes.CREATE_SCHEMA_NODE,\r
+                                       schemaName,\r
+                                       authName,\r
+                                       getContextManager()\r
+                                       );\r
+               }\r
+       |\r
+               <AUTHORIZATION> authName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) \r
+               {\r
+                       checkVersion( DataDictionary.DD_VERSION_DERBY_10_2, "AUTHORIZATION");\r
+                       if (authName.startsWith("SYS"))\r
+                               throw StandardException.newException(SQLState.INVALID_SCHEMA_SYS, authName);\r
+\r
+                       return (StatementNode) nodeFactory.getNode(\r
+                                       C_NodeTypes.CREATE_SCHEMA_NODE,\r
+                                       authName,\r
+                                       authName,\r
+                                       getContextManager()\r
+                                       );\r
+               }\r
+       )\r
+}\r
+\r
+/*\r
+ * <A NAME="tableDefinition">tableDefinition</A>\r
+ */\r
+StatementNode\r
+tableDefinition() throws StandardException :\r
+{\r
+       char                            lockGranularity = TableDescriptor.DEFAULT_LOCK_GRANULARITY;\r
+       Properties                      properties = null;\r
+       TableName                       tableName;\r
+       TableElementList        tableElementList;\r
+       ResultColumnList        resultColumns = null;\r
+       ResultSetNode           queryExpression;\r
+       boolean                         withData = true;\r
+}\r
+{\r
+       <TABLE> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+                       // Lookahead needed to choose between\r
+                       // tableElementList and tableColumnList\r
+       (               LOOKAHEAD({getToken(1).kind == LEFT_PAREN && \r
+                          getToken(3).kind != COMMA &&\r
+                          getToken(3).kind != RIGHT_PAREN})\r
+                       tableElementList = tableElementList()\r
+                       [ properties = propertyList(false)<CHECK_PROPERTIES>]\r
+                       {\r
+                               return (StatementNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.CREATE_TABLE_NODE,\r
+                                                                               tableName,\r
+                                                                               tableElementList,\r
+                                                                               properties,\r
+                                                                               new Character(lockGranularity),\r
+                                                                               getContextManager());\r
+                       }\r
+               |\r
+                       [ <LEFT_PAREN> resultColumns = tableColumnList() <RIGHT_PAREN> ]\r
+                       <AS>\r
+                       queryExpression = queryExpression(null, NO_SET_OP)\r
+                       <WITH> [ <NO> { withData = false; } ] <DATA>\r
+                       {\r
+                               // Raise error if WITH DATA is specified\r
+                               // (until it is implemented)\r
+                               if (withData) {\r
+                                       throw StandardException.newException(\r
+                                               SQLState.NOT_IMPLEMENTED, "WITH DATA");\r
+                               }\r
+                               /* Parameters not allowed in create table */\r
+                               HasNodeVisitor visitor =\r
+                                       new HasNodeVisitor(ParameterNode.class);\r
+                               queryExpression.accept(visitor);\r
+                               if (visitor.hasNode())\r
+                               {\r
+                                       throw StandardException.newException(\r
+                                               SQLState.LANG_NO_PARAMS_IN_TABLES);\r
+                               }\r
+                               \r
+                               return (StatementNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.CREATE_TABLE_NODE,\r
+                                                                               tableName,\r
+                                                                               resultColumns,\r
+                                                                               queryExpression,\r
+                                                                               getContextManager());\r
+                       }\r
+       )\r
+}\r
+\r
+ResultColumnList\r
+tableColumnList() throws StandardException :\r
+{\r
+       ResultColumnList resultColumns = (ResultColumnList) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                       getContextManager());\r
+}\r
+{\r
+       columnNameList(resultColumns)\r
+       {\r
+               return resultColumns;\r
+       }\r
+}\r
+\r
+/*\r
+ * This method is called when a comment starting with --derby-properties is found.\r
+ * Such a comment is a special directive to Derby and allows a sql to pass optimizer\r
+ * overrides. Derby looks for propertyName=value [,propertyName=value]* after\r
+ * --derby-properties and returns these properties in a Properties object as a return \r
+ * value of this method.\r
+ * The param propertiesUseAllowed true indicates that users are allowed to \r
+ * specify optimizer overrides in the given context. \r
+ * False means optimizer overrides in the given context are allowed internally \r
+ * only eg impl/load/import.java specifies property insertMode=replace/bulkInsert\r
+ * in the insert statement. This same property will not be acceptable from an \r
+ * insert statement from a user sql.\r
+ */\r
+Properties\r
+propertyList(boolean propertiesUseAllowed) throws StandardException :\r
+{\r
+       Properties properties = new FormatableProperties();\r
+       StringTokenizer commaSeparatedProperties;\r
+       StringTokenizer equalOperatorSeparatedProperty;\r
+}\r
+{\r
+       <DERBYDASHPROPERTIES> {\r
+               //first use StringTokenizer to get tokens which are delimited by ,s\r
+               commaSeparatedProperties = new StringTokenizer(getToken(1).image,",");\r
+               while (commaSeparatedProperties.hasMoreTokens()) {\r
+                       //Now verify that tokens delimited by ,s follow propertyName=value pattern\r
+                       String currentProperty = commaSeparatedProperties.nextToken();\r
+                       equalOperatorSeparatedProperty = new StringTokenizer(currentProperty,"=", true);\r
+                       if (equalOperatorSeparatedProperty.countTokens() != 3)\r
+                               throw StandardException.newException(SQLState.PROPERTY_SYNTAX_INVALID);\r
+                       else {\r
+                               String key = equalOperatorSeparatedProperty.nextToken().trim();\r
+                               if (!equalOperatorSeparatedProperty.nextToken().equals("="))\r
+                                       throw StandardException.newException(SQLState.PROPERTY_SYNTAX_INVALID);\r
+                               String value = equalOperatorSeparatedProperty.nextToken().trim();\r
+                               verifyImageLength(value);\r
+                               /* Trim off the leading and trailing ', and compress all '' to ' */\r
+                               if (value.startsWith("'") && value.endsWith("'"))\r
+                                       value = compressQuotes(value.substring(1, value.length() - 1), SINGLEQUOTES);\r
+                               /* Trim off the leading and trailing ", and compress all "" to " */\r
+                               else if (value.startsWith("\"") && value.endsWith("\""))\r
+                                       value = compressQuotes(value.substring(1, value.length() - 1), DOUBLEQUOTES);\r
+                               else \r
+                                       value = value.toUpperCase();\r
+                               // Do not allow user to specify multiple values for the same key\r
+                               if (properties.put(key, value) != null)\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_DUPLICATE_PROPERTY, key);\r
+                               }\r
+               }\r
+       }\r
+       //if this property override is supported in internal mode only, then do that verification here.\r
+       if (!propertiesUseAllowed) \r
+               checkInternalFeature("DERBY-PROPERTIES");\r
+       return properties;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="DB2lockGranularityClause">DB2lockGranularityClause</A>\r
+ */\r
+char\r
+DB2lockGranularityClause() throws StandardException :\r
+{\r
+       char lockGranularity;\r
+}\r
+{\r
+       <LOCKSIZE> lockGranularity = lockGranularity()\r
+       {\r
+               return lockGranularity;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="lockGranularity">lockGranularity</A>\r
+ */\r
+char\r
+lockGranularity() throws StandardException :\r
+{\r
+}\r
+{\r
+       <TABLE>\r
+       {\r
+               return TableDescriptor.TABLE_LOCK_GRANULARITY;\r
+       }\r
+|\r
+       <ROW>\r
+       {\r
+               return TableDescriptor.ROW_LOCK_GRANULARITY;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="indexDefinition">indexDefinition</A>\r
+ */\r
+StatementNode\r
+indexDefinition() throws StandardException :\r
+{\r
+       Boolean         unique = Boolean.FALSE;\r
+       Properties      properties = null;\r
+       TableName       indexName;\r
+       TableName       tableName;\r
+       Vector  indexColumnList = new Vector();\r
+}\r
+{\r
+       /*\r
+       ** fyi: The INDEX keyword is pushed into the indexType()\r
+       ** production to get the grammar to work...\r
+       */\r
+       [ unique = unique() ] <INDEX>\r
+               indexName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) <ON> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+                               <LEFT_PAREN> indexColumnList(indexColumnList) <RIGHT_PAREN>\r
+               [ properties = propertyList(false) <CHECK_PROPERTIES>]\r
+       {\r
+               /* User allowed to specify schema name on table and index.\r
+                * If no schema name specified for index, then it "inherits" \r
+                * its schema name from the table.\r
+                * If index has a schema name and table does not, then\r
+                * table "inherits" its schema name from the index.\r
+                * If schema names are specified for both objects, then the\r
+                * schema names must be the same.\r
+                */\r
+               if (indexName.getSchemaName() == null)\r
+               {\r
+                       indexName.setSchemaName(tableName.getSchemaName());\r
+               }\r
+               else if (tableName.getSchemaName() == null)\r
+               {\r
+                       tableName.setSchemaName(indexName.getSchemaName());\r
+               }\r
+               else\r
+               {\r
+                       /* schema name specified for both */\r
+                       if (! (indexName.getSchemaName().equals(\r
+                                               tableName.getSchemaName())))\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_INDEX_AND_TABLE_IN_DIFFERENT_SCHEMAS, \r
+                                                       indexName,\r
+                                                       tableName);\r
+                       }\r
+               }\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.CREATE_INDEX_NODE,\r
+                                                               unique,\r
+                                                               DEFAULT_INDEX_TYPE,\r
+                                                               indexName,\r
+                                                               tableName,\r
+                                                               indexColumnList,\r
+                                                               properties,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="unique">unique</A>\r
+ */\r
+Boolean\r
+unique() throws StandardException :\r
+{\r
+}\r
+{\r
+       <UNIQUE>\r
+       {\r
+               return Boolean.TRUE;\r
+       }\r
+}\r
+\r
+/**\r
+       CREATE PROCEDURE\r
+\r
+       procedureElements contains the description of the procedure.\r
+       (CREATE FUNCTIONS shares this lyout), see functionDefinition\r
+\r
+       0 - Object[] 3 element array for parameters\r
+       1 - TableName - specific name\r
+       2 - Integer - dynamic result set count\r
+       3 - String language (always java) - ignore\r
+       4 - String external name (also passed directly to create alias node - ignore\r
+       5 - Short parameter style (always java) - ignore \r
+       6 - Short - SQL allowed.\r
+       7 - Boolean - CALLED ON NULL INPUT (always TRUE for procedures)\r
+       8 - TypeDescriptor - return type (always NULL for procedures)\r
+*/\r
+\r
+StatementNode\r
+procedureDefinition() throws StandardException :\r
+{\r
+       TableName procedureName;\r
+       Object[] procedureElements = new Object[9];\r
+}\r
+{\r
+               <PROCEDURE> procedureName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+               procedureElements[0] = procedureParameterList()\r
+               ( routineElement(true, procedureElements) ) +\r
+               {\r
+                   checkRequiredRoutineClause(JAVA_ROUTINE_CLAUSES, procedureElements);\r
+\r
+                       return getCreateAliasNode(\r
+                                                       procedureName,\r
+                                                       (String) procedureElements[4],\r
+                                                       procedureElements,\r
+                                                       AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR,\r
+                                                       Boolean.FALSE);\r
+               }\r
+}\r
+\r
+void routineElement(boolean isProcedure, Object[] routineElements) throws StandardException :\r
+{\r
+       int drs;\r
+       int clausePosition = -1;\r
+       Object clauseValue = null;\r
+}\r
+{\r
+       (\r
+               <SPECIFIC> clauseValue = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+                       { clausePosition = 1; throw StandardException.newException(SQLState.NOT_IMPLEMENTED, "SPECIFIC identifier");}\r
+       |\r
+               [ <DYNAMIC> ] <RESULT> <SETS> drs = uint_value()\r
+               {\r
+                       if (!isProcedure)\r
+                               throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, "RESULT SETS");\r
+                       clauseValue = ReuseFactory.getInteger(drs); clausePosition = 2;\r
+               }\r
+       |\r
+               <LANGUAGE>  <JAVA> { clauseValue = "JAVA"; clausePosition = 3; }\r
+       |\r
+               <EXTERNAL> <NAME> clauseValue = string() { clausePosition = 4; }\r
+       |\r
+               <PARAMETER> <STYLE> clauseValue = parameterStyle() { clausePosition = 5; }\r
+\r
+       |       <NO> <SQL>                              { clauseValue = ReuseFactory.getShort(RoutineAliasInfo.NO_SQL); clausePosition = 6; }\r
+       |       <CONTAINS> <SQL>                { clauseValue = ReuseFactory.getShort(RoutineAliasInfo.CONTAINS_SQL); clausePosition = 6; }\r
+       |       <READS> <SQL> <DATA>    { clauseValue = ReuseFactory.getShort(RoutineAliasInfo.READS_SQL_DATA); clausePosition = 6; }\r
+       |       <MODIFIES> <SQL> <DATA>\r
+               {\r
+                       if (!isProcedure)\r
+                               throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR, "MODIFIES SQL DATA");\r
+                       clauseValue = ReuseFactory.getShort(RoutineAliasInfo.MODIFIES_SQL_DATA); clausePosition = 6;\r
+               }\r
+\r
+       |   clauseValue = calledOnNullInput(isProcedure) { clausePosition = 7; }\r
+       )\r
+\r
+       {\r
+               if (clausePosition != -1) {\r
+                       // check for repeated clause\r
+                       if (routineElements[clausePosition] != null) {\r
+\r
+                               String which = ROUTINE_CLAUSE_NAMES[clausePosition];\r
+                               throw StandardException.newException(SQLState.LANG_DB2_MULTIPLE_ELEMENTS, which);\r
+                       }\r
+                               \r
+                       routineElements[clausePosition] = clauseValue;\r
+               }\r
+       }\r
+}\r
+\r
+Boolean calledOnNullInput(boolean isProcedure) throws StandardException :\r
+{\r
+       Boolean calledOnNull;\r
+}\r
+{\r
+       (\r
+               <CALLED> { calledOnNull = Boolean.TRUE; }\r
+               | <RETURNS> <NULL> {\r
+                  if (isProcedure)\r
+                    throw StandardException.newException(SQLState.LANG_SYNTAX_ERROR,\r
+                            "RETURNS NULL ON NULL INPUT");\r
+                  \r
+                  calledOnNull = Boolean.FALSE;\r
+               }\r
+               \r
+       ) <ON> <NULL> <INPUT>\r
+       {\r
+               return calledOnNull;\r
+       }\r
+}\r
+\r
+Short parameterStyle() :\r
+{\r
+}\r
+{\r
+         <JAVA>               { return ReuseFactory.getShort(RoutineAliasInfo.PS_JAVA); }\r
+       }\r
+\r
+Object[]\r
+procedureParameterList() throws StandardException :\r
+{\r
+       Vector[] list = new Vector[3];\r
+       list[0] = new Vector(); // name\r
+       list[1] = new Vector(); // type\r
+       list[2] = new Vector(); // in/out\r
+}\r
+{\r
+       <LEFT_PAREN>\r
+               [ procedureParameterDefinition(list)\r
+                               ( <COMMA> procedureParameterDefinition(list) )* ]\r
+       <RIGHT_PAREN>\r
+       {\r
+               return list;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="Definition">procedureParameterDefinition</A>\r
+ */\r
+void\r
+procedureParameterDefinition(Vector[] list) throws StandardException :\r
+{\r
+       DataTypeDescriptor      typeDescriptor;\r
+       String                          parameterName = "";\r
+       Integer                         inout;\r
+}\r
+{\r
+       inout = inoutParameter()\r
+       \r
+       // Lookahead needed because token could satisfy identifier and dataTypeDDL\r
+       [   LOOKAHEAD( { commonDatatypeName(2, false) })\r
+           parameterName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       ]\r
+       typeDescriptor = dataTypeDDL() \r
+       {\r
+               list[0].addElement(parameterName);\r
+               list[1].addElement(typeDescriptor);\r
+               list[2].addElement(inout);\r
+       }\r
+}\r
+\r
+Integer\r
+inoutParameter() :\r
+{\r
+       int mode = JDBC30Translation.PARAMETER_MODE_IN;\r
+}\r
+{\r
+       [\r
+                 <IN> { }\r
+               | <OUT> { mode = JDBC30Translation.PARAMETER_MODE_OUT; }\r
+               | <INOUT> { mode = JDBC30Translation.PARAMETER_MODE_IN_OUT; }\r
+       ]\r
+       { return ReuseFactory.getInteger(mode); }\r
+}\r
+\r
+/**\r
+       CREATE FUNCTION\r
+\r
+       functionElements contains the description of the function.\r
+\r
+       0 - Object[] 3 element array for parameters\r
+       1 - TableName - specific name\r
+       2 - Integer - dynamic result set count - always 0\r
+       3 - String language (always java) - required to be set\r
+       4 - String external name (also passed directly to create alias node - ignore\r
+       5 - Short parameter style (always java) - required to be set \r
+       6 - Short - SQL allowed.\r
+       7 - Boolean - CALLED ON NULL INPUT\r
+       8 - TypeDescriptor - return type\r
+*/\r
+\r
+StatementNode\r
+functionDefinition() throws StandardException :\r
+{\r
+       TableName functionName;\r
+       Object[] functionElements = new Object[9];\r
+}\r
+{\r
+               <FUNCTION> functionName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+               functionElements[0] = functionParameterList()\r
+               <RETURNS> functionElements[8] = dataTypeCommon() \r
+               ( routineElement(false, functionElements) ) +\r
+               {\r
+                   checkRequiredRoutineClause(JAVA_ROUTINE_CLAUSES, functionElements);\r
+                   \r
+                       return getCreateAliasNode(\r
+                                                       functionName,\r
+                                                       (String) functionElements[4],\r
+                                                       functionElements,\r
+                                                       AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR,\r
+                                                       Boolean.FALSE);\r
+               }\r
+}\r
+\r
+Object[]\r
+functionParameterList() throws StandardException :\r
+{\r
+       Vector[] list = new Vector[3];\r
+       list[0] = new Vector(); // name\r
+       list[1] = new Vector(); // type\r
+       list[2] = new Vector(); // in/out - ALWAYS IN\r
+}\r
+{\r
+       <LEFT_PAREN>\r
+               [ functionParameterDefinition(list)\r
+                               ( <COMMA> functionParameterDefinition(list) )* ]\r
+       <RIGHT_PAREN>\r
+       {\r
+               return list;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="Definition">functionParameterDefinition</A>\r
+ */\r
+void\r
+functionParameterDefinition(Vector[] list) throws StandardException :\r
+{\r
+       DataTypeDescriptor      typeDescriptor;\r
+       String                          parameterName = "";\r
+       Integer                         inout;\r
+}\r
+{\r
+       // Lookahead needed because token could satisfy identifier and dataTypeDDL\r
+       [   LOOKAHEAD( { commonDatatypeName(2, false) })\r
+           parameterName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       ]\r
+       typeDescriptor = dataTypeDDL() \r
+       {\r
+               list[0].addElement(parameterName);\r
+               list[1].addElement(typeDescriptor);\r
+               list[2].addElement(ReuseFactory.getInteger(JDBC30Translation.PARAMETER_MODE_IN));\r
+       }\r
+}\r
+\r
+StatementNode\r
+viewDefinition(Token beginToken) throws StandardException :\r
+{\r
+       int                                     checkOptionType;\r
+       ResultColumnList        resultColumns = null;\r
+       ResultSetNode           queryExpression;\r
+       TableName                       tableName;\r
+       Token                           checkTok = null;\r
+       Token                           endToken;\r
+}\r
+{\r
+       <VIEW> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+               [ <LEFT_PAREN> resultColumns = viewColumnList() <RIGHT_PAREN> ]\r
+               <AS> queryExpression = queryExpression(null, NO_SET_OP)\r
+       {\r
+               checkOptionType = ViewDescriptor.NO_CHECK_OPTION;\r
+               endToken = getToken(0);\r
+               /* Parameters not allowed in create view */\r
+               HasNodeVisitor visitor = new HasNodeVisitor(ParameterNode.class);\r
+               queryExpression.accept(visitor);\r
+               if (visitor.hasNode())\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_NO_PARAMS_IN_VIEWS);\r
+               }\r
+\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.CREATE_VIEW_NODE,\r
+                                                               tableName, \r
+                                                               resultColumns, \r
+                                                               queryExpression,\r
+                                                               ReuseFactory.getInteger(checkOptionType),\r
+                                                               StringUtil.slice(statementSQLText,\r
+                                                                                               beginToken.beginOffset,\r
+                                                                                               endToken.endOffset,false),\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+ResultColumnList\r
+viewColumnList() throws StandardException :\r
+{\r
+       ResultColumnList        resultColumns = (ResultColumnList) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                       getContextManager());\r
+}\r
+{\r
+       /* RESOLVE: Passing null parameter for now just to keep Java happy */\r
+       columnNameList(resultColumns)\r
+       {\r
+               return resultColumns;\r
+       }\r
+}\r
+\r
+StatementNode\r
+triggerDefinition() throws StandardException :\r
+{\r
+       Boolean                         isBefore;\r
+       Boolean                         isRow = Boolean.FALSE;  // STATEMENT implicit by default\r
+       TableName                       tableName;\r
+       TableName                       triggerName;\r
+       Token[]                         tokenHolder = new Token[1];\r
+       Token                           beginToken;\r
+       Token                           checkTok = null;\r
+       Token                           endToken;\r
+       int                                     actionBegin;\r
+       int                                     actionEnd;\r
+       int                                     triggerEvent;\r
+       QueryTreeNode           actionNode;\r
+       ResultColumnList        triggerColumns = (ResultColumnList) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                       getContextManager());\r
+       Vector                          refClause = null;\r
+}\r
+{\r
+       <TRIGGER> triggerName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+       isBefore = beforeOrAfter()\r
+               triggerEvent = triggerEvent(triggerColumns)             // { INSERT | DELETE | UPDATE [ colList ] }\r
+               <ON> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+               [ refClause = triggerReferencingClause() ]              // REFERENCING OLD/NEW AS       \r
+               [ <FOR> <EACH> isRow = rowOrStatement() ]\r
+               [ <MODE> <DB2SQL> ]\r
+               //we are not top level statement\r
+               actionNode = proceduralStatement(tokenHolder)\r
+               // the trigger body\r
+       {\r
+               actionEnd = getToken(0).endOffset;\r
+               actionBegin = tokenHolder[0].beginOffset;\r
+\r
+               // No DML in action node for BEFORE triggers.\r
+               if (isBefore.booleanValue() && (actionNode instanceof DMLModStatementNode)) {\r
+                               throw StandardException.newException(\r
+                                       SQLState.LANG_UNSUPPORTED_TRIGGER_STMT,\r
+                                       ((StatementNode) actionNode).statementToString(), "BEFORE");\r
+                                       }\r
+\r
+\r
+               // no params in trigger action\r
+               HasNodeVisitor visitor = new HasNodeVisitor(ParameterNode.class);\r
+               actionNode.accept(visitor);\r
+               if (visitor.hasNode())\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_NO_PARAMS_IN_TRIGGER_ACTION);\r
+               }\r
+\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.CREATE_TRIGGER_NODE,\r
+                                                               triggerName, \r
+                                                               tableName,\r
+                                                               ReuseFactory.getInteger(triggerEvent),\r
+                                                               triggerColumns,\r
+                                                               isBefore,       \r
+                                                               isRow,\r
+                                                               Boolean.TRUE,                           // enabled\r
+                                                               refClause,                      // referencing clause\r
+                                                               null,// when clause node\r
+                                                               null,           // when clause text\r
+                                                               ReuseFactory.getInteger(0),\r
+                                                                                       // when clause begin offset\r
+                                                               actionNode,\r
+                                                               StringUtil.slice(statementSQLText,\r
+                                                                       actionBegin,\r
+                                                                       actionEnd,false),\r
+                                                               ReuseFactory.getInteger(actionBegin),\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+StatementNode\r
+synonymDefinition() throws StandardException :\r
+{\r
+       TableName synonymName;\r
+       TableName targetName;\r
+}\r
+{\r
+    <SYNONYM> synonymName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) <FOR>\r
+                targetName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+       {\r
+               checkVersion(DataDictionary.DD_VERSION_DERBY_10_1,\r
+                            "CREATE SYNONYM");\r
+\r
+               return  (StatementNode) getNodeFactory().getCreateAliasNode\r
+                       (\r
+                               synonymName,\r
+                               targetName,\r
+                               null,\r
+                               AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR,\r
+                               Boolean.FALSE,\r
+                               getContextManager()\r
+                       );\r
+       }\r
+}\r
+\r
+\r
+Boolean\r
+beforeOrAfter() :\r
+{}\r
+{\r
+       <NO> <CASCADE> <BEFORE> \r
+       {\r
+               return Boolean.TRUE;\r
+       }\r
+|      <AFTER>\r
+       {\r
+               return Boolean.FALSE;\r
+       }\r
+}\r
+\r
+int\r
+triggerEvent(ResultColumnList rcl) throws StandardException :\r
+{}\r
+{\r
+       <INSERT> \r
+       {\r
+               return TriggerDescriptor.TRIGGER_EVENT_INSERT;\r
+       }\r
+|      <DELETE>\r
+       {\r
+               return TriggerDescriptor.TRIGGER_EVENT_DELETE;\r
+       }\r
+|      <UPDATE> [ <OF> columnNameList(rcl) ]\r
+       {\r
+               return TriggerDescriptor.TRIGGER_EVENT_UPDATE;\r
+       }\r
+}\r
+\r
+Boolean\r
+rowOrStatement() :\r
+{\r
+}\r
+{\r
+       token = <ROW> \r
+       {\r
+               return Boolean.TRUE;\r
+       }\r
+|      token = <STATEMENT>\r
+       {\r
+               return Boolean.FALSE;\r
+       }\r
+}\r
+\r
+Vector\r
+triggerReferencingClause() throws StandardException :\r
+{\r
+       Vector vector = new Vector();\r
+}\r
+{\r
+       <REFERENCING> triggerReferencingExpression(vector) ( triggerReferencingExpression(vector) )*\r
+       {\r
+               return vector;\r
+       }\r
+}\r
+\r
+void\r
+triggerReferencingExpression(Vector vector) throws StandardException :\r
+{\r
+       String  identifier;\r
+       boolean isNew = true;\r
+       boolean isRow = true;\r
+}\r
+{\r
+       (\r
+         <NEW> \r
+         |\r
+         <OLD> {isNew = false;}\r
+         |\r
+         <NEW_TABLE> { isRow = false;}\r
+         |\r
+         <OLD_TABLE> { isNew = false; isRow = false;}\r
+       )\r
+\r
+       <AS> identifier = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               vector.addElement(new TriggerReferencingStruct(isRow, isNew, identifier));\r
+       }\r
+}\r
\r
+\r
+/*\r
+ * <A NAME="defaultClause">defaultClause</A>\r
+ */\r
+ValueNode\r
+defaultClause(long[] autoIncrementInfo, String columnName) throws StandardException :\r
+{\r
+       ValueNode       value;\r
+       Token           beginToken;\r
+       Token           endToken;\r
+}\r
+{\r
+       [ <WITH> ] beginToken = <_DEFAULT> value = defaultOption(beginToken, autoIncrementInfo, columnName)\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       value = generatedColumnOption(autoIncrementInfo)\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="defaultNullOnlyClause">defaultNullOnlyClause</A>\r
+ */\r
+ValueNode\r
+defaultNullOnlyClause() throws StandardException :\r
+{\r
+}\r
+\r
+{\r
+        <_DEFAULT> <NULL>\r
+        {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,\r
+                                                                       getContextManager());\r
+        }\r
+}\r
+\r
+/*\r
+ * <A NAME="generatedColumnOption">generatedColumnOption</A>\r
+ */\r
+\r
+//ToCleanUp\r
+//A specific class not such long[] should exists for autoIncrementInfo ...\r
+\r
+ValueNode\r
+generatedColumnOption(long[] autoIncrementInfo) throws StandardException :\r
+{\r
+       ValueNode       value = null;\r
+}\r
+{\r
+    {\r
+       autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_START_INDEX] = 1;\r
+       autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_INC_INDEX] = 1;\r
+       autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_IS_AUTOINCREMENT_INDEX] = 1;\r
+       autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_CREATE_MODIFY] = ColumnDefinitionNode.CREATE_AUTOINCREMENT;\r
+    }\r
+\r
+       <GENERATED> \r
+       (\r
+        <ALWAYS>  {\r
+               value = null;\r
+       }|\r
+        <BY> <_DEFAULT> { \r
+               checkVersion(DataDictionary.DD_VERSION_DERBY_10_1,\r
+                            "GENERATED BY DEFAULT");\r
+\r
+               value = (ValueNode) nodeFactory.getNode(C_NodeTypes.DEFAULT_NODE,\r
+                                                       getContextManager()) ;}\r
+       )\r
+       <AS> <IDENTITY> [<LEFT_PAREN> autoIncrementBeginEnd(autoIncrementInfo) <RIGHT_PAREN>]\r
+    {\r
+               return value;\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="autoIncrementBeginEnd">autoIncrementBeginEnd</A>\r
+ */\r
+void \r
+autoIncrementBeginEnd(long[] autoIncrementInfo) throws StandardException :\r
+{\r
+       long            autoIncrementInitial = 1;\r
+       long            autoIncrementIncrement = 1;\r
+}\r
+{\r
+        <INCREMENT> <BY> autoIncrementIncrement = exactNumber()\r
+    {\r
+               autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_INC_INDEX] = autoIncrementIncrement;\r
+               autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_CREATE_MODIFY] = ColumnDefinitionNode.CREATE_AUTOINCREMENT;\r
+               return;\r
+    }\r
+|\r
+               <START> <WITH> autoIncrementInitial = exactNumber() [<COMMA> <INCREMENT> <BY> autoIncrementIncrement = exactNumber() ]\r
+    {\r
+               autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_START_INDEX] = autoIncrementInitial;\r
+               autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_INC_INDEX] = autoIncrementIncrement;\r
+               autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_CREATE_MODIFY] = ColumnDefinitionNode.CREATE_AUTOINCREMENT;\r
+               return;\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="defaultOption">defaultOption</A>\r
+ */\r
+ValueNode\r
+defaultOption(Token beginToken, long[] autoIncrementInfo,\r
+       String columnName) throws StandardException :\r
+{\r
+       Token           endToken;\r
+       Token           errorTok = null;\r
+       Token           initialTok = null;\r
+       ValueNode       value;\r
+}\r
+{\r
+       //Look ahead required to tell NULL from a class name which starts with\r
+       // NULL (e.g., NULL::)\r
+       LOOKAHEAD( {getToken(1).kind == NULL && !(getToken(2).kind == PERIOD ||\r
+                       getToken(2).kind == DOUBLE_COLON)})\r
+       <NULL>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,\r
+                                                                       getContextManager());\r
+       }\r
+|\r
+       value = DB2DefaultOption(columnName)\r
+       {\r
+               endToken = getToken(0);\r
+               value.setBeginOffset( beginToken.beginOffset );\r
+               value.setEndOffset( endToken.endOffset );\r
+               value = (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.DEFAULT_NODE,\r
+                                                               value,\r
+                                                               StringUtil.slice(statementSQLText,\r
+                                                                       beginToken.beginOffset + 7,\r
+                                                                       endToken.endOffset,true),\r
+                                                               getContextManager()\r
+                                                       );\r
+               return value;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="DB2DefaultOption">DB2DefaultOption</A>\r
+ */\r
+ValueNode\r
+DB2DefaultOption(String columnName) throws StandardException :\r
+{\r
+       ValueNode       value;\r
+}\r
+{\r
+       // DB2 spec says default can only be one of the\r
+       // following: <constant>, <datetime-special-register> (ex.\r
+       // "current time"), CURRENT SCHEMA, USER, NULL, or\r
+       // <cast-function>.  We currently support all of these\r
+       // except the 'blob' function that is part of the DB2 valid\r
+       // <cast-function> grammar.  See beetle 5281 for plans\r
+       // support 'blob' function in future.\r
+\r
+       LOOKAHEAD({getToken(2).kind == SCHEMA || getToken(2).kind == SQLID}) \r
+       <CURRENT> (<SCHEMA> | <SQLID>)\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CURRENT_SCHEMA_NODE,\r
+                                               getContextManager());\r
+       }\r
+|\r
+       <USER>\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.USER_NODE,\r
+                                                               getContextManager());\r
+       }\r
+|\r
+       LOOKAHEAD({\r
+                               getToken(1).kind == DATE ||\r
+                getToken(1).kind == TIME ||\r
+                getToken(1).kind == TIMESTAMP\r
+                       })\r
+       value = miscBuiltins()\r
+       { // these functions are allowed as valid <cast-function> defaults.\r
+         // Once "BLOB" is allowed as a cast-function (5281), a case should be\r
+         // added for that, as well.\r
+               return value;\r
+       }\r
+|\r
+       LOOKAHEAD( {getToken(2).kind == LEFT_PAREN ||\r
+                      (getToken(4).kind == LEFT_PAREN && \r
+                       getToken(2).kind != COMMA)} ) \r
+               // Check against comma: see Derby-331 \r
+               // Before adding this, the following was erroneously\r
+               // flagged as invalid: \r
+               //         create table foo(.., b int default 0, unique (a))\r
+       value = miscBuiltins()\r
+       {\r
+               // If we have a function (as indicated by an open paren,\r
+               // which can be either the 2nd token (w/ normal function name)\r
+               // or the 4th token (w/ qualified function name)), then\r
+               // it's not valid.  Catch it here and throw an "invalid\r
+               // default" error (42894) instead of letting it go as\r
+               // a syntax error (this matches DB2 UDB behavior).\r
+               throw StandardException.newException(\r
+                       SQLState.LANG_DB2_INVALID_DEFAULT_VALUE,\r
+                       columnName);\r
+       }\r
+|\r
+       value = datetimeValueFunction()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       // Only (valid) thing left is literals (i.e. actual constants).\r
+       value = literal()\r
+       {\r
+               return value;\r
+       }\r
+\r
+}\r
+\r
+/*\r
+ * <A NAME="literal">literal</A>\r
+ */\r
+ValueNode\r
+literal() throws StandardException :\r
+{\r
+       String  sign = "";\r
+       Token   tok;\r
+       String  datetimeString;\r
+       String  bitString;\r
+       ValueNode               constantNode;\r
+}\r
+{\r
+       [ sign = sign() ] constantNode = numericLiteral(sign)\r
+       {\r
+               return constantNode;\r
+       }\r
+|\r
+       constantNode = stringLiteral()\r
+       {\r
+               return  constantNode;\r
+       }\r
+|\r
+       constantNode = hexLiteral()\r
+       {\r
+               return  constantNode;\r
+       }\r
+|\r
+       constantNode = dateTimeLiteral()\r
+       {\r
+               return constantNode;\r
+       }\r
+|\r
+       tok = booleanLiteral()\r
+       {\r
+               checkInternalFeature(tok.image);\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.BOOLEAN_CONSTANT_NODE,\r
+                                                                       StringUtil.SQLEqualsIgnoreCase(tok.image, "true") ?\r
+                                                                               Boolean.TRUE : Boolean.FALSE,\r
+                                                                       getContextManager());\r
+       }\r
+/*\r
+       JDBC and ODBC do not support the interval type, so let's not do it\r
+       ourselves for now.\r
+|\r
+       tok = <INTERVAL_LITERAL>\r
+       {\r
+               return nodeFactory.getIntervalNode(tok.image,\r
+                                       getTypeCompilationFactory(),\r
+                                       getContextManager());\r
+       }\r
+*/\r
+}\r
+\r
+/*\r
+ * <A NAME="numericLiteral">numericLiteral</A>\r
+ */\r
+ValueNode\r
+numericLiteral(String sign) throws StandardException :\r
+{\r
+       Token   tok;\r
+}\r
+{\r
+       tok = <EXACT_NUMERIC>\r
+       {\r
+               /*\r
+               ** The various java parse utilities can't handle leading +,\r
+               ** so only concatenate leading -.\r
+               */\r
+\r
+               String num = tok.image;\r
+\r
+               if (sign.equals("-"))\r
+                       num = sign.concat(num);\r
+\r
+               return getNumericNode(num);\r
+       }\r
+|\r
+       tok = <APPROXIMATE_NUMERIC>\r
+       {\r
+               StringBuffer doubleImage;\r
+               String doubleString;\r
+               int ePosn, dotPosn; // Position of letter e and '.' in value\r
+               Double          doubleValue;\r
+               \r
+               doubleImage = new StringBuffer(sign);\r
+               doubleImage.append(tok.image);\r
+               doubleString = doubleImage.toString();\r
+\r
+               ePosn = doubleString.indexOf('E');\r
+               if (ePosn == -1)\r
+                       ePosn = doubleString.indexOf('e');\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(ePosn != -1, "no E or e in approximate numeric");\r
+\r
+               // there is a limit on the length of a floatingpoint literal in DB2\r
+               if (doubleString.length() > Limits.DB2_MAX_FLOATINGPOINT_LITERAL_LENGTH)\r
+                       throw StandardException.newException(SQLState.LANG_DB2_TOO_LONG_FLOATING_POINT_LITERAL, doubleString, TypeId.DOUBLE_NAME);\r
+               // if there is no '.' before the e, put one in\r
+               dotPosn = doubleString.substring(0,ePosn).indexOf('.');\r
+               if (dotPosn == -1) {\r
+                       doubleImage.insert(ePosn,'.');\r
+                       doubleString = doubleImage.toString();\r
+                       ePosn++;\r
+               }\r
+\r
+               try\r
+               {\r
+                       doubleValue = Double.valueOf(doubleString);\r
+\r
+               }\r
+               catch (NumberFormatException nfe)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_FORMAT_EXCEPTION, TypeId.DOUBLE_NAME);\r
+               }\r
+\r
+               double dv = doubleValue.doubleValue();\r
+\r
+               // When the value is 0 it's possible rounded, try to detect it by checking if the mantissa is 0.0\r
+               //   "proof of correctness": any nonzero value (mantissa) with less than 30 characters will not be\r
+               //                           rounded to 0.0 by a float/real. This correctly detects the case when\r
+               //                           the radix/exponent being "too small" (1e-900) giving a value rounded to zero.\r
+               if ( (dv == 0.0d) && (Double.parseDouble(doubleString.substring(0, ePosn-1)) != 0.0d) )\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, TypeId.DOUBLE_NAME);\r
+               }\r
+\r
+               if (Double.isNaN(dv) || Double.isInfinite(dv))\r
+                       throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, TypeId.DOUBLE_NAME);\r
+\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.DOUBLE_CONSTANT_NODE,\r
+                                                                       doubleValue,\r
+                                                                       getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="dateTimeLiteral">dateTimeLiteral</A>\r
+ */\r
+ValueNode\r
+dateTimeLiteral() throws StandardException :\r
+{\r
+       ValueNode       constantNode;\r
+}\r
+{\r
+// RESOLVE: There is an incompatibility between Derby and DB2 here. The DB2 SQL parser does not recognize\r
+// JDBC date/time escapes. They are handled in a JDBC pre-processor. However embedded Derby does not have\r
+// a separate pre-processor. JDBC date/time escapes are handled by the Derby SQL parser. This will only\r
+// be visible if Derby is accessed through a non-JDBC pathway. (ODBC?) In that case Derby will allow\r
+// the JDBC date/time escape while DB2 will not.\r
+       (\r
+               ( <LEFT_BRACE> constantNode = escapedDateTimeLiteral() <RIGHT_BRACE> )\r
+       )\r
+       {\r
+               return constantNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="escapedDateTimeLiteral">escapedDateTimeLiteral</A>\r
+ */\r
+ValueNode\r
+escapedDateTimeLiteral() throws StandardException :\r
+{\r
+       ValueNode constantNode;\r
+}\r
+{\r
+       <D> constantNode = bareDateLiteral()\r
+       {\r
+               return constantNode;\r
+       }\r
+|\r
+       <T> constantNode = bareTimeLiteral()\r
+       {\r
+               return constantNode;\r
+       }\r
+|\r
+       <TS> constantNode = bareTimestampLiteral()\r
+       {\r
+               return constantNode;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="bareDateLiteral">bareDateLiteral</A>\r
+ */\r
+ValueNode\r
+bareDateLiteral() throws StandardException :\r
+{\r
+       String dateString;\r
+}\r
+{\r
+       dateString = string()\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.USERTYPE_CONSTANT_NODE,\r
+                                               getLanguageConnectionContext().getDataValueFactory().getDateValue(dateString, true),\r
+                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="bareTimeLiteral">bareTimeLiteral</A>\r
+ */\r
+ValueNode\r
+bareTimeLiteral() throws StandardException :\r
+{\r
+       String timeString;\r
+}\r
+{\r
+       timeString = string()\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.USERTYPE_CONSTANT_NODE,\r
+                                               getLanguageConnectionContext().getDataValueFactory().getTimeValue(timeString, true),\r
+                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="bareTimestampLiteral">bareTimestampLiteral</A>\r
+ */\r
+ValueNode\r
+bareTimestampLiteral() throws StandardException :\r
+{\r
+       String timestampString;\r
+}\r
+{\r
+       timestampString = string()\r
+       {\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.USERTYPE_CONSTANT_NODE,\r
+                                               getLanguageConnectionContext().getDataValueFactory().getTimestampValue(timestampString, true),\r
+                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="string">string</A>\r
+ */\r
+String\r
+string() throws StandardException :\r
+{\r
+       Token   tok;\r
+}\r
+{\r
+       tok = <STRING>\r
+       {\r
+               verifyImageLength(tok.image);\r
+               /* Trim off the leading and trailing ', and compress all '' to ' */\r
+               return compressQuotes(tok.image.substring(1, tok.image.length() - 1),\r
+                                                         SINGLEQUOTES);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="stringLiteral">stringLiteral</A>\r
+ */\r
+CharConstantNode\r
+stringLiteral() throws StandardException :\r
+{\r
+       Token   tok;\r
+       String  string;\r
+}\r
+{\r
+       tok = <STRING>\r
+       {\r
+               //there is a maximum limit on the length of the string\r
+               if (tok.image.length()-2 > Limits.DB2_MAX_CHARACTER_LITERAL_LENGTH)//-2 is for the beginning and ending quote\r
+                       throw StandardException.newException(SQLState.LANG_DB2_STRING_CONSTANT_TOO_LONG, StringUtil.formatForPrint(tok.image));\r
+               string = compressQuotes(tok.image.substring(1, tok.image.length() - 1), SINGLEQUOTES);\r
+               /* Trim quotes from string. */\r
+               return (CharConstantNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.CHAR_CONSTANT_NODE,\r
+                                                               string,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="hexLiteral">hexLiteral</A>\r
+ */\r
+ValueNode\r
+hexLiteral() throws StandardException :\r
+{\r
+       Token   tok;\r
+}\r
+{\r
+       tok = <HEX_STRING>\r
+       {\r
+               String hexLiteral = tok.image;\r
+\r
+               //there is a maximum limit on the length of the hex constant\r
+               if (hexLiteral.length()-3 > Limits.DB2_MAX_HEX_LITERAL_LENGTH)//-3 is for X' at the beginning and ' at the end\r
+                       throw StandardException.newException(SQLState.LANG_DB2_STRING_CONSTANT_TOO_LONG, StringUtil.formatForPrint(hexLiteral));\r
+               if ((hexLiteral.length()-3)%2 == 1)\r
+                       throw StandardException.newException(SQLState.LANG_DB2_INVALID_HEXADECIMAL_CONSTANT, StringUtil.formatForPrint(hexLiteral));\r
+\r
+               int bitLength = ((hexLiteral.length() - 3) / 2);\r
+               return (ValueNode)\r
+                               nodeFactory.getNode(C_NodeTypes.VARBIT_CONSTANT_NODE,\r
+                                                                       hexLiteral.substring(2, hexLiteral.length() - 1), ReuseFactory.getInteger(bitLength),\r
+                                                                       getContextManager());\r
+       }\r
+}\r
+\r
+\r
+TableName\r
+constraintNameDefinition() throws StandardException :\r
+{\r
+       TableName constraintName;\r
+}\r
+{\r
+       /* changed constraintName() to qualifiedName() for compaction */\r
+       <CONSTRAINT> constraintName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+       {\r
+               return constraintName;\r
+       }\r
+}\r
+\r
+/*\r
+ * DB2 requires column check constraints to refer to only that column. Derby\r
+ * doesn't care if check constraints are column level or table level. For DB2 compatibility\r
+ * check that column check constraints only refer to that column.\r
+ */\r
+ConstraintDefinitionNode\r
+checkConstraintDefinition(TableName constraintName, String columnName)\r
+                                                       throws StandardException :\r
+{  \r
+       Token           beginToken;\r
+       Token           endToken;\r
+       ValueNode       value;\r
+       ResultColumnList rclList = null;\r
+}\r
+{\r
+       /* valueExpression() was searchCondition() */\r
+       <CHECK>  beginToken = \r
+               <LEFT_PAREN> value = valueExpression(false) endToken = <RIGHT_PAREN>\r
+       {\r
+               if (columnName != null)\r
+               {\r
+                       /* Column check constraint */\r
+                       rclList = (ResultColumnList) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                       getContextManager());\r
+                       rclList.addElement((ResultColumn) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.RESULT_COLUMN,\r
+                                                                       columnName,\r
+                                                                       null,\r
+                                                                       getContextManager()));\r
+               }\r
+\r
+               value.setBeginOffset( beginToken.beginOffset );\r
+               value.setEndOffset( endToken.endOffset );\r
+               return (ConstraintDefinitionNode) nodeFactory.getNode(\r
+                                       C_NodeTypes.CONSTRAINT_DEFINITION_NODE,\r
+                                       constraintName,\r
+                                       ReuseFactory.getInteger(DataDictionary.CHECK_CONSTRAINT),\r
+                                       rclList,\r
+                                       null,\r
+                                       value,\r
+                                       StringUtil.slice(statementSQLText,\r
+                                               beginToken.beginOffset,\r
+                                               endToken.endOffset,true),\r
+                                       getContextManager()\r
+                                       );\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="spsRenameStatement">spsRenameStatement</A>\r
+ */\r
+StatementNode\r
+spsRenameStatement() throws StandardException :\r
+{\r
+       StatementNode qtn;\r
+}\r
+{\r
+       <RENAME> (\r
+               qtn = renameTableStatement() |\r
+               qtn = renameIndexStatement() |\r
+               qtn = renameColumnStatement()\r
+               )\r
+       {\r
+               return qtn;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="renameTableStatement">renameTableStatement</A>\r
+ */\r
+StatementNode\r
+renameTableStatement() throws StandardException :\r
+{\r
+       StatementNode qtn;\r
+       TableName tableName;\r
+       String newTableName;\r
+}\r
+{\r
+       <TABLE> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) <TO> newTableName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.RENAME_NODE,\r
+                                                               tableName,\r
+                                                               null,\r
+                                                               newTableName,\r
+                                                               Boolean.FALSE,\r
+                                                               ReuseFactory.getInteger(StatementType.RENAME_TABLE),\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="renameIndexStatement">renameIndexStatement</A>\r
+ */\r
+StatementNode\r
+renameIndexStatement() throws StandardException :\r
+{\r
+       String oldIndexName;\r
+       String newIndexName;\r
+}\r
+{\r
+       <INDEX> oldIndexName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) <TO> newIndexName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               StatementNode qtn = (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.RENAME_NODE,\r
+                                                               null,\r
+                                                               oldIndexName,\r
+                                                               newIndexName,\r
+                                                               Boolean.FALSE,\r
+ReuseFactory.getInteger(StatementType.RENAME_INDEX),\r
+                                                               getContextManager());\r
+\r
+               return qtn;\r
+\r
+       }\r
+}\r
+StatementNode\r
+renameColumnStatement() throws StandardException :\r
+{\r
+       String newColumnName;\r
+        ColumnReference oldColumnReference;\r
+}\r
+{\r
+       <COLUMN> oldColumnReference = columnReference()\r
+               <TO> newColumnName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               if (oldColumnReference.getTableNameNode() == null)\r
+                       throw StandardException.newException(\r
+                               SQLState.LANG_OBJECT_DOES_NOT_EXIST,\r
+                               "RENAME COLUMN",\r
+                               oldColumnReference.getColumnName());\r
+               return (StatementNode) nodeFactory.getNode(\r
+                       C_NodeTypes.RENAME_NODE,\r
+                       oldColumnReference.getTableNameNode(),\r
+                       oldColumnReference.getColumnName(),\r
+                       newColumnName,\r
+                       Boolean.FALSE,\r
+                       ReuseFactory.getInteger(StatementType.RENAME_COLUMN),\r
+                               getContextManager());\r
+       }\r
+}\r
+\r
+\r
+StatementNode\r
+lockStatement() throws StandardException :\r
+{\r
+       Boolean                                         exclusiveMode;\r
+       TableName                                       tableName;\r
+}\r
+{\r
+       <LOCK> <TABLE> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) <IN> exclusiveMode = lockMode() <MODE>\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.LOCK_TABLE_NODE,\r
+                                                               tableName,\r
+                                                               exclusiveMode,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+Boolean\r
+lockMode() :\r
+{\r
+}\r
+{\r
+       <EXCLUSIVE>\r
+       {\r
+               return Boolean.TRUE;\r
+       }\r
+|\r
+       <SHARE>\r
+       {\r
+               return Boolean.FALSE;\r
+       }\r
+}\r
+\r
+StatementNode\r
+execStatement() throws StandardException :\r
+{\r
+       TableName       stmtName;\r
+}\r
+{\r
+       <EXECUTE> <STATEMENT> stmtName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.EXEC_SPS_NODE,\r
+                                                               stmtName,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+TransactionStatementNode\r
+setIsolationStatement() throws StandardException :\r
+{\r
+       TransactionStatementNode tranNode;\r
+}\r
+{\r
+       setIsolationHeader() [ ( <EQUALS_OPERATOR> | <TO> ) ] tranNode = transactionMode()\r
+       {\r
+               return tranNode;\r
+       }\r
+}\r
+\r
+void\r
+setIsolationHeader() throws StandardException :\r
+{}\r
+{\r
+       <ISOLATION>\r
+|\r
+        LOOKAHEAD( { getToken(1).kind == CURRENT && getToken(2).kind == ISOLATION } )\r
+       <CURRENT> <ISOLATION>\r
+}\r
+\r
+\r
+TransactionStatementNode\r
+transactionMode() throws StandardException :\r
+{\r
+       int isolationLevel;\r
+}\r
+{\r
+       isolationLevel = isolationLevelDB2OrReset() \r
+       {\r
+               return (TransactionStatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.SET_TRANSACTION_ISOLATION_NODE,\r
+                                                               ReuseFactory.getInteger(isolationLevel),\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+int\r
+isolationLevelDB2OrReset() :\r
+{\r
+       int isolationLevel;\r
+}\r
+{\r
+        (\r
+                <RESET> { return ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL; }\r
+                | isolationLevel = isolationLevelDB2() { return isolationLevel; }\r
+        )\r
+}\r
+\r
+int\r
+isolationLevelDB2() :\r
+{\r
+        int isolationLevel;\r
+}\r
+{\r
+       (\r
+                isolationLevel = isolationLevelDB2Abbrev() { return isolationLevel; }\r
+                | ( ( <REPEATABLE> <READ> ) | <SERIALIZABLE> )\r
+                        { return ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL; }\r
+               | <CURSOR> <STABILITY>\r
+                        { return ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL; }\r
+\r
+               | <DIRTY> <READ>\r
+                        { return ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL; }\r
+\r
+               |\r
+                        LOOKAHEAD( { getToken(1).kind == READ && getToken(2).kind == COMMITTED } )\r
+                        <READ> <COMMITTED>\r
+                        { return ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL; }\r
+\r
+               |\r
+                        LOOKAHEAD( { getToken(1).kind == READ && getToken(2).kind == UNCOMMITTED } )\r
+                        <READ> <UNCOMMITTED>\r
+                        { return ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL; }\r
+       )\r
+}\r
+\r
+int\r
+isolationLevelDB2Abbrev() :\r
+{\r
+}\r
+{\r
+       (\r
+               <RR>\r
+                        { return ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL; }\r
+\r
+               | <RS> { return ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL; }\r
+\r
+               | <CS>\r
+                        { return ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL; }\r
+\r
+               | <UR>\r
+                        { return ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL; }\r
+       )\r
+}\r
+\r
+\r
+int\r
+isolationLevel() :\r
+{\r
+       int isolationLevel;\r
+}\r
+{\r
+       <ISOLATION> <LEVEL> isolationLevel = levelOfIsolation()\r
+       {\r
+               return isolationLevel;\r
+       }\r
+}\r
+\r
+int\r
+levelOfIsolation() :\r
+{\r
+}\r
+{\r
+       <READ>\r
+       {\r
+               return levelOfIsolationRead();\r
+       }\r
+| \r
+    <REPEATABLE> <READ>\r
+    {\r
+               return ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL;\r
+    }\r
+|\r
+       <SERIALIZABLE>\r
+       {\r
+               return ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL;\r
+       }\r
+}\r
+\r
+int\r
+levelOfIsolationRead() :\r
+{\r
+}\r
+{\r
+       <UNCOMMITTED> \r
+       {\r
+               return ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL;\r
+       }\r
+|\r
+       <COMMITTED> \r
+       {\r
+               return ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL;\r
+       }\r
+}\r
+\r
+\r
+/*\r
+ * <A NAME="simpleValueSpecification">simpleValueSpecification</A>\r
+ */\r
+ValueNode\r
+simpleValueSpecification() throws StandardException :\r
+{\r
+       ValueNode       value;\r
+}\r
+{\r
+       value = literal()\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+\r
+StatementNode\r
+setSchemaStatement() throws StandardException :\r
+{\r
+       StatementNode setSchema;\r
+}\r
+{\r
+       setSchemaHeader() [<EQUALS_OPERATOR>] setSchema = setSchemaValues()\r
+       {\r
+               if (parameterList != null && parameterList.size() > 0)\r
+               {\r
+                       setUpAndLinkParameters();\r
+                       // set the type of parameter node, it should be a varchar max Limits.MAX_IDENTIFIER_LENGTH - non nullable\r
+                       ParameterNode p = (ParameterNode)parameterList.elementAt(0);\r
+                       p.setType(new DataTypeDescriptor(TypeId.getBuiltInTypeId(Types.VARCHAR), false, Limits.MAX_IDENTIFIER_LENGTH));\r
+               }\r
+               return setSchema;\r
+       }\r
+}\r
+\r
+void \r
+setSchemaHeader() throws StandardException :\r
+{}\r
+{\r
+       <SCHEMA>\r
+|\r
+        LOOKAHEAD( { getToken(1).kind == CURRENT && ( getToken(2).kind == SCHEMA ||  getToken(2).kind == SQLID ) } )\r
+       <CURRENT> ( <SCHEMA>  | <SQLID> )\r
+}\r
+\r
+StatementNode\r
+setSchemaValues() throws StandardException :\r
+{\r
+       String schemaName;\r
+}\r
+{\r
+       schemaName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.SET_SCHEMA_NODE,\r
+                                                               schemaName,\r
+                                                               null,\r
+                                                               getContextManager());\r
+       }\r
+|\r
+       <USER>\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.SET_SCHEMA_NODE,\r
+                                                               null,\r
+                                                               ReuseFactory.getInteger(StatementType.SET_SCHEMA_USER),\r
+                                                               getContextManager());\r
+       }\r
+|   dynamicParameterSpecification()\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.SET_SCHEMA_NODE,\r
+                                                               null,\r
+                                                               ReuseFactory.getInteger(StatementType.SET_SCHEMA_DYNAMIC),\r
+                                                               getContextManager());\r
+       }\r
+|      schemaName = string()\r
+       {\r
+               /* Max length for schema name is Limits.MAX_IDENTIFIER_LENGTH */\r
+               checkIdentifierLengthLimit(schemaName, Limits.MAX_IDENTIFIER_LENGTH);\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.SET_SCHEMA_NODE,\r
+                                                               schemaName,\r
+                                                               null,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+\r
+\r
+// Set the locale for messages coming from the database system. This\r
+// is for support only, so we can get messages in our preferred language\r
+// (usually English). I didn't want to create all the execution wiring\r
+// to do this, so this command executes in the parser\r
+StatementNode\r
+setMessageLocaleStatement() throws StandardException :\r
+{\r
+       String messageLocale;\r
+}\r
+{\r
+       <MESSAGE_LOCALE> messageLocale = string()\r
+       {\r
+               getContextManager().setMessageLocale(messageLocale);\r
+\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.NOP_STATEMENT_NODE,\r
+                                                                                       getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="valueSpecification">valueSpecification</A>\r
+ */\r
+ValueNode\r
+valueSpecification() throws StandardException :\r
+{\r
+       ValueNode          value;\r
+       ValueNode          leftExpression;\r
+       ValueNode          rightExpression;\r
+}\r
+{\r
+       value = literal()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       value = generalValueSpecification()\r
+       {\r
+               return value;\r
+       }\r
+|\r
+       <NULLIF> <LEFT_PAREN> leftExpression = additiveExpression(null, 0, false) <COMMA> rightExpression = additiveExpression(null, 0, false) <RIGHT_PAREN>\r
+       {\r
+               // "NULLIF(L, R)" is the same as "L=R ? untyped NULL : L"\r
+               // An impl assumption here is that Derby can promote CHAR to any comparable datatypes such as numeric\r
+               ContextManager cm = getContextManager();\r
+               ValueNodeList thenElseList = (ValueNodeList) nodeFactory.getNode(C_NodeTypes.VALUE_NODE_LIST, cm);\r
+\r
+               //Use untyped null for then clause at this point. At the bind time, we will cast it to the datatype of L \r
+               thenElseList.addElement((ValueNode) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,\r
+                                                                       cm));\r
+               thenElseList.addElement(leftExpression);\r
+\r
+               return (ValueNode) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.CONDITIONAL_NODE,\r
+                                                                                       (ValueNode) nodeFactory.getNode(\r
+                                                                                                               C_NodeTypes.BINARY_EQUALS_OPERATOR_NODE,\r
+                                                                                                               leftExpression,\r
+                                                                                                               rightExpression,\r
+                                                                                                               cm),\r
+                                                                                       thenElseList,\r
+                                                                                       Boolean.TRUE,//this node is for nullif \r
+                                                                                       cm);\r
+       }\r
+|\r
+       // CASE WHEN P1 THEN [T1 | NULL] (WHEN Pi THEN [Ti | NULL])* [ELSE E | NULL] END\r
+       <CASE> value = whenThenExpression()\r
+       {\r
+               return value;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="caseExpression">caseExpression</A>\r
+ */\r
+ValueNode\r
+caseExpression() throws StandardException :\r
+{\r
+       ValueNode          expr;\r
+}\r
+{\r
+       <END>\r
+       {\r
+               ValueNode value = (ValueNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.CAST_NODE,\r
+                                                                               (ValueNode) nodeFactory.getNode(C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,\r
+                                                                                                                                               getContextManager()),\r
+                                                                               DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CHAR, 1), \r
+                                                                               getContextManager());\r
+               ((CastNode) value).setForExternallyGeneratedCASTnode();\r
+               return value;\r
+       }\r
+|\r
+       <ELSE> expr = thenElseExpression() <END>\r
+       {\r
+               return expr;\r
+       }\r
+|\r
+       expr = whenThenExpression()\r
+       {\r
+               return expr;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="whenThenExpression">whenThenExpression</A>\r
+ */\r
+ValueNode\r
+whenThenExpression() throws StandardException :\r
+{\r
+       ValueNode          expr;\r
+       ValueNode          thenExpr;\r
+       ValueNode          elseExpr;\r
+}\r
+{\r
+       <WHEN> expr = orExpression(null, false) \r
+                  (<OR> expr = orExpression(expr, false) )*\r
+       <THEN> thenExpr = thenElseExpression()\r
+       elseExpr = caseExpression()\r
+       {\r
+               ContextManager cm = getContextManager();\r
+               ValueNodeList thenElseList = (ValueNodeList) nodeFactory.getNode(C_NodeTypes.VALUE_NODE_LIST, cm);\r
+               thenElseList.addElement(thenExpr); // then\r
+               thenElseList.addElement(elseExpr); // else\r
+\r
+               return((ValueNode) nodeFactory.getNode(C_NodeTypes.CONDITIONAL_NODE,\r
+                                                                                               expr,\r
+                                                                                               thenElseList,\r
+                                                                                               Boolean.FALSE,\r
+                                                                                               cm));\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="thenElseExpression">thenElseExpression</A>\r
+ */\r
+ValueNode\r
+thenElseExpression() throws StandardException :\r
+{\r
+       ValueNode          expr;\r
+}\r
+{      \r
+       LOOKAHEAD ( {getToken(1).kind == NULL} )\r
+       <NULL>\r
+       {\r
+               ValueNode value = (ValueNode) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.CAST_NODE,\r
+                                                                               (ValueNode) nodeFactory.getNode(C_NodeTypes.UNTYPED_NULL_CONSTANT_NODE,\r
+                                                                                                                                               getContextManager()),\r
+                                                                               DataTypeDescriptor.getBuiltInDataTypeDescriptor(Types.CHAR, 1), \r
+                                                                               getContextManager());\r
+               ((CastNode) value).setForExternallyGeneratedCASTnode();\r
+               return value;\r
+       }\r
+|\r
+       expr = additiveExpression(null, 0, false)\r
+       {\r
+               return expr;\r
+       }\r
+}\r
+\r
+TableElementNode\r
+tableConstraintDefinition() throws StandardException :\r
+{\r
+       Properties properties = null;\r
+       ConstraintDefinitionNode tcdn;\r
+       TableName               constraintName = null;\r
+       //initialize following two booleans before handling table level constraints\r
+       explicitNotNull = false;\r
+       explicitNull = false;\r
+}\r
+{\r
+       [ constraintName = constraintNameDefinition() ] \r
+               tcdn = tableConstraint(constraintName) \r
+               [ properties = propertyList(false) <CHECK_PROPERTIES>]\r
+       {\r
+               if (properties != null)\r
+               {\r
+                       tcdn.setProperties(properties);\r
+               }\r
+               return tcdn;\r
+       }\r
+}\r
+\r
+ConstraintDefinitionNode\r
+tableConstraint(TableName constraintName) throws StandardException :\r
+{\r
+       ConstraintDefinitionNode tcdn;\r
+}\r
+{\r
+       tcdn = uniqueConstraintDefinition(constraintName) \r
+       {\r
+               return tcdn;\r
+       }\r
+|\r
+       tcdn = referentialConstraintDefinition(constraintName) \r
+       {\r
+               return tcdn;\r
+       }\r
+|\r
+       tcdn = checkConstraintDefinition(constraintName, null)\r
+       {\r
+               return tcdn;\r
+       }\r
+}\r
+\r
+ConstraintDefinitionNode\r
+uniqueConstraintDefinition(TableName constraintName) throws StandardException :\r
+{\r
+       int constraintType;\r
+       ResultColumnList uniqueColumnList;\r
+}\r
+{\r
+       //for table level constraint, second parameter will be null\r
+       constraintType = uniqueSpecification((DataTypeDescriptor) null, null) \r
+               <LEFT_PAREN> uniqueColumnList = uniqueColumnList() <RIGHT_PAREN>\r
+       {\r
+               //go through the unique columns list and if any of the columns in the\r
+               //list is explicitly defined null, throw an exception for this. Columns\r
+               //for which no nullability is defined are by default nullable. But in\r
+               //case of create table, there nullability changes automatically to \r
+               //non-nullable if primary key is defined on it. But if user explicitly\r
+               //defines the nullability, then defining a primary key on it in create\r
+               //table will result in an exception.\r
+               if (constraintType ==  DataDictionary.PRIMARYKEY_CONSTRAINT)\r
+               {\r
+                       for (int index = 0; index < uniqueColumnList.size(); index++)\r
+                       {\r
+                               String primaryKeyColumnName = ((ResultColumn) uniqueColumnList.elementAt(index)).getName();\r
+                               if (explicitlyNullableColumnsList.contains(primaryKeyColumnName))\r
+                               {\r
+                                       String errorState = SQLState.LANG_DB2_ADD_UNIQUE_OR_PRIMARY_KEY_ON_NULL_COLS;\r
+                                       throw StandardException.newException(errorState, primaryKeyColumnName);\r
+                               }\r
+                       }\r
+               }\r
+               return (ConstraintDefinitionNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CONSTRAINT_DEFINITION_NODE,\r
+                                               constraintName,\r
+                                               ReuseFactory.getInteger(constraintType),\r
+                                               uniqueColumnList,\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               getContextManager()\r
+                                               );\r
+       }\r
+}\r
+\r
+//the second parameter to the following method will always be null for a table level\r
+//constraint but not for a column level constraint\r
+int\r
+uniqueSpecification(DataTypeDescriptor dataTypeDescriptor,\r
+String columnName) throws StandardException :\r
+{\r
+}\r
+{\r
+       <UNIQUE> \r
+       {\r
+               return DataDictionary.UNIQUE_CONSTRAINT;\r
+       }\r
+|\r
+       <PRIMARY> <KEY>\r
+       {\r
+               //explicitNull can be true only if it's column level constraint and\r
+               //that column has null constraint defined on it. In that case, defining\r
+               //a column-level constraint of primary key on it will result in an error.\r
+               if (explicitNull) \r
+               {\r
+                       String errorState = SQLState.LANG_DB2_ADD_UNIQUE_OR_PRIMARY_KEY_ON_NULL_COLS;\r
+                       throw StandardException.newException(errorState, columnName);\r
+               }\r
+               return DataDictionary.PRIMARYKEY_CONSTRAINT;\r
+       }\r
+}\r
+\r
+ResultColumnList\r
+uniqueColumnList() throws StandardException :\r
+{\r
+       ResultColumnList        resultColumns = (ResultColumnList) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                       getContextManager());\r
+}\r
+{\r
+       columnNameList(resultColumns)\r
+       {\r
+               return resultColumns;\r
+       }\r
+}\r
+\r
+ConstraintDefinitionNode\r
+referentialConstraintDefinition(TableName constraintName) throws StandardException :\r
+{\r
+       ResultColumnList fkRcl = (ResultColumnList) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                               getContextManager());\r
+       ResultColumnList refRcl = (ResultColumnList) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                               getContextManager());\r
+       TableName referencedTable;\r
+       int[] refActions = {StatementType.RA_NOACTION, \r
+                           StatementType.RA_NOACTION}; //default values\r
+}\r
+{\r
+       <FOREIGN> <KEY> <LEFT_PAREN> columnNameList(fkRcl) <RIGHT_PAREN>\r
+               referencedTable = referencesSpecification(refRcl, refActions)\r
+       {\r
+               return (ConstraintDefinitionNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.FK_CONSTRAINT_DEFINITION_NODE,\r
+                                               constraintName,\r
+                                               referencedTable,\r
+                                               fkRcl,\r
+                                               refRcl,\r
+                                               refActions,\r
+                                               getContextManager());\r
+       }\r
+}\r
+\r
+TableName\r
+referencesSpecification(ResultColumnList rcl, int[] refActions) throws StandardException :\r
+{\r
+       TableName tableName = null;\r
+}\r
+{\r
+       <REFERENCES> tableName = referencedTableAndColumns(rcl)\r
+               // not supporting MATCH or referential actions beyond syntax for default\r
+               [ <ON> referentialTriggeredAction(refActions) ]\r
+       {\r
+               return tableName;\r
+       }\r
+}\r
+\r
+TableName\r
+referencedTableAndColumns(ResultColumnList rcl) throws StandardException :\r
+{\r
+       TableName       tableName = null;\r
+}\r
+{\r
+       tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) [ <LEFT_PAREN> columnNameList(rcl) <RIGHT_PAREN> ]\r
+       {\r
+               return tableName;\r
+       }\r
+}\r
+\r
+void\r
+referentialTriggeredAction(int [] refActions) throws StandardException :\r
+{}\r
+{\r
+       ( refActions[1] = updateRule() [<ON> refActions[0] = deleteRule() ] |\r
+       refActions[0] = deleteRule() [<ON> refActions[1] = updateRule() ] )\r
+}\r
+\r
+int\r
+updateRule() :\r
+{\r
+       int action;\r
+}\r
+{\r
+       <UPDATE> action = updateReferentialAction()\r
+       {\r
+               return action;\r
+       }\r
+}\r
+\r
+int\r
+deleteRule()  :\r
+{\r
+       int action;\r
+}\r
+{\r
+       <DELETE> action = deleteReferentialAction()\r
+       {\r
+               return action;\r
+       }\r
+\r
+}\r
+\r
+int\r
+updateReferentialAction() :\r
+{}\r
+{\r
+       \r
+         <RESTRICT> {return StatementType.RA_RESTRICT;}\r
+       | <NO> <ACTION> {return StatementType.RA_NOACTION;}\r
+\r
+}\r
+\r
+int\r
+deleteReferentialAction() :\r
+{}\r
+{\r
+       <CASCADE> {return StatementType.RA_CASCADE;}   \r
+       | <RESTRICT> {return StatementType.RA_RESTRICT;} \r
+       | <NO> <ACTION> {return StatementType.RA_NOACTION;}\r
+       | <SET> \r
+          (  <NULL> {return StatementType.RA_SETNULL;}    \r
+              |<_DEFAULT>  {return StatementType.RA_SETDEFAULT;}\r
+          )\r
+}\r
+\r
+/*\r
+ * <A NAME="columnConstraintDefinition">columnConstraintDefinition</A>\r
+ */\r
+void\r
+columnConstraintDefinition(DataTypeDescriptor dataTypeDescriptor,\r
+                                                  TableElementList tableElementList,\r
+                                                  String columnName) throws StandardException :\r
+{\r
+       int constraintType;\r
+       TableElementNode tcdn;\r
+       TableName constraintName = null;\r
+}\r
+{\r
+       [ constraintName = constraintNameDefinition() ]\r
+               tcdn = columnConstraint(constraintName, dataTypeDescriptor, columnName)\r
+       {\r
+               /* NOT NULL constraints are handled by marking the dataTypeDescriptor\r
+                * as being non-nullable.\r
+                */\r
+               if (tcdn == null)\r
+               {\r
+                       return;\r
+               }\r
+\r
+               /* All other constraints, whether column or table will be added as\r
+                * table constraints.  We do this to facilitate the handling of\r
+                * multiple column constraints on the same column.\r
+                */\r
+               tableElementList.addTableElement(tcdn);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="columnConstraint">columnConstraint</A>\r
+ */\r
+ConstraintDefinitionNode\r
+columnConstraint(TableName constraintName,\r
+                                DataTypeDescriptor dataTypeDescriptor,\r
+                                String columnName) throws StandardException :\r
+{\r
+       int constraintType;\r
+       Properties properties = null;\r
+       ConstraintDefinitionNode tcdn;\r
+       ResultColumnList refRcl = (ResultColumnList) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                               getContextManager());\r
+       TableName referencedTable;\r
+       int[] refActions = {StatementType.RA_NOACTION,\r
+                            StatementType.RA_NOACTION} ; //default: NO ACTION\r
+}\r
+{\r
+       <NOT> <NULL>\r
+       {\r
+               //if column is explicitly defined not nullable, set following flag\r
+               explicitNotNull = true;\r
+               //if both null and not null constraints are defined for a column,\r
+               //throw an exception\r
+               if (explicitNull) \r
+                   throw StandardException.newException(SQLState.LANG_ADDING_COLUMN_WITH_NULL_AND_NOT_NULL_CONSTRAINT, columnName); \r
+               dataTypeDescriptor.setNullability(false);\r
+               return null;\r
+       }\r
+|\r
+       //pass the columnname as the second parameter. It will be used to throw an\r
+       //exception if null constraint is defined for this column-level primary \r
+       //key constraint\r
+       constraintType = uniqueSpecification(dataTypeDescriptor,columnName)\r
+               [ properties = propertyList(false) <CHECK_PROPERTIES>]\r
+       {\r
+               ResultColumnList uniqueColumnList =\r
+                                                                               (ResultColumnList) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                               getContextManager());\r
+               uniqueColumnList.addElement(\r
+                       (ResultColumn) nodeFactory.getNode(\r
+                                                       C_NodeTypes.RESULT_COLUMN,\r
+                                                       columnName,\r
+                                                       null,\r
+                                                       getContextManager()));\r
+\r
+               return (ConstraintDefinitionNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CONSTRAINT_DEFINITION_NODE,\r
+                                               constraintName,\r
+                                               ReuseFactory.getInteger(constraintType),\r
+                                               uniqueColumnList,\r
+                                               properties,\r
+                                               null,\r
+                                               null,\r
+                                               getContextManager()\r
+                                               );\r
+       }\r
+|      \r
+       referencedTable = referencesSpecification(refRcl, refActions)\r
+               [ properties = propertyList(false)<CHECK_PROPERTIES>] \r
+       {\r
+               ResultColumnList fkRcl = (ResultColumnList) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                       getContextManager());\r
+               fkRcl.addElement(\r
+                                       (ResultColumn) nodeFactory.getNode(\r
+                                                                       C_NodeTypes.RESULT_COLUMN,\r
+                                                                       columnName,\r
+                                                                       null,\r
+                                                                       getContextManager())\r
+                               );\r
+               tcdn = (ConstraintDefinitionNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.FK_CONSTRAINT_DEFINITION_NODE,\r
+                                               constraintName,\r
+                                               referencedTable,\r
+                                               fkRcl,\r
+                                               refRcl,\r
+                                               refActions,\r
+                                               getContextManager());\r
+               if (properties != null)\r
+               {\r
+                       tcdn.setProperties(properties);\r
+               }\r
+               return tcdn;\r
+       }\r
+|\r
+       tcdn = checkConstraintDefinition(constraintName, columnName)\r
+       {\r
+               return tcdn;\r
+       }\r
+}\r
+\r
+StatementNode\r
+dropSchemaStatement() throws StandardException :\r
+{\r
+       String schemaName;\r
+}\r
+{\r
+       <SCHEMA> schemaName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) <RESTRICT>\r
+       {\r
+               StatementNode stmt =  (StatementNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.DROP_SCHEMA_NODE,\r
+                                                       schemaName,\r
+                                                       new Integer(StatementType.DROP_RESTRICT),\r
+                                                       getContextManager());\r
+\r
+               return stmt;\r
+       }\r
+}\r
+\r
+StatementNode\r
+alterTableStatement() throws StandardException :\r
+{\r
+       StatementNode           node;\r
+       TableName                       tableName;\r
+}\r
+{\r
+       <TABLE> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) node = alterTableBody(tableName)\r
+       {\r
+               return node;\r
+       }\r
+}\r
+\r
+StatementNode\r
+alterTableBody(TableName tableName) throws StandardException :\r
+{\r
+       StatementNode qtn;\r
+       char                            lockGranularity = '\0';\r
+       String               newTableName;\r
+       TableElementList        tableElementList =\r
+                                                                       (TableElementList) nodeFactory.getNode(\r
+                                                                                               C_NodeTypes.TABLE_ELEMENT_LIST,\r
+                                                                                               getContextManager());\r
+       Token                           tok = null;\r
+       int[]                           changeType = new int[1];\r
+       int[]                           behavior = new int[1];\r
+       boolean[]                       sequential = new boolean[1];\r
+}\r
+{\r
+//insert special key before compress so that only internal SP can know\r
+       <COMPRESS> [ tok = <SEQUENTIAL> ]\r
+       {               \r
+               checkInternalFeature("COMPRESS");\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.ALTER_TABLE_NODE,\r
+                                                       tableName,\r
+                                                       new Boolean(tok != null),\r
+                                                       getContextManager());\r
+       }\r
+|\r
+       lockGranularity = alterTableAction( tableElementList, changeType, behavior, sequential )\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.ALTER_TABLE_NODE,\r
+                                                       tableName,\r
+                                                       tableElementList,\r
+                                                       new Character(lockGranularity),\r
+                                                       changeType,\r
+                                                       behavior,\r
+                                                       sequential,\r
+                                                       getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="alterTableRenameTableStatement">alterTableRenameTableStatement</A>\r
+ */\r
+/*\r
+StatementNode\r
+alterTableRenameTableStatement(TableName tableName) throws StandardException :\r
+{\r
+       String newTableName;\r
+}\r
+{\r
+       <TO> newTableName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.RENAME_NODE,\r
+                                                       tableName,\r
+                                                       null,\r
+                                                       newTableName,\r
+                                                       Boolean.TRUE,\r
+ReuseFactory.getInteger(StatementType.RENAME_TABLE),\r
+                                                       getContextManager());\r
+       }\r
+}\r
+*/\r
+\r
+/*\r
+ * <A NAME="alterTableRenameColumnStatement">alterTableRenameColumnStatement</A>\r
+ */\r
+/*\r
+StatementNode\r
+alterTableRenameColumnStatement(TableName tableName) throws StandardException :\r
+{\r
+       String oldColumnName;\r
+       String newColumnName;\r
+}\r
+{\r
+       oldColumnName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) <TO> newColumnName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.RENAME_NODE,\r
+                                                       tableName,\r
+                                                       oldColumnName,\r
+                                                       newColumnName,\r
+                                                       Boolean.TRUE,\r
+ReuseFactory.getInteger(StatementType.RENAME_COLUMN),\r
+                                                       getContextManager());\r
+       }\r
+}\r
+*/\r
+char\r
+alterTableAction(TableElementList tableElementList, int[] changeType, int[] behavior, boolean[] sequential) throws StandardException :\r
+{\r
+       char                            lockGranularity = '\0';\r
+       TableElementNode        tableElement;\r
+       DataTypeDescriptor      typeDescriptor;\r
+       Token                           tok = null;\r
+       String                          columnName;\r
+       long[]                          autoIncrementInfo = new long[4];\r
+}\r
+{\r
+       <ADD>\r
+       (\r
+               tableElement = addColumnDefinition(tableElementList)\r
+               |\r
+               tableElement = tableConstraintDefinition()\r
+       )\r
+       {\r
+               if (tableElement instanceof ColumnDefinitionNode)\r
+               {\r
+                       //bug 5724 - auto increment columns not allowed in ALTER TABLE statement\r
+                       ColumnDefinitionNode cdn = (ColumnDefinitionNode) tableElement;\r
+                       if ( cdn.isAutoincrementColumn())\r
+                               throw StandardException.newException(SQLState.LANG_ALTER_TABLE_AUTOINCREMENT_COLUMN_NOT_ALLOWED);\r
+               }\r
+               changeType[0] = DDLStatementNode.ADD_TYPE;\r
+               tableElementList.addTableElement(tableElement);\r
+               return lockGranularity;\r
+       }\r
+|\r
+       <ALTER> [ <COLUMN> ] columnName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true) \r
+               tableElement = columnAlterClause(columnName)\r
+       {\r
+               changeType[0] = DDLStatementNode.MODIFY_TYPE;\r
+               tableElementList.addTableElement(tableElement);\r
+               return lockGranularity;\r
+       }\r
+|\r
+       <DROP>\r
+       (\r
+               tableElement = dropColumnDefinition(behavior)\r
+               |\r
+               tableElement = dropTableConstraintDefinition()\r
+       )\r
+       {\r
+               changeType[0] = DDLStatementNode.DROP_TYPE;\r
+               tableElementList.addTableElement(tableElement);\r
+               return lockGranularity;\r
+       }\r
+|\r
+       lockGranularity = DB2lockGranularityClause()\r
+       {\r
+               changeType[0] = DDLStatementNode.LOCKING_TYPE;\r
+               return lockGranularity;\r
+       }\r
+}\r
+\r
+/*\r
+ * Handle\r
+ *\r
+ *    ALTER TABLE tablename DROP [ COLUMN ] columnname [ CASCADE | RESTRICT ]\r
+ */\r
+TableElementNode\r
+dropColumnDefinition(int []behavior) throws StandardException :\r
+{\r
+       String columnName;\r
+       TableElementNode tableElement;\r
+}\r
+{\r
+       [ <COLUMN> ] columnName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+                                dropColumnReferentialAction(behavior)\r
+       {\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.DROP_COLUMN_NODE,\r
+                                               columnName, null,\r
+                                               null, null,\r
+                                               getContextManager());\r
+       }\r
+}\r
+void\r
+dropColumnReferentialAction(int []behavior) :\r
+{\r
+       int refBehavior = StatementType.DROP_CASCADE;\r
+}\r
+{\r
+       [ <CASCADE> {refBehavior = StatementType.DROP_CASCADE;}   \r
+         | <RESTRICT> {refBehavior = StatementType.DROP_RESTRICT;} \r
+    ]\r
+       {\r
+               behavior[0] = refBehavior;\r
+       }\r
+}\r
+\r
+TableElementNode\r
+addColumnDefinition(TableElementList tableElementList) throws StandardException :\r
+{\r
+       TableElementNode        tableElement;\r
+}\r
+{\r
+       [ <COLUMN> ] tableElement = columnDefinition(tableElementList)\r
+       {\r
+               return tableElement;\r
+       }\r
+}\r
+\r
+/*\r
+ * Various variants of the ALTER TABLE ALTER COLUMN statement.\r
+ *\r
+ * By the type we get here, we've parsed\r
+ *    ALTER TABLE tablename ALTER [COLUMN] columnname\r
+ * and here we parse the remainder of the ALTER COLUMN clause, one of:\r
+ *             SET DATA TYPE data_type\r
+ *             SET INCREMENT BY increment_value\r
+ *             RESTART WITH increment_restart_value\r
+ *             [WITH] DEFAULT default_value\r
+ *      [NOT] NULL\r
+ */\r
+TableElementNode\r
+columnAlterClause(String columnName) throws StandardException :\r
+{\r
+       ValueNode       defaultNode;\r
+       long[]                          autoIncrementInfo = new long[4];\r
+       long                            autoIncrementIncrement = 1;\r
+       long                            autoIncrementRestartWith = 1;\r
+       DataTypeDescriptor      typeDescriptor = null;\r
+}\r
+{\r
+       LOOKAHEAD( {getToken(2).kind == DATA} )\r
+       <SET> <DATA> <TYPE> typeDescriptor = dataTypeDDL()\r
+       {\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.MODIFY_COLUMN_TYPE_NODE,\r
+                                               columnName, null,\r
+                                               typeDescriptor, null,\r
+                                               getContextManager());\r
+       }\r
+|\r
+       LOOKAHEAD( {getToken(2).kind == INCREMENT} )\r
+       <SET> <INCREMENT> <BY> autoIncrementIncrement = exactNumber()\r
+       {\r
+               autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_INC_INDEX] = autoIncrementIncrement;\r
+               autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_CREATE_MODIFY] = ColumnDefinitionNode.MODIFY_AUTOINCREMENT_INC_VALUE;\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.MODIFY_COLUMN_DEFAULT_NODE,\r
+                                               columnName,\r
+                                               null, null, autoIncrementInfo,\r
+                                               getContextManager());\r
+       }\r
+|\r
+       <RESTART> <WITH> autoIncrementRestartWith = exactNumber()\r
+       {\r
+               autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_START_INDEX] = autoIncrementRestartWith;\r
+               autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_CREATE_MODIFY] = ColumnDefinitionNode.MODIFY_AUTOINCREMENT_RESTART_VALUE;\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.MODIFY_COLUMN_DEFAULT_NODE,\r
+                                               columnName,\r
+                                               null, null, autoIncrementInfo,\r
+                                               getContextManager());\r
+       }\r
+|\r
+       LOOKAHEAD( {getToken(1).kind == WITH || getToken(1).kind == _DEFAULT })\r
+       defaultNode = defaultClause(autoIncrementInfo, columnName)\r
+       {\r
+               if (autoIncrementInfo[QueryTreeNode.AUTOINCREMENT_IS_AUTOINCREMENT_INDEX]\r
+                                == 0)\r
+               {\r
+                       autoIncrementInfo = null;\r
+               }\r
+\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.MODIFY_COLUMN_DEFAULT_NODE,\r
+                                                               columnName,\r
+                                                               defaultNode, null, autoIncrementInfo,\r
+                                                               getContextManager());\r
+       }\r
+|\r
+       LOOKAHEAD ({getToken(1).kind == NULL })\r
+       <NULL>\r
+       {\r
+               // for a MODIFY column NULL clause form a modify_column node\r
+               // with all null values. In a column definition a [NOT] NULL\r
+               // column constraint is specified by setting the right value\r
+               // in the nullability field of the data type but we don't have\r
+               // a datatype here.\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.MODIFY_COLUMN_CONSTRAINT_NODE,\r
+                                                               columnName, null, null, null,\r
+                                                               getContextManager());\r
+       }\r
+|\r
+       LOOKAHEAD({getToken(1).kind == NOT})\r
+       <NOT> <NULL>\r
+       {\r
+               // for a MODIFY column NOT NULL clause form a modify_column node\r
+               // with all null values. In a column definition a [NOT] NULL\r
+               // column constraint is specified by setting the right value\r
+               // in the nullability field of the data type but we don't have\r
+               // a datatype here.\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.MODIFY_COLUMN_CONSTRAINT_NOT_NULL_NODE,\r
+                                                               columnName, null, null, null,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+\r
+TableElementNode\r
+dropTableConstraintDefinition() throws StandardException :\r
+{\r
+       TableName                constraintName;\r
+}\r
+{\r
+       LOOKAHEAD( {getToken(1).kind == CONSTRAINT} )\r
+       /* changed constraintName() to qualifiedName() for compaction */\r
+       <CONSTRAINT> constraintName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+       {\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CONSTRAINT_DEFINITION_NODE,\r
+                                               constraintName,\r
+                                               ReuseFactory.getInteger(DataDictionary.DROP_CONSTRAINT),\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               ReuseFactory.getInteger(StatementType.DROP_DEFAULT),\r
+                                               getContextManager()\r
+                                               );\r
+       }\r
+|\r
+       LOOKAHEAD( {getToken(1).kind == PRIMARY} )\r
+       <PRIMARY> <KEY>\r
+       {\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CONSTRAINT_DEFINITION_NODE,\r
+                                               null,\r
+                                               ReuseFactory.getInteger(DataDictionary.DROP_CONSTRAINT),\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               ReuseFactory.getInteger(StatementType.DROP_DEFAULT),\r
+                                               getContextManager()\r
+                                               );\r
+       }\r
+|\r
+       LOOKAHEAD( {getToken(1).kind == FOREIGN} )\r
+        <FOREIGN> <KEY> constraintName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+       {\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CONSTRAINT_DEFINITION_NODE,\r
+                                               constraintName,\r
+                                               ReuseFactory.getInteger(DataDictionary.DROP_CONSTRAINT),\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               ReuseFactory.getInteger(StatementType.DROP_DEFAULT),\r
+                                               ReuseFactory.getInteger(DataDictionary.FOREIGNKEY_CONSTRAINT),\r
+                                               getContextManager()\r
+                                               );\r
+       }\r
+|\r
+       LOOKAHEAD( {getToken(1).kind == UNIQUE} )\r
+        <UNIQUE> constraintName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+       {\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CONSTRAINT_DEFINITION_NODE,\r
+                                               constraintName,\r
+                                               ReuseFactory.getInteger(DataDictionary.DROP_CONSTRAINT),\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               ReuseFactory.getInteger(StatementType.DROP_DEFAULT),\r
+                                               ReuseFactory.getInteger(DataDictionary.UNIQUE_CONSTRAINT),\r
+                                               getContextManager()\r
+                                               );\r
+       }\r
+|\r
+        <CHECK> constraintName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+       {\r
+               return (TableElementNode) nodeFactory.getNode(\r
+                                               C_NodeTypes.CONSTRAINT_DEFINITION_NODE,\r
+                                               constraintName,\r
+                                               ReuseFactory.getInteger(DataDictionary.DROP_CONSTRAINT),\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               null,\r
+                                               ReuseFactory.getInteger(StatementType.DROP_DEFAULT),\r
+                                               ReuseFactory.getInteger(DataDictionary.CHECK_CONSTRAINT),\r
+                                               getContextManager()\r
+                                               );\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="dropTableStatement">dropTableStatement</A>\r
+ */\r
+StatementNode\r
+dropTableStatement() throws StandardException :\r
+{\r
+       TableName tableName;\r
+}\r
+{\r
+       <TABLE> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+       {\r
+               // DB2 does not support a drop behaviour\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                                                       C_NodeTypes.DROP_TABLE_NODE,\r
+                                                                                       tableName,\r
+                                                                                       new Integer(StatementType.DROP_DEFAULT),\r
+                                                                                       getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="dropIndexStatement">dropIndexStatement</A>\r
+ */\r
+StatementNode\r
+dropIndexStatement() throws StandardException :\r
+{\r
+       TableName indexName;\r
+}\r
+{\r
+       <INDEX> indexName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.DROP_INDEX_NODE,\r
+                                                               indexName,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="dropAliasStatement">dropAliasStatement</A>\r
+ */\r
+StatementNode\r
+dropAliasStatement() throws StandardException :\r
+{\r
+       Object aliasName;\r
+}\r
+{\r
+       <PROCEDURE> aliasName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+       {\r
+               return dropAliasNode(aliasName, AliasInfo.ALIAS_TYPE_PROCEDURE_AS_CHAR);\r
+       }  \r
+|      <FUNCTION> aliasName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+       {\r
+               return dropAliasNode(aliasName, AliasInfo.ALIAS_TYPE_FUNCTION_AS_CHAR);\r
+       }  \r
+|      <SYNONYM> aliasName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+       {\r
+               checkVersion(DataDictionary.DD_VERSION_DERBY_10_1, "DROP SYNONYM");\r
+\r
+               return dropAliasNode(aliasName, AliasInfo.ALIAS_TYPE_SYNONYM_AS_CHAR);\r
+       }\r
+}\r
+\r
+StatementNode\r
+dropViewStatement() throws StandardException :\r
+{\r
+       TableName viewName;\r
+}\r
+{\r
+       <VIEW> viewName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.DROP_VIEW_NODE,\r
+                                                               viewName,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+StatementNode\r
+dropTriggerStatement() throws StandardException :\r
+{\r
+       TableName triggerName;\r
+}\r
+{\r
+       <TRIGGER> triggerName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                               C_NodeTypes.DROP_TRIGGER_NODE,\r
+                                                               triggerName,\r
+                                                               getContextManager());\r
+       }\r
+}\r
+\r
+\r
+StatementNode\r
+truncateTableStatement() throws StandardException :\r
+{\r
+       TableName tableName;\r
+}\r
+{\r
+       <TRUNCATE> <TABLE> tableName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH) \r
+       {\r
+               return (StatementNode) nodeFactory.getNode(\r
+                                                       C_NodeTypes.ALTER_TABLE_NODE,\r
+                                                       tableName,\r
+                                                       getContextManager());\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="grantStatement">grantStatement</A>\r
+ */\r
+StatementNode\r
+grantStatement() throws StandardException :\r
+{\r
+    StatementNode node;\r
+}\r
+{\r
+       <GRANT>\r
+       {\r
+               checkVersion( DataDictionary.DD_VERSION_DERBY_10_2, "GRANT");\r
+               checkSqlStandardAccess( "GRANT");\r
+       }\r
+       ( node = tableGrantStatement() | node = routineGrantStatement() )\r
+       {\r
+               return node;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="tableGrantStatement">tableGrantStatement</A>\r
+ */\r
+StatementNode\r
+tableGrantStatement() throws StandardException :\r
+{\r
+    PrivilegeNode privileges;\r
+    List grantees;\r
+}\r
+{\r
+       privileges = tablePrivileges()\r
+       <TO> grantees = granteeList()\r
+    {\r
+        return (StatementNode) nodeFactory.getNode( C_NodeTypes.GRANT_NODE,\r
+                                    privileges, grantees,\r
+                                    getContextManager());\r
+    }\r
+}// end of tableGrantStatement\r
+\r
+/*\r
+ * <A NAME="tablePrivileges">tablePrivileges</A>\r
+ */\r
+PrivilegeNode tablePrivileges() throws StandardException :\r
+{\r
+    TablePrivilegesNode tablePrivilegesNode = null;\r
+    TableName objectName = null;\r
+}\r
+{\r
+    tablePrivilegesNode = tableActions()\r
+      <ON> [ <TABLE> ] objectName = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+    {\r
+        return (PrivilegeNode) nodeFactory.getNode( C_NodeTypes.PRIVILEGE_NODE,\r
+                                                    ReuseFactory.getInteger( PrivilegeNode.TABLE_PRIVILEGES),\r
+                                                    objectName, tablePrivilegesNode,\r
+                                                    getContextManager());\r
+    }\r
+} // end of   tablePrivilege                               \r
+\r
+/*\r
+ * <A NAME="tableActions">tableActions</A>\r
+ */\r
+TablePrivilegesNode tableActions() throws StandardException :\r
+{\r
+    TablePrivilegesNode tableActionsNode = (TablePrivilegesNode)\r
+      nodeFactory.getNode( C_NodeTypes.TABLE_PRIVILEGES_NODE, getContextManager());\r
+}\r
+{\r
+    <ALL> <PRIVILEGES>\r
+    {\r
+        tableActionsNode.addAll();\r
+        return tableActionsNode;\r
+    }\r
+|\r
+    tableAction( tableActionsNode) ( <COMMA> tableAction( tableActionsNode) )*\r
+    {\r
+        return tableActionsNode;\r
+    }\r
+} // end of tableActions\r
+\r
+/*\r
+ * <A NAME="routineGrantStatement">routineGrantStatement</A>\r
+ */\r
+StatementNode\r
+routineGrantStatement() throws StandardException :\r
+{\r
+    List grantees;\r
+    RoutineDesignator routine;\r
+}\r
+{\r
+    <EXECUTE> <ON> routine = routineDesignator()\r
+    <TO> grantees = granteeList()\r
+    {\r
+        PrivilegeNode routinePrivilege = (PrivilegeNode)\r
+          nodeFactory.getNode( C_NodeTypes.PRIVILEGE_NODE,\r
+                               ReuseFactory.getInteger( PrivilegeNode.ROUTINE_PRIVILEGES),\r
+                               routine, null,\r
+                               getContextManager());\r
+        return (StatementNode) nodeFactory.getNode( C_NodeTypes.GRANT_NODE,\r
+                                    routinePrivilege, grantees,\r
+                                    getContextManager());\r
+    }\r
+}// end of routineGrantStatement\r
+\r
+/*\r
+ * <A NAME="routineAlias">routineAlias</A>\r
+ */\r
+RoutineDesignator routineDesignator() throws StandardException :\r
+{\r
+    Token procOrFunction;\r
+    RoutineDesignator routine = null;\r
+    TableName name = null;\r
+    List paramTypeList = null;\r
+}\r
+{\r
+    ( procOrFunction = <FUNCTION> | procOrFunction = <PROCEDURE> )\r
+      name = qualifiedName(Limits.MAX_IDENTIFIER_LENGTH)\r
+      [ <LEFT_PAREN> paramTypeList = parameterTypeList() <RIGHT_PAREN> ]\r
+    {\r
+        return new RoutineDesignator( false,\r
+                                      name,\r
+                                      (procOrFunction.kind == FUNCTION),\r
+                                      paramTypeList);\r
+    }\r
+} // end of routineDesignator\r
+\r
+\r
+/*\r
+ * <A NAME="parameterTypeList">parameterTypeList</A>\r
+ */\r
+List parameterTypeList( ) throws StandardException :\r
+{\r
+    ArrayList list = new ArrayList();\r
+    DataTypeDescriptor dtd;\r
+}\r
+{\r
+    [ dtd = dataTypeCommon()\r
+        {\r
+            list.add( dtd);\r
+        }\r
+      ( <COMMA> dtd = dataTypeCommon()\r
+        {\r
+            list.add( dtd);\r
+        }\r
+      ) * ]\r
+    {\r
+        return list;\r
+    }\r
+} // end of parameterTypeList\r
+\r
+\r
+/*\r
+ * <A NAME="tableAction">tableAction</A>\r
+ */\r
+void tableAction( TablePrivilegesNode tablePrivilegesNode)  throws StandardException :\r
+{\r
+    ResultColumnList columnList = null;\r
+}\r
+{\r
+    <SELECT> [ columnList = privilegeColumnList() ]\r
+    {\r
+        tablePrivilegesNode.addAction( TablePrivilegeInfo.SELECT_ACTION, columnList);\r
+    }\r
+|\r
+    <DELETE>\r
+    {\r
+        tablePrivilegesNode.addAction( TablePrivilegeInfo.DELETE_ACTION, (ResultColumnList) null);\r
+    }\r
+|\r
+    <INSERT>\r
+    {\r
+        tablePrivilegesNode.addAction( TablePrivilegeInfo.INSERT_ACTION, (ResultColumnList) null);\r
+    }\r
+|\r
+    <UPDATE> [ columnList = privilegeColumnList() ]\r
+    {\r
+        tablePrivilegesNode.addAction( TablePrivilegeInfo.UPDATE_ACTION, columnList);\r
+    }\r
+|\r
+    <REFERENCES> [ columnList = privilegeColumnList() ]\r
+    {\r
+        tablePrivilegesNode.addAction( TablePrivilegeInfo.REFERENCES_ACTION, columnList);\r
+    }\r
+|\r
+    <TRIGGER>\r
+    {\r
+        tablePrivilegesNode.addAction( TablePrivilegeInfo.TRIGGER_ACTION, (ResultColumnList) null);\r
+    }\r
+} // end of tableAction\r
+\r
+/*\r
+ * <A NAME="privilegeColumnList">privilegeColumnList</A>\r
+ */\r
+ResultColumnList privilegeColumnList() throws StandardException :\r
+{\r
+    ResultColumnList cl = (ResultColumnList) nodeFactory.getNode( C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                  getContextManager());\r
+}\r
+{\r
+    <LEFT_PAREN> columnNameList( cl) <RIGHT_PAREN>\r
+    {\r
+        return cl;\r
+    }\r
+} // end of privilegeColumnList\r
+\r
+/*\r
+ * <A NAME="granteeList">granteeList</A>\r
+ */\r
+List granteeList() throws StandardException :\r
+{\r
+    ArrayList list = new ArrayList();\r
+}\r
+{\r
+    grantee( list) ( <COMMA> grantee( list) ) *\r
+    {\r
+        return list;\r
+    }\r
+}\r
+\r
+void\r
+grantee( List list)  throws StandardException :\r
+{\r
+    String str;\r
+}\r
+{\r
+    str = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+    {\r
+        checkAuthorizationLength(str);\r
+        list.add(str);\r
+    }\r
+|\r
+    <PUBLIC>\r
+    {\r
+        list.add( Authorizer.PUBLIC_AUTHORIZATION_ID);\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="revokeStatement">revokeStatement</A>\r
+ */\r
+StatementNode\r
+revokeStatement() throws StandardException :\r
+{\r
+    StatementNode node;\r
+}\r
+{\r
+    <REVOKE>\r
+      {\r
+          checkVersion( DataDictionary.DD_VERSION_DERBY_10_2, "REVOKE");\r
+          checkSqlStandardAccess( "REVOKE");\r
+      }\r
+    ( node = tableRevokeStatement() | node = routineRevokeStatement() )\r
+    {\r
+        return node;\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="tableRevokeStatement">tableRevokeStatement</A>\r
+ */\r
+StatementNode\r
+tableRevokeStatement() throws StandardException :\r
+{\r
+    PrivilegeNode privileges = null;\r
+    List grantees;\r
+}\r
+{\r
+       privileges = tablePrivileges()\r
+       <FROM> grantees = granteeList()\r
+    {\r
+        return (StatementNode) nodeFactory.getNode( C_NodeTypes.REVOKE_NODE,\r
+                                    privileges, grantees,\r
+                                    getContextManager());\r
+    }\r
+}// end of tableRevokeStatement\r
+\r
+/*\r
+ * <A NAME="routineRevokeStatement">routineRevokeStatement</A>\r
+ */\r
+StatementNode\r
+routineRevokeStatement() throws StandardException :\r
+{\r
+    List grantees;\r
+    RoutineDesignator routine = null;\r
+}\r
+{\r
+    <EXECUTE> <ON> routine = routineDesignator()\r
+    <FROM> grantees = granteeList() <RESTRICT>\r
+    {\r
+        PrivilegeNode routinePrivilege = (PrivilegeNode)\r
+          nodeFactory.getNode( C_NodeTypes.PRIVILEGE_NODE,\r
+                               ReuseFactory.getInteger( PrivilegeNode.ROUTINE_PRIVILEGES),\r
+                               routine, null,\r
+                               getContextManager());\r
+        return (StatementNode) nodeFactory.getNode( C_NodeTypes.REVOKE_NODE,\r
+                                    routinePrivilege, grantees,\r
+                                    getContextManager());\r
+    }\r
+}// end of routineRevokeStatement\r
+\r
+/*\r
+ * <A NAME="identifier">identifier</A>\r
+ */\r
+String\r
+internalIdentifier( int id_length_limit, boolean checkLength) throws StandardException :\r
+{\r
+       String  str;\r
+       Token   tok;\r
+}\r
+{\r
+       tok = <IDENTIFIER>\r
+       {\r
+        str = StringUtil.SQLToUpperCase(tok.image);\r
\r
+               if (checkLength) {//if checkLength false, then calling method would do the length limit checks\r
+                       //limit the identifier to the id length limit passed to this method\r
+                       checkIdentifierLengthLimit(str, id_length_limit);\r
+               }\r
+               // Remember whether last token was a delimited identifier\r
+               nextToLastTokenDelimitedIdentifier = lastTokenDelimitedIdentifier;\r
+               lastTokenDelimitedIdentifier = Boolean.FALSE;\r
+               nextToLastIdentifierToken = lastIdentifierToken;\r
+               lastIdentifierToken = tok;\r
+               return str;\r
+       }\r
+|\r
+       str = delimitedIdentifier()\r
+       {\r
+               if (checkLength) {//if checkLength false, then calling method would do the length limit checks\r
+                       //limit the identifier to the id length limit passed to this method\r
+                       checkIdentifierLengthLimit(str, id_length_limit);\r
+               } \r
+               return str;\r
+       }\r
+|\r
+       str = nonReservedKeyword()\r
+       {\r
+               return StringUtil.SQLToUpperCase(str);\r
+       }\r
+}\r
+\r
+String\r
+identifier(int id_length_limit, boolean checkLength) throws StandardException :\r
+{\r
+       String  id;\r
+}\r
+{\r
+    id = internalIdentifier( id_length_limit, checkLength)\r
+    {\r
+        return id;\r
+    }\r
+}\r
+\r
+/*\r
+ * <A NAME="delimitedIdentifier">delimitedIdentifier</A>\r
+ */\r
+String\r
+delimitedIdentifier() :\r
+{\r
+       String  str;\r
+       Token   tok;\r
+}\r
+{\r
+       tok = <DELIMITED_IDENTIFIER>\r
+       {\r
+               str = tok.image.substring(1, tok.image.length() -1);\r
+               str = normalizeDelimitedID( str );\r
+               // Remember whether last token was a delimited identifier\r
+               nextToLastTokenDelimitedIdentifier = lastTokenDelimitedIdentifier;\r
+               lastTokenDelimitedIdentifier = Boolean.TRUE;\r
+               nextToLastIdentifierToken = lastIdentifierToken;\r
+               lastIdentifierToken = tok;\r
+\r
+               return str;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="reservedKeyword">reservedKeyword</A>\r
+ */\r
+String\r
+reservedKeyword() :\r
+{\r
+       Token   tok;\r
+}\r
+{\r
+       /*\r
+               All reserved keywords have to be repeated here,\r
+               so that they may be used as normal identifiers.\r
+\r
+               NOTE: The same ones are commented out here as above in the token\r
+               rule, for the same reason.\r
+               \r
+               Derby-139 - LOCAL removed as reserved word as most other\r
+               databases do not enforce it. LOCAL not used at all in grammar so token removed.\r
+        */\r
+       (\r
+       /* SQL92 reserved Keywords */\r
+       tok = <ADD>\r
+|      tok = <ALL>\r
+|      tok = <ALLOCATE>\r
+|      tok = <ALTER>\r
+|      tok = <AND>\r
+|      tok = <ANY>\r
+|      tok = <ARE>\r
+|      tok = <AS>\r
+|      tok = <ASC>\r
+|      tok = <ASSERTION>\r
+|      tok = <AT>\r
+|      tok = <AUTHORIZATION>\r
+|      tok = <AVG>\r
+|      tok = <BEGIN>\r
+|      tok = <BETWEEN>\r
+|      tok = <BIT>\r
+|      tok = <BOTH>\r
+|      tok = <BY>\r
+|      tok = <CASCADE>\r
+|      tok = <CASCADED>\r
+|      tok = <CASE>\r
+|      tok = <CAST>\r
+|      tok = <CHAR>\r
+|      tok = <CHARACTER>\r
+|      tok = <CHECK>\r
+|      tok = <CLOSE>\r
+|      tok = <COLLATE>\r
+|      tok = <COLLATION>\r
+|      tok = <COLUMN>\r
+|      tok = <COMMIT>\r
+|      tok = <CONNECT>\r
+|      tok = <CONNECTION>\r
+|      tok = <CONSTRAINT>\r
+|      tok = <CONSTRAINTS>\r
+|      tok = <CONTINUE>\r
+|      tok = <CONVERT>\r
+|      tok = <CORRESPONDING>\r
+|      tok = <CREATE>\r
+|      tok = <CURRENT>\r
+|      tok = <CURRENT_DATE>\r
+|      tok = <CURRENT_TIME>\r
+|      tok = <CURRENT_TIMESTAMP>\r
+|      tok = <CURRENT_USER>\r
+|      tok = <CURSOR>\r
+|      tok = <DEALLOCATE>\r
+|      tok = <DEC>\r
+|      tok = <DECIMAL>\r
+|      tok = <DECLARE>\r
+|      tok = <_DEFAULT>\r
+|      tok = <DEFERRABLE>\r
+|      tok = <DEFERRED>\r
+|      tok = <DELETE>\r
+|      tok = <DESC>\r
+|      tok = <DESCRIBE>\r
+|      tok = <DIAGNOSTICS>\r
+|      tok = <DISCONNECT>\r
+|      tok = <DISTINCT>\r
+|      tok = <DOUBLE>\r
+|      tok = <DROP>\r
+|      tok = <ELSE>\r
+|      tok = <END>\r
+|      tok = <ENDEXEC>\r
+|      tok = <ESCAPE>\r
+|      tok = <EXCEPT>\r
+|      tok = <EXCEPTION>\r
+|      tok = <EXEC>\r
+|      tok = <EXECUTE>\r
+|      tok = <EXISTS>\r
+|      tok = <EXTERNAL>\r
+|      tok = <FALSE>\r
+|      tok = <FETCH>\r
+|      tok = <FIRST>\r
+|      tok = <FLOAT>\r
+|      tok = <FOR>\r
+|      tok = <FOREIGN>\r
+|      tok = <FOUND>\r
+|      tok = <FROM>\r
+|      tok = <FULL>\r
+|      tok = <FUNCTION>\r
+|      tok = <GET>\r
+|      tok = <GET_CURRENT_CONNECTION>\r
+|      tok = <GLOBAL>\r
+|      tok = <GO>\r
+|      tok = <GOTO>\r
+|      tok = <GRANT>\r
+|      tok = <GROUP>\r
+|      tok = <HAVING>\r
+|      tok = <HOUR>\r
+|      tok = <IDENTITY>\r
+|      tok = <IMMEDIATE>\r
+|      tok = <IN>\r
+|      tok = <INDICATOR>\r
+|      tok = <INITIALLY>\r
+|      tok = <INNER>\r
+|   tok = <INOUT>\r
+|      tok = <INPUT>\r
+|      tok = <INSENSITIVE>\r
+|      tok = <INSERT>\r
+|      tok = <INT>\r
+|      tok = <INTEGER>\r
+|      tok = <INTERSECT>\r
+// SQL92 says it is reserved, but we want it to be non-reserved.\r
+|      tok = <INTO>\r
+|      tok = <IS>\r
+|      tok = <ISOLATION>\r
+|      tok = <JOIN>\r
+|      tok = <KEY>\r
+|      tok = <LAST>\r
+|      tok = <LEADING>\r
+|      tok = <LEFT>\r
+|      tok = <LIKE>\r
+|      tok = <LOWER>\r
+|      tok = <MATCH>\r
+|      tok = <MAX>\r
+|      tok = <MIN>\r
+|      tok = <MINUTE>\r
+// SQL92 says it is reserved, but we want it to be non-reserved.\r
+|      tok = <NATIONAL>\r
+|      tok = <NATURAL>\r
+|      tok = <NCHAR>\r
+|      tok = <NVARCHAR> \r
+|      tok = <NEXT>\r
+|      tok = <NO>\r
+|      tok = <NOT>\r
+|      tok = <NULL>\r
+|      tok = <NULLIF>\r
+|      tok = <NUMERIC>\r
+|      tok = <OF>\r
+|      tok = <ON>\r
+|      tok = <ONLY>\r
+|      tok = <OPEN>\r
+|      tok = <OPTION>\r
+|      tok = <OR>\r
+|      tok = <ORDER>\r
+|   tok = <OUT>\r
+|      tok = <OUTER>\r
+|      tok = <OUTPUT>\r
+|      tok = <OVERLAPS>\r
+|      tok = <PAD>\r
+|      tok = <PARTIAL>\r
+|      tok = <PREPARE>\r
+|      tok = <PRESERVE>\r
+|      tok = <PRIMARY>\r
+|      tok = <PRIOR>\r
+|      tok = <PRIVILEGES>\r
+|      tok = <PROCEDURE>\r
+|      tok = <PUBLIC>\r
+|      tok = <READ>\r
+|      tok = <REAL>\r
+|      tok = <REFERENCES>\r
+|      tok = <RELATIVE>\r
+|      tok = <RESTRICT>\r
+|      tok = <REVOKE>\r
+|      tok = <RIGHT>\r
+|      tok = <ROLLBACK>\r
+|      tok = <ROWS>\r
+|      tok = <SCHEMA>\r
+|      tok = <SCROLL>\r
+|      tok = <SECOND>\r
+|      tok = <SELECT>\r
+|      tok = <SESSION_USER>\r
+|      tok = <SET>\r
+|      tok = <SMALLINT>\r
+|      tok = <SOME>\r
+|      tok = <SPACE>\r
+|      tok = <SQL>\r
+|      tok = <SQLCODE>\r
+|      tok = <SQLERROR>\r
+|      tok = <SQLSTATE>\r
+|      tok = <SUBSTRING>\r
+|      tok = <SUM>\r
+|      tok = <SYSTEM_USER>\r
+|      tok = <TABLE>\r
+|      tok = <TEMPORARY>\r
+|      tok = <TIMEZONE_HOUR>\r
+|      tok = <TIMEZONE_MINUTE>\r
+|      tok = <TO>\r
+|      tok = <TRAILING>\r
+|      tok = <TRANSACTION>\r
+|      tok = <TRANSLATE>\r
+|      tok = <TRANSLATION>\r
+|      tok = <TRUE>\r
+|      tok = <UNION>\r
+|      tok = <UNIQUE>\r
+|      tok = <UNKNOWN>\r
+|      tok = <UPDATE>\r
+|      tok = <UPPER>\r
+|      tok = <USER>\r
+|      tok = <USING>\r
+|      tok = <VALUES>\r
+|      tok = <VARCHAR>\r
+|      tok = <VARYING>\r
+|      tok = <VIEW>\r
+|      tok = <WHENEVER>\r
+|      tok = <WHERE>\r
+|      tok = <WITH>\r
+|      tok = <WORK>\r
+|      tok = <WRITE>\r
+|      tok = <YEAR>\r
+       /* Additional JSQL reserved keywords -- non-SQL92 reserved Keywords */\r
+|      tok = <BOOLEAN>\r
+|      tok = <CALL>\r
+|      tok = <EXPLAIN>\r
+|      tok = <LONGINT>\r
+|      tok = <LTRIM>\r
+|      tok = <RTRIM>\r
+|      tok = <TRIM>\r
+|      tok = <SUBSTR>\r
+|      tok = <XML>\r
+|      tok = <XMLPARSE>\r
+|      tok = <XMLSERIALIZE>\r
+|      tok = <XMLEXISTS>\r
+|      tok = <XMLQUERY>\r
+)\r
+       {\r
+               // Remember whether last token was a delimited identifier\r
+               nextToLastTokenDelimitedIdentifier = lastTokenDelimitedIdentifier;\r
+               lastTokenDelimitedIdentifier = Boolean.FALSE;\r
+               return tok.image;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="nonReservedKeyword">nonReservedKeyword</A>\r
+ */\r
+String\r
+nonReservedKeyword()  :\r
+{\r
+       Token   tok;\r
+}\r
+{\r
+       /*\r
+               All non-reserved keywords have to be repeated here,\r
+               so that they may be used as normal identifiers.\r
+\r
+               NOTE: The same ones are commented out here as above in the token\r
+               rule, for the same reason.\r
+        */\r
+       (\r
+        tok = <ABS>  \r
+       |       tok = <ABSVAL>  \r
+       |       tok = <ACTION>\r
+       |       tok = <AFTER>\r
+       |       tok = <ALWAYS>\r
+       |       tok = <BEFORE>\r
+       |       tok = <BINARY>\r
+       |       tok = <BLOB>\r
+       |       tok = <C>\r
+       |       tok = <CALLED>\r
+       |       tok = <CLASS>\r
+       |       tok = <CLOB>\r
+|      tok = <COALESCE>\r
+       |       tok = <COBOL>\r
+       |       tok = <COMMITTED>\r
+       |       tok = <COMPRESS>\r
+       |       tok = <CONCAT>\r
+       |       tok = <CONTAINS>\r
+       |       tok = <CONTENT>\r
+       |       tok = <COUNT>\r
+       |   tok = <CS>\r
+       |       tok = <CURDATE>\r
+       |       tok = <CURTIME>\r
+       |       tok = <D>\r
+       |       tok = <DATA>\r
+       |       tok = <DATE>\r
+       |       tok = <DAY>\r
+        |      tok = <DIRTY>\r
+       |       tok = <DYNAMIC>\r
+    |   tok = <DATABASE>\r
+       |       tok = <DB2SQL>\r
+       |       tok = <DOCUMENT>\r
+       |       tok = <EACH>\r
+       |       tok = <EMPTY>\r
+       |       tok = <EXCLUSIVE>\r
+       |       tok = <FN>\r
+       |       tok = <FORTRAN>\r
+       |       tok = <GENERATED>\r
+       |       tok = <IDENTITY_VAL_LOCAL>\r
+       |       tok = <INCREMENT>\r
+       |       tok = <INDEX>\r
+       |       tok = <INITIAL>\r
+// SQL92 says it is reserved, but we want it to be non-reserved.\r
+       |       tok = <INTERVAL>\r
+       |   tok = <JAVA>\r
+       |       tok = <LANGUAGE>\r
+       |       tok = <LARGE>\r
+    |   tok = <LCASE>\r
+       |       tok = <LENGTH>\r
+       |       tok = <LEVEL>\r
+    |   tok = <LOCATE>\r
+       |       tok = <LOCK>\r
+       |       tok = <LOCKS>\r
+       |       tok = <LOCKSIZE>\r
+       |       tok = <LOGGED>\r
+       |       tok = <LONG>\r
+       |       tok = <MESSAGE_LOCALE>\r
+       |       tok = <METHOD>\r
+       |       tok = <MOD>\r
+       |       tok = <MODE>\r
+       |       tok = <MODIFIES>\r
+       |       tok = <MODIFY>\r
+// SQL92 says it is reserved, but we want it to be non-reserved.\r
+       |       tok = <MODULE>\r
+       |       tok = <MONTH>\r
+       |       tok = <_MORE>\r
+       |       tok = <MUMPS>\r
+       |       tok = <NAME>\r
+       |       tok = <NCLOB>\r
+       |       tok = <NEW>\r
+       |   tok = <NEW_TABLE>\r
+       |       tok = <NULLABLE>\r
+       |       tok = <NUMBER>\r
+       |       tok = <OBJECT>\r
+       |       tok = <OFF>\r
+       |       tok = <OLD>\r
+       |       tok = <OLD_TABLE>\r
+       |       tok = <OJ>\r
+       |       tok = <PASCAL>\r
+       |       tok = <PASSING>\r
+       |       tok = <PLI>\r
+       |       tok = <PRECISION>\r
+       |       tok = <PROPERTIES>\r
+       |       tok = <READS>\r
+       |       tok = <REF>\r
+// SQL92 says it is reserved, but we want it to be non-reserved.\r
+       |       tok = <RELEASE>\r
+       |       tok = <RENAME>\r
+       |       tok = <REPEATABLE>\r
+       |       tok = <REFERENCING>\r
+       |       tok = <RESET>\r
+       |       tok = <RESTART>\r
+       |       tok = <RESULT>\r
+       |       tok = <RETAIN>\r
+       |       tok = <RETURNING>\r
+       |       tok = <RETURNS>\r
+       |       tok = <ROW>\r
+//     |       tok = <ROW_COUNT>\r
+       |   tok = <RR>\r
+       |   tok = <RS>\r
+       |       tok = <SCALE>\r
+       |       tok = <SAVEPOINT>\r
+       |       tok = <SEQUENCE>\r
+       |       tok = <SEQUENTIAL>\r
+       |       tok = <SERIALIZABLE>\r
+       |       tok = <SETS>\r
+       |       tok = <SHARE>\r
+       |   tok = <SPECIFIC>\r
+       |       tok = <SQLID>\r
+       |       tok = <SQL_TSI_FRAC_SECOND>\r
+       |       tok = <SQL_TSI_SECOND>\r
+       |       tok = <SQL_TSI_MINUTE>\r
+       |       tok = <SQL_TSI_HOUR>\r
+       |       tok = <SQL_TSI_DAY>\r
+       |       tok = <SQL_TSI_WEEK>\r
+       |       tok = <SQL_TSI_MONTH>\r
+       |       tok = <SQL_TSI_QUARTER>\r
+       |       tok = <SQL_TSI_YEAR>\r
+    |   tok = <SQRT>\r
+    |       tok = <STABILITY>\r
+       |       tok = <START>\r
+       |       tok = <STATEMENT>\r
+       |       tok = <STRIP>\r
+       |       tok = <SYNONYM>\r
+       |       tok = <STYLE>\r
+       |       tok = <T>\r
+       |       tok = <THEN>\r
+       |       tok = <TIME>\r
+       |       tok = <TIMESTAMP>\r
+       |       tok = <TIMESTAMPADD>\r
+       |       tok = <TIMESTAMPDIFF>\r
+    |   tok = <TRIGGER>\r
+       |       tok = <TRUNCATE>\r
+       |       tok = <TS>\r
+       |       tok = <TYPE>\r
+    |   tok = <UCASE>\r
+       |       tok = <UNCOMMITTED>\r
+       |   tok = <UR>\r
+       |       tok = <USAGE>\r
+// SQL92 says VALUE is reserved, but we want it to be nonreserved.\r
+       |       tok = <VALUE>\r
+       |       tok = <VARBINARY>\r
+       |       tok = <PARAMETER>\r
+       |       tok = <WHEN>\r
+       |       tok = <WHITESPACE>\r
+       )\r
+       {\r
+               // Remember whether last token was a delimited identifier\r
+               nextToLastTokenDelimitedIdentifier = lastTokenDelimitedIdentifier;\r
+               lastTokenDelimitedIdentifier = Boolean.FALSE;\r
+               nextToLastIdentifierToken = lastIdentifierToken;\r
+               lastIdentifierToken = tok;\r
+               return tok.image;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="caseSensitiveIdentifierPlusReservedWords">caseSensitiveIdentifierPlusReservedWords</A>\r
+ */\r
+String\r
+caseSensitiveIdentifierPlusReservedWords() :\r
+{\r
+       String str;\r
+}\r
+{\r
+       str = caseSensitiveIdentifier()\r
+       {\r
+               return str;\r
+       }\r
+|\r
+       str = reservedKeyword()\r
+       {\r
+               return str;\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="caseInsensitiveIdentifierPlusReservedWords">caseInsensitiveIdentifierPlusReservedWords</A>\r
+ */\r
+String\r
+caseInsensitiveIdentifierPlusReservedWords() throws StandardException :\r
+{\r
+       String str;\r
+}\r
+{\r
+       str = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)\r
+       {\r
+               return str;\r
+       }\r
+|\r
+       str = reservedKeyword()\r
+       {\r
+               return StringUtil.SQLToUpperCase(str);\r
+       }\r
+}\r
+\r
+/*\r
+ * <A NAME="caseSensitiveIdentifier">caseSensitiveIdentifier</A>\r
+ */\r
+String\r
+caseSensitiveIdentifier() :\r
+{\r
+       String  str;\r
+       Token   tok;\r
+}\r
+{\r
+       tok = <IDENTIFIER>\r
+       {\r
+               // Remember whether last token was a delimited identifier\r
+               nextToLastTokenDelimitedIdentifier = lastTokenDelimitedIdentifier;\r
+               lastTokenDelimitedIdentifier = Boolean.FALSE;\r
+               return tok.image;\r
+       }\r
+|\r
+       str = delimitedIdentifier()\r
+       {\r
+               return str;\r
+       }\r
+|\r
+       str = nonReservedKeyword()\r
+       {\r
+               return str;\r
+       }\r
+}\r