1 /* 2 Copyright (c) 2010, 2021, Oracle and/or its affiliates. 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License, version 2.0, 6 as published by the Free Software Foundation. 7 8 This program is also distributed with certain software (including 9 but not limited to OpenSSL) that is licensed under separate terms, 10 as designated in a particular file or component or in included license 11 documentation. The authors of MySQL hereby grant you an additional 12 permission to link the program and your derivative works with the 13 separately licensed software that they have included with MySQL. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License, version 2.0, for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 */ 24 25 package com.mysql.clusterj.core.query; 26 27 import com.mysql.clusterj.ClusterJException; 28 import com.mysql.clusterj.ClusterJFatalInternalException; 29 import com.mysql.clusterj.ClusterJUserException; 30 import com.mysql.clusterj.Query; 31 32 import com.mysql.clusterj.Query.Ordering; 33 import com.mysql.clusterj.core.query.PredicateImpl.ScanType; 34 import com.mysql.clusterj.core.spi.DomainFieldHandler; 35 import com.mysql.clusterj.core.spi.DomainTypeHandler; 36 import com.mysql.clusterj.core.spi.QueryExecutionContext; 37 import com.mysql.clusterj.core.spi.SessionSPI; 38 import com.mysql.clusterj.core.spi.ValueHandlerBatching; 39 40 import com.mysql.clusterj.core.store.Blob; 41 import com.mysql.clusterj.core.store.Column; 42 import com.mysql.clusterj.core.store.Index; 43 import com.mysql.clusterj.core.store.IndexOperation; 44 import com.mysql.clusterj.core.store.IndexScanOperation; 45 import com.mysql.clusterj.core.store.Operation; 46 import com.mysql.clusterj.core.store.ResultData; 47 import com.mysql.clusterj.core.store.ScanOperation; 48 49 import com.mysql.clusterj.core.util.I18NHelper; 50 import com.mysql.clusterj.core.util.Logger; 51 import com.mysql.clusterj.core.util.LoggerFactoryService; 52 53 import com.mysql.clusterj.query.Predicate; 54 import com.mysql.clusterj.query.PredicateOperand; 55 import com.mysql.clusterj.query.QueryDefinition; 56 import com.mysql.clusterj.query.QueryDomainType; 57 58 import java.math.BigDecimal; 59 import java.math.BigInteger; 60 import java.util.ArrayList; 61 import java.util.HashMap; 62 import java.util.List; 63 import java.util.Map; 64 65 public class QueryDomainTypeImpl<T> implements QueryDomainType<T> { 66 67 /** My message translator */ 68 static final I18NHelper local = I18NHelper.getInstance(QueryDomainTypeImpl.class); 69 70 /** My logger */ 71 static final Logger logger = LoggerFactoryService.getFactory().getInstance(QueryDomainTypeImpl.class); 72 73 /** My class. */ 74 protected Class<T> cls; 75 76 /** My DomainTypeHandler. */ 77 protected DomainTypeHandler<T> domainTypeHandler; 78 79 /** My where clause. */ 80 protected PredicateImpl where; 81 82 /** My parameters. These encapsulate the parameter names not the values. */ 83 protected Map<String, ParameterImpl> parameters = 84 new HashMap<String, ParameterImpl>(); 85 86 /** My properties. These encapsulate the property names not the values. */ 87 protected Map<String, PropertyImpl> properties = 88 new HashMap<String, PropertyImpl>(); 89 90 /** My index for this query */ 91 CandidateIndexImpl index = null; 92 93 /** My ordering fields for this query */ 94 String[] orderingFields = null; 95 96 /** My ordering for this query */ 97 Ordering ordering = null; 98 QueryDomainTypeImpl(DomainTypeHandler<T> domainTypeHandler, Class<T> cls)99 public QueryDomainTypeImpl(DomainTypeHandler<T> domainTypeHandler, Class<T> cls) { 100 this.cls = cls; 101 this.domainTypeHandler = domainTypeHandler; 102 } 103 QueryDomainTypeImpl(DomainTypeHandler<T> domainTypeHandler)104 public QueryDomainTypeImpl(DomainTypeHandler<T> domainTypeHandler) { 105 this.domainTypeHandler = domainTypeHandler; 106 } 107 get(String propertyName)108 public PredicateOperand get(String propertyName) { 109 // if called multiple times for the same property, 110 // return the same PropertyImpl instance 111 PropertyImpl property = properties.get(propertyName); 112 if (property != null) { 113 return property; 114 } else { 115 DomainFieldHandler fmd = domainTypeHandler.getFieldHandler(propertyName); 116 property = new PropertyImpl(this, fmd); 117 properties.put(propertyName, property); 118 return property; 119 } 120 } 121 122 /** Set the where clause. Mark parameters used by this query. 123 * @param predicate the predicate 124 * @return the query definition (this) 125 */ where(Predicate predicate)126 public QueryDefinition<T> where(Predicate predicate) { 127 if (predicate == null) { 128 throw new ClusterJUserException( 129 local.message("ERR_Query_Where_Must_Not_Be_Null")); 130 } 131 if (!(predicate instanceof PredicateImpl)) { 132 throw new UnsupportedOperationException( 133 local.message("ERR_NotImplemented")); 134 } 135 // if a previous where clause, unmark the parameters 136 if (where != null) { 137 where.unmarkParameters(); 138 where = null; 139 } 140 this.where = (PredicateImpl)predicate; 141 where.markParameters(); 142 // statically analyze the where clause, looking for: 143 // primary keys all specified with equal 144 // unique keys all specified with equal 145 // btree index keys partly specified with ranges 146 // none of the above 147 where.prepare(); 148 return this; 149 } 150 param(String parameterName)151 public PredicateOperand param(String parameterName) { 152 final ParameterImpl parameter = parameters.get(parameterName); 153 if (parameter != null) { 154 return parameter; 155 } else { 156 ParameterImpl result = new ParameterImpl(this, parameterName); 157 parameters.put(parameterName, result); 158 return result; 159 } 160 } 161 162 /** Convenience method to negate a predicate. 163 * @param predicate the predicate to negate 164 * @return the inverted predicate 165 */ not(Predicate predicate)166 public Predicate not(Predicate predicate) { 167 return predicate.not(); 168 } 169 170 /** Query.getResultList delegates to this method. 171 * @param skip the number of rows to skip 172 * @param limit the limit of rows to return after skipping 173 * @param orderingFields 174 * @param ordering 175 * 176 * @return the results of executing the query 177 */ getResultList(QueryExecutionContext context, long skip, long limit, Ordering ordering, String[] orderingFields)178 public List<T> getResultList(QueryExecutionContext context, long skip, long limit, 179 Ordering ordering, String[] orderingFields) { 180 assertAllParametersBound(context); 181 182 SessionSPI session = context.getSession(); 183 session.startAutoTransaction(); 184 // set up results and table information 185 List<T> resultList = new ArrayList<T>(); 186 try { 187 // execute the query 188 ResultData resultData = getResultData(context, skip, limit, ordering, orderingFields); 189 // put the result data into the result list 190 while (resultData.next()) { 191 T row = session.newInstance(resultData, domainTypeHandler); 192 resultList.add(row); 193 } 194 session.endAutoTransaction(); 195 return resultList; 196 } catch (ClusterJException ex) { 197 session.failAutoTransaction(); 198 throw ex; 199 } catch (Exception ex) { 200 session.failAutoTransaction(); 201 throw new ClusterJException( 202 local.message("ERR_Exception_On_Query"), ex); 203 } 204 } 205 206 /** Execute the query and return the result data. The type of operation 207 * (primary key lookup, unique key lookup, index scan, or table scan) 208 * depends on the where clause and the bound parameter values. 209 * 210 * @param context the query context, including the bound parameters 211 * @param skip the number of rows to skip 212 * @param limit the limit of rows to return after skipping 213 * @param orderingFields 214 * @param ordering 215 * @return the raw result data from the query 216 * @throws ClusterJUserException if not all parameters are bound 217 */ getResultData(QueryExecutionContext context, long skip, long limit, Ordering ordering, String[] orderingFields)218 public ResultData getResultData(QueryExecutionContext context, long skip, long limit, 219 Ordering ordering, String[] orderingFields) { 220 SessionSPI session = context.getSession(); 221 this.ordering = ordering; 222 this.orderingFields = orderingFields; 223 // execute query based on what kind of scan is needed 224 // if no where clause, scan the entire table 225 index = getCandidateIndex(context); 226 ScanType scanType = index.getScanType(); 227 228 if (logger.isDebugEnabled()) logger.debug("using index " + index.getIndexName() + " with scanType " + scanType); 229 Map<String, Object> explain = newExplain(index, scanType); 230 context.setExplain(explain); 231 ResultData result = null; 232 Index storeIndex; 233 Operation op = null; 234 235 try { 236 switch (scanType) { 237 238 case PRIMARY_KEY: { 239 // if skipping any results or limit is zero, return no results 240 if (skip > 0 || limit < 1) { 241 return resultDataEmpty; 242 } 243 // perform a select operation 244 op = session.getSelectOperation(domainTypeHandler.getStoreTable()); 245 op.beginDefinition(); 246 // set key values into the operation 247 index.operationSetKeys(context, op); 248 // set the expected columns into the operation 249 domainTypeHandler.operationGetValues(op); 250 op.endDefinition(); 251 // execute the select and get results 252 result = op.resultData(); 253 break; 254 } 255 256 case INDEX_SCAN: { 257 storeIndex = index.getStoreIndex(); 258 // perform an index scan operation 259 if (index.isMultiRange()) { 260 op = session.getIndexScanOperationMultiRange(storeIndex, domainTypeHandler.getStoreTable()); 261 262 } else { 263 op = session.getIndexScanOperation(storeIndex, domainTypeHandler.getStoreTable()); 264 265 } 266 op.beginDefinition(); 267 // set ordering if not already set to allow skip and limit to work 268 if (ordering == null && (skip != 0 || limit != Long.MAX_VALUE)) { 269 ordering = Ordering.ASCENDING; 270 } 271 ((ScanOperation)op).setOrdering(ordering); 272 // set the expected columns into the operation 273 domainTypeHandler.operationGetValues(op); 274 // set the bounds into the operation 275 index.operationSetBounds(context, (IndexScanOperation)op); 276 // set additional filter conditions 277 if (where != null) { 278 where.filterCmpValue(context, (IndexScanOperation)op); 279 } 280 op.endDefinition(); 281 // execute the scan and get results 282 result = ((ScanOperation)op).resultData(true, skip, limit); 283 break; 284 } 285 286 case TABLE_SCAN: { 287 if (ordering != null) { 288 throw new ClusterJUserException(local.message("ERR_Cannot_Use_Ordering_With_Table_Scan")); 289 } 290 // perform a table scan operation 291 op = session.getTableScanOperation(domainTypeHandler.getStoreTable()); 292 op.beginDefinition(); 293 // set the expected columns into the operation 294 domainTypeHandler.operationGetValues(op); 295 // set filter conditions into the operation 296 if (where != null) { 297 where.filterCmpValue(context, (ScanOperation)op); 298 } 299 op.endDefinition(); 300 // execute the scan and get results 301 result = ((ScanOperation)op).resultData(true, skip, limit); 302 break; 303 } 304 305 case UNIQUE_KEY: { 306 // if skipping any results or limit is zero, return no results 307 if (skip > 0 || limit < 1) { 308 return resultDataEmpty; 309 } 310 storeIndex = index.getStoreIndex(); 311 // perform a unique lookup operation 312 op = session.getUniqueIndexOperation(storeIndex, domainTypeHandler.getStoreTable()); 313 op.beginDefinition(); 314 // set the keys of the indexName into the operation 315 where.operationEqual(context, op); 316 // set the expected columns into the operation 317 //domainTypeHandler.operationGetValuesExcept(op, indexName); 318 domainTypeHandler.operationGetValues(op); 319 op.endDefinition(); 320 // execute the select and get results 321 result = op.resultData(); 322 break; 323 } 324 325 default: 326 session.failAutoTransaction(); 327 throw new ClusterJFatalInternalException( 328 local.message("ERR_Illegal_Scan_Type", scanType)); 329 } 330 } 331 catch (ClusterJException ex) { 332 if (op != null) { 333 op.freeResourcesAfterExecute(); 334 } 335 session.failAutoTransaction(); 336 throw ex; 337 } catch (Exception ex) { 338 if (op != null) { 339 op.freeResourcesAfterExecute(); 340 } 341 session.failAutoTransaction(); 342 throw new ClusterJException( 343 local.message("ERR_Exception_On_Query"), ex); 344 } 345 return result; 346 } 347 348 /** Delete the instances that satisfy the query and return the number 349 * of instances deleted. The type of operation used to find the instances 350 * (primary key lookup, unique key lookup, index scan, or table scan) 351 * depends on the where clause and the bound parameter values. 352 * 353 * @param context the query context, including the bound parameters 354 * @return the number of instances deleted 355 * @throws ClusterJUserException if not all parameters are bound 356 */ deletePersistentAll(QueryExecutionContext context)357 public int deletePersistentAll(QueryExecutionContext context) { 358 SessionSPI session = context.getSession(); 359 // calculate what kind of scan is needed 360 // if no where clause, scan the entire table 361 index = getCandidateIndex(context); 362 ScanType scanType = index.getScanType(); 363 Map<String, Object> explain = newExplain(index, scanType); 364 context.setExplain(explain); 365 int result = 0; 366 int errorCode = 0; 367 Index storeIndex; 368 session.startAutoTransaction(); 369 Operation op = null; 370 try { 371 switch (scanType) { 372 373 case PRIMARY_KEY: { 374 // perform a delete by primary key operation 375 if (logger.isDetailEnabled()) logger.detail("Using delete by primary key."); 376 op = session.getDeleteOperation(domainTypeHandler.getStoreTable()); 377 op.beginDefinition(); 378 // set key values into the operation 379 index.operationSetKeys(context, op); 380 op.endDefinition(); 381 // execute the delete operation 382 session.executeNoCommit(false, true); 383 errorCode = op.errorCode(); 384 // a non-zero result means the row was not deleted 385 result = (errorCode == 0?1:0); 386 break; 387 } 388 389 case UNIQUE_KEY: { 390 storeIndex = index.getStoreIndex(); 391 if (logger.isDetailEnabled()) logger.detail( 392 "Using delete by unique key " + index.getIndexName()); 393 // perform a delete by unique key operation 394 op = session.getUniqueIndexDeleteOperation(storeIndex, 395 domainTypeHandler.getStoreTable()); 396 // set the keys of the indexName into the operation 397 where.operationEqual(context, op); 398 // execute the delete operation 399 session.executeNoCommit(false, true); 400 errorCode = op.errorCode(); 401 // a non-zero result means the row was not deleted 402 result = (errorCode == 0?1:0); 403 break; 404 } 405 406 case INDEX_SCAN: { 407 storeIndex = index.getStoreIndex(); 408 if (logger.isDetailEnabled()) logger.detail( 409 "Using delete by index scan with index " + index.getIndexName()); 410 // perform an index scan operation 411 op = session.getIndexScanDeleteOperation(storeIndex, 412 domainTypeHandler.getStoreTable()); 413 // set the expected columns into the operation 414 domainTypeHandler.operationGetValues(op); 415 // set the bounds into the operation 416 index.operationSetBounds(context, (IndexScanOperation)op); 417 // set additional filter conditions 418 where.filterCmpValue(context, (IndexScanOperation)op); 419 // delete results of the scan; don't abort if no row found 420 result = session.deletePersistentAll((IndexScanOperation)op, false); 421 break; 422 } 423 424 case TABLE_SCAN: { 425 if (logger.isDetailEnabled()) logger.detail("Using delete by table scan"); 426 // perform a table scan operation 427 op = session.getTableScanDeleteOperation(domainTypeHandler.getStoreTable()); 428 // set the expected columns into the operation 429 domainTypeHandler.operationGetValues(op); 430 // set the bounds into the operation 431 if (where != null) { 432 where.filterCmpValue(context, (ScanOperation)op); 433 } 434 // delete results of the scan; don't abort if no row found 435 result = session.deletePersistentAll((ScanOperation)op, false); 436 break; 437 } 438 439 default: 440 throw new ClusterJFatalInternalException( 441 local.message("ERR_Illegal_Scan_Type", scanType)); 442 } 443 session.endAutoTransaction(); 444 return result; 445 } catch (ClusterJException e) { 446 if (op != null) { 447 op.freeResourcesAfterExecute(); 448 } 449 session.failAutoTransaction(); 450 throw e; 451 } catch (Exception e) { 452 if (op != null) { 453 op.freeResourcesAfterExecute(); 454 } 455 session.failAutoTransaction(); 456 throw new ClusterJException(local.message("ERR_Exception_On_Query"), e); 457 } 458 } 459 460 /** Update the instances that satisfy the query and return the number 461 * of instances updated. The type of operation used to update the instances 462 * (primary key lookup, unique key lookup, index scan, or table scan) 463 * depends on the where clause and the bound parameter values. 464 * Currently only update by primary key or unique key are supported. 465 * 466 * @param context the query context, including the batch of parameters 467 * @return the number of instances updated for each set in the batch of parameters 468 * @throws ClusterJUserException if not all parameters are bound 469 */ updatePersistentAll(QueryExecutionContext context, ValueHandlerBatching valueHandler)470 public long[] updatePersistentAll(QueryExecutionContext context, ValueHandlerBatching valueHandler) { 471 SessionSPI session = context.getSession(); 472 // calculate what kind of scan is needed 473 // if no where clause, scan the entire table 474 index = getCandidateIndex(context); 475 ScanType scanType = index.getScanType(); 476 Map<String, Object> explain = newExplain(index, scanType); 477 context.setExplain(explain); 478 long[] result = null; 479 List<Operation> ops = new ArrayList<Operation>(); 480 481 try { 482 switch (scanType) { 483 484 case PRIMARY_KEY: { 485 result = new long[valueHandler.getNumberOfStatements()]; 486 session.startAutoTransaction(); 487 // perform an update by primary key operation 488 if (logger.isDetailEnabled()) logger.detail("Update by primary key."); 489 // iterate the valueHandlerBatching and for each set of parameters, update one row 490 while (valueHandler.next()) { 491 Operation op = session.getUpdateOperation(domainTypeHandler.getStoreTable()); 492 // set key values into the operation 493 index.operationSetKeys(context, op); 494 // set modified field values into the operation 495 domainTypeHandler.operationSetModifiedNonPKValues(valueHandler, op); 496 ops.add(op); 497 } 498 // execute the update operations 499 session.endAutoTransaction(); 500 if (session.currentTransaction().isActive()) { 501 // autotransaction is not set; need to explicitly execute the transaction 502 session.executeNoCommit(false, true); 503 } 504 for (int i = 0; i < result.length; i++) { 505 // evaluate the results 506 int errorCode = ops.get(i).errorCode(); 507 // a non-zero result means the row was not updated 508 result[i] = (errorCode == 0 ? 1 : 0); 509 } 510 break; 511 } 512 513 case UNIQUE_KEY: { 514 result = new long[valueHandler.getNumberOfStatements()]; 515 session.startAutoTransaction(); 516 Index storeIndex = index.getStoreIndex(); 517 if (logger.isDetailEnabled()) logger.detail("Update by unique key."); 518 // iterate the valueHandlerBatching and for each set of parameters, update one row 519 while (valueHandler.next()) { 520 IndexOperation op = session.getUniqueIndexUpdateOperation(storeIndex, 521 domainTypeHandler.getStoreTable()); 522 // set the keys of the indexName into the operation 523 index.operationSetKeys(context, op); 524 // set modified field values into the operation 525 domainTypeHandler.operationSetModifiedNonPKValues(valueHandler, op); 526 ops.add(op); 527 } 528 // execute the update operations 529 session.endAutoTransaction(); 530 if (session.currentTransaction().isActive()) { 531 // autotransaction is not set; need to explicitly execute the transaction 532 session.executeNoCommit(false, true); 533 } 534 for (int i = 0; i < result.length; i++) { 535 // evaluate the results 536 int errorCode = ops.get(i).errorCode(); 537 // a non-zero result means the row was not updated 538 result[i] = (errorCode == 0 ? 1 : 0); 539 } 540 break; 541 } 542 543 case INDEX_SCAN: { 544 // not supported 545 break; 546 } 547 548 case TABLE_SCAN: { 549 // not supported 550 break; 551 } 552 553 default: 554 throw new ClusterJFatalInternalException( 555 local.message("ERR_Illegal_Scan_Type", scanType)); 556 } 557 return result; 558 } catch (ClusterJException e) { 559 for (Operation op: ops) { 560 op.freeResourcesAfterExecute(); 561 } 562 session.failAutoTransaction(); 563 throw e; 564 } catch (Exception e) { 565 for (Operation op: ops) { 566 op.freeResourcesAfterExecute(); 567 } 568 session.failAutoTransaction(); 569 throw new ClusterJException(local.message("ERR_Exception_On_Query"), e); 570 } 571 } 572 createCandidateIndexes()573 protected CandidateIndexImpl[] createCandidateIndexes() { 574 return domainTypeHandler.createCandidateIndexes(); 575 } 576 577 /** Explain how this query will be or was executed and store 578 * the result in the context. 579 * 580 * @param context the context, including bound parameters 581 */ explain(QueryExecutionContext context)582 public void explain(QueryExecutionContext context) { 583 assertAllParametersBound(context); 584 CandidateIndexImpl index = getCandidateIndex(context); 585 ScanType scanType = index.getScanType(); 586 Map<String, Object> explain = newExplain(index, scanType); 587 context.setExplain(explain); 588 } 589 getCandidateIndex(QueryExecutionContext context)590 private CandidateIndexImpl getCandidateIndex(QueryExecutionContext context) { 591 if (where == null) { 592 // there is no filter, so without ordering this is a table scan 593 // with ordering, choose an index that contains all ordering fields 594 CandidateIndexImpl[] candidateIndexImpls = domainTypeHandler.createCandidateIndexes(); 595 for (CandidateIndexImpl candidateIndexImpl: candidateIndexImpls) { 596 // choose the first index that contains all ordering fields 597 if (candidateIndexImpl.containsAllOrderingFields(orderingFields)) { 598 index = candidateIndexImpl; 599 return index; 600 } 601 } 602 index = CandidateIndexImpl.getIndexForNullWhereClause(); 603 } else { 604 // there is a filter; choose the best index that contains all ordering fields 605 index = where.getBestCandidateIndex(context, orderingFields); 606 } 607 return index; 608 } 609 610 /** Create a new explain for this query. 611 * @param index the index used 612 * @param scanType the scan type 613 * @return the explain 614 */ newExplain(CandidateIndexImpl index, ScanType scanType)615 protected Map<String, Object> newExplain(CandidateIndexImpl index, 616 ScanType scanType) { 617 Map<String, Object> explain = new HashMap<String, Object>(); 618 explain.put(Query.SCAN_TYPE, scanType.toString()); 619 explain.put(Query.INDEX_USED, index.getIndexName()); 620 return explain; 621 } 622 623 /** Assert that all parameters used by this query are bound. 624 * @param context the context, including the parameter map 625 * @throws ClusterJUserException if not all parameters are bound 626 */ assertAllParametersBound(QueryExecutionContext context)627 protected void assertAllParametersBound(QueryExecutionContext context) { 628 if (where != null) { 629 // Make sure all marked parameters (used in the query) are bound. 630 for (ParameterImpl param: parameters.values()) { 631 if (param.isMarkedAndUnbound(context)) { 632 throw new ClusterJUserException( 633 local.message("ERR_Parameter_Not_Bound", param.getName())); 634 } 635 } 636 } 637 } 638 getType()639 public Class<T> getType() { 640 return cls; 641 } 642 643 private ResultData resultDataEmpty = new ResultData() { 644 645 public boolean next() { 646 // this ResultData has no results 647 return false; 648 } 649 650 public BigInteger getBigInteger(Column columnName) { 651 return null; 652 } 653 654 public BigInteger getBigInteger(int columnNumber) { 655 return null; 656 } 657 658 public Blob getBlob(Column storeColumn) { 659 return null; 660 } 661 662 public Blob getBlob(int columnNumber) { 663 return null; 664 } 665 666 public boolean getBoolean(Column storeColumn) { 667 return false; 668 } 669 670 public boolean getBoolean(int columnNumber) { 671 return false; 672 } 673 674 public boolean[] getBooleans(Column storeColumn) { 675 return null; 676 } 677 678 public boolean[] getBooleans(int columnNumber) { 679 return null; 680 } 681 682 public byte getByte(Column storeColumn) { 683 return 0; 684 } 685 686 public byte getByte(int columnNumber) { 687 return 0; 688 } 689 690 public byte[] getBytes(Column storeColumn) { 691 return null; 692 } 693 694 public byte[] getBytes(int columnNumber) { 695 return null; 696 } 697 698 public Column[] getColumns() { 699 return null; 700 } 701 702 public BigDecimal getDecimal(Column storeColumn) { 703 return null; 704 } 705 706 public BigDecimal getDecimal(int columnNumber) { 707 return null; 708 } 709 710 public double getDouble(Column storeColumn) { 711 return 0; 712 } 713 714 public double getDouble(int columnNumber) { 715 return 0; 716 } 717 718 public float getFloat(Column storeColumn) { 719 return 0; 720 } 721 722 public float getFloat(int columnNumber) { 723 return 0; 724 } 725 726 public int getInt(Column storeColumn) { 727 return 0; 728 } 729 730 public int getInt(int columnNumber) { 731 return 0; 732 } 733 734 public long getLong(Column storeColumn) { 735 return 0; 736 } 737 738 public long getLong(int columnNumber) { 739 return 0; 740 } 741 742 public Object getObject(Column storeColumn) { 743 return null; 744 } 745 746 public Object getObject(int column) { 747 return null; 748 } 749 750 public Boolean getObjectBoolean(Column storeColumn) { 751 return null; 752 } 753 754 public Boolean getObjectBoolean(int columnNumber) { 755 return null; 756 } 757 758 public Byte getObjectByte(Column storeColumn) { 759 return null; 760 } 761 762 public Byte getObjectByte(int columnNumber) { 763 return null; 764 } 765 766 public Double getObjectDouble(Column storeColumn) { 767 return null; 768 } 769 770 public Double getObjectDouble(int columnNumber) { 771 return null; 772 } 773 774 public Float getObjectFloat(Column storeColumn) { 775 return null; 776 } 777 778 public Float getObjectFloat(int columnNumber) { 779 return null; 780 } 781 782 public Integer getObjectInteger(Column storeColumn) { 783 return null; 784 } 785 786 public Integer getObjectInteger(int columnNumber) { 787 return null; 788 } 789 790 public Long getObjectLong(Column storeColumn) { 791 return null; 792 } 793 794 public Long getObjectLong(int columnNumber) { 795 return null; 796 } 797 798 public Short getObjectShort(Column storeColumn) { 799 return null; 800 } 801 802 public Short getObjectShort(int columnNumber) { 803 return null; 804 } 805 806 public short getShort(Column storeColumn) { 807 return 0; 808 } 809 810 public short getShort(int columnNumber) { 811 return 0; 812 } 813 814 public String getString(Column storeColumn) { 815 return null; 816 } 817 818 public String getString(int columnNumber) { 819 return null; 820 } 821 822 }; 823 } 824