1 21 22 package org.apache.derby.impl.sql.compile; 23 24 25 import org.apache.derby.iapi.services.compiler.ClassBuilder; 26 import org.apache.derby.iapi.services.compiler.MethodBuilder; 27 import org.apache.derby.iapi.services.compiler.JavaFactory; 28 import org.apache.derby.iapi.services.compiler.LocalField; 29 import org.apache.derby.iapi.reference.ClassName; 30 31 import org.apache.derby.iapi.services.sanity.SanityManager; 32 33 import org.apache.derby.iapi.sql.compile.CompilerContext; 34 import org.apache.derby.iapi.sql.compile.ExpressionClassBuilderInterface; 35 36 import org.apache.derby.iapi.sql.execute.ResultSetFactory; 37 import org.apache.derby.iapi.sql.execute.ExecutionFactory; 38 import org.apache.derby.iapi.sql.execute.ExecIndexRow; 39 40 import org.apache.derby.iapi.sql.Activation; 41 import org.apache.derby.iapi.sql.ParameterValueSet; 42 import org.apache.derby.iapi.sql.Row; 43 44 import org.apache.derby.iapi.sql.execute.ExecRow; 45 46 import org.apache.derby.impl.sql.compile.OrderedColumnList; 47 import org.apache.derby.impl.sql.compile.ResultColumnList; 48 import org.apache.derby.impl.sql.execute.IndexColumnOrder; 49 import org.apache.derby.iapi.store.access.ColumnOrdering; 50 51 import org.apache.derby.iapi.types.DataValueDescriptor; 52 import org.apache.derby.iapi.types.DataTypeDescriptor; 53 import org.apache.derby.iapi.types.DataValueFactory; 54 import org.apache.derby.iapi.types.TypeId; 55 56 import org.apache.derby.iapi.sql.compile.TypeCompiler; 57 58 import org.apache.derby.iapi.error.StandardException; 59 import org.apache.derby.iapi.util.ByteArray; 60 61 import org.apache.derby.iapi.services.loader.ClassFactory; 62 import org.apache.derby.iapi.services.loader.GeneratedClass; 63 import org.apache.derby.iapi.services.loader.GeneratedByteCode; 64 import org.apache.derby.iapi.services.loader.GeneratedMethod; 65 66 import java.lang.reflect.Modifier ; 67 import org.apache.derby.iapi.services.classfile.VMOpcode; 68 69 import org.apache.derby.iapi.services.monitor.Monitor; 70 71 import org.apache.derby.iapi.services.io.FormatableArrayHolder; 72 73 import java.io.Serializable ; 74 75 84 abstract class ExpressionClassBuilder implements ExpressionClassBuilderInterface 85 { 86 92 static final protected String currentDatetimeFieldName = "cdt"; 93 94 100 protected ClassBuilder cb; 101 protected GeneratedClass gc; 102 protected int nextExprNum; 103 protected int nextNonFastExpr; 104 protected int nextFieldNum; 105 protected MethodBuilder constructor; 106 CompilerContext myCompCtx; 107 MethodBuilder executeMethod; 109 protected LocalField cdtField; 110 111 113 private String currentRowScanResultSetName; 114 115 116 122 132 ExpressionClassBuilder (String superClass, String className, CompilerContext cc ) 133 throws StandardException 134 { 135 int modifiers = Modifier.PUBLIC | Modifier.FINAL; 136 137 myCompCtx = cc; 138 JavaFactory javaFac = myCompCtx.getJavaFactory(); 139 140 if ( className == null ) { className = myCompCtx.getUniqueClassName(); } 141 142 cb = javaFac.newClassBuilder(myCompCtx.getClassFactory(), 144 getPackageName(), modifiers, 145 className, superClass); 146 147 beginConstructor(); 148 } 149 150 156 161 abstract String getPackageName(); 162 163 170 abstract int getRowCount() 171 throws StandardException; 172 173 179 abstract void setNumSubqueries() 180 throws StandardException; 181 182 190 abstract MethodBuilder beginExecuteMethod() 191 throws StandardException; 192 193 194 200 abstract void finishExecuteMethod(boolean genMarkAsTopNode ) 201 throws StandardException; 202 203 204 210 218 abstract String getBaseClassName(); 219 220 MethodBuilder getConstructor() { 221 return constructor; 222 } 223 224 ClassBuilder getClassBuilder() { 225 return cb; 226 } 227 228 234 MethodBuilder getExecuteMethod() { 235 return executeMethod; 236 } 237 238 239 245 private final void beginConstructor() 246 { 247 MethodBuilder realConstructor = 249 cb.newConstructorBuilder(Modifier.PUBLIC); 250 realConstructor.callSuper(); 251 realConstructor.methodReturn(); 252 realConstructor.complete(); 253 254 constructor = cb.newMethodBuilder(Modifier.PUBLIC, "void", "postConstructor"); 255 constructor.addThrownException(ClassName.StandardException); 256 } 257 258 264 265 void finishConstructor() 266 throws StandardException 267 { 268 int numResultSets; 269 270 271 setNumSubqueries(); 272 273 numResultSets = getRowCount(); 274 275 278 if (numResultSets >= 1) 279 { 280 addNewArrayOfRows(numResultSets); 281 } 282 283 286 constructor.methodReturn(); 287 constructor.complete(); 288 } 289 290 295 private void addNewArrayOfRows(int numResultSets) 296 { 297 300 301 constructor.pushThis(); 302 constructor.pushNewArray(ClassName.ExecRow, numResultSets); 303 constructor.putField(ClassName.BaseActivation, "row", ClassName.ExecRow + "[]"); 304 constructor.endStatement(); 305 } 306 307 313 322 LocalField newFieldDeclaration(int modifiers, String type, String name) 323 { 324 return cb.addField(type, name, modifiers); 325 } 326 327 341 342 LocalField newFieldDeclaration(int modifiers, String type) 343 { 344 return cb.addField(type, newFieldName(), modifiers); 345 } 346 347 353 373 MethodBuilder newGeneratedFun(String returnType, int modifiers) { 374 375 return newGeneratedFun(returnType, modifiers, 376 (String []) null); 377 } 378 379 MethodBuilder newGeneratedFun(String returnType, 380 int modifiers, 381 String [] params) { 382 383 String exprName = "g".concat(Integer.toString(nextNonFastExpr++)); 384 return newGeneratedFun(exprName, returnType, modifiers, 385 params); 386 387 } 388 389 private MethodBuilder newGeneratedFun(String exprName, String returnType, 390 int modifiers, 391 String [] params) { 392 393 394 395 MethodBuilder exprMethod; 400 if (params == null) 401 { 402 exprMethod = cb.newMethodBuilder(modifiers, returnType, exprName); 403 } 404 else 405 { 406 exprMethod = cb.newMethodBuilder(modifiers, returnType, 407 exprName, params); 408 } 409 410 exprMethod.addThrownException(ClassName.StandardException); 415 416 return exprMethod; 417 } 418 419 439 MethodBuilder newExprFun() 440 { 441 String exprName = "e".concat(Integer.toString(nextExprNum++)); 443 444 return newGeneratedFun(exprName, "java.lang.Object", Modifier.PUBLIC, (String []) null); 445 } 446 447 451 void pushMethodReference(MethodBuilder mb, MethodBuilder exprMethod) { 452 453 mb.pushThis(); mb.push(exprMethod.getName()); mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.GeneratedByteCode, 456 "getMethod", 457 ClassName.GeneratedMethod, 458 1 459 ); 460 } 461 462 471 MethodBuilder newUserExprFun() { 472 473 MethodBuilder mb = newExprFun(); 474 mb.addThrownException("java.lang.Exception"); 475 return mb; 476 } 477 478 484 490 void getCurrentDateExpression(MethodBuilder mb) { 491 LocalField lf = getCurrentSetup(); 493 494 mb.getField(lf); 497 mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String ) null, "getCurrentDate", "java.sql.Date", 0); 498 } 499 500 506 void getCurrentTimeExpression(MethodBuilder mb) { 507 LocalField lf = getCurrentSetup(); 509 510 mb.getField(lf); 513 mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String ) null, "getCurrentTime", "java.sql.Time", 0); 514 } 515 516 522 void getCurrentTimestampExpression(MethodBuilder mb) { 523 LocalField lf = getCurrentSetup(); 525 526 mb.getField(lf); 529 mb.callMethod(VMOpcode.INVOKEVIRTUAL, (String ) null, 530 "getCurrentTimestamp", "java.sql.Timestamp", 0); 531 } 532 533 539 555 FormatableArrayHolder getColumnOrdering(ResultColumnList rclist) 556 { 557 IndexColumnOrder[] ordering; 558 int numCols = (rclist == null) ? 0 : rclist.size(); 559 int numRealCols = 0; 563 for (int i=0; i<numCols; i++) 564 { 565 if (!(rclist.getResultColumn(i+1).isGeneratedForUnmatchedColumnInInsert())) 566 numRealCols++; 567 } 568 569 ordering = new IndexColumnOrder[numRealCols]; 570 for (int i=0, j=0; i<numCols; i++) 571 { 572 if (!(rclist.getResultColumn(i+1).isGeneratedForUnmatchedColumnInInsert())) 573 { 574 ordering[j] = new IndexColumnOrder(i); 575 j++; 576 } 577 } 578 return new FormatableArrayHolder(ordering); 579 } 580 581 588 FormatableArrayHolder addColumnToOrdering( 589 FormatableArrayHolder orderingHolder, 590 int columnNum) 591 { 592 596 ColumnOrdering[] ordering = (ColumnOrdering[])orderingHolder. 597 getArray(ColumnOrdering.class); 598 int length = ordering.length; 599 for (int i = 0; i < length; i++) 600 { 601 if (ordering[i].getColumnId() == columnNum) 602 return orderingHolder; 603 } 604 605 609 IndexColumnOrder[] newOrdering = new IndexColumnOrder[length+1]; 610 System.arraycopy(ordering, 0, newOrdering, 0, length); 611 newOrdering[length] = new IndexColumnOrder(columnNum); 612 613 return new FormatableArrayHolder(newOrdering); 614 } 615 616 617 FormatableArrayHolder getColumnOrdering(OrderedColumnList oclist) { 618 int numCols = (oclist == null) ? 0 : oclist.size(); 619 620 if (numCols == 0) 621 { 622 return new FormatableArrayHolder(new IndexColumnOrder[0]); 623 } 624 625 return new FormatableArrayHolder(oclist.getColumnOrdering()); 626 } 627 628 int addItem(Object o) 629 { 630 if (SanityManager.DEBUG) 631 { 632 if ((o != null) && !(o instanceof Serializable )) 633 { 634 SanityManager.THROWASSERT( 635 "o (" + o.getClass().getName() + 636 ") expected to be instanceof java.io.Serializable"); 637 } 638 } 639 return myCompCtx.addSavedObject(o); 640 } 641 642 648 651 private Object getDVF; 652 void pushDataValueFactory(MethodBuilder mb) 653 { 654 658 if (getDVF == null) { 659 getDVF = mb.describeMethod(VMOpcode.INVOKEVIRTUAL, 660 getBaseClassName(), 661 "getDataValueFactory", 662 ClassName.DataValueFactory); 663 } 664 665 mb.pushThis(); 666 mb.callMethod(getDVF); 667 } 668 669 675 682 private Object getRSF; 683 void pushGetResultSetFactoryExpression(MethodBuilder mb) { 684 if (getRSF == null) { 688 getRSF = mb.describeMethod(VMOpcode.INVOKEVIRTUAL, getBaseClassName(), 689 "getResultSetFactory", 690 ClassName.ResultSetFactory); 691 } 692 mb.pushThis(); 693 mb.callMethod(getRSF); 694 } 695 696 705 private Object getEF; 706 void pushGetExecutionFactoryExpression(MethodBuilder mb) { 707 if (getEF == null) { 708 getEF = mb.describeMethod(VMOpcode.INVOKEVIRTUAL, getBaseClassName(), 709 "getExecutionFactory", 710 ClassName.ExecutionFactory); 711 } 712 713 mb.pushThis(); 717 mb.callMethod(getEF); 718 } 719 720 728 735 741 void pushColumnReference(MethodBuilder mb, int rsNumber, int colId) 742 { 743 mb.pushThis(); 744 mb.push(rsNumber); 745 mb.push(colId); 746 mb.callMethod(VMOpcode.INVOKEVIRTUAL, ClassName.BaseActivation, "getColumnFromRow", 747 ClassName.DataValueDescriptor, 2); 748 749 } 755 756 761 void pushPVSReference(MethodBuilder mb) 762 { 763 mb.pushThis(); 765 mb.getField(ClassName.BaseActivation, "pvs", ClassName.ParameterValueSet); 766 } 767 768 774 778 protected LocalField getCurrentSetup() { 779 if (cdtField != null) 780 return cdtField; 781 782 cdtField = newFieldDeclaration( 786 Modifier.PRIVATE, 787 ClassName.CurrentDatetime, 788 currentDatetimeFieldName); 789 790 793 constructor.pushNewStart(ClassName.CurrentDatetime); 794 constructor.pushNewComplete(0); 795 constructor.setField(cdtField); 796 797 return cdtField; 798 } 799 800 809 private String newFieldName() 810 { 811 return "e".concat(Integer.toString(nextFieldNum++)); 812 } 813 814 815 821 822 835 protected TypeCompiler getTypeCompiler(TypeId typeId) 836 { 837 return myCompCtx.getTypeCompilerFactory().getTypeCompiler(typeId); 838 } 839 840 846 856 GeneratedClass getGeneratedClass(ByteArray savedBytes) throws StandardException { 857 if (gc != null) return gc; 858 859 if (savedBytes != null) 860 { 861 ByteArray classBytecode = cb.getClassBytecode(); 862 863 savedBytes.setBytes(classBytecode.getArray()); 867 savedBytes.setLength(classBytecode.getLength()); 868 } 869 870 gc = cb.getGeneratedClass(); 871 872 return gc; } 874 875 880 void pushThisAsActivation(MethodBuilder mb) { 881 mb.pushThis(); 883 mb.upCast(ClassName.Activation); 884 } 885 886 891 void generateNull(MethodBuilder mb, TypeCompiler tc) { 892 pushDataValueFactory(mb); 893 mb.pushNull(tc.interfaceName()); 894 tc.generateNull(mb); 895 } 896 897 902 void generateNullWithExpress(MethodBuilder mb, TypeCompiler tc) { 903 pushDataValueFactory(mb); 904 mb.swap(); mb.cast(tc.interfaceName()); 906 tc.generateNull(mb); 907 } 908 909 915 void generateDataValue(MethodBuilder mb, TypeCompiler tc, LocalField field) { 916 pushDataValueFactory(mb); 917 mb.swap(); tc.generateDataValue(mb, field); 919 } 920 921 922 928 929 String newRowLocationScanResultSetName() 930 { 931 currentRowScanResultSetName = newFieldName(); 932 return currentRowScanResultSetName; 933 } 934 935 String getRowLocationScanResultSetName() 937 { 938 return currentRowScanResultSetName; 939 } 940 941 942 } 943 944 945 946 947 948 949 950 951 952 | Popular Tags |