Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / sql / execute / NestedLoopJoinResultSet.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/execute/NestedLoopJoinResultSet.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/execute/NestedLoopJoinResultSet.java
new file mode 100644 (file)
index 0000000..1cc1b04
--- /dev/null
@@ -0,0 +1,289 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.execute.NestedLoopJoinResultSet\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.execute;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.loader.GeneratedMethod;\r
+import org.apache.derby.iapi.sql.Activation;\r
+import org.apache.derby.iapi.sql.execute.ExecRow;\r
+import org.apache.derby.iapi.sql.execute.NoPutResultSet;\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+\r
+\r
+/**\r
+ * Takes 2 NoPutResultSets and a join filter and returns\r
+ * the join's rows satisfying the filter as a result set.\r
+ */\r
+class NestedLoopJoinResultSet extends JoinResultSet\r
+{\r
+       private boolean returnedRowMatchingRightSide = false;\r
+       private ExecRow rightTemplate;\r
+\r
+       //\r
+       // ResultSet interface (leftover from NoPutResultSet)\r
+       //\r
+\r
+       /**\r
+        * Clear any private state that changes during scans.\r
+        * This includes things like the last row seen, etc.\r
+        * THis does not include immutable things that are\r
+        * typically set up in the constructor.\r
+        * <p>\r
+        * This method is called on open()/close() and reopen()\r
+        * <p>\r
+        * WARNING: this should be implemented in every sub\r
+        * class and it should always call super.clearScanState().\r
+        */\r
+       void clearScanState()\r
+       {\r
+               returnedRowMatchingRightSide = false;\r
+               super.clearScanState();\r
+       }\r
+\r
+       /**\r
+     * Return the requested values computed\r
+     * from the next row (if any) for which\r
+     * the restriction evaluates to true.\r
+     * <p>\r
+     * restriction parameters\r
+     * are evaluated for each row.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        * @exception StandardException         ResultSetNotOpen thrown if closed\r
+        * @return the next row in the join result\r
+        */\r
+       public ExecRow  getNextRowCore() throws StandardException\r
+       {\r
+           ExecRow result = null;\r
+               boolean haveRow = false;\r
+           boolean restrict = false;\r
+               int colInCtr;\r
+               int colOutCtr;\r
+           DataValueDescriptor restrictBoolean;\r
+\r
+               beginTime = getCurrentTimeMillis();\r
+               if (! isOpen)\r
+                       throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, "next");\r
+\r
+               /* If we have a row from the left side and the right side is not open, \r
+                * then we get an error on the previous next, either on the next on\r
+                * the left or the open on the right.  So, we do a next on the left\r
+                * and then open the right if that succeeds.\r
+                */\r
+               if (! isRightOpen && leftRow != null)\r
+               {                \r
+                       leftRow = leftResultSet.getNextRowCore();\r
+                       if (leftRow == null)\r
+                       {\r
+                               closeRight();\r
+                       }\r
+                       else\r
+                       {\r
+                               rowsSeenLeft++;\r
+                               openRight();\r
+                       }\r
+               }\r
+\r
+               while (leftRow != null && !haveRow)\r
+               {\r
+                       if (oneRowRightSide && returnedRowMatchingRightSide)\r
+                       {\r
+                               rightRow = null;\r
+                               returnedRowMatchingRightSide = false;\r
+                       }\r
+                       else\r
+                       {\r
+                               rightRow = rightResultSet.getNextRowCore();\r
+\r
+                               /* If this is a NOT EXISTS join, we just need to reverse the logic\r
+                                * of EXISTS join.  To make the implementation simple, we create a\r
+                                * right side template, which is never really needed. (beetle 5173)\r
+                                */\r
+                               if (notExistsRightSide)\r
+                               {\r
+                                       if (rightRow == null)      //none satisfied\r
+                                               rightRow = rightTemplate;  //then we are\r
+                                       else\r
+                                               rightRow = null;\r
+                               }\r
+\r
+                               returnedRowMatchingRightSide = (rightRow != null);\r
+                       }\r
+\r
+                       if (rightRow == null)\r
+                       {\r
+                               /* Current scan on right is exhausted.  Need to close old scan \r
+                                * and open new scan with new "parameters".  openRight()        \r
+                                * will reopen if already open.\r
+                                */\r
+                               leftRow = leftResultSet.getNextRowCore();\r
+                               if (leftRow == null)\r
+                               {\r
+                                       closeRight();\r
+                               }\r
+                               else\r
+                               {\r
+                                       rowsSeenLeft++;\r
+                                       openRight();\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               rowsSeenRight++;\r
+\r
+                               if (restriction != null)\r
+                               {\r
+                                       restrictBoolean =\r
+                                               (DataValueDescriptor) restriction.invoke(activation);\r
+\r
+                               // if the result is null, we make it false --\r
+                                       // so the row won't be returned.\r
+                                       restrict = (! restrictBoolean.isNull()) &&\r
+                                                                       restrictBoolean.getBoolean();\r
+\r
+                                       if (! restrict)\r
+                                       {\r
+                                               /* Update the run time statistics */\r
+                                               rowsFiltered++;\r
+                                               continue;\r
+                                       }\r
+                               }\r
+\r
+                               /* Merge the rows, doing just in time allocation for mergedRow.\r
+                                * (By convention, left Row is to left of right Row.)\r
+                                */\r
+                               if (mergedRow == null)\r
+                               {\r
+                                       mergedRow = getExecutionFactory().getValueRow(leftNumCols + rightNumCols);\r
+                               }\r
+\r
+                               for (colInCtr = 1, colOutCtr = 1; colInCtr <= leftNumCols;\r
+                                        colInCtr++, colOutCtr++)\r
+                                       {\r
+                                                mergedRow.setColumn(colOutCtr, \r
+                                                                                        leftRow.getColumn(colInCtr));\r
+                                       }\r
+                               if (! notExistsRightSide)\r
+                               {\r
+                                       for (colInCtr = 1; colInCtr <= rightNumCols; \r
+                                                colInCtr++, colOutCtr++)\r
+                                       {\r
+                                                mergedRow.setColumn(colOutCtr, \r
+                                                                                        rightRow.getColumn(colInCtr));\r
+                                       }\r
+                               }\r
+\r
+                               setCurrentRow(mergedRow);\r
+                               haveRow = true;\r
+                       }\r
+               }\r
+\r
+               /* Do we have a row to return? */\r
+           if (haveRow)\r
+           {\r
+                       result = mergedRow;\r
+                       rowsReturned++;\r
+           }\r
+               else\r
+               {\r
+                       clearCurrentRow();\r
+               }\r
+\r
+               nextTime += getElapsedMillis(beginTime);\r
+           return result;\r
+       }\r
+\r
+       /**\r
+        * If the result set has been opened,\r
+        * close the open scan.\r
+        *\r
+        * @exception StandardException thrown on error\r
+        */\r
+       public void     close() throws StandardException\r
+       {\r
+           if ( isOpen )\r
+           {\r
+                       beginTime = getCurrentTimeMillis();\r
+\r
+                       // we don't want to keep around a pointer to the\r
+                       // row ... so it can be thrown away.\r
+                       // REVISIT: does this need to be in a finally\r
+                       // block, to ensure that it is executed?\r
+                   clearCurrentRow();\r
+\r
+                       super.close();\r
+                       returnedRowMatchingRightSide = false;\r
+                       closeTime += getElapsedMillis(beginTime);\r
+           }\r
+\r
+       }\r
+\r
+\r
+       /**\r
+        * Return the total amount of time spent in this ResultSet\r
+        *\r
+        * @param type  CURRENT_RESULTSET_ONLY - time spent only in this ResultSet\r
+        *                              ENTIRE_RESULTSET_TREE  - time spent in this ResultSet and below.\r
+        *\r
+        * @return long         The total amount of time spent (in milliseconds).\r
+        */\r
+       public long getTimeSpent(int type)\r
+       {\r
+               long totTime = constructorTime + openTime + nextTime + closeTime;\r
+\r
+               if (type == NoPutResultSet.CURRENT_RESULTSET_ONLY)\r
+               {\r
+                       return  totTime - leftResultSet.getTimeSpent(ENTIRE_RESULTSET_TREE) -\r
+                                                         rightResultSet.getTimeSpent(ENTIRE_RESULTSET_TREE);\r
+               }\r
+               else\r
+               {\r
+                       return totTime;\r
+               }\r
+       }\r
+\r
+    /*\r
+     * class interface\r
+     *\r
+     */\r
+    NestedLoopJoinResultSet(NoPutResultSet leftResultSet,\r
+                                                                  int leftNumCols,\r
+                                                                  NoPutResultSet rightResultSet,\r
+                                                                  int rightNumCols,\r
+                                                                  Activation activation,\r
+                                                                  GeneratedMethod restriction,\r
+                                                                  int resultSetNumber,\r
+                                                                  boolean oneRowRightSide,\r
+                                                                  boolean notExistsRightSide,\r
+                                                                  double optimizerEstimatedRowCount,\r
+                                                                  double optimizerEstimatedCost,\r
+                                                                  String userSuppliedOptimizerOverrides)\r
+    {\r
+               super(leftResultSet, leftNumCols, rightResultSet, rightNumCols,\r
+                         activation, restriction, resultSetNumber, \r
+                         oneRowRightSide, notExistsRightSide, optimizerEstimatedRowCount, \r
+                         optimizerEstimatedCost, userSuppliedOptimizerOverrides);\r
+               if (notExistsRightSide)\r
+                       rightTemplate = getExecutionFactory().getValueRow(rightNumCols);\r
+    }\r
+}\r