1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 import org.apache.derby.iapi.error.StandardException; 26 import org.apache.derby.iapi.sql.execute.CursorResultSet; 27 import org.apache.derby.iapi.sql.execute.ExecRow; 28 import org.apache.derby.iapi.sql.execute.ExecutionFactory; 29 import org.apache.derby.iapi.sql.execute.TemporaryRowHolder; 30 import org.apache.derby.iapi.sql.Activation; 31 import org.apache.derby.iapi.sql.ResultDescription; 32 import org.apache.derby.iapi.store.access.ConglomerateController; 33 import org.apache.derby.iapi.store.access.ScanController; 34 import org.apache.derby.iapi.store.access.TransactionController; 35 36 import org.apache.derby.iapi.types.CloneableObject; 37 import org.apache.derby.iapi.types.RowLocation; 38 import org.apache.derby.iapi.types.DataValueDescriptor; 39 import org.apache.derby.iapi.types.SQLRef; 40 import org.apache.derby.iapi.types.SQLLongint; 41 42 43 import org.apache.derby.iapi.services.io.FormatableBitSet; 44 import java.util.Properties ; 45 46 57 class TemporaryRowHolderImpl implements TemporaryRowHolder 58 { 59 public static final int DEFAULT_OVERFLOWTHRESHOLD = 5; 60 61 protected static final int STATE_UNINIT = 0; 62 protected static final int STATE_INSERT = 1; 63 protected static final int STATE_DRAIN = 2; 64 65 66 protected ExecRow[] rowArray; 67 protected int lastArraySlot; 68 private int numRowsIn; 69 protected int state = STATE_UNINIT; 70 71 protected long CID; 72 private boolean conglomCreated; 73 private ConglomerateController cc; 74 private Properties properties; 75 private ScanController scan; 76 private ResultDescription resultDescription; 77 78 Activation activation; 79 80 private boolean isUniqueStream; 81 82 87 private boolean isVirtualMemHeap; 88 private boolean uniqueIndexCreated; 89 private boolean positionIndexCreated; 90 private long uniqueIndexConglomId; 91 private long positionIndexConglomId; 92 private ConglomerateController uniqueIndex_cc; 93 private ConglomerateController positionIndex_cc; 94 private DataValueDescriptor[] uniqueIndexRow = null; 95 private DataValueDescriptor[] positionIndexRow = null; 96 private RowLocation destRowLocation; private SQLLongint position_sqllong; 98 99 100 110 public TemporaryRowHolderImpl 111 ( 112 Activation activation, 113 Properties properties, 114 ResultDescription resultDescription 115 ) 116 { 117 this(activation, properties, resultDescription, 118 DEFAULT_OVERFLOWTHRESHOLD, false, false); 119 } 120 121 132 public TemporaryRowHolderImpl 133 ( 134 Activation activation, 135 Properties properties, 136 ResultDescription resultDescription, 137 boolean isUniqueStream 138 ) 139 { 140 this(activation, properties, resultDescription, 1, isUniqueStream, 141 false); 142 } 143 144 145 157 public TemporaryRowHolderImpl 158 ( 159 Activation activation, 160 Properties properties, 161 ResultDescription resultDescription, 162 int overflowToConglomThreshold, 163 boolean isUniqueStream, 164 boolean isVirtualMemHeap 165 ) 166 { 167 if (SanityManager.DEBUG) 168 { 169 if (overflowToConglomThreshold <= 0) 170 { 171 SanityManager.THROWASSERT("It is assumed that "+ 172 "the overflow threshold is > 0. "+ 173 "If you you need to change this you have to recode some of "+ 174 "this class."); 175 } 176 } 177 178 this.activation = activation; 179 this.properties = properties; 180 this.resultDescription = resultDescription; 181 this.isUniqueStream = isUniqueStream; 182 this.isVirtualMemHeap = isVirtualMemHeap; 183 rowArray = new ExecRow[overflowToConglomThreshold]; 184 lastArraySlot = -1; 185 } 186 187 199 private ExecRow cloneRow(ExecRow inputRow) 200 { 201 DataValueDescriptor[] cols = inputRow.getRowArray(); 202 int ncols = cols.length; 203 ExecRow cloned = ((ValueRow) inputRow).cloneMe(); 204 for (int i = 0; i < ncols; i++) 205 { 206 if (cols[i] != null) 207 { 208 209 cloned.setColumn(i + 1, (DataValueDescriptor)((CloneableObject) cols[i]).cloneObject()); 210 } 211 } 212 if (inputRow instanceof IndexValueRow) 213 return new IndexValueRow(cloned); 214 else 215 return cloned; 216 } 217 218 225 public void insert(ExecRow inputRow) 226 throws StandardException 227 { 228 229 if (SanityManager.DEBUG) 230 { 231 if(!isUniqueStream && !isVirtualMemHeap) 232 SanityManager.ASSERT(state != STATE_DRAIN, "you cannot insert rows after starting to drain"); 233 } 234 if (! isVirtualMemHeap) 235 state = STATE_INSERT; 236 237 if(uniqueIndexCreated) 238 { 239 if(isRowAlreadyExist(inputRow)) 240 return; 241 } 242 243 numRowsIn++; 244 245 if (lastArraySlot + 1 < rowArray.length) 246 { 247 rowArray[++lastArraySlot] = cloneRow(inputRow); 248 249 if(!isUniqueStream) 253 return; 254 } 255 256 if (!conglomCreated) 257 { 258 TransactionController tc = activation.getTransactionController(); 259 260 263 CID = tc.createConglomerate("heap", 264 inputRow.getRowArray(), 265 null, properties, 267 TransactionController.IS_TEMPORARY | 268 TransactionController.IS_KEPT); 269 conglomCreated = true; 270 271 cc = tc.openConglomerate(CID, 272 false, 273 TransactionController.OPENMODE_FORUPDATE, 274 TransactionController.MODE_TABLE, 275 TransactionController.ISOLATION_SERIALIZABLE); 276 if(isUniqueStream) 277 destRowLocation = cc.newRowLocationTemplate(); 278 279 } 280 281 int status = 0; 282 if(isUniqueStream) 283 { 284 cc.insertAndFetchLocation(inputRow.getRowArray(), destRowLocation); 285 insertToPositionIndex(numRowsIn -1, destRowLocation); 286 if(!uniqueIndexCreated) 288 isRowAlreadyExist(inputRow); 289 290 }else 291 { 292 status = cc.insert(inputRow.getRowArray()); 293 if (isVirtualMemHeap) 294 state = STATE_INSERT; 295 } 296 297 if (SanityManager.DEBUG) 298 { 299 if (status != 0) 300 { 301 SanityManager.THROWASSERT("got funky status ("+status+") back from "+ 302 "ConglomerateConstroller.insert()"); 303 } 304 } 305 } 306 307 308 315 316 317 private boolean isRowAlreadyExist(ExecRow inputRow) throws StandardException 318 { 319 DataValueDescriptor rlColumn; 320 RowLocation baseRowLocation; 321 rlColumn = inputRow.getColumn(inputRow.nColumns()); 322 323 if(CID!=0 && rlColumn instanceof SQLRef) 324 { 325 baseRowLocation = 326 (RowLocation) (rlColumn).getObject(); 327 328 if(!uniqueIndexCreated) 329 { 330 TransactionController tc = 331 activation.getTransactionController(); 332 int numKeys = 2; 333 uniqueIndexRow = new DataValueDescriptor[numKeys]; 334 uniqueIndexRow[0] = baseRowLocation; 335 uniqueIndexRow[1] = baseRowLocation; 336 Properties props = makeIndexProperties(uniqueIndexRow, CID); 337 uniqueIndexConglomId = 338 tc.createConglomerate("BTREE",uniqueIndexRow , null, props, 339 TransactionController.IS_TEMPORARY | 340 TransactionController.IS_KEPT); 341 uniqueIndex_cc = tc.openConglomerate( 342 uniqueIndexConglomId, 343 false, 344 TransactionController.OPENMODE_FORUPDATE, 345 TransactionController.MODE_TABLE, 346 TransactionController.ISOLATION_SERIALIZABLE); 347 uniqueIndexCreated = true; 348 } 349 350 uniqueIndexRow[0] = baseRowLocation; 351 uniqueIndexRow[1] = baseRowLocation; 352 int status; 354 if ((status = uniqueIndex_cc.insert(uniqueIndexRow))!= 0) 355 { 356 if(status == ConglomerateController.ROWISDUPLICATE) 357 { 358 return true ; } 360 else 361 { 362 if (SanityManager.DEBUG) 363 { 364 if (status != 0) 365 { 366 SanityManager.THROWASSERT("got funky status ("+status+") back from "+ 367 "Unique Index insert()"); 368 } 369 } 370 } 371 } 372 } 373 374 return false; 375 } 376 377 378 385 386 private void insertToPositionIndex(int position, RowLocation rl ) throws StandardException 387 { 388 if(!positionIndexCreated) 389 { 390 TransactionController tc = activation.getTransactionController(); 391 int numKeys = 2; 392 position_sqllong = new SQLLongint(); 393 positionIndexRow = new DataValueDescriptor[numKeys]; 394 positionIndexRow[0] = position_sqllong; 395 positionIndexRow[1] = rl; 396 Properties props = makeIndexProperties(positionIndexRow, CID); 397 positionIndexConglomId = 398 tc.createConglomerate("BTREE", positionIndexRow, null, props, 399 TransactionController.IS_TEMPORARY | 400 TransactionController.IS_KEPT); 401 positionIndex_cc = tc.openConglomerate( 402 positionIndexConglomId, 403 false, 404 TransactionController.OPENMODE_FORUPDATE, 405 TransactionController.MODE_TABLE, 406 TransactionController.ISOLATION_SERIALIZABLE); 407 positionIndexCreated = true; 408 } 409 410 position_sqllong.setValue(position); 411 positionIndexRow[0] = position_sqllong; 412 positionIndexRow[1] = rl; 413 positionIndex_cc.insert(positionIndexRow); 415 } 416 417 423 public CursorResultSet getResultSet() 424 { 425 state = STATE_DRAIN; 426 TransactionController tc = activation.getTransactionController(); 427 if(isUniqueStream) 428 { 429 return new TemporaryRowHolderResultSet(tc, rowArray, 430 resultDescription, isVirtualMemHeap, 431 true, positionIndexConglomId, this); 432 } 433 else 434 { 435 return new TemporaryRowHolderResultSet(tc, rowArray, resultDescription, isVirtualMemHeap, this); 436 437 } 438 } 439 440 448 public void truncate() throws StandardException 449 { 450 close(); 451 452 for (int i = 0; i < rowArray.length; i++) 453 { 454 rowArray[i] = null; 455 } 456 lastArraySlot = -1; 457 numRowsIn = 0; 458 state = STATE_UNINIT; 459 460 467 if (conglomCreated) 468 { 469 TransactionController tc = activation.getTransactionController(); 470 tc.dropConglomerate(CID); 471 conglomCreated = false; 472 } 473 } 474 475 public long getTemporaryConglomId() 476 { 477 return CID; 478 } 479 480 public long getPositionIndexConglomId() 481 { 482 return positionIndexConglomId; 483 } 484 485 486 487 private Properties makeIndexProperties(DataValueDescriptor[] 488 indexRowArray, long conglomId ) throws StandardException { 489 int nCols = indexRowArray.length; 490 Properties props = new Properties (); 491 props.put("allowDuplicates", "false"); 492 props.put("nKeyFields", String.valueOf(nCols)); 494 props.put("nUniqueColumns", String.valueOf(nCols-1)); 495 props.put("rowLocationColumn", String.valueOf(nCols-1)); 496 props.put("baseConglomerateId", String.valueOf(conglomId)); 497 return props; 498 } 499 500 public void setRowHolderTypeToUniqueStream() 501 { 502 isUniqueStream = true; 503 } 504 505 510 public void close() throws StandardException 511 { 512 if (scan != null) 513 { 514 scan.close(); 515 scan = null; 516 } 517 518 if (cc != null) 519 { 520 cc.close(); 521 cc = null; 522 } 523 524 if (uniqueIndex_cc != null) 525 { 526 uniqueIndex_cc.close(); 527 uniqueIndex_cc = null; 528 } 529 530 if (positionIndex_cc != null) 531 { 532 positionIndex_cc.close(); 533 positionIndex_cc = null; 534 } 535 536 TransactionController tc = activation.getTransactionController(); 537 538 if (uniqueIndexCreated) 539 { 540 tc.dropConglomerate(uniqueIndexConglomId); 541 uniqueIndexCreated = false; 542 } 543 544 if (positionIndexCreated) 545 { 546 tc.dropConglomerate(positionIndexConglomId); 547 uniqueIndexCreated = false; 548 } 549 550 if (conglomCreated) 551 { 552 tc.dropConglomerate(CID); 553 conglomCreated = false; 554 } 555 556 state = STATE_UNINIT; 557 lastArraySlot = -1; 558 } 559 } 560 561 | Popular Tags |