1 /* Copyright (c) 2001-2015, The HSQL Development Group 2 * All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of the HSQL Development Group nor the names of its 15 * contributors may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, 22 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 32 package org.hsqldb; 33 34 import org.hsqldb.HsqlNameManager.HsqlName; 35 import org.hsqldb.error.Error; 36 import org.hsqldb.error.ErrorCode; 37 import org.hsqldb.lib.HashMappedList; 38 import org.hsqldb.lib.HashSet; 39 import org.hsqldb.lib.OrderedHashSet; 40 import org.hsqldb.lib.OrderedIntHashSet; 41 import org.hsqldb.result.Result; 42 import org.hsqldb.result.ResultConstants; 43 import org.hsqldb.types.Type; 44 45 /** 46 * Implementation of Statement for PSM compound statements. 47 48 * @author Fred Toussi (fredt@users dot sourceforge.net) 49 * @version 2.3.3 50 * @since 1.9.0 51 */ 52 public class StatementCompound extends Statement implements RangeGroup { 53 54 final boolean isLoop; 55 HsqlName label; 56 StatementHandler[] handlers = StatementHandler.emptyExceptionHandlerArray; 57 boolean hasUndoHandler; 58 StatementQuery loopCursor; 59 Statement[] statements; 60 StatementExpression condition; 61 boolean isAtomic; 62 63 // 64 ColumnSchema[] variables = ColumnSchema.emptyArray; 65 StatementCursor[] cursors = StatementCursor.emptyArray; 66 HashMappedList scopeVariables = new HashMappedList(); 67 RangeVariable[] rangeVariables = RangeVariable.emptyArray; 68 Table[] tables = Table.emptyArray; 69 HashMappedList scopeTables; 70 71 // 72 int variablesOffset; 73 74 // 75 public static final StatementCompound[] emptyStatementArray = 76 new StatementCompound[]{}; 77 StatementCompound(int type, HsqlName label, StatementCompound parent)78 StatementCompound(int type, HsqlName label, StatementCompound parent) { 79 80 super(type, StatementTypes.X_SQL_CONTROL); 81 82 this.label = label; 83 isTransactionStatement = false; 84 85 switch (type) { 86 87 case StatementTypes.FOR : 88 case StatementTypes.LOOP : 89 case StatementTypes.WHILE : 90 case StatementTypes.REPEAT : 91 isLoop = true; 92 break; 93 94 case StatementTypes.BEGIN_END : 95 case StatementTypes.IF : 96 isLoop = false; 97 break; 98 99 default : 100 throw Error.runtimeError(ErrorCode.U_S0500, 101 "StatementCompound"); 102 } 103 104 this.parent = parent; 105 } 106 getSQL()107 public String getSQL() { 108 109 /* 110 StringBuffer sb = new StringBuffer(); 111 112 if (label != null) { 113 sb.append(label.getStatementName()).append(':').append(' '); 114 } 115 116 switch (type) { 117 case StatementTypes.FOR : 118 // todo 119 break; 120 121 case StatementTypes.LOOP : 122 sb.append(Tokens.T_LOOP).append(' '); 123 124 for (int i = 0; i < statements.length; i++) { 125 sb.append(statements[i].getSQL()).append(';'); 126 } 127 128 sb.append(Tokens.T_END).append(' ').append(Tokens.T_LOOP); 129 break; 130 131 case StatementTypes.WHILE : 132 sb.append(Tokens.T_WHILE).append(' '); 133 sb.append(condition.getSQL()).append(' ').append(Tokens.T_DO); 134 sb.append(' '); 135 136 for (int i = 0; i < statements.length; i++) { 137 sb.append(statements[i].getSQL()).append(';'); 138 } 139 140 sb.append(Tokens.T_END).append(' ').append(Tokens.T_WHILE); 141 break; 142 143 case StatementTypes.REPEAT : 144 sb.append(Tokens.T_REPEAT).append(' '); 145 146 for (int i = 0; i < statements.length; i++) { 147 sb.append(statements[i].getSQL()).append(';'); 148 } 149 150 sb.append(Tokens.T_UNTIL).append(' '); 151 sb.append(condition.getSQL()).append(' '); 152 sb.append(Tokens.T_END).append(' ').append(Tokens.T_REPEAT); 153 break; 154 155 case StatementTypes.BEGIN_END : 156 sb.append(Tokens.T_BEGIN).append(' ').append(Tokens.T_ATOMIC); 157 sb.append(' '); 158 159 for (int i = 0; i < handlers.length; i++) { 160 sb.append(handlers[i].getSQL()).append(';'); 161 } 162 163 for (int i = 0; i < variables.length; i++) { 164 sb.append(Tokens.T_DECLARE).append(' '); 165 sb.append(variables[i].getSQL()); 166 167 if (variables[i].hasDefault()) { 168 sb.append(' ').append(Tokens.T_DEFAULT).append(' '); 169 sb.append(variables[i].getDefaultSQL()); 170 } 171 172 sb.append(';'); 173 } 174 175 for (int i = 0; i < statements.length; i++) { 176 sb.append(statements[i].getSQL()).append(';'); 177 } 178 179 sb.append(Tokens.T_END); 180 break; 181 182 case StatementTypes.IF : 183 for (int i = 0; i < statements.length; i++) { 184 if (statements[i].type == StatementTypes.CONDITION) { 185 if (i != 0) { 186 sb.append(Tokens.T_ELSE).append(' '); 187 } 188 189 sb.append(Tokens.T_IF).append(' '); 190 sb.append(statements[i].getSQL()).append(' '); 191 sb.append(Tokens.T_THEN).append(' '); 192 } else { 193 sb.append(statements[i].getSQL()).append(';'); 194 } 195 } 196 197 sb.append(Tokens.T_END).append(' ').append(Tokens.T_IF); 198 break; 199 } 200 201 return sb.toString(); 202 */ 203 return sql; 204 } 205 describe(Session session, int blanks)206 String describe(Session session, int blanks) { 207 208 StringBuffer sb = new StringBuffer(); 209 210 sb.append('\n'); 211 212 for (int i = 0; i < blanks; i++) { 213 sb.append(' '); 214 } 215 216 sb.append(Tokens.T_STATEMENT); 217 218 return sb.toString(); 219 } 220 isLoop()221 boolean isLoop() { 222 return isLoop; 223 } 224 setLocalDeclarations(Object[] declarations)225 void setLocalDeclarations(Object[] declarations) { 226 227 int varCount = 0; 228 int handlerCount = 0; 229 int cursorCount = 0; 230 int tableCount = 0; 231 232 for (int i = 0; i < declarations.length; i++) { 233 if (declarations[i] instanceof ColumnSchema) { 234 varCount++; 235 } else if (declarations[i] instanceof StatementHandler) { 236 handlerCount++; 237 } else if (declarations[i] instanceof Table) { 238 tableCount++; 239 } else { 240 cursorCount++; 241 } 242 } 243 244 if (varCount > 0) { 245 variables = new ColumnSchema[varCount]; 246 } 247 248 if (handlerCount > 0) { 249 handlers = new StatementHandler[handlerCount]; 250 } 251 252 if (tableCount > 0) { 253 tables = new Table[tableCount]; 254 } 255 256 if (cursorCount > 0) { 257 cursors = new StatementCursor[cursorCount]; 258 } 259 260 varCount = 0; 261 handlerCount = 0; 262 tableCount = 0; 263 cursorCount = 0; 264 265 for (int i = 0; i < declarations.length; i++) { 266 if (declarations[i] instanceof ColumnSchema) { 267 variables[varCount++] = (ColumnSchema) declarations[i]; 268 } else if (declarations[i] instanceof StatementHandler) { 269 StatementHandler handler = (StatementHandler) declarations[i]; 270 271 handler.setParent(this); 272 273 handlers[handlerCount++] = handler; 274 275 if (handler.handlerType == StatementHandler.UNDO) { 276 hasUndoHandler = true; 277 } 278 } else if (declarations[i] instanceof Table) { 279 Table table = (Table) declarations[i]; 280 281 tables[tableCount++] = table; 282 } else { 283 StatementCursor cursor = (StatementCursor) declarations[i]; 284 285 cursors[cursorCount++] = cursor; 286 } 287 } 288 289 setVariables(); 290 setHandlers(); 291 setTables(); 292 setCursors(); 293 } 294 setLoopStatement(HsqlName name, StatementQuery cursorStatement)295 void setLoopStatement(HsqlName name, StatementQuery cursorStatement) { 296 297 loopCursor = cursorStatement; 298 299 HsqlName[] colNames = 300 cursorStatement.queryExpression.getResultColumnNames(); 301 Type[] colTypes = cursorStatement.queryExpression.getColumnTypes(); 302 ColumnSchema[] columns = new ColumnSchema[colNames.length]; 303 304 for (int i = 0; i < colNames.length; i++) { 305 columns[i] = new ColumnSchema(colNames[i], colTypes[i], false, 306 false, null); 307 308 columns[i].setParameterMode(SchemaObject.ParameterModes.PARAM_IN); 309 } 310 311 setLocalDeclarations(columns); 312 } 313 setStatements(Statement[] statements)314 void setStatements(Statement[] statements) { 315 316 for (int i = 0; i < statements.length; i++) { 317 statements[i].setParent(this); 318 } 319 320 this.statements = statements; 321 } 322 setCondition(StatementExpression condition)323 void setCondition(StatementExpression condition) { 324 this.condition = condition; 325 } 326 execute(Session session)327 public Result execute(Session session) { 328 329 Result result; 330 331 switch (type) { 332 333 case StatementTypes.BEGIN_END : { 334 initialiseVariables(session); 335 336 result = executeBlock(session); 337 338 break; 339 } 340 case StatementTypes.FOR : 341 result = executeForLoop(session); 342 break; 343 344 case StatementTypes.LOOP : 345 case StatementTypes.WHILE : 346 case StatementTypes.REPEAT : { 347 result = executeLoop(session); 348 349 break; 350 } 351 case StatementTypes.IF : { 352 result = executeIf(session); 353 354 break; 355 } 356 default : 357 throw Error.runtimeError(ErrorCode.U_S0500, 358 "StatementCompound"); 359 } 360 361 if (result.isError()) { 362 result.getException().setStatementType(group, type); 363 } 364 365 return result; 366 } 367 executeBlock(Session session)368 private Result executeBlock(Session session) { 369 370 Result result = Result.updateZeroResult; 371 boolean push = !root.isTrigger(); 372 373 if (push) { 374 session.sessionContext.push(); 375 376 if (hasUndoHandler) { 377 String name = HsqlNameManager.getAutoSavepointNameString( 378 session.actionTimestamp, session.sessionContext.depth); 379 380 session.savepoint(name); 381 } 382 } 383 384 for (int i = 0; i < statements.length; i++) { 385 result = executeProtected(session, statements[i]); 386 result = handleCondition(session, result); 387 388 if (result.isError()) { 389 break; 390 } 391 392 if (result.getType() == ResultConstants.VALUE) { 393 break; 394 } 395 396 if (result.getType() == ResultConstants.DATA) { 397 break; 398 } 399 } 400 401 if (result.getType() == ResultConstants.VALUE) { 402 if (result.getErrorCode() == StatementTypes.LEAVE) { 403 if (result.getMainString() == null) { 404 result = Result.updateZeroResult; 405 } else if (label != null 406 && label.name.equals(result.getMainString())) { 407 result = Result.updateZeroResult; 408 } 409 } 410 } 411 412 if (push) { 413 session.sessionContext.pop(); 414 } 415 416 return result; 417 } 418 handleCondition(Session session, Result result)419 private Result handleCondition(Session session, Result result) { 420 421 String sqlState = null; 422 423 if (result.isError()) { 424 sqlState = result.getSubString(); 425 } else if (session.getLastWarning() != null) { 426 sqlState = session.getLastWarning().getSQLState(); 427 } else { 428 return result; 429 } 430 431 if (sqlState != null) { 432 for (int i = 0; i < handlers.length; i++) { 433 StatementHandler handler = handlers[i]; 434 435 session.clearWarnings(); 436 437 /** 438 * @todo - if condition is "transaction rollback" promote to 439 * top call level without any further action 440 * if condition is system related promote to top level 441 * schema manipulation conditions are never handled 442 */ 443 if (handler.handlesCondition(sqlState)) { 444 String labelString = label == null ? null 445 : label.name; 446 447 switch (handler.handlerType) { 448 449 case StatementHandler.CONTINUE : 450 result = Result.updateZeroResult; 451 break; 452 453 case StatementHandler.UNDO : 454 session.rollbackToSavepoint(); 455 456 result = Result.newPSMResult(StatementTypes.LEAVE, 457 labelString, null); 458 break; 459 460 case StatementHandler.EXIT : 461 result = Result.newPSMResult(StatementTypes.LEAVE, 462 labelString, null); 463 break; 464 } 465 466 Result actionResult = executeProtected(session, handler); 467 468 if (actionResult.isError()) { 469 result = actionResult; 470 471 // parent should handle this 472 } else if (actionResult.getType() 473 == ResultConstants.VALUE) { 474 result = actionResult; 475 } 476 } 477 } 478 479 if (result.isError() && parent != null) { 480 481 // unhandled exception condition 482 return parent.handleCondition(session, result); 483 } 484 } 485 486 return result; 487 } 488 executeForLoop(Session session)489 private Result executeForLoop(Session session) { 490 491 Result queryResult = loopCursor.execute(session); 492 493 if (queryResult.isError()) { 494 return queryResult; 495 } 496 497 Result result = Result.updateZeroResult; 498 499 while (queryResult.navigator.hasNext()) { 500 queryResult.navigator.next(); 501 502 Object[] data = queryResult.navigator.getCurrent(); 503 504 initialiseVariables(session, data, 505 queryResult.metaData.getColumnCount()); 506 507 for (int i = 0; i < statements.length; i++) { 508 result = executeProtected(session, statements[i]); 509 result = handleCondition(session, result); 510 511 if (result.isError()) { 512 break; 513 } 514 515 if (result.getType() == ResultConstants.VALUE) { 516 break; 517 } 518 519 if (result.getType() == ResultConstants.DATA) { 520 break; 521 } 522 } 523 524 if (result.isError()) { 525 break; 526 } 527 528 if (result.getType() == ResultConstants.VALUE) { 529 if (result.getErrorCode() == StatementTypes.ITERATE) { 530 if (result.getMainString() == null) { 531 continue; 532 } 533 534 if (label != null 535 && label.name.equals(result.getMainString())) { 536 continue; 537 } 538 539 break; 540 } 541 542 if (result.getErrorCode() == StatementTypes.LEAVE) { 543 break; 544 } 545 546 // return 547 break; 548 } 549 550 if (result.getType() == ResultConstants.DATA) { 551 break; 552 } 553 } 554 555 queryResult.navigator.release(); 556 557 return result; 558 } 559 executeLoop(Session session)560 private Result executeLoop(Session session) { 561 562 Result result = Result.updateZeroResult; 563 564 while (true) { 565 if (type == StatementTypes.WHILE) { 566 result = condition.execute(session); 567 568 if (result.isError()) { 569 break; 570 } 571 572 if (!Boolean.TRUE.equals(result.getValueObject())) { 573 result = Result.updateZeroResult; 574 575 break; 576 } 577 } 578 579 for (int i = 0; i < statements.length; i++) { 580 result = executeProtected(session, statements[i]); 581 result = handleCondition(session, result); 582 583 if (result.getType() == ResultConstants.VALUE) { 584 break; 585 } 586 587 if (result.getType() == ResultConstants.DATA) { 588 break; 589 } 590 } 591 592 if (result.isError()) { 593 break; 594 } 595 596 if (result.getType() == ResultConstants.VALUE) { 597 if (result.getErrorCode() == StatementTypes.ITERATE) { 598 if (result.getMainString() == null) { 599 continue; 600 } 601 602 if (label != null 603 && label.name.equals(result.getMainString())) { 604 continue; 605 } 606 607 break; 608 } 609 610 if (result.getErrorCode() == StatementTypes.LEAVE) { 611 if (result.getMainString() == null) { 612 result = Result.updateZeroResult; 613 } 614 615 if (label != null 616 && label.name.equals(result.getMainString())) { 617 result = Result.updateZeroResult; 618 } 619 620 break; 621 } 622 623 // return 624 break; 625 } 626 627 if (result.getType() == ResultConstants.DATA) { 628 break; 629 } 630 631 if (type == StatementTypes.REPEAT) { 632 result = condition.execute(session); 633 634 if (result.isError()) { 635 break; 636 } 637 638 if (Boolean.TRUE.equals(result.getValueObject())) { 639 result = Result.updateZeroResult; 640 641 break; 642 } 643 } 644 } 645 646 return result; 647 } 648 executeIf(Session session)649 private Result executeIf(Session session) { 650 651 Result result = Result.updateZeroResult; 652 boolean execute = false; 653 654 for (int i = 0; i < statements.length; i++) { 655 if (statements[i].getType() == StatementTypes.CONDITION) { 656 if (execute) { 657 break; 658 } 659 660 result = executeProtected(session, statements[i]); 661 662 if (result.isError()) { 663 break; 664 } 665 666 Object value = result.getValueObject(); 667 668 execute = Boolean.TRUE.equals(value); 669 670 i++; 671 } 672 673 result = Result.updateZeroResult; 674 675 if (!execute) { 676 continue; 677 } 678 679 result = executeProtected(session, statements[i]); 680 result = handleCondition(session, result); 681 682 if (result.isError()) { 683 break; 684 } 685 686 if (result.getType() == ResultConstants.VALUE) { 687 break; 688 } 689 } 690 691 return result; 692 } 693 executeProtected(Session session, Statement statement)694 private Result executeProtected(Session session, Statement statement) { 695 696 int actionIndex = session.rowActionList.size(); 697 698 session.actionTimestamp = 699 session.database.txManager.getNextGlobalChangeTimestamp(); 700 701 Result result = statement.execute(session); 702 703 if (result.isError()) { 704 session.rollbackAction(actionIndex, session.actionTimestamp); 705 } 706 707 return result; 708 } 709 resolve(Session session)710 public void resolve(Session session) { 711 712 for (int i = 0; i < statements.length; i++) { 713 if (statements[i].getType() == StatementTypes.LEAVE 714 || statements[i].getType() == StatementTypes.ITERATE) { 715 if (!findLabel((StatementSimple) statements[i])) { 716 throw Error.error( 717 ErrorCode.X_42508, 718 ((StatementSimple) statements[i]).label.name); 719 } 720 721 continue; 722 } 723 724 if (statements[i].getType() == StatementTypes.RETURN) { 725 if (!root.isFunction()) { 726 throw Error.error(ErrorCode.X_42602, Tokens.T_RETURN); 727 } 728 } 729 } 730 731 for (int i = 0; i < statements.length; i++) { 732 statements[i].resolve(session); 733 } 734 735 for (int i = 0; i < handlers.length; i++) { 736 handlers[i].resolve(session); 737 } 738 739 OrderedHashSet writeTableNamesSet = new OrderedHashSet(); 740 OrderedHashSet readTableNamesSet = new OrderedHashSet(); 741 OrderedHashSet set = new OrderedHashSet(); 742 743 for (int i = 0; i < variables.length; i++) { 744 OrderedHashSet refs = variables[i].getReferences(); 745 746 if (refs != null) { 747 set.addAll(refs); 748 } 749 } 750 751 if (condition != null) { 752 set.addAll(condition.getReferences()); 753 readTableNamesSet.addAll(condition.getTableNamesForRead()); 754 } 755 756 for (int i = 0; i < statements.length; i++) { 757 set.addAll(statements[i].getReferences()); 758 readTableNamesSet.addAll(statements[i].getTableNamesForRead()); 759 writeTableNamesSet.addAll(statements[i].getTableNamesForWrite()); 760 } 761 762 for (int i = 0; i < handlers.length; i++) { 763 set.addAll(handlers[i].getReferences()); 764 readTableNamesSet.addAll(handlers[i].getTableNamesForRead()); 765 writeTableNamesSet.addAll(handlers[i].getTableNamesForWrite()); 766 } 767 768 readTableNamesSet.removeAll(writeTableNamesSet); 769 770 readTableNames = new HsqlName[readTableNamesSet.size()]; 771 772 readTableNamesSet.toArray(readTableNames); 773 774 writeTableNames = new HsqlName[writeTableNamesSet.size()]; 775 776 writeTableNamesSet.toArray(writeTableNames); 777 778 references = set; 779 } 780 setRoot(Routine routine)781 public void setRoot(Routine routine) { 782 783 root = routine; 784 /* 785 if (condition != null) { 786 condition.setRoot(routine); 787 } 788 789 for (int i = 0; i < statements.length; i++) { 790 statements[i].setRoot(routine); 791 } 792 */ 793 } 794 describe(Session session)795 public String describe(Session session) { 796 return ""; 797 } 798 getReferences()799 public OrderedHashSet getReferences() { 800 return references; 801 } 802 setAtomic(boolean atomic)803 public void setAtomic(boolean atomic) { 804 this.isAtomic = atomic; 805 } 806 807 // setVariables()808 private void setVariables() { 809 810 HashMappedList list = new HashMappedList(); 811 812 if (parent != null && parent.scopeVariables != null) { 813 for (int i = 0; i < parent.scopeVariables.size(); i++) { 814 list.add(parent.scopeVariables.getKey(i), 815 parent.scopeVariables.get(i)); 816 } 817 } 818 819 variablesOffset = list.size(); 820 821 for (int i = 0; i < variables.length; i++) { 822 String name = variables[i].getName().name; 823 boolean added = list.add(name, variables[i]); 824 825 if (!added) { 826 throw Error.error(ErrorCode.X_42606, name); 827 } 828 829 if (root.getParameterIndex(name) != -1) { 830 throw Error.error(ErrorCode.X_42606, name); 831 } 832 } 833 834 scopeVariables = list; 835 836 RangeVariable[] parameterRangeVariables = root.getRangeVariables(); 837 RangeVariable range = new RangeVariable(list, null, true, 838 RangeVariable.VARIALBE_RANGE); 839 840 rangeVariables = new RangeVariable[parameterRangeVariables.length + 1]; 841 842 for (int i = 0; i < parameterRangeVariables.length; i++) { 843 rangeVariables[i] = parameterRangeVariables[i]; 844 } 845 846 rangeVariables[parameterRangeVariables.length] = range; 847 root.variableCount = list.size(); 848 } 849 setHandlers()850 private void setHandlers() { 851 852 if (handlers.length == 0) { 853 return; 854 } 855 856 HashSet statesSet = new HashSet(); 857 OrderedIntHashSet typesSet = new OrderedIntHashSet(); 858 859 for (int i = 0; i < handlers.length; i++) { 860 int[] types = handlers[i].getConditionTypes(); 861 862 for (int j = 0; j < types.length; j++) { 863 if (!typesSet.add(types[j])) { 864 throw Error.error(ErrorCode.X_42601); 865 } 866 } 867 868 String[] states = handlers[i].getConditionStates(); 869 870 for (int j = 0; j < states.length; j++) { 871 if (!statesSet.add(states[j])) { 872 throw Error.error(ErrorCode.X_42601); 873 } 874 } 875 } 876 } 877 setTables()878 private void setTables() { 879 880 if (tables.length == 0) { 881 return; 882 } 883 884 HashMappedList list = new HashMappedList(); 885 886 if (parent != null && parent.scopeTables != null) { 887 for (int i = 0; i < parent.scopeTables.size(); i++) { 888 list.add(parent.scopeTables.getKey(i), 889 parent.scopeTables.get(i)); 890 } 891 } 892 893 for (int i = 0; i < tables.length; i++) { 894 String name = tables[i].getName().name; 895 boolean added = list.add(name, tables[i]); 896 897 if (!added) { 898 throw Error.error(ErrorCode.X_42606, name); 899 } 900 } 901 902 scopeTables = list; 903 } 904 setCursors()905 private void setCursors() { 906 907 if (cursors.length == 0) { 908 return; 909 } 910 911 HashSet list = new HashSet(); 912 913 for (int i = 0; i < cursors.length; i++) { 914 StatementCursor cursor = cursors[i]; 915 boolean added = list.add(cursor.getCursorName().name); 916 917 if (!added) { 918 throw Error.error(ErrorCode.X_42606, 919 cursor.getCursorName().name); 920 } 921 } 922 } 923 findLabel(StatementSimple statement)924 private boolean findLabel(StatementSimple statement) { 925 926 if (label != null && statement.label.name.equals(label.name)) { 927 if (!isLoop && statement.getType() == StatementTypes.ITERATE) { 928 return false; 929 } 930 931 return true; 932 } 933 934 if (parent == null) { 935 return false; 936 } 937 938 return parent.findLabel(statement); 939 } 940 initialiseVariables(Session session)941 private void initialiseVariables(Session session) { 942 943 Object[] vars = session.sessionContext.routineVariables; 944 int offset = parent == null ? 0 945 : parent.scopeVariables.size(); 946 947 for (int i = 0; i < variables.length; i++) { 948 try { 949 vars[offset + i] = variables[i].getDefaultValue(session); 950 } catch (HsqlException e) {} 951 } 952 } 953 initialiseVariables(Session session, Object[] data, int count)954 private void initialiseVariables(Session session, Object[] data, 955 int count) { 956 957 Object[] vars = session.sessionContext.routineVariables; 958 959 for (int i = 0; i < count; i++) { 960 try { 961 vars[variablesOffset + i] = data[i]; 962 } catch (HsqlException e) {} 963 } 964 } 965 getRangeVariables()966 public RangeVariable[] getRangeVariables() { 967 return rangeVariables; 968 } 969 setCorrelated()970 public void setCorrelated() { 971 972 // 973 } 974 isVariable()975 public boolean isVariable() { 976 return true; 977 } 978 } 979