1 10 11 package mondrian.rolap.aggmatcher; 12 13 import mondrian.olap.*; 14 import mondrian.resource.MondrianResource; 15 import mondrian.recorder.MessageRecorder; 16 import mondrian.rolap.*; 17 import mondrian.rolap.sql.SqlQuery; 18 import org.apache.log4j.Logger; 19 20 import javax.sql.DataSource ; 21 import java.io.PrintWriter ; 22 import java.io.StringWriter ; 23 import java.sql.*; 24 import java.util.*; 25 26 46 public class AggStar { 47 private static final Logger LOGGER = Logger.getLogger(AggStar.class); 48 49 static Logger getLogger() { 50 return LOGGER; 51 } 52 53 private static final MondrianResource mres = MondrianResource.instance(); 54 55 59 public static AggStar makeAggStar( 60 final RolapStar star, 61 final JdbcSchema.Table dbTable, 62 final MessageRecorder msgRecorder) { 63 64 AggStar aggStar = new AggStar(star, dbTable); 65 AggStar.FactTable aggStarFactTable = aggStar.getFactTable(); 66 67 for (Iterator<JdbcSchema.Table.Column.Usage> it = 69 dbTable.getColumnUsages(JdbcSchema.UsageType.FACT_COUNT); 70 it.hasNext();) { 71 JdbcSchema.Table.Column.Usage usage = it.next(); 72 aggStarFactTable.loadFactCount(usage); 73 } 74 75 for (Iterator<JdbcSchema.Table.Column.Usage> it = 77 dbTable.getColumnUsages(JdbcSchema.UsageType.MEASURE); 78 it.hasNext();) { 79 JdbcSchema.Table.Column.Usage usage = it.next(); 80 aggStarFactTable.loadMeasure(usage); 81 } 82 83 for (Iterator<JdbcSchema.Table.Column.Usage> it = 85 dbTable.getColumnUsages(JdbcSchema.UsageType.FOREIGN_KEY); 86 it.hasNext();) { 87 JdbcSchema.Table.Column.Usage usage = it.next(); 88 aggStarFactTable.loadForeignKey(usage); 89 } 90 91 for (Iterator<JdbcSchema.Table.Column.Usage> it = 93 dbTable.getColumnUsages(JdbcSchema.UsageType.LEVEL); 94 it.hasNext();) { 95 JdbcSchema.Table.Column.Usage usage = it.next(); 96 aggStarFactTable.loadLevel(usage); 97 } 98 99 for (FactTable.Measure measure : aggStarFactTable.measures) { 102 if (measure.aggregator.isDistinct() && 103 measure.argument instanceof MondrianDef.Column) { 104 setLevelBits( 105 measure.rollableLevelBitKey, 106 aggStarFactTable, 107 (MondrianDef.Column) measure.argument, 108 star.getFactTable()); 109 } 110 } 111 112 return aggStar; 113 } 114 115 131 private static void setLevelBits( 132 final BitKey bitKey, 133 Table aggTable, 134 MondrianDef.Column column, 135 RolapStar.Table table) { 136 final Set<RolapStar.Column> columns = new HashSet<RolapStar.Column>(); 137 RolapStar.collectColumns(columns, table, column); 138 139 final List<Table.Level> levelList = new ArrayList<Table.Level>(); 140 collectLevels(levelList, aggTable, null); 141 142 for (Table.Level level : levelList) { 143 if (columns.contains(level.starColumn)) { 144 bitKey.set(level.getBitPosition()); 145 } 146 } 147 } 148 149 private static void collectLevels( 150 List<Table.Level> levelList, 151 Table table, 152 MondrianDef.Column joinColumn) { 153 if (joinColumn == null) { 154 levelList.addAll(table.levels); 155 } 156 for (Table dimTable : table.children) { 157 if (joinColumn != null && 158 !dimTable.getJoinCondition().left.equals(joinColumn)) { 159 continue; 160 } 161 collectLevels(levelList, dimTable, null); 162 } 163 } 164 165 private final RolapStar star; 166 private final AggStar.FactTable aggTable; 167 168 172 private final BitKey bitKey; 173 174 177 private final BitKey levelBitKey; 178 179 182 private final BitKey measureBitKey; 183 184 187 private final BitKey foreignKeyBitKey; 188 189 193 private final BitKey distinctMeasureBitKey; 194 private final AggStar.Table.Column[] columns; 195 196 AggStar(final RolapStar star, final JdbcSchema.Table aggTable) { 197 this.star = star; 198 this.bitKey = BitKey.Factory.makeBitKey(star.getColumnCount()); 199 this.levelBitKey = bitKey.emptyCopy(); 200 this.measureBitKey = bitKey.emptyCopy(); 201 this.foreignKeyBitKey = bitKey.emptyCopy(); 202 this.distinctMeasureBitKey = bitKey.emptyCopy(); 203 this.aggTable = new AggStar.FactTable(aggTable); 204 this.columns = new AggStar.Table.Column[star.getColumnCount()]; 205 } 206 207 public AggStar.FactTable getFactTable() { 208 return aggTable; 209 } 210 211 217 public int getSize() { 218 return MondrianProperties.instance().ChooseAggregateByVolume.get() ? 219 getFactTable().getVolume() : 220 getFactTable().getNumberOfRows(); 221 } 222 223 void setForeignKey(int index) { 224 this.foreignKeyBitKey.set(index); 225 } 226 public BitKey getForeignKeyBitKey() { 227 return this.foreignKeyBitKey; 228 } 229 230 237 public boolean superSetMatch(final BitKey bitKey) { 238 return getBitKey().isSuperSetOf(bitKey); 239 } 240 241 247 public boolean select( 248 final BitKey levelBitKey, 249 final BitKey coreLevelBitKey, 250 final BitKey measureBitKey) { 251 if (!getMeasureBitKey().isSuperSetOf(measureBitKey)) { 252 return false; 253 } 254 if (getLevelBitKey().equals(levelBitKey)) { 255 return true; 256 } else if (getLevelBitKey().isSuperSetOf(levelBitKey) && 257 getLevelBitKey().andNot(coreLevelBitKey).equals( 258 levelBitKey.andNot(coreLevelBitKey))) { 259 return true; 262 } else { 263 return false; 264 } 265 } 266 267 270 public RolapStar getStar() { 271 return star; 272 } 273 274 277 public boolean hasMeasures() { 278 return getFactTable().hasMeasures(); 279 } 280 281 284 public boolean hasLevels() { 285 return getFactTable().hasLevels(); 286 } 287 288 291 public boolean hasForeignKeys() { 292 return getFactTable().hasChildren(); 293 } 294 295 298 public BitKey getBitKey() { 299 return bitKey; 300 } 301 302 305 public BitKey getLevelBitKey() { 306 return levelBitKey; 307 } 308 309 312 public BitKey getMeasureBitKey() { 313 return measureBitKey; 314 } 315 316 319 public BitKey getDistinctMeasureBitKey() { 320 return distinctMeasureBitKey; 321 } 322 323 326 private SqlQuery getSqlQuery() { 327 return getStar().getSqlQuery(); 328 } 329 330 339 public AggStar.FactTable.Measure lookupMeasure(final int bitPos) { 340 AggStar.Table.Column column = lookupColumn(bitPos); 341 return (column instanceof AggStar.FactTable.Measure) 342 ? (AggStar.FactTable.Measure) column 343 : null; 344 } 345 354 public AggStar.Table.Level lookupLevel(final int bitPos) { 355 AggStar.Table.Column column = lookupColumn(bitPos); 356 return (column instanceof AggStar.FactTable.Level) 357 ? (AggStar.FactTable.Level) column 358 : null; 359 } 360 361 366 public AggStar.Table.Column lookupColumn(final int bitPos) { 367 return columns[bitPos]; 368 } 369 370 375 private void addColumn(final AggStar.Table.Column column) { 376 columns[column.getBitPosition()] = column; 377 } 378 379 private static final Logger JOIN_CONDITION_LOGGER = 380 Logger.getLogger(AggStar.Table.JoinCondition.class); 381 382 387 public abstract class Table { 388 389 393 public class JoinCondition { 394 private final MondrianDef.Expression left; 396 private final MondrianDef.Expression right; 397 398 private JoinCondition(final MondrianDef.Expression left, 399 final MondrianDef.Expression right) { 400 if (!(left instanceof MondrianDef.Column)) { 401 JOIN_CONDITION_LOGGER.debug( 402 "JoinCondition.left NOT Column: " 403 +left.getClass().getName()); 404 } 405 this.left = left; 406 this.right = right; 407 } 408 409 412 public Table getTable() { 413 return AggStar.Table.this; 414 } 415 416 419 String toString(final SqlQuery query) { 420 StringBuilder buf = new StringBuilder (64); 421 buf.append(left.getExpression(query)); 422 buf.append(" = "); 423 buf.append(right.getExpression(query)); 424 return buf.toString(); 425 } 426 public String toString() { 427 StringWriter sw = new StringWriter (128); 428 PrintWriter pw = new PrintWriter (sw); 429 print(pw, ""); 430 pw.flush(); 431 return sw.toString(); 432 } 433 434 437 public void print(final PrintWriter pw, final String prefix) { 438 SqlQuery sqlQueuy = getTable().getSqlQuery(); 439 pw.print(prefix); 440 pw.println("JoinCondition:"); 441 String subprefix = prefix + " "; 442 443 pw.print(subprefix); 444 pw.print("left="); 445 if (left instanceof MondrianDef.Column) { 446 MondrianDef.Column c = (MondrianDef.Column) left; 447 mondrian.rolap.RolapStar.Column col = getTable().getAggStar().getStar().getFactTable().lookupColumn(c.name); 448 if (col != null) { 449 pw.print(" ("); 450 pw.print(col.getBitPosition()); 451 pw.print(") "); 452 } 453 } 454 pw.println(left.getExpression(sqlQueuy)); 455 456 pw.print(subprefix); 457 pw.print("right="); 458 pw.println(right.getExpression(sqlQueuy)); 459 } 460 } 461 462 463 466 public class Column { 467 468 private final String name; 469 private final MondrianDef.Expression expression; 470 private final SqlQuery.Datatype datatype; 471 476 private final Column nameColumn; 477 478 479 private final int bitPosition; 480 481 protected Column( 482 final String name, 483 final MondrianDef.Expression expression, 484 final SqlQuery.Datatype datatype, 485 final int bitPosition) { 486 this.name = name; 487 this.expression = expression; 488 this.datatype = datatype; 489 this.bitPosition = bitPosition; 490 491 this.nameColumn = null; 492 493 if (bitPosition >= 0) { 495 AggStar.this.bitKey.set(bitPosition); 496 AggStar.this.addColumn(this); 497 } 498 } 499 500 503 public String getName() { 504 return name; 505 } 506 507 510 public AggStar.Table getTable() { 511 return AggStar.Table.this; 512 } 513 514 518 public int getBitPosition() { 519 return bitPosition; 520 } 521 522 525 public SqlQuery.Datatype getDatatype() { 526 return datatype; 527 } 528 529 public SqlQuery getSqlQuery() { 530 return getTable().getAggStar().getSqlQuery(); 531 } 532 533 public MondrianDef.Expression getExpression() { 534 return expression; 535 } 536 537 541 public String generateExprString(final SqlQuery query) { 542 return getExpression().getExpression(query); 543 } 544 545 public String toString() { 546 StringWriter sw = new StringWriter (256); 547 PrintWriter pw = new PrintWriter (sw); 548 print(pw, ""); 549 pw.flush(); 550 return sw.toString(); 551 } 552 public void print(final PrintWriter pw, final String prefix) { 553 SqlQuery sqlQuery = getSqlQuery(); 554 pw.print(prefix); 555 pw.print(getName()); 556 pw.print(" ("); 557 pw.print(getBitPosition()); 558 pw.print("): "); 559 pw.print(generateExprString(sqlQuery)); 560 } 561 } 562 563 567 final class ForeignKey extends Column { 568 569 private ForeignKey( 570 final String name, 571 final MondrianDef.Expression expression, 572 final SqlQuery.Datatype datatype, 573 final int bitPosition) { 574 super(name, expression, datatype, bitPosition); 575 AggStar.this.levelBitKey.set(bitPosition); 576 } 577 } 578 579 583 final class Level extends Column { 584 private final RolapStar.Column starColumn; 585 586 private Level( 587 final String name, 588 final MondrianDef.Expression expression, 589 final int bitPosition, 590 RolapStar.Column starColumn) { 591 super(name, expression, starColumn.getDatatype(), bitPosition); 592 this.starColumn = starColumn; 593 AggStar.this.levelBitKey.set(bitPosition); 594 } 595 } 596 597 598 private final String name; 599 private final MondrianDef.Relation relation; 600 protected final List<Level> levels = new ArrayList<Level>(); 601 protected List<DimTable> children; 602 603 Table(final String name, final MondrianDef.Relation relation) { 604 this.name = name; 605 this.relation = relation; 606 this.children = Collections.emptyList(); 607 } 608 609 612 public String getName() { 613 return name; 614 } 615 616 620 public abstract boolean hasParent(); 621 622 625 public abstract Table getParent(); 626 627 631 public abstract boolean hasJoinCondition(); 632 public abstract Table.JoinCondition getJoinCondition(); 633 634 public MondrianDef.Relation getRelation() { 635 return relation; 636 } 637 638 641 protected AggStar getAggStar() { 642 return AggStar.this; 643 } 644 645 648 protected SqlQuery getSqlQuery() { 649 return getAggStar().getSqlQuery(); 650 } 651 652 657 protected void addLevel(final AggStar.Table.Level level) { 658 this.levels.add(level); 659 } 660 661 664 public List<Level> getLevels() { 665 return levels; 666 } 667 668 671 public boolean hasLevels() { 672 return ! levels.isEmpty(); 673 } 674 675 680 protected void addTable(final DimTable child) { 681 if (children == Collections.EMPTY_LIST) { 682 children = new ArrayList<DimTable>(); 683 } 684 children.add(child); 685 } 686 687 690 public List<DimTable> getChildTables() { 691 return children; 692 } 693 694 697 public boolean hasChildren() { 698 return ! children.isEmpty(); 699 } 700 701 709 protected AggStar.DimTable convertTable( 710 final RolapStar.Table rTable, 711 final String rightJoinConditionColumnName) { 712 String tableName = rTable.getAlias(); 713 MondrianDef.Relation relation = rTable.getRelation(); 714 RolapStar.Condition rjoinCondition = rTable.getJoinCondition(); 715 MondrianDef.Expression rleft = rjoinCondition.getLeft(); 716 MondrianDef.Expression rright = rjoinCondition.getRight(); 717 718 MondrianDef.Column left = null; 719 if (rightJoinConditionColumnName != null) { 720 left = new MondrianDef.Column(getName(), 721 rightJoinConditionColumnName); 722 } else { 723 if (rleft instanceof MondrianDef.Column) { 724 MondrianDef.Column lcolumn = (MondrianDef.Column) rleft; 725 left = new MondrianDef.Column(getName(), lcolumn.name); 726 } else { 727 728 String msg = mres.BadRolapStarLeftJoinCondition.str( 730 "AggStar.Table", 731 rleft.getClass().getName(), left.toString()); 732 getLogger().warn(msg); 733 } 734 } 735 mondrian.rolap.RolapStar.Column col = 740 getAggStar().getStar().getFactTable().lookupColumn(left.name); 741 if (col != null) { 742 getAggStar().setForeignKey(col.getBitPosition()); 743 } 744 JoinCondition joinCondition = new JoinCondition(left, rright); 745 DimTable dimTable = 746 new DimTable(this, tableName, relation, joinCondition); 747 748 dimTable.convertColumns(rTable); 749 dimTable.convertChildren(rTable); 750 751 return dimTable; 752 } 753 754 760 protected void convertColumns(final RolapStar.Table rTable) { 761 for (RolapStar.Column column : rTable.getColumns()) { 763 String name = column.getName(); 764 MondrianDef.Expression expression = column.getExpression(); 765 int bitPosition = column.getBitPosition(); 766 767 Level level = new Level( 768 name, 769 expression, 770 bitPosition, 771 column); 772 addLevel(level); 773 } 774 } 775 776 782 protected void convertChildren(final RolapStar.Table rTable) { 783 for (RolapStar.Table rTableChild : rTable.getChildren()) { 785 DimTable dimChild = convertTable(rTableChild, null); 786 787 addTable(dimChild); 788 } 789 } 790 791 799 public void addToFrom(final SqlQuery query, 800 final boolean failIfExists, 801 final boolean joinToParent) { 802 query.addFrom(relation, name, failIfExists); 803 if (joinToParent) { 804 if (hasParent()) { 805 getParent().addToFrom(query, failIfExists, joinToParent); 806 } 807 if (hasJoinCondition()) { 808 query.addWhere(getJoinCondition().toString(query)); 809 } 810 } 811 } 812 813 public String toString() { 814 StringWriter sw = new StringWriter (256); 815 PrintWriter pw = new PrintWriter (sw); 816 print(pw, ""); 817 pw.flush(); 818 return sw.toString(); 819 } 820 public abstract void print(final PrintWriter pw, final String prefix); 821 } 822 823 826 public class FactTable extends Table { 827 828 831 public class Measure extends Table.Column { 832 private final RolapAggregator aggregator; 833 836 private final MondrianDef.Expression argument; 837 842 private final BitKey rollableLevelBitKey; 843 844 private Measure( 845 final String name, 846 final MondrianDef.Expression expression, 847 final SqlQuery.Datatype datatype, 848 final int bitPosition, 849 final RolapAggregator aggregator, 850 final MondrianDef.Expression argument) { 851 super(name, expression, datatype, bitPosition); 852 this.aggregator = aggregator; 853 this.argument = argument; 854 assert (argument != null) == aggregator.isDistinct(); 855 this.rollableLevelBitKey = 856 BitKey.Factory.makeBitKey(star.getColumnCount()); 857 858 AggStar.this.measureBitKey.set(bitPosition); 859 } 860 861 public boolean isDistinct() { 862 return aggregator.isDistinct(); 863 } 864 865 868 public RolapAggregator getAggregator() { 869 return aggregator; 870 } 871 872 876 public BitKey getRollableLevelBitKey() { 877 return rollableLevelBitKey; 878 } 879 880 885 892 904 public String generateRollupString(SqlQuery query) { 905 String expr = generateExprString(query); 906 Aggregator rollup = null; 907 908 BitKey fkbk = AggStar.this.getForeignKeyBitKey(); 909 if (fkbk.get(getBitPosition())) { 913 rollup = (getAggregator().isDistinct()) 914 ? getAggregator().getNonDistinctAggregator() 915 : getAggregator().getRollup(); 916 } else { 917 rollup = getAggregator().getRollup(); 918 } 919 920 String s = ((RolapAggregator) rollup).getExpression(expr); 921 return s; 922 } 923 public void print(final PrintWriter pw, final String prefix) { 924 SqlQuery sqlQuery = getSqlQuery(); 925 pw.print(prefix); 926 pw.print(getName()); 927 pw.print(" ("); 928 pw.print(getBitPosition()); 929 pw.print("): "); 930 pw.print(generateRollupString(sqlQuery)); 931 } 932 } 933 934 private Column factCountColumn; 935 private final List<Measure> measures; 936 private final int totalColumnSize; 937 private int numberOfRows; 938 939 FactTable(final JdbcSchema.Table aggTable) { 940 this(aggTable.getName(), 941 aggTable.table, 942 aggTable.getTotalColumnSize(), 943 aggTable.getNumberOfRows()); 944 } 945 FactTable(final String name, 946 final MondrianDef.Relation relation, 947 final int totalColumnSize, 948 final int numberOfRows) { 949 super(name, relation); 950 this.totalColumnSize = totalColumnSize; 951 this.measures = new ArrayList<Measure>(); 952 this.numberOfRows = numberOfRows; 953 } 954 public Table getParent() { 955 return null; 956 } 957 public boolean hasParent() { 958 return false; 959 } 960 public boolean hasJoinCondition() { 961 return false; 962 } 963 public Table.JoinCondition getJoinCondition() { 964 return null; 965 } 966 967 970 public int getVolume() { 971 return getTotalColumnSize() * getNumberOfRows(); 972 } 973 974 977 public int getTotalColumnSize() { 978 return totalColumnSize; 979 } 980 981 984 public int getNumberOfRows() { 985 if (numberOfRows == -1) { 986 makeNumberOfRows(); 987 } 988 return numberOfRows; 989 } 990 991 996 void setNumberOfRows(int numberOfRows) { 997 this.numberOfRows = numberOfRows; 998 } 999 1000 1003 public List<Measure> getMeasures() { 1004 return measures; 1005 } 1006 1007 1010 public boolean hasMeasures() { 1011 return ! measures.isEmpty(); 1012 } 1013 1014 1017 public List<Column> getColumns() { 1018 List<Column> list = new ArrayList<Column>(); 1019 list.addAll(measures); 1020 list.addAll(levels); 1021 for (DimTable dimTable : getChildTables()) { 1022 dimTable.addColumnsToList(list); 1023 } 1024 return list; 1025 } 1026 1027 1032 private void loadForeignKey(final JdbcSchema.Table.Column.Usage usage) { 1033 if (usage.rTable != null) { 1034 DimTable child = convertTable( 1035 usage.rTable, 1036 usage.rightJoinConditionColumnName); 1037 addTable(child); 1038 } else { 1039 JdbcSchema.Table.Column column = usage.getColumn(); 1043 String name = column.getName(); 1044 String symbolicName = usage.getSymbolicName(); 1045 if (symbolicName == null) { 1046 symbolicName = name; 1047 } 1048 1049 MondrianDef.Expression expression = 1050 new MondrianDef.Column(getName(), name); 1051 SqlQuery.Datatype datatype = column.getDatatype(); 1052 RolapStar.Column rColumn = usage.rColumn; 1053 if (rColumn == null) { 1054 String msg = "loadForeignKey: for column " + 1055 name + 1056 ", rColumn == null"; 1057 getLogger().warn(msg); 1058 } else { 1059 int bitPosition = rColumn.getBitPosition(); 1060 ForeignKey c = 1061 new ForeignKey( 1062 symbolicName, expression, datatype, bitPosition); 1063 getAggStar().setForeignKey(c.getBitPosition()); 1064 } 1065 } 1066 } 1067 1068 1073 private void loadMeasure(final JdbcSchema.Table.Column.Usage usage) { 1074 final JdbcSchema.Table.Column column = usage.getColumn(); 1075 String name = column.getName(); 1076 String symbolicName = usage.getSymbolicName(); 1077 if (symbolicName == null) { 1078 symbolicName = name; 1079 } 1080 SqlQuery.Datatype datatype = column.getDatatype(); 1081 RolapAggregator aggregator = usage.getAggregator(); 1082 1083 MondrianDef.Expression expression; 1084 if (column.hasUsage(JdbcSchema.UsageType.FOREIGN_KEY) && 1085 ! aggregator.isDistinct()) { 1086 expression = factCountColumn.getExpression(); 1087 } else { 1088 expression = new MondrianDef.Column(getName(), name); 1089 } 1090 1091 MondrianDef.Expression argument; 1092 if (aggregator.isDistinct()) { 1093 argument = usage.rMeasure.getExpression(); 1094 } else { 1095 argument = null; 1096 } 1097 1098 int bitPosition = usage.rMeasure.getBitPosition(); 1099 1100 Measure aggMeasure = new Measure( 1101 symbolicName, 1102 expression, 1103 datatype, 1104 bitPosition, 1105 aggregator, 1106 argument); 1107 1108 measures.add(aggMeasure); 1109 1110 if (aggMeasure.aggregator.isDistinct()) { 1111 distinctMeasureBitKey.set(bitPosition); 1112 } 1113 } 1114 1115 1120 private void loadFactCount(final JdbcSchema.Table.Column.Usage usage) { 1121 String name = usage.getColumn().getName(); 1122 String symbolicName = usage.getSymbolicName(); 1123 if (symbolicName == null) { 1124 symbolicName = name; 1125 } 1126 1127 MondrianDef.Expression expression = 1128 new MondrianDef.Column(getName(), name); 1129 SqlQuery.Datatype datatype = usage.getColumn().getDatatype(); 1130 int bitPosition = -1; 1131 1132 Column aggColumn = new Column( 1133 symbolicName, 1134 expression, 1135 datatype, 1136 bitPosition); 1137 1138 factCountColumn = aggColumn; 1139 } 1140 1141 1146 private void loadLevel(final JdbcSchema.Table.Column.Usage usage) { 1147 String name = usage.getSymbolicName(); 1148 MondrianDef.Expression expression = 1149 new MondrianDef.Column(getName(), usage.levelColumnName); 1150 int bitPosition = usage.rColumn.getBitPosition(); 1151 Level level = new Level( 1152 name, 1153 expression, 1154 bitPosition, 1155 usage.rColumn); 1156 addLevel(level); 1157 } 1158 1159 public void print(final PrintWriter pw, final String prefix) { 1160 pw.print(prefix); 1161 pw.println("Table:"); 1162 String subprefix = prefix + " "; 1163 String subsubprefix = subprefix + " "; 1164 1165 pw.print(subprefix); 1166 pw.print("name="); 1167 pw.println(getName()); 1168 1169 if (getRelation() != null) { 1170 pw.print(subprefix); 1171 pw.print("relation="); 1172 pw.println(getRelation()); 1173 } 1174 1175 pw.print(subprefix); 1176 pw.print("numberofrows="); 1177 pw.println(getNumberOfRows()); 1178 1179 pw.print(subprefix); 1180 pw.println("FactCount:"); 1181 factCountColumn.print(pw, subsubprefix); 1182 pw.println(); 1183 1184 pw.print(subprefix); 1185 pw.println("Measures:"); 1186 for (Measure column : getMeasures()) { 1187 column.print(pw, subsubprefix); 1188 pw.println(); 1189 } 1190 1191 pw.print(subprefix); 1192 pw.println("Levels:"); 1193 for (Level level : getLevels()) { 1194 level.print(pw, subsubprefix); 1195 pw.println(); 1196 } 1197 1198 for (DimTable child : getChildTables()) { 1199 child.print(pw, subprefix); 1200 } 1201 } 1202 1203 private void makeNumberOfRows() { 1204 SqlQuery query = getSqlQuery(); 1205 query.addSelect("count(*)"); 1206 query.addFrom(getRelation(), getName(), false); 1207 DataSource dataSource = getAggStar().getStar().getDataSource(); 1208 SqlStatement stmt = 1209 RolapUtil.executeQuery( 1210 dataSource, query.toString(), 1211 "AggStar.FactTable.makeNumberOfRows", 1212 "Counting rows in aggregate table"); 1213 try { 1214 ResultSet resultSet = stmt.getResultSet(); 1215 if (resultSet.next()) { 1216 ++stmt.rowCount; 1217 numberOfRows = resultSet.getInt(1); 1218 } else { 1219 String msg = 1220 mres.SqlQueryFailed.str( 1221 "AggStar.FactTable.makeNumberOfRows", 1222 query.toString()); 1223 getLogger().warn(msg); 1224 1225 numberOfRows = Integer.MAX_VALUE / getTotalColumnSize(); 1227 } 1228 } catch (SQLException e) { 1229 stmt.handle(e); 1230 } finally { 1231 stmt.close(); 1232 } 1233 } 1234 } 1235 1236 1239 public class DimTable extends Table { 1240 private final Table parent; 1241 private final JoinCondition joinCondition; 1242 1243 DimTable(final Table parent, 1244 final String name, 1245 final MondrianDef.Relation relation, 1246 final JoinCondition joinCondition) { 1247 super(name, relation); 1248 this.parent = parent; 1249 this.joinCondition = joinCondition; 1250 } 1251 public Table getParent() { 1252 return parent; 1253 } 1254 public boolean hasParent() { 1255 return true; 1256 } 1257 public boolean hasJoinCondition() { 1258 return true; 1259 } 1260 public Table.JoinCondition getJoinCondition() { 1261 return joinCondition; 1262 } 1263 1264 1270 public void addColumnsToList(final List<Column> list) { 1271 list.addAll(levels); 1272 for (DimTable dimTable : getChildTables()) { 1273 dimTable.addColumnsToList(list); 1274 } 1275 } 1276 1277 public void print(final PrintWriter pw, final String prefix) { 1278 pw.print(prefix); 1279 pw.println("Table:"); 1280 String subprefix = prefix + " "; 1281 String subsubprefix = subprefix + " "; 1282 1283 pw.print(subprefix); 1284 pw.print("name="); 1285 pw.println(getName()); 1286 1287 if (getRelation() != null) { 1288 pw.print(subprefix); 1289 pw.print("relation="); 1290 pw.println(getRelation()); 1291 } 1292 1293 pw.print(subprefix); 1294 pw.println("Levels:"); 1295 1296 for (Level level : getLevels()) { 1297 level.print(pw, subsubprefix); 1298 pw.println(); 1299 } 1300 1301 joinCondition.print(pw, subprefix); 1302 1303 for (DimTable child : getChildTables()) { 1304 child.print(pw, subprefix); 1305 } 1306 } 1307 } 1308 1309 public String toString() { 1310 StringWriter sw = new StringWriter (256); 1311 PrintWriter pw = new PrintWriter (sw); 1312 print(pw, ""); 1313 pw.flush(); 1314 return sw.toString(); 1315 } 1316 1317 1323 public void print(final PrintWriter pw, final String prefix) { 1324 pw.print(prefix); 1325 pw.println("AggStar:"); 1326 String subprefix = prefix + " "; 1327 1328 pw.print(subprefix); 1329 pw.print(" bk="); 1330 pw.println(bitKey); 1331 1332 pw.print(subprefix); 1333 pw.print("fbk="); 1334 pw.println(levelBitKey); 1335 1336 pw.print(subprefix); 1337 pw.print("mbk="); 1338 pw.println(measureBitKey); 1339 1340 pw.print(subprefix); 1341 pw.print("has foreign key="); 1342 pw.println(aggTable.hasChildren()); 1343 1344 aggTable.print(pw, subprefix); 1345 } 1346} 1347 1348 | Popular Tags |