KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > execute > NoRowsResultSetImpl


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.NoRowsResultSetImpl
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.sql.execute;
23
24 import org.apache.derby.iapi.services.monitor.Monitor;
25
26 import org.apache.derby.iapi.services.sanity.SanityManager;
27
28 import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
29 import org.apache.derby.iapi.services.stream.InfoStreams;
30
31 import org.apache.derby.iapi.error.StandardException;
32 import org.apache.derby.iapi.services.i18n.MessageService;
33
34 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
35 import org.apache.derby.iapi.sql.conn.StatementContext;
36
37 import org.apache.derby.iapi.reference.SQLState;
38
39
40 import org.apache.derby.iapi.sql.execute.ExecRow;
41 import org.apache.derby.iapi.sql.execute.ExecutionContext;
42 import org.apache.derby.iapi.sql.execute.NoPutResultSet;
43 import org.apache.derby.iapi.sql.execute.ResultSetStatisticsFactory;
44
45 import org.apache.derby.iapi.sql.Activation;
46 import org.apache.derby.iapi.sql.ResultSet;
47 import org.apache.derby.iapi.sql.ResultDescription;
48 import org.apache.derby.iapi.sql.Row;
49
50 import org.apache.derby.iapi.services.loader.GeneratedMethod;
51
52 import org.apache.derby.iapi.types.DataValueDescriptor;
53
54 import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
55 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
56 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
57 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
58
59 import java.sql.Timestamp JavaDoc;
60 import java.sql.SQLWarning JavaDoc;
61
62 /**
63  * This implementation of ResultSet
64  * is meant to be overridden by subtypes
65  * in the execution engine. Its primary users
66  * will be DDL, which only need to define a
67  * constructor to create the DDL object being
68  * defined. All other ResultSet operations will
69  * be handled by this superclass -- i.e., nothing
70  * is allowed to be done to a DDL Result Set, since
71  * it has no rows to provide.
72  * <p>
73  * This abstract class does not define the entire ResultSet
74  * interface, but leaves the 'get' half of the interface
75  * for subtypes to implement. It is package-visible only,
76  * with its methods being public for exposure by its subtypes.
77  * <p>
78  *
79  * @author ames
80  */

81 abstract class NoRowsResultSetImpl implements ResultSet
82 {
83     final Activation activation;
84     private boolean dumpedStats;
85     NoPutResultSet[] subqueryTrackingArray;
86
87     private final boolean statisticsTimingOn;
88     private boolean isClosed;
89
90     /* fields used for formating run time statistics output */
91     protected String JavaDoc indent;
92     protected String JavaDoc subIndent;
93     protected int sourceDepth;
94
95     /* Run time statistics variables */
96     final LanguageConnectionContext lcc;
97     protected long beginTime;
98     protected long endTime;
99     protected long beginExecutionTime;
100     protected long endExecutionTime;
101
102     NoRowsResultSetImpl(Activation activation)
103         throws StandardException
104     {
105         this.activation = activation;
106
107         if (SanityManager.DEBUG) {
108             if (activation == null)
109                 SanityManager.THROWASSERT("activation is null in result set " + getClass());
110         }
111
112         lcc = activation.getLanguageConnectionContext();
113         statisticsTimingOn = lcc.getStatisticsTiming();
114
115         /* NOTE - We can't get the current time until after setting up the
116          * activation, as we end up using the activation to get the
117          * LanguageConnectionContext.
118          */

119         beginTime = getCurrentTimeMillis();
120         beginExecutionTime = beginTime;
121
122         StatementContext sc = lcc.getStatementContext();
123         sc.setTopResultSet(this, (NoPutResultSet[]) null);
124
125         // Pick up any materialized subqueries
126
if (subqueryTrackingArray == null)
127         {
128             subqueryTrackingArray = sc.getSubqueryTrackingArray();
129         }
130     }
131
132     /**
133      * Returns FALSE
134      */

135      public final boolean returnsRows() { return false; }
136
137     /**
138      * Returns zero.
139      */

140     public int modifiedRowCount() { return 0; }
141
142     /**
143      * Returns null.
144      */

145     public ResultDescription getResultDescription()
146     {
147         return (ResultDescription)null;
148     }
149     
150     public final Activation getActivation()
151     {
152         return activation;
153     }
154
155     /**
156      * Returns the row at the absolute position from the query,
157      * and returns NULL when there is no such position.
158      * (Negative position means from the end of the result set.)
159      * Moving the cursor to an invalid position leaves the cursor
160      * positioned either before the first row (negative position)
161      * or after the last row (positive position).
162      * NOTE: An exception will be thrown on 0.
163      *
164      * @param row The position.
165      * @return The row at the absolute position, or NULL if no such position.
166      *
167      * @exception StandardException Thrown on failure
168      * @see Row
169      */

170     public ExecRow getAbsoluteRow(int row) throws StandardException
171     {
172         /*
173             The JDBC use of this class will never call here.
174             Only the DB API used directly can get this exception.
175          */

176         throw StandardException.newException(SQLState.LANG_DOES_NOT_RETURN_ROWS, "absolute");
177     }
178
179     /**
180      * Returns the row at the relative position from the current
181      * cursor position, and returns NULL when there is no such position.
182      * (Negative position means toward the beginning of the result set.)
183      * Moving the cursor to an invalid position leaves the cursor
184      * positioned either before the first row (negative position)
185      * or after the last row (positive position).
186      * NOTE: 0 is valid.
187      * NOTE: An exception is thrown if the cursor is not currently
188      * positioned on a row.
189      *
190      * @param row The position.
191      * @return The row at the relative position, or NULL if no such position.
192      *
193      * @exception StandardException Thrown on failure
194      * @see Row
195      */

196     public ExecRow getRelativeRow(int row) throws StandardException
197     {
198         /*
199             The JDBC use of this class will never call here.
200             Only the DB API used directly can get this exception.
201          */

202         throw StandardException.newException(SQLState.LANG_DOES_NOT_RETURN_ROWS, "relative");
203     }
204
205     /**
206      * Sets the current position to before the first row and returns NULL
207      * because there is no current row.
208      *
209      * @return NULL.
210      *
211      * @exception StandardException Thrown on failure
212      * @see Row
213      */

214     public ExecRow setBeforeFirstRow()
215         throws StandardException
216     {
217         /*
218             The JDBC use of this class will never call here.
219             Only the DB API used directly can get this exception.
220          */

221         throw StandardException.newException(SQLState.LANG_DOES_NOT_RETURN_ROWS, "beforeFirst");
222     }
223
224     /**
225      * Returns the first row from the query, and returns NULL when there
226      * are no rows.
227      *
228      * @return The first row, or NULL if no rows.
229      *
230      * @exception StandardException Thrown on failure
231      * @see Row
232      */

233     public ExecRow getFirstRow()
234         throws StandardException
235     {
236         /*
237             The JDBC use of this class will never call here.
238             Only the DB API used directly can get this exception.
239          */

240         throw StandardException.newException(SQLState.LANG_DOES_NOT_RETURN_ROWS, "first");
241     }
242
243     /**
244      * No rows to return, so throw an exception.
245      *
246      * @exception StandardException Always throws a
247      * StandardException to indicate
248      * that this method is not intended to
249      * be used.
250      */

251     public ExecRow getNextRow() throws StandardException
252     {
253         /*
254             The JDBC use of this class will never call here.
255             Only the DB API used directly can get this exception.
256          */

257         throw StandardException.newException(SQLState.LANG_DOES_NOT_RETURN_ROWS, "next");
258     }
259
260     /**
261      * Returns the previous row from the query, and returns NULL when there
262      * are no more previous rows.
263      *
264      * @return The previous row, or NULL if no more previous rows.
265      *
266      * @exception StandardException Thrown on failure
267      * @see Row
268      */

269     public ExecRow getPreviousRow()
270         throws StandardException
271     {
272         /*
273             The JDBC use of this class will never call here.
274             Only the DB API used directly can get this exception.
275          */

276         throw StandardException.newException(SQLState.LANG_DOES_NOT_RETURN_ROWS, "previous");
277     }
278
279     /**
280      * Returns the last row from the query, and returns NULL when there
281      * are no rows.
282      *
283      * @return The last row, or NULL if no rows.
284      *
285      * @exception StandardException Thrown on failure
286      * @see Row
287      */

288     public ExecRow getLastRow()
289         throws StandardException
290     {
291         /*
292             The JDBC use of this class will never call here.
293             Only the DB API used directly can get this exception.
294          */

295         throw StandardException.newException(SQLState.LANG_DOES_NOT_RETURN_ROWS, "last");
296     }
297
298     /**
299      * Sets the current position to after the last row and returns NULL
300      * because there is no current row.
301      *
302      * @return NULL.
303      *
304      * @exception StandardException Thrown on failure
305      * @see Row
306      */

307     public ExecRow setAfterLastRow()
308         throws StandardException
309     {
310         /*
311             The JDBC use of this class will never call here.
312             Only the DB API used directly can get this exception.
313          */

314         throw StandardException.newException(SQLState.LANG_DOES_NOT_RETURN_ROWS, "afterLast");
315     }
316
317     /**
318      * Clear the current row. This is done after a commit on holdable
319      * result sets.
320      * This is a no-op on result set which do not provide rows.
321      */

322     public final void clearCurrentRow()
323     {
324         
325     }
326
327     /**
328      * Determine if the cursor is before the first row in the result
329      * set.
330      *
331      * @return true if before the first row, false otherwise. Returns
332      * false when the result set contains no rows.
333      */

334     public boolean checkRowPosition(int isType)
335     {
336         return false;
337     }
338
339     /**
340      * Returns the row number of the current row. Row
341      * numbers start from 1 and go to 'n'. Corresponds
342      * to row numbering used to position current row
343      * in the result set (as per JDBC).
344      *
345      * @return the row number, or 0 if not on a row
346      *
347      */

348     public int getRowNumber()
349     {
350         return 0;
351     }
352
353     /**
354      * No rows to return, does nothing
355      *
356      * @exception StandardException thrown on error
357      */

358     public void close() throws StandardException
359     {
360         isClosed = true;
361     }
362
363     /**
364         Just report that it is always closed.
365         RESOLVE: if we don't report that we are closed,
366         then we will wind up with a dependency problem when
367         we send an invalidateFor on our own Statement. It
368         will call lcc.verifyNoOpenResultSets(), which is really
369         supposed to be verify that there are no read only
370         result sets that are open.
371      */

372     public boolean isClosed() {
373         return isClosed;
374         //return true;
375
}
376
377     /**
378      * doesn't need to do anything, as no calls
379      * are made that need to be restricted once
380      * the result set is 'finished'.
381      *
382      * @exception StandardException on error
383      */

384     public void finish() throws StandardException {
385         if (! dumpedStats)
386         {
387             /*
388             ** If run time statistics tracing is turned on, then now is the
389             ** time to dump out the information.
390             ** NOTE - We make a special exception for commit. If autocommit
391             ** is on, then the run time statistics from the autocommit is the
392             ** only one that the user would ever see. So, we don't overwrite
393             ** the run time statistics object for a commit.
394             */

395             if (lcc.getRunTimeStatisticsMode() &&
396                 ! doesCommit())
397             {
398                 endExecutionTime = getCurrentTimeMillis();
399
400                 ExecutionContext ec = lcc.getExecutionContext();
401                 ResultSetStatisticsFactory rssf;
402                 rssf = ec.getResultSetStatisticsFactory();
403
404                 lcc.setRunTimeStatisticsObject(
405                     rssf.getRunTimeStatistics(activation, this, subqueryTrackingArray));
406
407                 HeaderPrintWriter istream = lcc.getLogQueryPlan() ? Monitor.getStream() : null;
408                 if (istream != null)
409                 {
410                     istream.printlnWithHeader(LanguageConnectionContext.xidStr +
411                                               lcc.getTransactionExecute().getTransactionIdString() +
412                                               "), " +
413                                               LanguageConnectionContext.lccStr +
414                                               lcc.getInstanceNumber() +
415                                               "), " +
416                                               lcc.getRunTimeStatisticsObject().getStatementText() + " ******* " +
417                                               lcc.getRunTimeStatisticsObject().getStatementExecutionPlanText());
418                 }
419             }
420             dumpedStats = true;
421         }
422
423         /* This is the top ResultSet,
424          * close all of the open subqueries.
425          */

426         int staLength = (subqueryTrackingArray == null) ? 0 :
427                             subqueryTrackingArray.length;
428
429         for (int index = 0; index < staLength; index++)
430         {
431             if (subqueryTrackingArray[index] == null)
432             {
433                 continue;
434             }
435             if (subqueryTrackingArray[index].isClosed())
436             {
437                 continue;
438             }
439             subqueryTrackingArray[index].close();
440         }
441     }
442
443     /**
444      * Get the execution time in milliseconds.
445      *
446      * @return long The execution time in milliseconds.
447      */

448     public long getExecuteTime()
449     {
450         return endTime - beginTime;
451     }
452
453     /**
454      * Get the Timestamp for the beginning of execution.
455      *
456      * @return Timestamp The Timestamp for the beginning of execution.
457      */

458     public Timestamp JavaDoc getBeginExecutionTimestamp()
459     {
460         if (beginExecutionTime == 0)
461         {
462             return null;
463         }
464         else
465         {
466             return new Timestamp JavaDoc(beginExecutionTime);
467         }
468     }
469
470     /**
471      * Get the Timestamp for the end of execution.
472      *
473      * @return Timestamp The Timestamp for the end of execution.
474      */

475     public Timestamp JavaDoc getEndExecutionTimestamp()
476     {
477         if (endExecutionTime == 0)
478         {
479             return null;
480         }
481         else
482         {
483             return new Timestamp JavaDoc(endExecutionTime);
484         }
485     }
486
487     /**
488      * RESOLVE - This method will go away once it is overloaded in all subclasses.
489      * Return the query plan as a String.
490      *
491      * @param depth Indentation level.
492      *
493      * @return String The query plan as a String.
494      */

495     public String JavaDoc getQueryPlanText(int depth)
496     {
497         return MessageService.getTextMessage(
498                 SQLState.LANG_GQPT_NOT_SUPPORTED,
499                 getClass().getName());
500     }
501
502     /**
503      * Return the total amount of time spent in this ResultSet
504      *
505      * @param type CURRENT_RESULTSET_ONLY - time spent only in this ResultSet
506      * ENTIRE_RESULTSET_TREE - time spent in this ResultSet and below.
507      *
508      * @return long The total amount of time spent (in milliseconds).
509      */

510     public long getTimeSpent(int type)
511     {
512         /* RESOLVE - this should be overloaded in all subclasses */
513         return 0;
514     }
515
516     /**
517      * @see ResultSet#getSubqueryTrackingArray
518      */

519     public final NoPutResultSet[] getSubqueryTrackingArray(int numSubqueries)
520     {
521         if (subqueryTrackingArray == null)
522         {
523             subqueryTrackingArray = new NoPutResultSet[numSubqueries];
524         }
525
526         return subqueryTrackingArray;
527     }
528
529     /**
530      * @see ResultSet#getAutoGeneratedKeysResultset
531      */

532     public ResultSet getAutoGeneratedKeysResultset()
533     {
534         //A non-null resultset would be returned only for an insert statement
535
return (ResultSet)null;
536     }
537
538     /**
539         Return the cursor name, null in this case.
540
541         @see ResultSet#getCursorName
542     */

543     public String JavaDoc getCursorName() {
544         return null;
545     }
546
547     // class implementation
548

549     /**
550      * Return the current time in milliseconds, if DEBUG and RunTimeStats is
551      * on, else return 0. (Only pay price of system call if need to.)
552      *
553      * @return long Current time in milliseconds.
554      */

555     protected final long getCurrentTimeMillis()
556     {
557         if (statisticsTimingOn)
558         {
559             return System.currentTimeMillis();
560         }
561         else
562         {
563             return 0;
564         }
565     }
566
567     /**
568       * Run a check constraint against the current row. Raise an error if
569       * the check constraint is violated.
570       *
571       * @param checkGM Generated code to run the check constraint.
572       * @param checkName Name of the constraint to check.
573       * @param heapConglom Number of heap conglomerate.
574       * @param activation Class in which checkGM lives.
575       *
576       * @exception StandardException thrown on error
577       */

578     public static void evaluateACheckConstraint
579     (
580       GeneratedMethod checkGM,
581       String JavaDoc checkName,
582       long heapConglom,
583       Activation activation
584     )
585         throws StandardException
586     {
587         if (checkGM != null)
588         {
589             DataValueDescriptor checkBoolean;
590
591             checkBoolean = (DataValueDescriptor) checkGM.invoke(activation);
592
593             /* Throw exception if check constraint is violated.
594              * (Only if check constraint evaluates to false.)
595              */

596             if ((checkBoolean != null) &&
597                 (! checkBoolean.isNull()) &&
598                 (! checkBoolean.getBoolean()))
599             {
600                 /* Now we have a lot of painful work to get the
601                  * table name for the error message. All we have
602                  * is the conglomerate number to work with.
603                  */

604                 DataDictionary dd = activation.getLanguageConnectionContext().getDataDictionary();
605                 ConglomerateDescriptor cd = dd.getConglomerateDescriptor( heapConglom );
606                 TableDescriptor td = dd.getTableDescriptor(cd.getTableID());
607
608                 StandardException se = StandardException.newException(SQLState.LANG_CHECK_CONSTRAINT_VIOLATED,
609                     td.getQualifiedName(), checkName);
610
611                 throw se;
612             }
613         }
614
615     }
616
617     /**
618       * Run check constraints against the current row. Raise an error if
619       * a check constraint is violated.
620       *
621       * @param checkGM Generated code to run the check constraint.
622       * @param activation Class in which checkGM lives.
623       *
624       * @exception StandardException thrown on error
625       */

626     public static void evaluateCheckConstraints
627     (
628       GeneratedMethod checkGM,
629       Activation activation
630     )
631         throws StandardException
632     {
633         if (checkGM != null)
634         {
635             // Evaluate the expression containing the check constraints.
636
// This expression will throw an exception if there is a
637
// violation, so there is no need to check the result.
638
checkGM.invoke(activation);
639         }
640
641     }
642       
643     /**
644      * Does this ResultSet cause a commit or rollback.
645      *
646      * @return Whether or not this ResultSet cause a commit or rollback.
647      */

648     public boolean doesCommit()
649     {
650         return false;
651     }
652
653     public java.sql.SQLWarning JavaDoc getWarnings() {
654         return null;
655     }
656
657 }
658
Popular Tags