1 21 22 package org.apache.derby.impl.sql.compile; 23 24 import org.apache.derby.iapi.sql.compile.RowOrdering; 25 import org.apache.derby.iapi.sql.compile.Optimizable; 26 27 import org.apache.derby.iapi.services.sanity.SanityManager; 28 29 import org.apache.derby.iapi.error.StandardException; 30 31 import java.util.Vector ; 32 33 class RowOrderingImpl implements RowOrdering { 34 35 36 Vector ordering; 37 38 44 ColumnOrdering columnsAlwaysOrdered; 45 46 50 Vector alwaysOrderedOptimizables; 51 52 ColumnOrdering currentColumnOrdering; 53 54 55 Vector unorderedOptimizables; 56 57 RowOrderingImpl() { 58 ordering = new Vector (); 59 unorderedOptimizables = new Vector (); 60 columnsAlwaysOrdered = new ColumnOrdering(RowOrdering.DONTCARE); 61 alwaysOrderedOptimizables = new Vector (); 62 } 63 64 69 public boolean orderedOnColumn(int direction, 70 int orderPosition, 71 int tableNumber, 72 int columnNumber) 73 throws StandardException { 74 75 78 if (vectorContainsOptimizable(tableNumber, alwaysOrderedOptimizables)) 79 { 80 return true; 81 } 82 83 86 if (columnsAlwaysOrdered.contains(tableNumber, columnNumber)) { 87 return true; 88 } 89 90 94 if (orderPosition >= ordering.size()) 95 return false; 96 97 ColumnOrdering co = (ColumnOrdering) ordering.elementAt(orderPosition); 98 99 103 return co.ordered(direction, tableNumber, columnNumber); 104 } 105 106 111 public boolean orderedOnColumn(int direction, 112 int tableNumber, 113 int columnNumber) 114 throws StandardException { 115 116 119 if (vectorContainsOptimizable(tableNumber, alwaysOrderedOptimizables)) 120 { 121 return true; 122 } 123 124 127 if (columnsAlwaysOrdered.contains(tableNumber, columnNumber)) { 128 return true; 129 } 130 131 boolean ordered = false; 132 133 for (int i = 0; i < ordering.size(); i++) { 134 ColumnOrdering co = (ColumnOrdering) ordering.elementAt(i); 135 136 140 boolean thisOrdered = co.ordered(direction, 141 tableNumber, 142 columnNumber); 143 144 if (thisOrdered) { 145 ordered = true; 146 break; 147 } 148 } 149 150 return ordered; 151 } 152 153 157 private boolean vectorContainsOptimizable(int tableNumber, Vector vec) 158 { 159 int i; 160 161 for (i = vec.size() - 1; i >= 0; i--) 162 { 163 Optimizable optTable = 164 (Optimizable) vec.elementAt(i); 165 166 if (optTable.hasTableNumber()) 167 { 168 if (optTable.getTableNumber() == tableNumber) 169 { 170 return true; 171 } 172 } 173 } 174 175 return false; 176 } 177 178 179 public void addOrderedColumn(int direction, 180 int tableNumber, 181 int columnNumber) 182 { 183 if (unorderedOptimizables.size() > 0) 184 return; 185 186 ColumnOrdering currentColumnOrdering; 187 188 if (ordering.size() == 0) 189 { 190 currentColumnOrdering = new ColumnOrdering(direction); 191 ordering.addElement(currentColumnOrdering); 192 } 193 else 194 { 195 currentColumnOrdering = 196 (ColumnOrdering) ordering.elementAt(ordering.size() - 1); 197 } 198 199 if (SanityManager.DEBUG) 200 { 201 if (currentColumnOrdering.direction() != direction) 202 { 203 SanityManager.THROWASSERT("direction == " + direction + 204 ", currentColumnOrdering.direction() == " + 205 currentColumnOrdering.direction()); 206 } 207 } 208 209 currentColumnOrdering.addColumn(tableNumber, columnNumber); 210 } 211 212 213 public void nextOrderPosition(int direction) 214 { 215 if (unorderedOptimizables.size() > 0) 216 return; 217 218 currentColumnOrdering = new ColumnOrdering(direction); 219 ordering.addElement(currentColumnOrdering); 220 } 221 222 public void optimizableAlwaysOrdered(Optimizable optimizable) 223 { 224 if (unorderedOptimizablesOtherThan(optimizable)) 226 { 227 return; 228 } 229 230 242 boolean hasTableNumber = optimizable.hasTableNumber(); 243 int tableNumber = (hasTableNumber ? optimizable.getTableNumber() : 0); 244 if ( 245 ( 246 (ordering.size() == 0) || 247 ( 248 hasTableNumber && 249 ((ColumnOrdering) ordering.elementAt(0)).hasTable( 250 tableNumber) 251 ) 252 ) 253 && 254 ( 255 hasTableNumber && 256 ! columnsAlwaysOrdered.hasAnyOtherTable(tableNumber) 257 ) 258 ) 259 { 260 if (optimizable.hasTableNumber()) 261 removeOptimizable(optimizable.getTableNumber()); 262 263 alwaysOrderedOptimizables.addElement(optimizable); 264 } 265 } 266 267 268 public void columnAlwaysOrdered(Optimizable optimizable, int columnNumber) 269 { 270 columnsAlwaysOrdered.addColumn(optimizable.getTableNumber(), 271 columnNumber); 272 } 273 274 275 public boolean alwaysOrdered(int tableNumber) 276 { 277 return vectorContainsOptimizable( 278 tableNumber, 279 alwaysOrderedOptimizables 280 ); 281 } 282 283 284 public void removeOptimizable(int tableNumber) 285 { 286 int i; 287 288 292 for (i = ordering.size() - 1; i >= 0; i--) 293 { 294 297 ColumnOrdering ord = (ColumnOrdering) ordering.elementAt(i); 298 ord.removeColumns(tableNumber); 299 if (ord.empty()) 300 ordering.removeElementAt(i); 301 } 302 303 304 columnsAlwaysOrdered.removeColumns(tableNumber); 305 306 307 removeOptimizableFromVector(tableNumber, unorderedOptimizables); 308 309 310 removeOptimizableFromVector(tableNumber, alwaysOrderedOptimizables); 311 } 312 313 317 private void removeOptimizableFromVector(int tableNumber, Vector vec) 318 { 319 int i; 320 321 for (i = vec.size() - 1; i >= 0; i--) 322 { 323 Optimizable optTable = 324 (Optimizable) vec.elementAt(i); 325 326 if (optTable.hasTableNumber()) 327 { 328 if (optTable.getTableNumber() == tableNumber) 329 { 330 vec.removeElementAt(i); 331 } 332 } 333 } 334 } 335 336 337 public void addUnorderedOptimizable(Optimizable optimizable) 338 { 339 unorderedOptimizables.addElement(optimizable); 340 } 341 342 343 public void copy(RowOrdering copyTo) { 344 if (SanityManager.DEBUG) { 345 if ( ! (copyTo instanceof RowOrderingImpl) ) { 346 SanityManager.THROWASSERT( 347 "copyTo should be a RowOrderingImpl, is a " + 348 copyTo.getClass().getName()); 349 } 350 } 351 352 RowOrderingImpl dest = (RowOrderingImpl) copyTo; 353 354 355 dest.ordering.removeAllElements(); 356 dest.currentColumnOrdering = null; 357 358 dest.unorderedOptimizables.removeAllElements(); 359 for (int i = 0; i < unorderedOptimizables.size(); i++) { 360 dest.unorderedOptimizables.addElement( 361 unorderedOptimizables.elementAt(i)); 362 } 363 364 dest.alwaysOrderedOptimizables.removeAllElements(); 365 for (int i = 0; i < alwaysOrderedOptimizables.size(); i++) { 366 dest.alwaysOrderedOptimizables.addElement( 367 alwaysOrderedOptimizables.elementAt(i)); 368 } 369 370 for (int i = 0; i < ordering.size(); i++) { 371 ColumnOrdering co = (ColumnOrdering) ordering.elementAt(i); 372 373 dest.ordering.addElement(co.cloneMe()); 374 375 if (co == currentColumnOrdering) 376 dest.rememberCurrentColumnOrdering(i); 377 } 378 379 dest.columnsAlwaysOrdered = null; 380 if (columnsAlwaysOrdered != null) 381 dest.columnsAlwaysOrdered = columnsAlwaysOrdered.cloneMe(); 382 } 383 384 private void rememberCurrentColumnOrdering(int posn) { 385 currentColumnOrdering = (ColumnOrdering) ordering.elementAt(posn); 386 } 387 388 public String toString() { 389 String retval = null; 390 391 if (SanityManager.DEBUG) { 392 int i; 393 394 retval = "Unordered optimizables: "; 395 396 for (i = 0; i < unorderedOptimizables.size(); i++) 397 { 398 Optimizable opt = (Optimizable) unorderedOptimizables.elementAt(i); 399 if (opt.getBaseTableName() != null) 400 { 401 retval += opt.getBaseTableName(); 402 } 403 else 404 { 405 retval += unorderedOptimizables.elementAt(i).toString(); 406 } 407 retval += " "; 408 } 409 retval += "\n"; 410 411 retval += "\nAlways ordered optimizables: "; 412 413 for (i = 0; i < alwaysOrderedOptimizables.size(); i++) 414 { 415 Optimizable opt = (Optimizable) alwaysOrderedOptimizables.elementAt(i); 416 if (opt.getBaseTableName() != null) 417 { 418 retval += opt.getBaseTableName(); 419 } 420 else 421 { 422 retval += alwaysOrderedOptimizables.elementAt(i).toString(); 423 } 424 retval += " "; 425 } 426 retval += "\n"; 427 428 for (i = 0; i < ordering.size(); i++) { 429 retval += " ColumnOrdering " + i + ": " + ordering.elementAt(i); 430 } 431 } 432 433 return retval; 434 } 435 436 440 private boolean unorderedOptimizablesOtherThan(Optimizable optimizable) 441 { 442 for (int i = 0; i < unorderedOptimizables.size(); i++) 443 { 444 Optimizable thisOpt = 445 (Optimizable) unorderedOptimizables.elementAt(i); 446 447 if (thisOpt != optimizable) 448 return true; 449 } 450 451 return false; 452 } 453 } 454 | Popular Tags |