--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.iapi.store.access.Qualifier\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.iapi.store.access;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+/**\r
+ <p>\r
+ A structure which is used to "qualify" a column. Specifies\r
+ that the column value in a given column identified by column\r
+ id is to be compared via a specific operator to a particular\r
+ DataValueDescriptor value.\r
+ <p>\r
+ The implementation of this interface is provided by the client; \r
+ the methods of Qualifier are the methods the access code uses to use it.\r
+ <p>\r
+ Arrays of qualifiers are provided to restrict the rows \r
+ returned by scans. A row is returned from a scan if all qualifications\r
+ in the array return true. \r
+ <p>\r
+ A qualification returns true if in the following pseudo-code compare_result\r
+ is true.\r
+ <p>\r
+ <blockquote><pre>\r
+ if (qualifier.negateCompareResult())\r
+ {\r
+ compare_result = \r
+ row[(qualifier.getColumnId())].compare(\r
+ qualifier.getOperator(), \r
+ qualifier.getOrderable(),\r
+ qualifier.getOrderedNulls(), \r
+ qualifier.getUnknownRV()) \r
+ if (qualifier.negateCompareResult())\r
+ {\r
+ compare_result = !(compare_result);\r
+ }\r
+ }\r
+ </blockquote></pre>\r
+ <p>\r
+ Qualifiers are often passed through interfaces as a set of Qualifiers,\r
+ rather than one at a time, for example see the qualifier argument in \r
+ TransactionController.openScan(). \r
+ <p>\r
+ To make this consistent the following protocols are to be used when passing\r
+ around sets of Qualifiers.\r
+ <p>\r
+ A single dimensional array is to be used to pass around a set of AND'd \r
+ qualifiers. Thus qualifier[] argument is to be treated as:\r
+ <blockquote><pre>\r
+ qualifier[0] AND qualifer[1] ... AND qualifier[qualifer.length - 1]\r
+ </blockquote></pre>\r
+ <p>\r
+ A two dimensional array is to be used to pass around a AND's and OR's in\r
+ conjunctive normal form. The top slot of the 2 dimensional array is optimized\r
+ for the more frequent where no OR's are present. The first array slot is \r
+ always a list of AND's to be treated as described above for single dimensional\r
+ AND qualifier arrays. The subsequent slots are to be treated as AND'd arrays\r
+ of OR's. Thus the 2 dimensional array qual[][] argument is to be treated as \r
+ the following, note if qual.length = 1 then only the first array is valid and\r
+ it is and an array of AND clauses:\r
+ <blockquote><pre>\r
+ (qual[0][0] AND qual[0][0] ... AND qual[0][qual[0].length - 1])\r
+ AND\r
+ (qual[1][0] OR qual[1][1] ... OR qual[1][qual[1].length - 1])\r
+ AND\r
+ (qual[2][0] OR qual[2][1] ... OR qual[2][qual[2].length - 1])\r
+ ...\r
+ AND (qual[qual.length - 1][0] OR qual[1][1] ... OR qual[1][2])\r
+ </blockquote></pre>\r
+ <p>\r
+ If any of the array's qual[0].length ... qual[qual.length -1] are 0 length\r
+ they will be evaluated as TRUE; but they must be not NULL. See Example 4 for\r
+ encoding of (a or b) that takes advantage of this.\r
+ <p>\r
+ Note that any of the arrays qual[0].length ... qual[qual.length -1] may also\r
+ be of length 1, thus no guarantee is made the presence of OR\r
+ predicates if qual.length > 1. See example 1a.\r
+ <p>\r
+ The following give pseudo-code examples of building Qualifier arrays:\r
+ <p>\r
+ Example 1: "a AND b AND c"\r
+ <blockquote><pre>\r
+ qualifier = new Qualifier[1][3]; // 3 AND clauses\r
+\r
+ qualifier[0][0] = a\r
+ qualifier[0][1] = b\r
+ qualifier[0][2] = c\r
+ </blockquote></pre>\r
+ <p>\r
+ Example 1a "a AND b AND c" - less efficient than example 1 but legal\r
+ <blockquote><pre>\r
+ qualifier = new Qualifier[3]; // 3 AND clauses\r
+ qualifier[0] = new Qualifier[1];\r
+ qualifier[1] = new Qualifier[1];\r
+ qualifier[2] = new Qualifier[1];\r
+ \r
+ qualifier[0][0] = a\r
+ qualifier[1][0] = b\r
+ qualifier[2][0] = c\r
+ </blockquote></pre>\r
+ <p>\r
+ Example 2: "(f) AND (a OR b) AND (c OR d OR e)"\r
+ Would be represented by an array that looks like the following:\r
+ <blockquote><pre>\r
+ qualifier = new Qualifier[3]; // 3 and clauses\r
+ qualifier[0] = new Qualifier[1]; // to be intitialized to f\r
+ qualifier[1] = new Qualifier[2]; // to be initialized to (a OR b)\r
+ qualifier[2] = new Qualifier[3]; // to be initialized to (c OR d OR e)\r
+\r
+ qualifier[0][0] = f\r
+ qualifier[1][0] = a\r
+ qualifier[1][1] = b\r
+ qualifier[2][0] = c\r
+ qualifier[2][1] = d\r
+ qualifier[2][2] = e\r
+ </blockquote></pre>\r
+ <p>\r
+ Example 3: "(a OR b) AND (c OR d) AND (e OR f)" \r
+ <blockquote><pre>\r
+ qualifier = new Qualifier[3]; // 3 and clauses\r
+ qualifier = new Qualifier[4]; // 4 and clauses\r
+ qualifier[0] = new Qualifier[1]; // to be intitialized to TRUE\r
+ qualifier[1] = new Qualifier[2]; // to be initialized to (a OR b)\r
+ qualifier[2] = new Qualifier[2]; // to be initialized to (c OR d)\r
+ qualifier[3] = new Qualifier[2]; // to be initialized to (e OR f)\r
+\r
+ qualifier[0][0] = TRUE\r
+ qualifier[1][0] = a\r
+ qualifier[1][1] = b\r
+ qualifier[2][0] = c\r
+ qualifier[2][1] = d\r
+ qualifier[3][0] = e\r
+ qualifier[3][1] = f\r
+ </blockquote></pre>\r
+ <p>\r
+ Example 4: "(a OR b)" \r
+ <blockquote><pre>\r
+ qualifier = new Qualifier[2]; // 2 and clauses\r
+ qualifier[0] = new Qualifier[0]; // 0 length array is TRUE\r
+ qualifier[1] = new Qualifier[2]; // to be initialized to (a OR b)\r
+\r
+ qualifier[1][0] = a\r
+ qualifier[1][1] = b\r
+ </blockquote></pre>\r
+\r
+ @see ScanController\r
+ @see TransactionController#openScan \r
+ @see DataValueDescriptor#compare\r
+**/\r
+\r
+\r
+public interface Qualifier\r
+{\r
+\r
+ /** \r
+ * The DataValueDescriptor can be 1 of 4 types:<ul>\r
+ * <li> VARIANT - cannot be cached as its value can vary \r
+ * within a scan</li>\r
+ * <li> SCAN_INVARIANT - can be cached within a scan as its value \r
+ * will not change within a scan </li>\r
+ * <li> QUERY_INVARIANT- can be cached across the life of the query\r
+ * as its value will never change </li>\r
+ * <li> CONSTANT - can be cached across executions. </li></ul>\r
+ * <p>\r
+ * <b>NOTE</b>: the following is guaranteed: <i> \r
+ * VARIANT < SCAN_INVARIANT < QUERY_INVARIANT < CONSTANT\r
+ */\r
+ public static final int VARIANT = 0;\r
+ public static final int SCAN_INVARIANT = 1;\r
+ public static final int QUERY_INVARIANT = 2;\r
+ public static final int CONSTANT = 3;\r
+\r
+ /** \r
+ * Get the (zero based) id of the column to be qualified.\r
+ * <p>\r
+ * This id is the column number of the column in the table, no matter \r
+ * whether a partial column set is being retrieved by the actual fetch.\r
+ * Note that the column being specified in the qualifier must appear in\r
+ * the column list being fetched.\r
+ **/\r
+ int getColumnId();\r
+\r
+ /**\r
+ * Get the value that the column is to be compared to.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ DataValueDescriptor getOrderable() throws StandardException;\r
+\r
+ /** Get the operator to use in the comparison. \r
+ *\r
+ * @see DataValueDescriptor#compare\r
+ **/\r
+ int getOperator();\r
+\r
+ /** Determine if the result from the compare operation should be negated. \r
+ * If true then only rows which fail the compare operation will qualify.\r
+ *\r
+ * @see DataValueDescriptor#compare\r
+ **/\r
+ boolean negateCompareResult();\r
+\r
+ /** Get the getOrderedNulls argument to use in the comparison. \r
+ * \r
+ * @see DataValueDescriptor#compare\r
+ **/\r
+ boolean getOrderedNulls();\r
+\r
+ /** Get the getOrderedNulls argument to use in the comparison.\r
+ * \r
+ * @see DataValueDescriptor#compare\r
+ **/\r
+ boolean getUnknownRV();\r
+\r
+ /** Clear the DataValueDescriptor cache, if one exists.\r
+ * (The DataValueDescriptor can be 1 of 3 types:\r
+ * o VARIANT - cannot be cached as its value can \r
+ * vary within a scan\r
+ * o SCAN_INVARIANT - can be cached within a scan as its\r
+ * value will not change within a scan\r
+ * o QUERY_INVARIANT- can be cached across the life of the query\r
+ * as its value will never change\r
+ */\r
+ void clearOrderableCache();\r
+\r
+\r
+ /** \r
+ * This method reinitializes all the state of\r
+ * the Qualifier. It is used to distinguish between\r
+ * resetting something that is query invariant\r
+ * and something that is constant over every\r
+ * execution of a query. Basically, clearOrderableCache()\r
+ * will only clear out its cache if it is a VARIANT\r
+ * or SCAN_INVARIANT value. However, each time a\r
+ * query is executed, the QUERY_INVARIANT qualifiers need\r
+ * to be reset.\r
+ */\r
+ void reinitialize();\r
+}\r