| 1 21 package com.db4o.test.nativequery; 22 23 import java.lang.reflect.*; 24 25 import com.db4o.*; 26 import com.db4o.inside.query.*; 27 import com.db4o.nativequery.*; 28 import com.db4o.nativequery.expr.*; 29 import com.db4o.nativequery.main.*; 30 import com.db4o.query.*; 31 import com.db4o.test.*; 32 import com.db4o.test.nativequery.expr.*; 33 34 import db4ounit.*; 35 import db4ounit.TestSuite; 36 import db4ounit.extensions.*; 37 import db4ounit.extensions.fixtures.*; 38 39 40 public class NQRegressionTestCase extends AbstractDb4oTestCase { 41 private final static boolean RUN_LOADTIME=false; 42 43 private static final String CSTR = "Cc"; 44 private static final String BSTR = "Ba"; 45 private static final String ASTR = "Aa"; 46 public final static Integer INTWRAPPER=new Integer (1); 47 private final static Integer PRIVATE_INTWRAPPER=new Integer (1); 48 49 private static abstract class Base { 50 int id; 51 Integer idWrap; 52 53 public Base(int id) { 54 this.id=id; 55 idWrap=new Integer (id); 56 } 57 58 public int getId() { 59 return id; 60 } 61 } 62 63 private static class Other extends Base { 64 public Other() { 65 super(1); 66 } 67 } 68 69 private static class Data extends Base { 70 boolean bool; 71 float value; 72 String name; 73 Data prev; 74 int id2; 75 Boolean boolWrap; 76 77 public Data(int id, boolean bool,float value, String name,Data prev, int id2) { 78 super(id); 79 this.bool=bool; 80 this.boolWrap=Boolean.valueOf(bool); 81 this.value=value; 82 this.name = name; 83 this.prev=prev; 84 this.id2=id2; 85 } 86 87 public float getValue() { 88 return value; 89 } 90 91 public String getName() { 92 return name; 93 } 94 95 public boolean getBool() { 96 return bool; 97 } 98 99 public Data getPrev() { 100 return prev; 101 } 102 } 103 104 public static void main(String [] args) { 105 TestSuite suite=new Db4oTestSuiteBuilder(new Db4oSolo(),NQRegressionTestCase.class).build(); 106 new TestRunner(suite).run(); 107 } 108 109 public void store() { 110 Data a=new Data(1,false,1.1f,ASTR,null, 0); 111 Data b=new Data(2,false,1.1f,BSTR,a, Integer.MIN_VALUE); 112 Data c=new Data(3,true,2.2f,CSTR,b, Integer.MIN_VALUE); 113 Data cc=new Data(3,false,3.3f,CSTR,null, Integer.MIN_VALUE); 114 ObjectContainer db=db(); 115 db.set(a); 116 db.set(b); 117 db.set(c); 118 db.set(cc); 119 db.set(new Other()); 120 } 121 122 private abstract static class ExpectingPredicate extends Predicate { 123 private String _name; 124 125 public ExpectingPredicate(String name) { 126 _name=name; 127 } 128 129 public ExpectingPredicate(String name,Class extentType) { 130 super(extentType); 131 _name=name; 132 } 133 134 public abstract int expected(); 135 136 public String toString() { 137 return _name; 138 } 139 } 140 141 private static ExpectingPredicate[] _PREDICATES={ 142 new ExpectingPredicate("unconditional/untyped") { 144 public int expected() { return 5;} 145 public boolean match(Object candidate) { 146 return true; 147 } 148 }, 149 new ExpectingPredicate("unconditional: Base") { 151 public int expected() { return 5;} 152 public boolean match(Base candidate) { 153 return true; 154 } 155 }, 156 new ExpectingPredicate("unconditional: Data") { 157 public int expected() { return 4;} 158 public boolean match(Data candidate) { 159 return true; 160 } 161 }, 162 new ExpectingPredicate("bool") { 170 public int expected() { return 1;} 171 public boolean match(Data candidate) { 172 return candidate.bool; 173 } 174 }, 175 new ExpectingPredicate("!bool") { 176 public int expected() { return 3;} 177 public boolean match(Data candidate) { 178 return !candidate.bool; 179 } 180 }, 181 new ExpectingPredicate("id2==0") { 182 public int expected() { return 1;} 183 public boolean match(Data candidate) { 184 return candidate.id2==0; 185 } 186 }, 187 new ExpectingPredicate("id==1") { 188 public int expected() { return 1;} 189 public boolean match(Data candidate) { 190 return candidate.id==1; 191 } 192 }, 193 new ExpectingPredicate("id==3") { 194 public int expected() { return 2;} 195 public boolean match(Data candidate) { 196 return candidate.id==3; 197 } 198 }, 199 new ExpectingPredicate("value==1.1") { 200 public int expected() { return 2;} 201 public boolean match(Data candidate) { 202 return candidate.value==1.1f; 203 } 204 }, 205 new ExpectingPredicate("value==3.3") { 206 public int expected() { return 1;} 207 public boolean match(Data candidate) { 208 return candidate.value==3.3f; 209 } 210 }, 211 new ExpectingPredicate("name.eq(ASTR)") { 213 public int expected() { return 1;} 214 public boolean match(Data candidate) { 215 return candidate.name.equals(ASTR); 216 } 217 }, 218 new ExpectingPredicate("name.eq(CSTR)") { 219 public int expected() { return 2;} 220 public boolean match(Data candidate) { 221 return candidate.name.equals(CSTR); 222 } 223 }, 224 new ExpectingPredicate("name.contains('a')") { 226 public int expected() { return 2;} 227 public boolean match(Data candidate) { 228 return candidate.name.contains("a"); 229 } 230 }, 231 new ExpectingPredicate("name.contains('A')") { 232 public int expected() { return 1;} 233 public boolean match(Data candidate) { 234 return candidate.name.contains("A"); 235 } 236 }, 237 new ExpectingPredicate("name.contains('C')") { 238 public int expected() { return 2;} 239 public boolean match(Data candidate) { 240 return candidate.name.contains("C"); 241 } 242 }, 243 new ExpectingPredicate("name.startsWith('C')") { 244 public int expected() { return 2;} 245 public boolean match(Data candidate) { 246 return candidate.name.startsWith("C"); 247 } 248 }, 249 new ExpectingPredicate("name.startsWith('a')") { 250 public int expected() { return 0;} 251 public boolean match(Data candidate) { 252 return candidate.name.startsWith("a"); 253 } 254 }, 255 new ExpectingPredicate("name.endsWith('A')") { 256 public int expected() { return 2;} 257 public boolean match(Data candidate) { 258 return candidate.name.endsWith("a"); 259 } 260 }, 261 new ExpectingPredicate("name.endsWith('A')") { 262 public int expected() { return 0;} 263 public boolean match(Data candidate) { 264 return candidate.name.endsWith("A"); 265 } 266 }, 267 new ExpectingPredicate("!(name.contains('A'))") { 268 public int expected() { return 3;} 269 public boolean match(Data candidate) { 270 return !candidate.name.contains("A"); 271 } 272 }, 273 new ExpectingPredicate("!(name.startsWith('C'))") { 274 public int expected() { return 2;} 275 public boolean match(Data candidate) { 276 return !candidate.name.startsWith("C"); 277 } 278 }, 279 new ExpectingPredicate("id<2") { 281 public int expected() { return 1;} 282 public boolean match(Data candidate) { 283 return candidate.id<2; 284 } 285 }, 286 new ExpectingPredicate("id>2") { 287 public int expected() { return 2;} 288 public boolean match(Data candidate) { 289 return candidate.id>2; 290 } 291 }, 292 new ExpectingPredicate("id<=2") { 293 public int expected() { return 2;} 294 public boolean match(Data candidate) { 295 return candidate.id<=2; 296 } 297 }, 298 new ExpectingPredicate("id>=2") { 299 public int expected() { return 3;} 300 public boolean match(Data candidate) { 301 return candidate.id>=2; 302 } 303 }, 304 new ExpectingPredicate("value>2.9") { 306 public int expected() { return 1;} 307 public boolean match(Data candidate) { 308 return candidate.value>2.9f; 309 } 310 }, 311 new ExpectingPredicate("1.5>=value") { 312 public int expected() { return 2;} 313 public boolean match(Data candidate) { 314 return 1.5f >= candidate.value; 315 } 316 }, 317 new ExpectingPredicate("id==1.0") { 319 public int expected() { return 1;} 320 public boolean match(Data candidate) { 321 return candidate.id==1.0f; 322 } 323 }, 324 new ExpectingPredicate("id!=1.0") { 325 public int expected() { return 3;} 326 public boolean match(Data candidate) { 327 return candidate.id!=1.0f; 328 } 329 }, 330 new ExpectingPredicate("value!=1") { 331 public int expected() { return 4;} 332 public boolean match(Data candidate) { 333 return candidate.value!=1; 334 } 335 }, 336 new ExpectingPredicate("getPrev().getId()>=1") { 345 public int expected() { return 2;} 346 public boolean match(Data candidate) { 347 return candidate.getPrev()!=null&&candidate.getPrev().getId()>=1; 348 } 349 }, 350 new ExpectingPredicate("BSTR.eq(getPrev().getName()") { 351 public int expected() { return 1;} 352 public boolean match(Data candidate) { 353 return (candidate.getPrev()!=null)&&(BSTR.equals(candidate.getPrev().getName())); 354 } 355 }, 356 new ExpectingPredicate("getPrev().getName().eq('')") { 357 public int expected() { return 0;} 358 public boolean match(Data candidate) { 359 return candidate.getPrev()!=null&&candidate.getPrev().getName().equals(""); 360 } 361 }, 362 new ExpectingPredicate("getId()==2") { 364 public int expected() { return 1;} 365 public boolean match(Data candidate) { 366 return candidate.getId()==2; 367 } 368 }, 369 new ExpectingPredicate("getId()<2") { 370 public int expected() { return 1;} 371 public boolean match(Data candidate) { 372 return candidate.getId()<2; 373 } 374 }, 375 new ExpectingPredicate("getId()>2") { 376 public int expected() { return 2;} 377 public boolean match(Data candidate) { 378 return candidate.getId()>2; 379 } 380 }, 381 new ExpectingPredicate("getId()<=2") { 382 public int expected() { return 2;} 383 public boolean match(Data candidate) { 384 return candidate.getId()<=2; 385 } 386 }, 387 new ExpectingPredicate("getId()>=2") { 388 public int expected() { return 3;} 389 public boolean match(Data candidate) { 390 return candidate.getId()>=2; 391 } 392 }, 393 new ExpectingPredicate("getName().eq(CSTR)") { 394 public int expected() { return 2;} 395 public boolean match(Data candidate) { 396 return candidate.getName().equals(CSTR); 397 } 398 }, 399 new ExpectingPredicate("!(id==1)") { 401 public int expected() { return 3;} 402 public boolean match(Data candidate) { 403 return !(candidate.id==1); 404 } 405 }, 406 new ExpectingPredicate("!(getId()>2)") { 407 public int expected() { return 2;} 408 public boolean match(Data candidate) { 409 return !(candidate.getId()>2); 410 } 411 }, 412 new ExpectingPredicate("!getName().eq(CSTR)") { 413 public int expected() { return 2;} 414 public boolean match(Data candidate) { 415 return !(candidate.getName().equals(CSTR)); 416 } 417 }, 418 new ExpectingPredicate("bool&&!getBool()") { 420 public int expected() { return 0;} 421 public boolean match(Data candidate) { 422 return candidate.bool&&!candidate.getBool(); 423 } 424 }, 425 new ExpectingPredicate("id>1&&getName().eq(CSTR)") { 426 public int expected() { return 2;} 427 public boolean match(Data candidate) { 428 return (candidate.id>1)&&candidate.getName().equals(CSTR); 429 } 430 }, 431 new ExpectingPredicate("id>1&&getId()<=2") { 432 public int expected() { return 1;} 433 public boolean match(Data candidate) { 434 return (candidate.id>1)&&(candidate.getId()<=2); 435 } 436 }, 437 new ExpectingPredicate("id>1&&getId()<1") { 438 public int expected() { return 0;} 439 public boolean match(Data candidate) { 440 return (candidate.id>1)&&(candidate.getId()<1); 441 } 442 }, 443 new ExpectingPredicate("bool||getId()==1") { 445 public int expected() { return 2;} 446 public boolean match(Data candidate) { 447 return candidate.bool||candidate.getId()==1; 448 } 449 }, 450 new ExpectingPredicate("id==1||getName().eq(CSTR)") { 451 public int expected() { return 3;} 452 public boolean match(Data candidate) { 453 return (candidate.id==1)||candidate.getName().equals(CSTR); 454 } 455 }, 456 new ExpectingPredicate("id>1||getId()<=2") { 457 public int expected() { return 4;} 458 public boolean match(Data candidate) { 459 return (candidate.id>1)||(candidate.getId()<=2); 460 } 461 }, 462 new ExpectingPredicate("id<=1||getId()>=3") { 463 public int expected() { return 3;} 464 public boolean match(Data candidate) { 465 return (candidate.id<=1)||(candidate.getId()>=3); 466 } 467 }, 468 new ExpectingPredicate("id>=1||getName().eq(CSTR)&&getId()<3") { 470 public int expected() { return 2;} 471 public boolean match(Data candidate) { 472 return ((candidate.id>=1)||candidate.getName().equals(CSTR))&&candidate.getId()<3; 473 } 474 }, 475 new ExpectingPredicate("(id==2||getId()<=1)&&!(getName().eq(BSTR))") { 476 public int expected() { return 1;} 477 public boolean match(Data candidate) { 478 return ((candidate.id==2)||candidate.getId()<=1)&&!candidate.getName().equals(BSTR); 479 } 480 }, 481 new ExpectingPredicate("id>=P.id") { 483 private int id=2; 484 485 public int expected() { return 3;} 486 public boolean match(Data candidate) { 487 return candidate.id>=id; 488 } 489 }, 490 new ExpectingPredicate("getName().eq(P.name)") { 491 private String name=BSTR; 492 493 public int expected() { return 1;} 494 public boolean match(Data candidate) { 495 return candidate.getName().equals(name); 496 } 497 }, 498 new ExpectingPredicate("id>=P.id+1") { 500 private int id=2; 501 502 public int expected() { return 2;} 503 public boolean match(Data candidate) { 504 return candidate.id>=id+1; 505 } 506 }, 507 new ExpectingPredicate("id>=P.calc()") { 508 private int factor=2; 509 510 private int calc() { 511 return factor+1; 512 } 513 514 public int expected() { return 2;} 515 public boolean match(Data candidate) { 516 return candidate.id>=calc(); 517 } 518 }, 519 new ExpectingPredicate("getValue()==P.calc()") { 520 private float predFactor=2.0f; 521 522 private float calc() { 523 return predFactor*1.1f; 524 } 525 526 public int expected() { return 1;} 527 public boolean match(Data candidate) { 528 return candidate.getValue()==calc(); 529 } 530 }, 531 new ExpectingPredicate("force extent",Data.class) { 533 public int expected() { return 1;} 534 public boolean match(Object candidate) { 535 return ((Data)candidate).getId()==1; 536 } 537 }, 538 new ExpectingPredicate("id==P.data[3]") { 540 private int[] data={0,1,2,3,4}; 541 542 public int expected() { return 2;} 543 public boolean match(Data candidate) { 544 return candidate.id==data[3]; 545 } 546 }, 547 new ExpectingPredicate("prev==P.data[3]") { 548 private Data[] data={null,null,null,null}; 549 550 public int expected() { return 2;} 551 public boolean match(Data candidate) { 552 return candidate.prev==data[3]; 553 } 554 }, 555 new ExpectingPredicate("id==Integer.parseInt('3')") { 557 public int expected() { return 2;} 558 public boolean match(Data candidate) { 559 return candidate.id==Integer.parseInt("3"); 560 } 561 }, 562 new ExpectingPredicate("id==P.sum(3,0)") { 563 public int expected() { return 2;} 564 private int sum(int a,int b) { 565 return a+b; 566 } 567 public boolean match(Data candidate) { 568 return candidate.id==sum(3,0); 569 } 570 }, 571 new ExpectingPredicate("boolWrapper") { 573 public int expected() { return 1;} 574 public boolean match(Data candidate) { 575 return candidate.boolWrap.booleanValue(); 576 } 577 }, 578 new ExpectingPredicate("INTWRAPPER.eq(idwrap)") { 579 public int expected() { return 1;} 580 public boolean match(Data candidate) { 581 return NQRegressionTestCase.INTWRAPPER.equals(candidate.idWrap); 582 } 583 }, 584 new ExpectingPredicate("idwrap.value==1") { 585 public int expected() { return 1;} 586 public boolean match(Data candidate) { 587 return candidate.idWrap.intValue()==1; 588 } 589 }, 590 new ExpectingPredicate("id==INTWRAPPER.intValue()") { 591 public int expected() { return 1;} 592 public boolean match(Data candidate) { 593 return candidate.id==INTWRAPPER.intValue(); 594 } 595 }, 596 new ExpectingPredicate("idwrap.compareTo(INTWRAPPER)<2") { 597 public int expected() { return 3;} 598 public boolean match(Data candidate) { 599 return candidate.idWrap.compareTo(INTWRAPPER)>0; 600 } 601 }, 602 new ExpectingPredicate("PRIVATE_INTWRAPPER.eq(idWrap)") { 605 public int expected() { return 1;} 606 public boolean match(Data candidate) { 607 return NQRegressionTestCase.PRIVATE_INTWRAPPER.equals(candidate.idWrap); 608 } 609 }, 610 }; 611 612 private static ExpectingPredicate[] PREDICATES=_PREDICATES; 613 614 public void testAll() { 615 for (int predIdx = 0; predIdx < PREDICATES.length; predIdx++) { 616 ExpectingPredicate predicate = PREDICATES[predIdx]; 617 assertNQResult(predicate); 618 } 619 } 620 621 private void assertNQResult(final ExpectingPredicate predicate) { 622 final String predicateId = "PREDICATE: "+predicate; 623 ObjectContainer db=db(); 624 Db4oQueryExecutionListener listener = new Db4oQueryExecutionListener() { 625 private int run=0; 626 627 public void notifyQueryExecuted(NQOptimizationInfo info) { 628 if(run<2) { 629 Assert.areEqual(info.predicate(),predicate,predicateId); 630 } 631 String expMsg=null; 632 switch(run) { 633 case 0: 634 expMsg=NativeQueryHandler.UNOPTIMIZED; 635 Assert.isNull(info.optimized(),predicateId); 636 break; 637 case 1: 638 expMsg=NativeQueryHandler.DYNOPTIMIZED; 639 Assert.isTrue(info.optimized() instanceof Expression,predicateId); 640 break; 641 case 2: 642 expMsg=NativeQueryHandler.PREOPTIMIZED; 643 Assert.isNull(info.optimized(),predicateId); 644 break; 645 } 646 Assert.areEqual(expMsg,info.message(),predicateId); 647 run++; 648 } 649 }; 650 ((YapStream)db).getNativeQueryHandler().addListener(listener); 651 db.ext().configure().optimizeNativeQueries(false); 652 ObjectSet raw=db.query(predicate); 653 db.ext().configure().optimizeNativeQueries(true); 654 if(NQDebug.LOG) { 655 System.err.println("PREDICATE: "+predicate); 656 } 657 ObjectSet optimized=db.query(predicate); 658 if(!raw.equals(optimized)) { 659 System.out.println("RAW"); 660 raw.reset(); 661 while(raw.hasNext()) { 662 System.out.println(raw.next()); 663 } 664 System.out.println("OPT"); 665 optimized.reset(); 666 while(optimized.hasNext()) { 667 System.out.println(optimized.next()); 668 } 669 } 670 Assert.areEqual(raw,optimized,predicateId); 671 Assert.areEqual(predicate.expected(),raw.size(),predicateId); 672 673 if(RUN_LOADTIME) { 674 db.ext().configure().optimizeNativeQueries(false); 675 try { 676 Db4oEnhancingClassloader loader=new Db4oEnhancingClassloader(getClass().getClassLoader()); 677 Class filterClass=loader.loadClass(predicate.getClass().getName()); 678 Constructor constr=null; 679 Object [] args=null; 680 try { 681 constr=filterClass.getDeclaredConstructor(new Class []{String .class}); 682 args=new Object []{filterClass.getName()}; 683 } 684 catch(NoSuchMethodException exc) { 685 constr=filterClass.getDeclaredConstructor(new Class []{String .class,Class .class}); 686 args=new Object []{filterClass.getName(),Data.class}; 687 } 688 constr.setAccessible(true); 689 Predicate clPredicate=(Predicate)constr.newInstance(args); 690 ObjectSet preoptimized=db.query(clPredicate); 691 Assert.areEqual(predicate.expected(),preoptimized.size(),predicateId); 692 Assert.areEqual(raw,preoptimized,predicateId); 693 Assert.areEqual(optimized,preoptimized,predicateId); 694 } 695 catch (Throwable exc) { 696 exc.printStackTrace(); 697 } 698 } 699 ((YapStream)db).getNativeQueryHandler().clearListeners(); 700 db.ext().configure().optimizeNativeQueries(true); 701 } 702 } 703 | Popular Tags |