| 1 65 66 67 package org.hsqldb; 68 69 import java.io.DataInput ; 70 import java.io.IOException ; 71 import java.io.OutputStream ; 72 import java.util.NoSuchElementException ; 73 74 import org.hsqldb.lib.Iterator; 75 import org.hsqldb.rowio.RowInputBinary; 76 import org.hsqldb.rowio.RowOutputBinary; 77 78 85 101 public class Result { 102 103 public Record rRoot; 105 private Record rTail; 106 private int size; 107 108 private int significantColumns; 110 111 public int mode; 113 114 int databaseID; 117 118 int sessionID; 120 121 String mainString; 123 String subString; 124 125 String subSubString; 127 128 private Throwable exception; 130 131 int statementID; 133 134 int updateCount; 136 public ResultMetaData metaData; 137 138 139 public static class ResultMetaData { 140 141 public String [] colLabels; 143 public String [] tableNames; 144 public String [] colNames; 145 public boolean[] isLabelQuoted; 146 public int[] colTypes; 147 public int[] colSizes; 148 public int[] colScales; 149 150 public String [] catalogNames; 152 public String [] schemaNames; 153 public int[] colNullable; 154 public boolean[] isIdentity; 155 public boolean[] isWritable; 156 public int[] paramMode; 157 158 public String [] classNames; 164 boolean isParameterDescription; 165 166 ResultMetaData() {} 167 168 ResultMetaData(int n) { 169 prepareData(n); 170 } 171 172 177 private void prepareData(int columns) { 178 179 colLabels = new String [columns]; 180 tableNames = new String [columns]; 181 colNames = new String [columns]; 182 isLabelQuoted = new boolean[columns]; 183 colTypes = new int[columns]; 184 colSizes = new int[columns]; 185 colScales = new int[columns]; 186 catalogNames = new String [columns]; 187 schemaNames = new String [columns]; 188 colNullable = new int[columns]; 189 isIdentity = new boolean[columns]; 190 isWritable = new boolean[columns]; 191 classNames = new String [columns]; 192 } 193 194 public int[] getParameterTypes() { 195 return colTypes; 196 } 197 198 boolean isTableColumn(int i) { 199 return tableNames[i] != null && tableNames[i].length() > 0 200 && colNames[i] != null && colNames[i].length() > 0; 201 } 202 203 private void decodeTableColumnAttrs(int in, int i) { 204 205 colNullable[i] = in & 0x0000000f; 206 isIdentity[i] = (in & 0x00000010) != 0; 207 isWritable[i] = (in & 0x00000020) != 0; 208 } 209 210 private void writeTableColumnAttrs(RowOutputBinary out, 211 int i) 212 throws IOException , HsqlException { 213 214 out.writeIntData(encodeTableColumnAttrs(i)); 252 out.writeString(catalogNames[i] == null ? "" 253 : catalogNames[i]); 254 out.writeString(schemaNames[i] == null ? "" 255 : schemaNames[i]); 256 } 257 258 private int encodeTableColumnAttrs(int i) { 259 260 int out = colNullable[i]; 262 if (isIdentity[i]) { 263 out |= 0x00000010; 264 } 265 266 if (isWritable[i]) { 267 out |= 0x00000020; 268 } 269 270 return out; 271 } 272 273 private void readTableColumnAttrs(RowInputBinary in, 274 int i) 275 throws IOException , HsqlException { 276 277 decodeTableColumnAttrs(in.readIntData(), i); 278 279 catalogNames[i] = in.readString(); 280 schemaNames[i] = in.readString(); 281 } 282 283 ResultMetaData(RowInputBinary in, 284 int mode) throws HsqlException, IOException { 285 286 int l = in.readIntData(); 287 288 prepareData(l); 289 290 if (mode == ResultConstants.PARAM_META_DATA) { 291 isParameterDescription = true; 292 paramMode = new int[l]; 293 } 294 295 for (int i = 0; i < l; i++) { 296 colTypes[i] = in.readType(); 297 298 colSizes[i] = in.readIntData(); 300 colScales[i] = in.readIntData(); 301 colLabels[i] = in.readString(); 302 tableNames[i] = in.readString(); 303 colNames[i] = in.readString(); 304 classNames[i] = in.readString(); 305 306 if (isTableColumn(i)) { 307 readTableColumnAttrs(in, i); 308 } 309 310 if (mode == ResultConstants.PARAM_META_DATA) { 311 paramMode[i] = in.readIntData(); 312 } 313 } 314 } 315 316 void write(RowOutputBinary out, 317 int colCount) throws HsqlException, IOException { 318 319 out.writeIntData(colCount); 320 321 for (int i = 0; i < colCount; i++) { 322 out.writeType(colTypes[i]); 323 324 out.writeIntData(colSizes[i]); 326 out.writeIntData(colScales[i]); 327 out.writeString(colLabels[i] == null ? "" 328 : colLabels[i]); 329 out.writeString(tableNames[i] == null ? "" 330 : tableNames[i]); 331 out.writeString(colNames[i] == null ? "" 332 : colNames[i]); 333 out.writeString(classNames[i] == null ? "" 334 : classNames[i]); 335 336 if (isTableColumn(i)) { 337 writeTableColumnAttrs(out, i); 338 } 339 340 if (isParameterDescription) { 341 out.writeIntData(paramMode[i]); 342 } 343 } 344 } 345 } 346 347 350 public Result(int type) { 351 352 mode = type; 353 354 359 if (type == ResultConstants.DATA 360 || type == ResultConstants.PARAM_META_DATA 361 || type == ResultConstants.SQLEXECUTE 362 || type == ResultConstants.SETSESSIONATTR) { 363 metaData = new ResultMetaData(); 364 } 365 } 366 367 Result(ResultMetaData md) { 368 369 mode = ResultConstants.DATA; 370 significantColumns = md.colTypes.length; 371 metaData = md; 372 } 373 374 376 383 Result(String error, String state, int code) { 384 385 mode = ResultConstants.ERROR; 386 mainString = error; 387 subString = state; 388 statementID = code; 389 subSubString = ""; 390 } 391 392 397 Result(int type, int columns) { 398 399 metaData = new ResultMetaData(); 400 401 metaData.prepareData(columns); 402 403 if (type == ResultConstants.PARAM_META_DATA) { 404 metaData.isParameterDescription = true; 405 metaData.paramMode = new int[columns]; 406 } 407 408 mode = type; 409 significantColumns = columns; 410 } 411 412 415 public Result(int type, int[] types, int id) { 416 417 mode = type; 418 metaData = new ResultMetaData(); 419 metaData.colTypes = types; 420 significantColumns = types.length; 421 statementID = id; 422 } 423 424 430 Result(RowInputBinary in) throws HsqlException { 431 432 try { 433 mode = in.readIntData(); 434 435 if (mode == ResultConstants.MULTI) { 436 readMultiResult(in); 437 438 return; 439 } 440 441 databaseID = in.readIntData(); 442 sessionID = in.readIntData(); 443 444 switch (mode) { 445 446 case ResultConstants.GETSESSIONATTR : 447 case ResultConstants.SQLDISCONNECT : 448 case ResultConstants.SQLSTARTTRAN : 449 case ResultConstants.HSQLRESETSESSION : 450 break; 451 452 case ResultConstants.SQLPREPARE : 453 setStatementType(in.readIntData()); 454 455 mainString = in.readString(); 456 break; 457 458 case ResultConstants.PREPARE_ACK : 459 case ResultConstants.SQLFREESTMT : 460 statementID = in.readIntData(); 461 break; 462 463 case ResultConstants.SQLEXECDIRECT : 464 updateCount = in.readIntData(); 465 statementID = in.readIntData(); 466 mainString = in.readString(); 467 break; 468 469 case ResultConstants.ERROR : 470 case ResultConstants.SQLCONNECT : 471 mainString = in.readString(); 472 subString = in.readString(); 473 subSubString = in.readString(); 474 statementID = in.readIntData(); 475 476 break; 478 479 case ResultConstants.UPDATECOUNT : 480 updateCount = in.readIntData(); 481 break; 482 483 case ResultConstants.SQLENDTRAN : { 484 int type = in.readIntData(); 485 486 setEndTranType(type); 488 switch (type) { 489 490 case ResultConstants.SAVEPOINT_NAME_RELEASE : 491 case ResultConstants.SAVEPOINT_NAME_ROLLBACK : 492 mainString = in.readString(); } 494 495 break; 496 } 497 case ResultConstants.BATCHEXECUTE : 498 case ResultConstants.BATCHEXECDIRECT : 499 case ResultConstants.SQLEXECUTE : 500 case ResultConstants.SETSESSIONATTR : { 501 updateCount = in.readIntData(); 502 statementID = in.readIntData(); 503 504 int l = in.readIntData(); 505 506 metaData = new ResultMetaData(l); 507 significantColumns = l; 508 509 for (int i = 0; i < l; i++) { 510 metaData.colTypes[i] = in.readType(); 511 } 512 513 int count = in.readIntData(); 514 515 while (count-- > 0) { 516 add(in.readData(metaData.colTypes)); 517 } 518 519 break; 520 } 521 case ResultConstants.DATA : 522 case ResultConstants.PARAM_META_DATA : { 523 metaData = new ResultMetaData(in, mode); 524 significantColumns = metaData.colLabels.length; 525 526 int count = in.readIntData(); 527 528 while (count-- > 0) { 529 add(in.readData(metaData.colTypes)); 530 } 531 532 break; 533 } 534 case ResultConstants.SQLSETCONNECTATTR : { 535 int type = in.readIntData(); 537 setConnectionAttrType(type); 538 539 switch (type) { 540 541 case ResultConstants.SQL_ATTR_SAVEPOINT_NAME : 542 mainString = in.readString(); 544 } 548 549 break; 550 } 551 default : 552 throw new HsqlException( 553 Trace.getMessage( 554 Trace.Result_Result, true, new Object []{ 555 new Integer (mode) }), null, 0); 556 } 557 } catch (IOException e) { 558 throw Trace.error(Trace.TRANSFER_CORRUPTED); 559 } 560 } 561 562 static Result newSingleColumnResult(String colName, int colType) { 563 564 Result result = new Result(ResultConstants.DATA, 1); 565 566 result.metaData.colNames[0] = colName; 567 result.metaData.colLabels[0] = colName; 568 result.metaData.tableNames[0] = ""; 569 result.metaData.colTypes[0] = colType; 570 571 return result; 572 } 573 574 static Result newPrepareResponse(int csid, Result rsmd, Result pmd) { 575 576 Result out; 577 Result pack; 578 579 out = new Result(ResultConstants.MULTI); 580 581 pack = new Result(ResultConstants.PREPARE_ACK); 583 pack.statementID = csid; 584 585 out.add(new Object []{ pack }); 586 out.add(new Object []{ rsmd }); 587 out.add(new Object []{ pmd }); 588 589 return out; 590 } 591 592 static Result newParameterDescriptionResult(int len) { 593 594 Result r = new Result(ResultConstants.PARAM_META_DATA, len); 595 596 r.metaData.isParameterDescription = true; 597 r.metaData.paramMode = new int[len]; 598 599 return r; 600 } 601 602 public static Result newFreeStmtRequest(int statementID) { 603 604 Result r = new Result(ResultConstants.SQLFREESTMT); 605 606 r.statementID = statementID; 607 608 return r; 609 } 610 611 static Result newExecuteDirectRequest(String sql) { 612 613 Result out; 614 615 out = new Result(ResultConstants.SQLEXECDIRECT); 616 617 out.setMainString(sql); 618 619 return out; 620 } 621 622 public static Result newReleaseSavepointRequest(String name) { 623 624 Result out; 625 626 out = new Result(ResultConstants.SQLENDTRAN); 627 628 out.setMainString(name); 629 out.setEndTranType(ResultConstants.SAVEPOINT_NAME_RELEASE); 630 631 return out; 632 } 633 634 public static Result newRollbackToSavepointRequest(String name) { 635 636 Result out; 637 638 out = new Result(ResultConstants.SQLENDTRAN); 639 640 out.setMainString(name); 641 out.setEndTranType(ResultConstants.SAVEPOINT_NAME_ROLLBACK); 642 643 return out; 644 } 645 646 public static Result newSetSavepointRequest(String name) { 647 648 Result out; 649 650 out = new Result(ResultConstants.SQLSETCONNECTATTR); 651 652 out.setConnectionAttrType(ResultConstants.SQL_ATTR_SAVEPOINT_NAME); 653 out.setMainString(name); 654 655 return out; 656 } 657 658 663 public int getSize() { 664 return size; 665 } 666 667 672 void setColumnCount(int columns) { 673 significantColumns = columns; 674 } 675 676 681 public int getColumnCount() { 682 return significantColumns; 683 } 684 685 690 void append(Result a) { 691 692 if (a.rRoot == null) { 693 return; 694 } 695 696 if (rRoot == null) { 697 rRoot = a.rRoot; 698 } else { 699 rTail.next = a.rRoot; 700 } 701 702 rTail = a.rTail; 703 size += a.size; 704 } 705 706 void addAll(Result r) { 707 708 if (r == null) { 709 return; 710 } 711 712 Record from = r.rRoot; 713 714 while (from != null) { 715 add(from.data); 716 717 from = from.next; 718 } 719 } 720 721 public void clear() { 722 723 rRoot = null; 724 rTail = null; 725 size = 0; 726 } 727 728 public boolean isEmpty() { 729 return rRoot == null; 730 } 731 732 737 void setRows(Result a) { 738 739 if (a == null) { 740 rRoot = null; 741 rTail = null; 742 size = 0; 743 } else { 744 rRoot = a.rRoot; 745 rTail = a.rTail; 746 size = a.size; 747 } 748 } 749 750 755 public void add(Object [] d) { 756 757 Record r = new Record(); 758 759 r.data = d; 760 761 if (rRoot == null) { 762 rRoot = r; 763 } else { 764 rTail.next = r; 765 } 766 767 rTail = r; 768 769 size++; 770 } 771 772 778 779 void trimResult(int limitstart, int limitcount) { 782 783 Record n = rRoot; 784 785 if (n == null) { 786 return; 787 } 788 789 if (limitstart >= size) { 790 size = 0; 791 rRoot = rTail = null; 792 793 return; 794 } 795 796 size -= limitstart; 797 798 for (int i = 0; i < limitstart; i++) { 799 n = n.next; 800 801 if (n == null) { 802 803 size = 0; 805 rRoot = rTail = n; 806 807 return; 808 } 809 } 810 811 rRoot = n; 812 813 if (limitcount == 0 || limitcount >= size) { 814 return; 815 } 816 817 for (int i = 1; i < limitcount; i++) { 818 n = n.next; 819 820 if (n == null) { 821 822 return; 824 } 825 } 826 827 size = limitcount; 828 n.next = null; 829 rTail = n; 830 } 831 832 838 void removeDuplicates(Session session) throws HsqlException { 839 removeDuplicates(session, significantColumns); 840 } 841 842 848 849 void removeDuplicates(Session session, 852 int columnCount) throws HsqlException { 853 854 if (rRoot == null) { 855 return; 856 } 857 858 int[] order = new int[columnCount]; 859 int[] way = new int[columnCount]; 860 861 for (int i = 0; i < columnCount; i++) { 862 order[i] = i; 863 way[i] = 1; 864 } 865 866 sortResult(session, order, way); 867 868 Record n = rRoot; 869 870 for (;;) { 871 Record next = n.next; 872 873 if (next == null) { 874 break; 875 } 876 877 if (compareRecord(session, n.data, next.data, columnCount) == 0) { 878 n.next = next.next; 879 880 size--; 881 } else { 882 n = next; 883 } 884 } 885 886 rTail = n; 887 } 888 889 896 void removeSecond(Session session, Result minus, 897 int columnCount) throws HsqlException { 898 899 removeDuplicates(session, columnCount); 900 minus.removeDuplicates(session, columnCount); 901 902 Record n = rRoot; 903 Record last = rRoot; 904 boolean rootr = true; Record n2 = minus.rRoot; 906 int i = 0; 907 908 while (n != null && n2 != null) { 909 i = compareRecord(session, n.data, n2.data, columnCount); 910 911 if (i == 0) { 912 if (rootr) { 913 rRoot = last = n.next; 914 } else { 915 last.next = n.next; 916 } 917 918 n = n.next; 919 920 size--; 921 } else if (i > 0) { n2 = n2.next; 923 } else { last = n; 925 rootr = false; 926 n = n.next; 927 } 928 } 929 930 for (; n != null; ) { 931 last = n; 932 n = n.next; 933 } 934 935 rTail = last; 936 } 937 938 946 void removeDifferent(Session session, Result r2, 947 int columnCount) throws HsqlException { 948 949 removeDuplicates(session, columnCount); 950 r2.removeDuplicates(session, columnCount); 951 952 Record n = rRoot; 953 Record last = rRoot; 954 boolean rootr = true; Record n2 = r2.rRoot; 956 int i = 0; 957 958 size = 0; 959 960 while (n != null && n2 != null) { 961 i = compareRecord(session, n.data, n2.data, columnCount); 962 963
|