1 10 11 package mondrian.rolap.agg; 12 13 import mondrian.olap.Util; 14 import mondrian.rolap.RolapStar; 15 import mondrian.rolap.StarColumnPredicate; 16 import mondrian.rolap.sql.SqlQuery; 17 18 26 class SegmentArrayQuerySpec extends AbstractQuerySpec { 27 private final Segment[] segments; 28 29 34 SegmentArrayQuerySpec(final Segment[] segments) { 35 super(segments[0].aggregation.getStar()); 36 this.segments = segments; 37 assert isValid(true); 38 } 39 40 47 private boolean isValid(boolean fail) { 48 assert segments.length > 0; 49 for (Segment segment : segments) { 50 if (segment.aggregation != segments[0].aggregation) { 51 assert!fail; 52 return false; 53 } 54 int n = segment.axes.length; 55 if (n != segments[0].axes.length) { 56 assert!fail; 57 return false; 58 } 59 for (int j = 0; j < segment.axes.length; j++) { 60 if (segment.axes[j].getPredicate() != 64 segments[0].axes[j].getPredicate()) { 65 assert!fail; 66 return false; 67 } 68 } 69 } 70 return true; 71 } 72 73 public int getMeasureCount() { 74 return segments.length; 75 } 76 77 public RolapStar.Measure getMeasure(final int i) { 78 return segments[i].measure; 79 } 80 81 public String getMeasureAlias(final int i) { 82 return "m" + Integer.toString(i); 83 } 84 85 public RolapStar.Column[] getColumns() { 86 return segments[0].aggregation.getColumns(); 87 } 88 89 94 public String getColumnAlias(final int i) { 95 return "c" + Integer.toString(i); 96 } 97 98 public StarColumnPredicate getColumnPredicate(final int i) { 99 return segments[0].axes[i].getPredicate(); 100 } 101 102 public String generateSqlQuery() { 103 SqlQuery sqlQuery = newSqlQuery(); 104 105 int k = getDistinctMeasureCount(); 106 final SqlQuery.Dialect dialect = sqlQuery.getDialect(); 107 if (!dialect.allowsCountDistinct() && k > 0 || 108 !dialect.allowsMultipleCountDistinct() && k > 1) { 109 distinctGenerateSql(sqlQuery); 110 } else { 111 nonDistinctGenerateSql(sqlQuery, false, false); 112 } 113 114 return sqlQuery.toString(); 115 } 116 117 122 protected int getDistinctMeasureCount() { 123 int k = 0; 124 for (int i = 0, count = getMeasureCount(); i < count; i++) { 125 RolapStar.Measure measure = getMeasure(i); 126 if (measure.getAggregator().isDistinct()) { 127 ++k; 128 } 129 } 130 return k; 131 } 132 133 protected void addMeasure(final int i, final SqlQuery sqlQuery) { 134 RolapStar.Measure measure = getMeasure(i); 135 Util.assertTrue(measure.getTable() == getStar().getFactTable()); 136 measure.getTable().addToFrom(sqlQuery, false, true); 137 138 String exprInner = measure.generateExprString(sqlQuery); 139 String exprOuter = measure.getAggregator().getExpression(exprInner); 140 sqlQuery.addSelect(exprOuter, getMeasureAlias(i)); 141 } 142 143 protected boolean isAggregate() { 144 return true; 145 } 146 147 154 protected void distinctGenerateSql(final SqlQuery outerSqlQuery) { 155 final SqlQuery.Dialect dialect = outerSqlQuery.getDialect(); 156 163 final SqlQuery innerSqlQuery = newSqlQuery(); 164 innerSqlQuery.setDistinct(true); 165 166 RolapStar.Column[] columns = getColumns(); 168 int arity = columns.length; 169 for (int i = 0; i < arity; i++) { 170 RolapStar.Column column = columns[i]; 171 RolapStar.Table table = column.getTable(); 172 if (table.isFunky()) { 173 continue; 175 } 176 table.addToFrom(innerSqlQuery, false, true); 177 String expr = column.generateExprString(innerSqlQuery); 178 StarColumnPredicate predicate = getColumnPredicate(i); 179 final String where = RolapStar.Column.createInExpr( 180 expr, 181 predicate, 182 column.getDatatype(), 183 innerSqlQuery.getDialect()); 184 if (!where.equals("true")) { 185 innerSqlQuery.addWhere(where); 186 } 187 final String alias = "d" + i; 188 innerSqlQuery.addSelect(expr, alias); 189 final String quotedAlias = dialect.quoteIdentifier(alias); 190 outerSqlQuery.addSelect(quotedAlias); 191 outerSqlQuery.addGroupBy(quotedAlias); 192 } 193 for (int i = 0, count = getMeasureCount(); i < count; i++) { 194 RolapStar.Measure measure = getMeasure(i); 195 196 Util.assertTrue(measure.getTable() == getStar().getFactTable()); 197 measure.getTable().addToFrom(innerSqlQuery, false, true); 198 199 String alias = getMeasureAlias(i); 200 String expr = measure.generateExprString(outerSqlQuery); 201 innerSqlQuery.addSelect(expr, alias); 202 203 outerSqlQuery.addSelect( 204 measure.getAggregator().getNonDistinctAggregator().getExpression( 205 dialect.quoteIdentifier(alias))); 206 } 207 outerSqlQuery.addFrom(innerSqlQuery, "dummyname", true); 208 } 209 } 210 211 | Popular Tags |