1 10 11 package mondrian.rolap.aggmatcher; 12 13 import mondrian.olap.MondrianDef; 14 import mondrian.olap.Util; 15 import mondrian.rolap.RolapStar; 16 import mondrian.rolap.sql.SqlQuery; 17 import mondrian.rolap.RolapAggregator; 18 import org.apache.log4j.Logger; 19 import java.io.PrintWriter ; 20 import java.io.StringWriter ; 21 import java.util.List ; 22 import java.util.ArrayList ; 23 import java.util.Set ; 24 import java.util.HashSet ; 25 import java.util.Map ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.sql.SQLException ; 29 import java.sql.Types ; 30 31 39 public class AggGen { 40 private static final Logger LOGGER = Logger.getLogger(AggGen.class); 41 42 private final RolapStar star; 43 private final RolapStar.Column[] columns; 44 45 46 private final Map <RolapStar.Table, List <JdbcSchema.Table.Column.Usage>> collapsedColumnUsages; 47 48 49 private final Set <JdbcSchema.Table.Column.Usage> notLostColumnUsages; 50 51 52 private final List <JdbcSchema.Table.Column.Usage> measures; 53 private boolean isReady; 54 55 public AggGen(RolapStar star, RolapStar.Column[] columns) { 56 this.star = star; 57 this.columns = columns; 58 this.notLostColumnUsages = new HashSet <JdbcSchema.Table.Column.Usage>(); 59 this.collapsedColumnUsages = new HashMap <RolapStar.Table, List <JdbcSchema.Table.Column.Usage>>(); 60 this.measures = new ArrayList <JdbcSchema.Table.Column.Usage>(); 61 init(); 62 } 63 private Logger getLogger() { 64 return LOGGER; 65 } 66 67 71 public boolean isReady() { 72 return isReady; 73 } 74 75 protected RolapStar.Table getFactTable() { 76 return star.getFactTable(); 77 } 78 79 protected String getFactTableName() { 80 return getFactTable().getAlias(); 81 } 82 83 protected SqlQuery getSqlQuery() { 84 return star.getSqlQuery(); 85 } 86 87 protected String getFactCount() { 88 return "fact_count"; 89 } 90 91 protected JdbcSchema.Table getTable(JdbcSchema db, RolapStar.Table rt) { 92 JdbcSchema.Table jt = getTable(db, rt.getAlias()); 93 return (jt == null) 94 ? getTable(db, rt.getTableName()) 95 : jt; 96 } 97 98 protected JdbcSchema.Table getTable(JdbcSchema db, String name) { 99 return db.getTable(name); 100 } 101 102 protected JdbcSchema.Table.Column getColumn( 103 JdbcSchema.Table table, 104 String name) { 105 return table.getColumn(name); 106 } 107 108 protected String getRolapStarColumnName(RolapStar.Column rColumn) { 109 MondrianDef.Expression expr = rColumn.getExpression(); 110 if (expr instanceof MondrianDef.Column) { 111 MondrianDef.Column cx = (MondrianDef.Column) expr; 112 return cx.getColumnName(); 113 } 114 return null; 115 } 116 protected void addForeignKeyToNotLostColumnUsages( 117 JdbcSchema.Table.Column column) { 118 119 String cname = column.getName(); 121 for (JdbcSchema.Table.Column.Usage usage : notLostColumnUsages) { 122 JdbcSchema.Table.Column c = usage.getColumn(); 123 if (cname.equals(c.getName())) { 124 return; 125 } 126 } 127 JdbcSchema.Table.Column.Usage usage; 128 if (column.hasUsage(JdbcSchema.UsageType.FOREIGN_KEY)) { 129 Iterator <JdbcSchema.Table.Column.Usage> it = 130 column.getUsages(JdbcSchema.UsageType.FOREIGN_KEY); 131 it.hasNext(); 132 usage = it.next(); 133 } else { 134 usage = column.newUsage(JdbcSchema.UsageType.FOREIGN_KEY); 135 usage.setSymbolicName(JdbcSchema.UsageType.FOREIGN_KEY.name()); 136 } 137 notLostColumnUsages.add(usage); 138 } 139 140 150 private void init() { 151 JdbcSchema db = JdbcSchema.makeDB(star.getDataSource()); 152 try { 153 db.load(); 154 } catch (SQLException ex) { 155 getLogger().error(ex); 156 return; 157 } 158 159 JdbcSchema.Table factTable = getTable(db, getFactTableName()); 160 if (factTable == null) { 161 StringBuilder buf = new StringBuilder (64); 162 buf.append("Init: "); 163 buf.append("No fact table with name \""); 164 buf.append(getFactTableName()); 165 buf.append("\""); 166 getLogger().warn(buf.toString()); 167 return; 168 } 169 try { 170 factTable.load(); 171 } catch (SQLException ex) { 172 getLogger().error(ex); 173 return; 174 } 175 176 if (getLogger().isDebugEnabled()) { 177 StringBuilder buf = new StringBuilder (512); 178 buf.append("Init: "); 179 buf.append("RolapStar:"); 180 buf.append(Util.nl); 181 buf.append(getFactTable()); 182 buf.append(Util.nl); 183 buf.append("FactTable:"); 184 buf.append(Util.nl); 185 buf.append(factTable); 186 getLogger().debug(buf.toString()); 187 } 188 189 for (RolapStar.Column column : columns) { 191 if (getLogger().isDebugEnabled()) { 192 StringBuilder buf = new StringBuilder (64); 193 buf.append("Init: "); 194 buf.append("Column: "); 195 buf.append(column); 196 getLogger().debug(buf.toString()); 197 } 198 RolapStar.Table table = column.getTable(); 199 200 if (table.getParentTable() == null) { 201 204 if (!addSpecialCollapsedColumn(db, column)) { 209 return; 210 } 211 212 213 MondrianDef.Expression expr = column.getExpression(); 214 if (expr instanceof MondrianDef.Column) { 215 MondrianDef.Column exprColumn = (MondrianDef.Column) expr; 216 String name = exprColumn.getColumnName(); 217 JdbcSchema.Table.Column c = getColumn(factTable, name); 218 if (c == null) { 219 StringBuilder buf = new StringBuilder (64); 220 buf.append("Init: "); 221 buf.append("FactTable:"); 222 buf.append(getFactTableName()); 223 buf.append(Util.nl); 224 buf.append("No Column with name \""); 225 buf.append(name); 226 buf.append("\""); 227 getLogger().warn(buf.toString()); 228 return; 229 } 230 if (getLogger().isDebugEnabled()) { 231 getLogger().debug(" Jdbc Column: c=" + c); 232 } 233 addForeignKeyToNotLostColumnUsages(c); 234 } 235 236 } else { 237 238 if (!addCollapsedColumn(db, column)) { 239 return; 240 } 241 242 while (table.getParentTable().getParentTable() != null) { 243 table = table.getParentTable(); 244 } 245 RolapStar.Condition cond = table.getJoinCondition(); 246 if (getLogger().isDebugEnabled()) { 247 getLogger().debug(" RolapStar.Condition: cond=" + cond); 248 } 249 MondrianDef.Expression left = cond.getLeft(); 250 if (left instanceof MondrianDef.Column) { 251 MondrianDef.Column leftColumn = (MondrianDef.Column) left; 252 String name = leftColumn.getColumnName(); 253 JdbcSchema.Table.Column c = getColumn(factTable, name); 254 if (c == null) { 255 StringBuilder buf = new StringBuilder (64); 256 buf.append("Init: "); 257 buf.append("FactTable:"); 258 buf.append(getFactTableName()); 259 buf.append(Util.nl); 260 buf.append("No Column with name \""); 261 buf.append(name); 262 buf.append("\""); 263 getLogger().warn(buf.toString()); 264 return; 265 } 266 if (getLogger().isDebugEnabled()) { 267 getLogger().debug(" Jdbc Column: c=" + c); 268 } 269 addForeignKeyToNotLostColumnUsages(c); 270 } 271 } 272 } 273 274 for (RolapStar.Column rColumn : getFactTable().getColumns()) { 276 String name = getRolapStarColumnName(rColumn); 277 if (name == null) { 278 StringBuilder buf = new StringBuilder (64); 279 buf.append("Init: "); 280 buf.append("For fact table \""); 281 buf.append(getFactTableName()); 282 buf.append( 283 "\", could not get column name for RolapStar.Column: "); 284 buf.append(rColumn); 285 getLogger().warn(buf.toString()); 286 return; 287 } 288 RolapAggregator aggregator; 289 if (!(rColumn instanceof RolapStar.Measure)) { 290 getLogger().warn("not a measure: " + name); 293 continue; 294 } else { 295 RolapStar.Measure rMeasure = (RolapStar.Measure) rColumn; 296 aggregator = rMeasure.getAggregator(); 297 } 298 JdbcSchema.Table.Column c = getColumn(factTable, name); 299 if (c == null) { 300 StringBuilder buf = new StringBuilder (64); 301 buf.append("For RolapStar: \""); 302 buf.append(getFactTable().getAlias()); 303 buf.append("\" measure with name, "); 304 buf.append(name); 305 buf.append(", is not a column name. "); 306 buf.append("The measure's column name may be an expression"); 307 buf.append(" and currently AggGen does not handle expressions."); 308 buf.append(" You will have to add this measure to the"); 309 buf.append(" aggregate table definition by hand."); 310 getLogger().warn(buf.toString()); 311 continue; 312 } 313 if (getLogger().isDebugEnabled()) { 314 getLogger().debug(" Jdbc Column m=" + c); 315 } 316 323 324 JdbcSchema.Table.Column.Usage usage = null; 325 if (c.hasUsage(JdbcSchema.UsageType.MEASURE)) { 326 for (Iterator <JdbcSchema.Table.Column.Usage> uit = 327 c.getUsages(JdbcSchema.UsageType.MEASURE); 328 uit.hasNext();) { 329 JdbcSchema.Table.Column.Usage tmpUsage = uit.next(); 330 if ((tmpUsage.getAggregator() == aggregator) && 331 tmpUsage.getSymbolicName().equals(rColumn.getName())) { 332 usage = tmpUsage; 333 break; 334 } 335 } 336 } 337 if (usage == null) { 338 usage = c.newUsage(JdbcSchema.UsageType.MEASURE); 339 usage.setAggregator(aggregator); 340 usage.setSymbolicName(rColumn.getName()); 341 } 342 measures.add(usage); 343 } 344 345 isReady = true; 347 } 348 private boolean addSpecialCollapsedColumn(final JdbcSchema db, 349 final RolapStar.Column rColumn) { 350 String rname = getRolapStarColumnName(rColumn); 351 if (rname == null) { 352 StringBuilder buf = new StringBuilder (64); 353 buf.append("Adding Special Collapsed Column: "); 354 buf.append("For fact table \""); 355 buf.append(getFactTableName()); 356 buf.append("\", could not get column name for RolapStar.Column: "); 357 buf.append(rColumn); 358 getLogger().warn(buf.toString()); 359 return false; 360 } 361 RolapStar.Table rt = rColumn.getTable(); 363 364 JdbcSchema.Table jt = getTable(db, rt); 365 if (jt == null) { 366 StringBuilder buf = new StringBuilder (64); 367 buf.append("Adding Special Collapsed Column: "); 368 buf.append("For fact table \""); 369 buf.append(getFactTableName()); 370 buf.append("\", could not get jdbc schema table "); 371 buf.append("for RolapStar.Table with alias \""); 372 buf.append(rt.getAlias()); 373 buf.append("\""); 374 getLogger().warn(buf.toString()); 375 return false; 376 } 377 try { 378 jt.load(); 379 } catch (SQLException ex) { 380 getLogger().error(ex); 381 return false; 382 } 383 384 List <JdbcSchema.Table.Column.Usage> list = collapsedColumnUsages.get(rt); 385 if (list == null) { 386 list = new ArrayList <JdbcSchema.Table.Column.Usage>(); 387 collapsedColumnUsages.put(rt, list); 388 } 389 390 JdbcSchema.Table.Column c = getColumn(jt, rname); 391 if (c == null) { 392 StringBuilder buf = new StringBuilder (64); 393 buf.append("Adding Special Collapsed Column: "); 394 buf.append("For fact table \""); 395 buf.append(getFactTableName()); 396 buf.append("\", could not get jdbc schema column "); 397 buf.append("for RolapStar.Table with alias \""); 398 buf.append(rt.getAlias()); 399 buf.append("\" and column name \""); 400 buf.append(rname); 401 buf.append("\""); 402 getLogger().warn(buf.toString()); 403 return false; 404 } 405 list.add(c.newUsage(JdbcSchema.UsageType.FOREIGN_KEY)); 409 410 RolapStar.Column prColumn = rColumn; 411 while (prColumn.getParentColumn() != null) { 412 prColumn = prColumn.getParentColumn(); 413 rname = getRolapStarColumnName(prColumn); 414 if (rname == null) { 415 StringBuilder buf = new StringBuilder (64); 416 buf.append("Adding Special Collapsed Column: "); 417 buf.append("For fact table \""); 418 buf.append(getFactTableName()); 419 buf.append("\", could not get parent column name"); 420 buf.append("for RolapStar.Column \""); 421 buf.append(rname); 422 buf.append("\" for RolapStar.Table with alias \""); 423 buf.append(rt.getAlias()); 424 buf.append("\""); 425 getLogger().warn(buf.toString()); 426 return false; 427 } 428 c = getColumn(jt, rname); 429 if (c == null) { 430 getLogger().warn("Can not find column: " +rname); 431 break; 432 } 433 list.add(c.newUsage(JdbcSchema.UsageType.FOREIGN_KEY)); 437 } 438 439 return true; 440 } 441 442 private boolean addCollapsedColumn(final JdbcSchema db, 443 final RolapStar.Column rColumn) { 444 String rname = getRolapStarColumnName(rColumn); 446 if (rname == null) { 447 StringBuilder buf = new StringBuilder (64); 448 buf.append("Adding Collapsed Column: "); 449 buf.append("For fact table \""); 450 buf.append(getFactTableName()); 451 buf.append("\", could not get column name for RolapStar.Column: "); 452 buf.append(rColumn); 453 getLogger().warn(buf.toString()); 454 return false; 455 } 456 457 RolapStar.Table rt = rColumn.getTable(); 458 459 JdbcSchema.Table jt = getTable(db, rt); 460 if (jt == null) { 461 StringBuilder buf = new StringBuilder (64); 462 buf.append("Adding Collapsed Column: "); 463 buf.append("For fact table \""); 464 buf.append(getFactTableName()); 465 buf.append("\", could not get jdbc schema table "); 466 buf.append("for RolapStar.Table with alias \""); 467 buf.append(rt.getAlias()); 468 buf.append("\""); 469 getLogger().warn(buf.toString()); 470 return false; 471 } 472 try { 473 jt.load(); 474 } catch (SQLException ex) { 475 getLogger().error(ex); 476 return false; 477 } 478 479 try { 481 jt.load(); 482 } catch (SQLException sqle) { 483 getLogger().error(sqle); 484 return false; 485 } 486 487 List <JdbcSchema.Table.Column.Usage> list = 490 new ArrayList <JdbcSchema.Table.Column.Usage>(); 491 for (RolapStar.Column rc : rt.getColumns()) { 492 if (rc.isNameColumn()) { 494 continue; 495 } 496 String name = getRolapStarColumnName(rc); 497 if (name == null) { 498 StringBuilder buf = new StringBuilder (64); 499 buf.append("Adding Collapsed Column: "); 500 buf.append("For fact table \""); 501 buf.append(getFactTableName()); 502 buf.append("\", could not get column name"); 503 buf.append(" for RolapStar.Column \""); 504 buf.append(rc); 505 buf.append("\" for RolapStar.Table with alias \""); 506 buf.append(rt.getAlias()); 507 buf.append("\""); 508 getLogger().warn(buf.toString()); 509 return false; 510 } 511 JdbcSchema.Table.Column c = getColumn(jt, name); 512 if (c == null) { 513 getLogger().warn("Can not find column: " + name); 514 break; 515 } 516 517 JdbcSchema.Table.Column.Usage usage = 518 c.newUsage(JdbcSchema.UsageType.FOREIGN_KEY); 519 usage.usagePrefix = rc.getUsagePrefix(); 520 521 list.add(usage); 522 523 if (rname.equals(name)) { 524 break; 525 } 526 } 527 List <JdbcSchema.Table.Column.Usage> l = collapsedColumnUsages.get(rt); 529 if ((l == null) || (l.size() < list.size())) { 530 collapsedColumnUsages.put(rt, list); 531 } 532 533 return true; 534 } 535 536 private static final String AGG_LOST_PREFIX = "agg_l_XXX_"; 537 538 String makeLostAggregateTableName(String factTableName) { 539 StringBuilder buf = new StringBuilder (64); 540 buf.append(AGG_LOST_PREFIX); 541 buf.append(factTableName); 542 return buf.toString(); 543 } 544 545 private static final String AGG_COLLAPSED_PREFIX = "agg_c_XXX_"; 546 547 String makeCollapsedAggregateTableName(String factTableName) { 548 StringBuilder buf = new StringBuilder (64); 549 buf.append(AGG_COLLAPSED_PREFIX); 550 buf.append(factTableName); 551 return buf.toString(); 552 } 553 554 555 556 562 public String createLost() { 563 StringWriter sw = new StringWriter (512); 564 PrintWriter pw = new PrintWriter (sw); 565 String prefix = " "; 566 567 pw.print("CREATE TABLE "); 568 pw.print(makeLostAggregateTableName(getFactTableName())); 569 pw.println(" ("); 570 571 for (JdbcSchema.Table.Column.Usage usage : notLostColumnUsages) { 573 addColumnCreate(pw, prefix, usage); 574 } 575 576 for (JdbcSchema.Table.Column.Usage usage : measures) { 578 addColumnCreate(pw, prefix, usage); 579 } 580 pw.print(prefix); 582 pw.print(getFactCount()); 583 pw.println(" INTEGER NOT NULL"); 584 585 pw.println(");"); 586 return sw.toString(); 587 } 588 589 593 public String insertIntoLost() { 594 StringWriter sw = new StringWriter (512); 595 PrintWriter pw = new PrintWriter (sw); 596 String prefix = " "; 597 String factTableName = getFactTableName(); 598 SqlQuery sqlQuery = getSqlQuery(); 599 600 pw.print("INSERT INTO "); 601 pw.print(makeLostAggregateTableName(getFactTableName())); 602 pw.println(" ("); 603 604 for (JdbcSchema.Table.Column.Usage usage : notLostColumnUsages) { 605 JdbcSchema.Table.Column c = usage.getColumn(); 606 607 pw.print(prefix); 608 pw.print(c.getName()); 609 pw.println(','); 610 } 611 612 for (JdbcSchema.Table.Column.Usage usage : measures) { 613 JdbcSchema.Table.Column c = usage.getColumn(); 614 615 pw.print(prefix); 616 String name = getUsageName(usage); 617 pw.print(name); 618 pw.println(','); 619 } 620 pw.print(prefix); 622 pw.print(getFactCount()); 623 pw.println(")"); 624 625 pw.println("SELECT"); 626 for (JdbcSchema.Table.Column.Usage usage : notLostColumnUsages) { 627 JdbcSchema.Table.Column c = usage.getColumn(); 628 629 pw.print(prefix); 630 pw.print(sqlQuery.getDialect().quoteIdentifier(factTableName, 631 c.getName())); 632 pw.print(" AS "); 633 pw.print(sqlQuery.getDialect().quoteIdentifier(c.getName())); 634 pw.println(','); 635 } 636 for (JdbcSchema.Table.Column.Usage usage : measures) { 637 JdbcSchema.Table.Column c = usage.getColumn(); 638 RolapAggregator agg = usage.getAggregator(); 639 640 pw.print(prefix); 641 pw.print( 642 agg.getExpression(sqlQuery.getDialect().quoteIdentifier( 643 factTableName, c.getName())).toUpperCase()); 644 pw.print(" AS "); 645 pw.print(sqlQuery.getDialect().quoteIdentifier(c.getName())); 646 pw.println(','); 647 } 648 649 pw.print(prefix); 651 pw.print("COUNT(*) AS "); 652 pw.println(sqlQuery.getDialect().quoteIdentifier(getFactCount())); 653 654 pw.println("FROM "); 655 pw.print(prefix); 656 pw.print(sqlQuery.getDialect().quoteIdentifier(factTableName)); 657 pw.print(" "); 658 pw.println(sqlQuery.getDialect().quoteIdentifier(factTableName)); 659 660 pw.println("GROUP BY "); 661 int k = 0; 662 for (JdbcSchema.Table.Column.Usage notLostColumnUsage : notLostColumnUsages) { 663 if (k++ > 0) { 664 pw.println(","); 665 } 666 JdbcSchema.Table.Column.Usage usage = notLostColumnUsage; 667 JdbcSchema.Table.Column c = usage.getColumn(); 668 669 pw.print(prefix); 670 pw.print(sqlQuery.getDialect().quoteIdentifier(factTableName, 671 c.getName())); 672 } 673 674 pw.println(';'); 675 return sw.toString(); 676 } 677 683 public String createCollapsed() { 684 StringWriter sw = new StringWriter (512); 685 PrintWriter pw = new PrintWriter (sw); 686 String prefix = " "; 687 688 pw.print("CREATE TABLE "); 689 pw.print(makeCollapsedAggregateTableName(getFactTableName())); 690 pw.println(" ("); 691 692 for (List <JdbcSchema.Table.Column.Usage> list : collapsedColumnUsages.values()) { 694 for (JdbcSchema.Table.Column.Usage usage : list) { 695 addColumnCreate(pw, prefix, usage); 696 } 697 } 698 699 for (JdbcSchema.Table.Column.Usage usage : measures) { 701 addColumnCreate(pw, prefix, usage); 702 } 703 pw.print(prefix); 705 pw.print(getFactCount()); 706 pw.println(" INTEGER NOT NULL"); 707 708 pw.println(");"); 709 return sw.toString(); 710 } 711 712 716 public String insertIntoCollapsed() { 717 StringWriter sw = new StringWriter (512); 718 PrintWriter pw = new PrintWriter (sw); 719 String prefix = " "; 720 String factTableName = getFactTableName(); 721 SqlQuery sqlQuery = getSqlQuery(); 722 723 pw.print("INSERT INTO "); 724 pw.print(makeCollapsedAggregateTableName(getFactTableName())); 725 pw.println(" ("); 726 727 728 for (List <JdbcSchema.Table.Column.Usage> list : collapsedColumnUsages.values()) { 729 for (JdbcSchema.Table.Column.Usage usage : list) { 730 JdbcSchema.Table.Column c = usage.getColumn(); 731 pw.print(prefix); 732 if (usage.usagePrefix != null) { 733 pw.print(usage.usagePrefix); 734 } 735 pw.print(c.getName()); 736 pw.println(','); 737 } 738 } 739 740 for (JdbcSchema.Table.Column.Usage usage : measures) { 741 JdbcSchema.Table.Column c = usage.getColumn(); 742 743 pw.print(prefix); 744 String name = getUsageName(usage); 745 pw.print(name); 746 pw.println(','); 748 } 749 pw.print(prefix); 751 pw.print(getFactCount()); 752 pw.println(")"); 753 754 pw.println("SELECT"); 755 for (List <JdbcSchema.Table.Column.Usage> list : collapsedColumnUsages.values()) { 756 for (JdbcSchema.Table.Column.Usage usage : list) { 757 JdbcSchema.Table.Column c = usage.getColumn(); 758 JdbcSchema.Table t = c.getTable(); 759 760 pw.print(prefix); 761 pw.print(sqlQuery.getDialect().quoteIdentifier(t.getName(), 762 c.getName())); 763 pw.print(" AS "); 764 String n = (usage.usagePrefix == null) 765 ? c.getName() : usage.usagePrefix + c.getName(); 766 pw.print(sqlQuery.getDialect().quoteIdentifier(n)); 767 pw.println(','); 768 } 769 } 770 for (JdbcSchema.Table.Column.Usage usage : measures) { 771 JdbcSchema.Table.Column c = usage.getColumn(); 772 JdbcSchema.Table t = c.getTable(); 773 RolapAggregator agg = usage.getAggregator(); 774 775 pw.print(prefix); 776 pw.print( 777 agg.getExpression(sqlQuery.getDialect().quoteIdentifier( 778 t.getName(), c.getName())).toUpperCase()); 779 pw.print(" AS "); 780 pw.print(sqlQuery.getDialect().quoteIdentifier(c.getName())); 781 pw.println(','); 782 } 783 784 pw.print(prefix); 786 pw.print("COUNT(*) AS "); 787 pw.println(sqlQuery.getDialect().quoteIdentifier(getFactCount())); 788 789 pw.println("FROM "); 790 pw.print(prefix); 791 pw.print(sqlQuery.getDialect().quoteIdentifier(factTableName)); 792 pw.print(" "); 793 pw.print(sqlQuery.getDialect().quoteIdentifier(factTableName)); 794 pw.println(','); 795 796 int k = 0; 798 for (RolapStar.Table rt : collapsedColumnUsages.keySet()) { 799 if (k++ > 0) { 800 pw.println(','); 801 } 802 pw.print(prefix); 803 pw.print(sqlQuery.getDialect().quoteIdentifier(rt.getAlias())); 804 pw.print(" AS "); 805 pw.print(sqlQuery.getDialect().quoteIdentifier(rt.getAlias())); 806 807 if (rt.getParentTable() != null) { 809 while (rt.getParentTable().getParentTable() != null) { 810 rt = rt.getParentTable(); 811 812 pw.println(','); 813 814 pw.print(prefix); 815 pw.print(sqlQuery 816 .getDialect().quoteIdentifier(rt.getAlias())); 817 pw.print(" AS "); 818 pw.print(sqlQuery 819 .getDialect().quoteIdentifier(rt.getAlias())); 820 } 821 } 822 } 823 824 pw.println(); 825 pw.println("WHERE "); 826 k = 0; 827 for (RolapStar.Table rt : collapsedColumnUsages.keySet()) { 828 if (k++ > 0) { 829 pw.println(" and"); 830 } 831 832 RolapStar.Condition cond = rt.getJoinCondition(); 833 if (cond == null) { 834 continue; 835 } 836 pw.print(prefix); 837 pw.print(cond.toString(sqlQuery)); 838 839 if (rt.getParentTable() != null) { 840 while (rt.getParentTable().getParentTable() != null) { 841 rt = rt.getParentTable(); 842 cond = rt.getJoinCondition(); 843 844 pw.println(" and"); 845 846 pw.print(prefix); 847 pw.print(cond.toString(sqlQuery)); 848 } 849 } 850 } 851 852 pw.println(); 853 pw.println("GROUP BY "); 854 k = 0; 855 for (List <JdbcSchema.Table.Column.Usage> list : collapsedColumnUsages.values()) { 856 for (JdbcSchema.Table.Column.Usage usage : list) { 857 if (k++ > 0) { 858 pw.println(","); 859 } 860 JdbcSchema.Table.Column c = usage.getColumn(); 861 JdbcSchema.Table t = c.getTable(); 862 863 String n = (usage.usagePrefix == null) 864 ? c.getName() : usage.usagePrefix + c.getName(); 865 pw.print(prefix); 866 pw.print(sqlQuery.getDialect().quoteIdentifier(t.getName(), n)); 867 } 868 } 869 pw.println(';'); 870 871 return sw.toString(); 872 } 873 874 875 876 private String getUsageName(final JdbcSchema.Table.Column.Usage usage) { 877 JdbcSchema.Table.Column c = usage.getColumn(); 878 String name = c.getName(); 879 if (usage.getUsageType() == JdbcSchema.UsageType.MEASURE) { 883 if (c.hasUsage(JdbcSchema.UsageType.FOREIGN_KEY)) { 884 name = usage.getSymbolicName().replace(' ', '_').toUpperCase(); 885 } 886 } 887 return name; 888 } 889 890 private void addColumnCreate(final PrintWriter pw, 891 final String prefix, 892 final JdbcSchema.Table.Column.Usage usage) { 893 JdbcSchema.Table.Column c = usage.getColumn(); 894 String name = getUsageName(usage); 895 896 pw.print(prefix); 897 if (usage.usagePrefix != null) { 898 pw.print(usage.usagePrefix); 899 } 900 pw.print(name); 901 pw.print(' '); 902 pw.print(c.getTypeName().toUpperCase()); 903 switch (c.getType()) { 904 case Types.NUMERIC: 905 case Types.DECIMAL: 906 pw.print('('); 907 pw.print(c.getNumPrecRadix()); 908 pw.print(","); 909 pw.print(c.getDecimalDigits()); 910 pw.print(')'); 911 break; 912 case Types.CHAR: 913 case Types.VARCHAR: 914 pw.print('('); 915 pw.print(c.getCharOctetLength()); 916 pw.print(')'); 917 break; 918 default: 919 } 920 if (! c.isNullable()) { 921 pw.print(" NOT NULL"); 922 } 923 pw.println(','); 924 925 } 926 } 927 928 | Popular Tags |