1 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.sql.Activation; 33 import org.apache.derby.iapi.sql.ResultSet; 34 import org.apache.derby.iapi.types.DataValueDescriptor; 35 import org.apache.derby.iapi.reference.SQLState; 36 37 import org.apache.derby.iapi.sql.execute.ExecRow; 38 import org.apache.derby.iapi.sql.execute.ExecutionContext; 39 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 40 41 import org.apache.derby.iapi.services.loader.GeneratedMethod; 42 43 44 51 class NestedLoopLeftOuterJoinResultSet extends NestedLoopJoinResultSet 52 { 53 protected GeneratedMethod emptyRowFun; 54 55 private boolean wasRightOuterJoin; 56 57 58 private boolean matchRight = false; 59 private boolean returnedEmptyRight = false; 60 private ExecRow rightEmptyRow = null; 61 62 public int emptyRightRowsReturned = 0; 63 64 68 80 public ExecRow getNextRowCore() throws StandardException 81 { 82 ExecRow result = null; 83 boolean haveRow = false; 84 boolean restrict = false; 85 DataValueDescriptor restrictBoolean; 86 87 beginTime = getCurrentTimeMillis(); 88 if (! isOpen) 89 throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, "next"); 90 91 94 if (returnedEmptyRight) 95 { 96 100 leftRow = leftResultSet.getNextRowCore(); 101 if (leftRow == null) 102 { 103 closeRight(); 104 } 105 else 106 { 107 rowsSeenLeft++; 108 openRight(); 109 } 110 returnedEmptyRight = false; 111 } 112 113 while (leftRow != null && !haveRow) 114 { 115 rightRow = rightResultSet.getNextRowCore(); 116 117 if (rightRow == null) 118 { 119 123 if (! matchRight) 124 { 125 haveRow = true; 126 returnedEmptyRight = true; 127 if (rightEmptyRow == null) 128 { 129 rightEmptyRow = (ExecRow) emptyRowFun.invoke(activation); 130 } 131 132 getMergedRow(leftRow, rightEmptyRow); 133 emptyRightRowsReturned++; 134 continue; 135 } 136 137 141 matchRight = false; 142 leftRow = leftResultSet.getNextRowCore(); 143 if (leftRow == null) 144 { 145 closeRight(); 146 } 147 else 148 { 149 rowsSeenLeft++; 150 openRight(); 151 } 152 } 153 else 154 { 155 rowsSeenRight++; 156 157 if (restriction != null) 158 { 159 restrictBoolean = 160 (DataValueDescriptor) restriction.invoke(activation); 161 162 restrict = (! restrictBoolean.isNull()) && 165 restrictBoolean.getBoolean(); 166 167 if (! restrict) 168 { 169 170 rowsFiltered++; 171 continue; 172 } 173 } 174 175 matchRight = true; 176 177 getMergedRow(leftRow, rightRow); 178 haveRow = true; 179 } 180 } 181 182 183 if (haveRow) 184 { 185 result = mergedRow; 186 setCurrentRow(mergedRow); 187 rowsReturned++; 188 } 189 else 190 { 191 clearCurrentRow(); 192 } 193 194 nextTime += getElapsedMillis(beginTime); 195 return result; 196 } 197 198 protected void getMergedRow(ExecRow leftRow, ExecRow rightRow) 199 throws StandardException 200 { 201 int colInCtr; 202 int colOutCtr; 203 int leftNumCols; 204 int rightNumCols; 205 206 210 if (wasRightOuterJoin) 211 { 212 ExecRow tmp; 213 214 tmp = leftRow; 215 leftRow = rightRow; 216 rightRow = tmp; 217 leftNumCols = this.rightNumCols; 218 rightNumCols = this.leftNumCols; 219 } 220 else 221 { 222 leftNumCols = this.leftNumCols; 223 rightNumCols = this.rightNumCols; 224 } 225 226 229 if (mergedRow == null) 230 { 231 mergedRow = getExecutionFactory().getValueRow(leftNumCols + rightNumCols); 232 } 233 234 for (colInCtr = 1, colOutCtr = 1; colInCtr <= leftNumCols; 235 colInCtr++, colOutCtr++) 236 { 237 mergedRow.setColumn(colOutCtr, 238 leftRow.getColumn(colInCtr)); 239 } 240 for (colInCtr = 1; colInCtr <= rightNumCols; 241 colInCtr++, colOutCtr++) 242 { 243 mergedRow.setColumn(colOutCtr, 244 rightRow.getColumn(colInCtr)); 245 } 246 } 247 248 259 void clearScanState() 260 { 261 matchRight = false; 262 returnedEmptyRight = false; 263 rightEmptyRow = null; 264 emptyRightRowsReturned = 0; 265 super.clearScanState(); 266 } 267 268 269 273 NestedLoopLeftOuterJoinResultSet( 274 NoPutResultSet leftResultSet, 275 int leftNumCols, 276 NoPutResultSet rightResultSet, 277 int rightNumCols, 278 Activation activation, 279 GeneratedMethod restriction, 280 int resultSetNumber, 281 GeneratedMethod emptyRowFun, 282 boolean wasRightOuterJoin, 283 boolean oneRowRightSide, 284 boolean notExistsRightSide, 285 double optimizerEstimatedRowCount, 286 double optimizerEstimatedCost, 287 String userSuppliedOptimizerOverrides) 288 { 289 super(leftResultSet, leftNumCols, rightResultSet, rightNumCols, 290 activation, restriction, resultSetNumber, 291 oneRowRightSide, notExistsRightSide, 292 optimizerEstimatedRowCount, optimizerEstimatedCost, 293 userSuppliedOptimizerOverrides); 294 this.emptyRowFun = emptyRowFun; 295 this.wasRightOuterJoin = wasRightOuterJoin; 296 } 297 } 298 | Popular Tags |