1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.error.StandardException; 25 26 import org.apache.derby.iapi.services.loader.GeneratedMethod; 27 import org.apache.derby.iapi.services.sanity.SanityManager; 28 29 import org.apache.derby.iapi.sql.Activation; 30 import org.apache.derby.iapi.sql.ResultDescription; 31 32 import org.apache.derby.iapi.sql.execute.CursorResultSet; 33 import org.apache.derby.iapi.sql.execute.ExecPreparedStatement; 34 import org.apache.derby.iapi.sql.execute.ExecRow; 35 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 36 37 import org.apache.derby.iapi.types.DataValueDescriptor; 38 import org.apache.derby.iapi.types.Orderable; 39 import org.apache.derby.iapi.types.RowLocation; 40 41 import org.apache.derby.impl.sql.compile.IntersectOrExceptNode; 42 43 48 class SetOpResultSet extends NoPutResultSetImpl 49 implements CursorResultSet 50 { 51 private final NoPutResultSet leftSource; 52 private final NoPutResultSet rightSource; 53 private final Activation activation; 54 private final int opType; 55 private final boolean all; 56 private final int resultSetNumber; 57 private DataValueDescriptor[] prevCols; 60 private int rightDuplicateCount; private ExecRow leftInputRow; 62 private ExecRow rightInputRow; 63 64 private final int[] intermediateOrderByColumns; 65 private final int[] intermediateOrderByDirection; 66 67 68 private int rowsSeenLeft; 69 private int rowsSeenRight; 70 private int rowsReturned; 71 72 SetOpResultSet( NoPutResultSet leftSource, 73 NoPutResultSet rightSource, 74 Activation activation, 75 int resultSetNumber, 76 long optimizerEstimatedRowCount, 77 double optimizerEstimatedCost, 78 int opType, 79 boolean all, 80 int intermediateOrderByColumnsSavedObject, 81 int intermediateOrderByDirectionSavedObject) 82 { 83 super(activation, resultSetNumber, 84 optimizerEstimatedRowCount, optimizerEstimatedCost); 85 this.leftSource = leftSource; 86 this.rightSource = rightSource; 87 this.activation = activation; 88 this.resultSetNumber = resultSetNumber; 89 this.opType = opType; 90 this.all = all; 91 92 ExecPreparedStatement eps = activation.getPreparedStatement(); 93 intermediateOrderByColumns = (int[]) eps.getSavedObject(intermediateOrderByColumnsSavedObject); 94 intermediateOrderByDirection = (int[]) eps.getSavedObject(intermediateOrderByDirectionSavedObject); 95 constructorTime += getElapsedMillis(beginTime); 96 } 97 98 102 public void openCore() throws StandardException 103 { 104 beginTime = getCurrentTimeMillis(); 105 if (SanityManager.DEBUG) 106 SanityManager.ASSERT( ! isOpen, "SetOpResultSet already open"); 107 108 isOpen = true; 109 leftSource.openCore(); 110 rightSource.openCore(); 111 rightInputRow = rightSource.getNextRowCore(); 112 if (rightInputRow != null) 113 { 114 rowsSeenRight++; 115 } 116 117 numOpens++; 118 119 openTime += getElapsedMillis(beginTime); 120 } 122 126 public ExecRow getNextRowCore() throws StandardException 127 { 128 beginTime = getCurrentTimeMillis(); 129 if ( isOpen ) 130 { 131 while( (leftInputRow = leftSource.getNextRowCore()) != null) 132 { 133 rowsSeenLeft++; 134 135 DataValueDescriptor[] leftColumns = leftInputRow.getRowArray(); 136 if( !all) 137 { 138 if( isDuplicate( leftColumns)) 139 continue; prevCols = leftInputRow.getRowArrayClone(); 141 } 142 int compare = 0; 143 while ( rightInputRow != null && (compare = compare(leftColumns, rightInputRow.getRowArray())) > 0) 145 { 146 rightInputRow = rightSource.getNextRowCore(); 147 if (rightInputRow != null) 148 { 149 rowsSeenRight++; 150 } 151 } 152 153 if( rightInputRow == null || compare < 0) 154 { 155 if( opType == IntersectOrExceptNode.EXCEPT_OP) 157 break; 159 } 160 else 161 { 162 if( SanityManager.DEBUG) 164 SanityManager.ASSERT( rightInputRow != null && compare == 0, 165 "Intersect/Except execution has gotten confused."); 166 if ( all) 167 { 168 rightInputRow = rightSource.getNextRowCore(); 170 if (rightInputRow != null) 171 { 172 rowsSeenRight++; 173 } 174 } 175 176 if( opType == IntersectOrExceptNode.INTERSECT_OP) 179 break; 181 } 184 } 185 } 186 currentRow = leftInputRow; 187 setCurrentRow( currentRow ); 188 189 if (currentRow != null) { 190 rowsReturned++; 191 } 192 193 nextTime += getElapsedMillis(beginTime); 194 return currentRow; 195 } 197 private void advanceRightPastDuplicates( DataValueDescriptor[] leftColumns) 198 throws StandardException 199 { 200 while ((rightInputRow = rightSource.getNextRowCore()) != null) 201 { 202 rowsSeenRight++; 203 204 if (compare(leftColumns, rightInputRow.getRowArray()) == 0) 205 continue; 206 } 207 } 209 private int compare( DataValueDescriptor[] leftCols, DataValueDescriptor[] rightCols) 210 throws StandardException 211 { 212 for( int i = 0; i < intermediateOrderByColumns.length; i++) 213 { 214 int colIdx = intermediateOrderByColumns[i]; 215 if( leftCols[colIdx].compare( Orderable.ORDER_OP_LESSTHAN, 216 rightCols[colIdx], 217 true, false)) 219 return -1 * intermediateOrderByDirection[i]; 220 if( ! leftCols[colIdx].compare( Orderable.ORDER_OP_EQUALS, 221 rightCols[colIdx], 222 true, false)) 224 return intermediateOrderByDirection[i]; 225 } 226 return 0; 227 } 229 private boolean isDuplicate( DataValueDescriptor[] curColumns) 230 throws StandardException 231 { 232 if( prevCols == null) 233 return false; 234 237 for( int i = 0; i < intermediateOrderByColumns.length; i++) 238 { 239 int colIdx = intermediateOrderByColumns[i]; 240 if( ! curColumns[colIdx].compare( Orderable.ORDER_OP_EQUALS, prevCols[colIdx], true, false)) 241 return false; 242 } 243 return true; 244 } 245 246 public ExecRow getCurrentRow() 247 { 248 return currentRow; 249 } 250 251 257 public void close() throws StandardException 258 { 259 beginTime = getCurrentTimeMillis(); 260 if ( isOpen ) 261 { 262 clearCurrentRow(); 263 prevCols = null; 264 leftSource.close(); 265 rightSource.close(); 266 super.close(); 267 } 268 else 269 if (SanityManager.DEBUG) 270 SanityManager.DEBUG("CloseRepeatInfo","Close of SetOpResultSet repeated"); 271 272 closeTime += getElapsedMillis(beginTime); 273 } 275 public void finish() throws StandardException 276 { 277 leftSource.finish(); 278 rightSource.finish(); 279 finishAndRTS(); 280 } 281 282 290 public long getTimeSpent(int type) 291 { 292 long totTime = constructorTime + openTime + nextTime + closeTime; 293 294 if (type == NoPutResultSet.CURRENT_RESULTSET_ONLY) 295 { 296 return totTime - leftSource.getTimeSpent(ENTIRE_RESULTSET_TREE) 297 - rightSource.getTimeSpent(ENTIRE_RESULTSET_TREE); 298 } 299 else 300 { 301 return totTime; 302 } 303 } 305 311 public RowLocation getRowLocation() throws StandardException 312 { 313 return ((CursorResultSet)leftSource).getRowLocation(); 316 } 317 318 328 public int getOpType() 329 { 330 return opType; 331 } 332 333 338 public int getResultSetNumber() 339 { 340 return resultSetNumber; 341 } 342 343 349 public NoPutResultSet getLeftSourceInput() 350 { 351 return leftSource; 352 } 353 354 360 public NoPutResultSet getRightSourceInput() 361 { 362 return rightSource; 363 } 364 365 370 public int getRowsSeenLeft() 371 { 372 return rowsSeenLeft; 373 } 374 375 380 public int getRowsSeenRight() 381 { 382 return rowsSeenRight; 383 } 384 385 390 public int getRowsReturned() 391 { 392 return rowsReturned; 393 } 394 } 395 | Popular Tags |