001: /*
002:
003: Derby - Class org.apache.derby.iapi.store.access.Qualifier
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.store.access;
023:
024: import org.apache.derby.iapi.types.DataValueDescriptor;
025:
026: import org.apache.derby.iapi.error.StandardException;
027:
028: /**
029: <p>
030: A structure which is used to "qualify" a column. Specifies
031: that the column value in a given column identified by column
032: id is to be compared via a specific operator to a particular
033: DataValueDescriptor value.
034: <p>
035: The implementation of this interface is provided by the client;
036: the methods of Qualifier are the methods the access code uses to use it.
037: <p>
038: Arrays of qualifiers are provided to restrict the rows
039: returned by scans. A row is returned from a scan if all qualifications
040: in the array return true.
041: <p>
042: A qualification returns true if in the following pseudo-code compare_result
043: is true.
044: <p>
045: <blockquote><pre>
046: if (qualifier.negateCompareResult())
047: {
048: compare_result =
049: row[(qualifier.getColumnId())].compare(
050: qualifier.getOperator(),
051: qualifier.getOrderable(),
052: qualifier.getOrderedNulls(),
053: qualifier.getUnknownRV())
054: if (qualifier.negateCompareResult())
055: {
056: compare_result = !(compare_result);
057: }
058: }
059: </blockquote></pre>
060: <p>
061: Qualifiers are often passed through interfaces as a set of Qualifiers,
062: rather than one at a time, for example see the qualifier argument in
063: TransactionController.openScan().
064: <p>
065: To make this consistent the following protocols are to be used when passing
066: around sets of Qualifiers.
067: <p>
068: A single dimensional array is to be used to pass around a set of AND'd
069: qualifiers. Thus qualifier[] argument is to be treated as:
070: <blockquote><pre>
071: qualifier[0] AND qualifer[1] ... AND qualifier[qualifer.length - 1]
072: </blockquote></pre>
073: <p>
074: A two dimensional array is to be used to pass around a AND's and OR's in
075: conjunctive normal form. The top slot of the 2 dimensional array is optimized
076: for the more frequent where no OR's are present. The first array slot is
077: always a list of AND's to be treated as described above for single dimensional
078: AND qualifier arrays. The subsequent slots are to be treated as AND'd arrays
079: of OR's. Thus the 2 dimensional array qual[][] argument is to be treated as
080: the following, note if qual.length = 1 then only the first array is valid and
081: it is and an array of AND clauses:
082: <blockquote><pre>
083: (qual[0][0] AND qual[0][0] ... AND qual[0][qual[0].length - 1])
084: AND
085: (qual[1][0] OR qual[1][1] ... OR qual[1][qual[1].length - 1])
086: AND
087: (qual[2][0] OR qual[2][1] ... OR qual[2][qual[2].length - 1])
088: ...
089: AND (qual[qual.length - 1][0] OR qual[1][1] ... OR qual[1][2])
090: </blockquote></pre>
091: <p>
092: If any of the array's qual[0].length ... qual[qual.length -1] are 0 length
093: they will be evaluated as TRUE; but they must be not NULL. See Example 4 for
094: encoding of (a or b) that takes advantage of this.
095: <p>
096: Note that any of the arrays qual[0].length ... qual[qual.length -1] may also
097: be of length 1, thus no guarantee is made the presence of OR
098: predicates if qual.length > 1. See example 1a.
099: <p>
100: The following give pseudo-code examples of building Qualifier arrays:
101: <p>
102: Example 1: "a AND b AND c"
103: <blockquote><pre>
104: qualifier = new Qualifier[1][3]; // 3 AND clauses
105:
106: qualifier[0][0] = a
107: qualifier[0][1] = b
108: qualifier[0][2] = c
109: </blockquote></pre>
110: <p>
111: Example 1a "a AND b AND c" - less efficient than example 1 but legal
112: <blockquote><pre>
113: qualifier = new Qualifier[3]; // 3 AND clauses
114: qualifier[0] = new Qualifier[1];
115: qualifier[1] = new Qualifier[1];
116: qualifier[2] = new Qualifier[1];
117:
118: qualifier[0][0] = a
119: qualifier[1][0] = b
120: qualifier[2][0] = c
121: </blockquote></pre>
122: <p>
123: Example 2: "(f) AND (a OR b) AND (c OR d OR e)"
124: Would be represented by an array that looks like the following:
125: <blockquote><pre>
126: qualifier = new Qualifier[3]; // 3 and clauses
127: qualifier[0] = new Qualifier[1]; // to be intitialized to f
128: qualifier[1] = new Qualifier[2]; // to be initialized to (a OR b)
129: qualifier[2] = new Qualifier[3]; // to be initialized to (c OR d OR e)
130:
131: qualifier[0][0] = f
132: qualifier[1][0] = a
133: qualifier[1][1] = b
134: qualifier[2][0] = c
135: qualifier[2][1] = d
136: qualifier[2][2] = e
137: </blockquote></pre>
138: <p>
139: Example 3: "(a OR b) AND (c OR d) AND (e OR f)"
140: <blockquote><pre>
141: qualifier = new Qualifier[3]; // 3 and clauses
142: qualifier = new Qualifier[4]; // 4 and clauses
143: qualifier[0] = new Qualifier[1]; // to be intitialized to TRUE
144: qualifier[1] = new Qualifier[2]; // to be initialized to (a OR b)
145: qualifier[2] = new Qualifier[2]; // to be initialized to (c OR d)
146: qualifier[3] = new Qualifier[2]; // to be initialized to (e OR f)
147:
148: qualifier[0][0] = TRUE
149: qualifier[1][0] = a
150: qualifier[1][1] = b
151: qualifier[2][0] = c
152: qualifier[2][1] = d
153: qualifier[3][0] = e
154: qualifier[3][1] = f
155: </blockquote></pre>
156: <p>
157: Example 4: "(a OR b)"
158: <blockquote><pre>
159: qualifier = new Qualifier[2]; // 2 and clauses
160: qualifier[0] = new Qualifier[0]; // 0 length array is TRUE
161: qualifier[1] = new Qualifier[2]; // to be initialized to (a OR b)
162:
163: qualifier[1][0] = a
164: qualifier[1][1] = b
165: </blockquote></pre>
166:
167: @see ScanController
168: @see TransactionController#openScan
169: @see DataValueDescriptor#compare
170: **/
171:
172: public interface Qualifier {
173:
174: /**
175: * The DataValueDescriptor can be 1 of 4 types:<ul>
176: * <li> VARIANT - cannot be cached as its value can vary
177: * within a scan</li>
178: * <li> SCAN_INVARIANT - can be cached within a scan as its value
179: * will not change within a scan </li>
180: * <li> QUERY_INVARIANT- can be cached across the life of the query
181: * as its value will never change </li>
182: * <li> CONSTANT - can be cached across executions. </li></ul>
183: * <p>
184: * <b>NOTE</b>: the following is guaranteed: <i>
185: * VARIANT < SCAN_INVARIANT < QUERY_INVARIANT < CONSTANT
186: */
187: public static final int VARIANT = 0;
188: public static final int SCAN_INVARIANT = 1;
189: public static final int QUERY_INVARIANT = 2;
190: public static final int CONSTANT = 3;
191:
192: /**
193: * Get the (zero based) id of the column to be qualified.
194: * <p>
195: * This id is the column number of the column in the table, no matter
196: * whether a partial column set is being retrieved by the actual fetch.
197: * Note that the column being specified in the qualifier must appear in
198: * the column list being fetched.
199: **/
200: int getColumnId();
201:
202: /**
203: * Get the value that the column is to be compared to.
204: *
205: * @exception StandardException Thrown on error
206: */
207: DataValueDescriptor getOrderable() throws StandardException;
208:
209: /** Get the operator to use in the comparison.
210: *
211: * @see DataValueDescriptor#compare
212: **/
213: int getOperator();
214:
215: /** Determine if the result from the compare operation should be negated.
216: * If true then only rows which fail the compare operation will qualify.
217: *
218: * @see DataValueDescriptor#compare
219: **/
220: boolean negateCompareResult();
221:
222: /** Get the getOrderedNulls argument to use in the comparison.
223: *
224: * @see DataValueDescriptor#compare
225: **/
226: boolean getOrderedNulls();
227:
228: /** Get the getOrderedNulls argument to use in the comparison.
229: *
230: * @see DataValueDescriptor#compare
231: **/
232: boolean getUnknownRV();
233:
234: /** Clear the DataValueDescriptor cache, if one exists.
235: * (The DataValueDescriptor can be 1 of 3 types:
236: * o VARIANT - cannot be cached as its value can
237: * vary within a scan
238: * o SCAN_INVARIANT - can be cached within a scan as its
239: * value will not change within a scan
240: * o QUERY_INVARIANT- can be cached across the life of the query
241: * as its value will never change
242: */
243: void clearOrderableCache();
244:
245: /**
246: * This method reinitializes all the state of
247: * the Qualifier. It is used to distinguish between
248: * resetting something that is query invariant
249: * and something that is constant over every
250: * execution of a query. Basically, clearOrderableCache()
251: * will only clear out its cache if it is a VARIANT
252: * or SCAN_INVARIANT value. However, each time a
253: * query is executed, the QUERY_INVARIANT qualifiers need
254: * to be reset.
255: */
256: void reinitialize();
257: }
|