1 9 package mondrian.rolap; 10 11 import java.util.*; 12 13 import mondrian.mdx.MemberExpr; 14 import mondrian.mdx.ResolvedFunCall; 15 import mondrian.olap.*; 16 import mondrian.rolap.sql.MemberChildrenConstraint; 17 import mondrian.rolap.sql.SqlQuery; 18 import mondrian.rolap.sql.TupleConstraint; 19 import mondrian.rolap.aggmatcher.AggStar; 20 21 39 public class SqlContextConstraint implements MemberChildrenConstraint, 40 TupleConstraint { 41 List<Object > cacheKey; 42 private Evaluator evaluator; 43 private boolean strict; 44 45 48 public static boolean isValidContext(Evaluator context) { 49 return isValidContext(context, true, null); 50 } 51 52 59 public static boolean isValidContext( 60 Evaluator context, 61 boolean disallowVirtualCube, 62 Level [] levels) 63 { 64 if (context == null) { 65 return false; 66 } 67 RolapCube cube = (RolapCube) context.getCube(); 68 if (disallowVirtualCube) { 69 if (cube.isVirtual()) { 70 return false; 71 } 72 } 73 if (cube.isVirtual()) { 74 Query query = context.getQuery(); 75 Set<Map<RolapLevel, RolapStar.Column>> baseCubesLevelToColumnMaps = 76 new HashSet<Map<RolapLevel, RolapStar.Column>>(); 77 Map<Map<RolapLevel, RolapStar.Column>, RolapMember> measureMap = 78 new HashMap<Map<RolapLevel, RolapStar.Column>, RolapMember>(); 79 if (!findVirtualCubeJoinLevels( 80 query, 81 baseCubesLevelToColumnMaps, 82 measureMap)) 83 { 84 return false; 85 } 86 assert(levels != null); 87 for (Map<RolapLevel, RolapStar.Column> map : baseCubesLevelToColumnMaps) { 91 for (Level level : levels) { 92 if (map.get((RolapLevel) level) == null) { 93 return false; 94 } 95 } 96 } 97 query.setVirtualCubeBaseCubeMaps(baseCubesLevelToColumnMaps); 98 query.setLevelMapToMeasureMap(measureMap); 99 } 100 return true; 101 } 102 103 115 private static boolean findVirtualCubeJoinLevels( 116 Query query, 117 Set<Map<RolapLevel, RolapStar.Column>> baseCubesLevelToColumnMaps, 118 Map<Map<RolapLevel, RolapStar.Column>, RolapMember> measureMap) 119 { 120 Set<Member> measureMembers = query.getMeasuresMembers(); 124 if (measureMembers.isEmpty()) { 127 Cube cube = query.getCube(); 128 Dimension dimension = cube.getDimensions()[0]; 129 query.addMeasuresMembers( 130 dimension.getHierarchy().getDefaultMember()); 131 } 132 for (Member member : query.getMeasuresMembers()) { 133 if (member instanceof RolapStoredMeasure) { 134 addMeasure( 135 (RolapStoredMeasure) member, 136 baseCubesLevelToColumnMaps, 137 measureMap); 138 } else if (member instanceof RolapCalculatedMember) { 139 findMeasures( 140 member.getExpression(), 141 baseCubesLevelToColumnMaps, 142 measureMap); 143 } 144 } 145 if (measureMap.isEmpty()) { 146 return false; 147 } 148 149 return true; 150 } 151 152 160 private static void addMeasure( 161 RolapStoredMeasure measure, 162 Set<Map<RolapLevel, RolapStar.Column>> baseCubesLevelToColumnMaps, 163 Map<Map<RolapLevel, RolapStar.Column>, RolapMember> measureMap) 164 { 165 RolapStar.Measure starMeasure = 166 (RolapStar.Measure) measure.getStarMeasure(); 167 RolapStar star = starMeasure.getStar(); 168 RolapCube baseCube = measure.getCube(); 169 Map<RolapLevel, RolapStar.Column> levelToColumnMap = 170 star.getLevelToColumnMap(baseCube); 171 if (baseCubesLevelToColumnMaps.add(levelToColumnMap)) { 172 measureMap.put(levelToColumnMap, (RolapMember) measure); 173 } 174 } 175 176 185 private static void findMeasures( 186 Exp exp, 187 Set<Map<RolapLevel, RolapStar.Column>> baseCubesLevelToColumnMaps, 188 Map<Map<RolapLevel, RolapStar.Column>, RolapMember> measureMap) 189 { 190 if (exp instanceof MemberExpr) { 191 MemberExpr memberExpr = (MemberExpr) exp; 192 Member member = memberExpr.getMember(); 193 if (member instanceof RolapStoredMeasure) { 194 addMeasure( 195 (RolapStoredMeasure) member, 196 baseCubesLevelToColumnMaps, 197 measureMap); 198 } else if (member instanceof RolapCalculatedMember) { 199 findMeasures( 200 member.getExpression(), 201 baseCubesLevelToColumnMaps, 202 measureMap); 203 } 204 } else if (exp instanceof ResolvedFunCall) { 205 ResolvedFunCall funCall = (ResolvedFunCall) exp; 206 Exp [] args = funCall.getArgs(); 207 for (Exp arg : args) { 208 findMeasures( 209 arg, 210 baseCubesLevelToColumnMaps, 211 measureMap); 212 } 213 } 214 } 215 216 224 SqlContextConstraint(RolapEvaluator evaluator, boolean strict) { 225 this.evaluator = evaluator; 226 this.strict = strict; 227 cacheKey = new ArrayList<Object >(); 228 cacheKey.add(getClass()); 229 cacheKey.add(strict); 230 cacheKey.addAll(Arrays.asList(evaluator.getMembers())); 231 } 232 233 237 public void addMemberConstraint( 238 SqlQuery sqlQuery, 239 Map<RolapLevel, RolapStar.Column> levelToColumnMap, 240 AggStar aggStar, 241 RolapMember parent) 242 { 243 if (parent.isCalculated()) { 244 throw Util.newInternal("cannot restrict SQL to calculated member"); 245 } 246 Evaluator e = evaluator.push(parent); 247 SqlConstraintUtils.addContextConstraint(sqlQuery, aggStar, e, strict); 248 SqlConstraintUtils.addMemberConstraint( 249 sqlQuery, levelToColumnMap, aggStar, parent, true); 250 } 251 252 public void addMemberConstraint( 253 SqlQuery sqlQuery, 254 Map<RolapLevel, RolapStar.Column> levelToColumnMap, 255 AggStar aggStar, 256 List<RolapMember> parents) 257 { 258 SqlConstraintUtils.addContextConstraint( 259 sqlQuery, aggStar, evaluator, strict); 260 SqlConstraintUtils.addMemberConstraint( 261 sqlQuery, levelToColumnMap, aggStar, parents, true, false); 262 } 263 264 268 public void addConstraint( 269 SqlQuery sqlQuery, Map<RolapLevel, RolapStar.Column> levelToColumnMap) { 270 SqlConstraintUtils.addContextConstraint( 271 sqlQuery, null, evaluator, strict); 272 } 273 274 282 protected boolean isJoinRequired() { 283 Member[] members = evaluator.getMembers(); 284 for (int i = 1; i < members.length; i++) { 286 if (!members[i].isAll()) { 287 return true; 288 } 289 } 290 return false; 291 } 292 293 public void addLevelConstraint( 294 SqlQuery sqlQuery, 295 AggStar aggStar, 296 RolapLevel level, 297 Map<RolapLevel, RolapStar.Column> levelToColumnMap) { 298 if (!isJoinRequired()) { 299 return; 300 } 301 SqlConstraintUtils.joinLevelTableToFactTable( 302 sqlQuery, aggStar, evaluator, level, levelToColumnMap); 303 } 304 305 public MemberChildrenConstraint getMemberChildrenConstraint(RolapMember parent) { 306 return this; 307 } 308 309 public Object getCacheKey() { 310 return cacheKey; 311 } 312 313 public Evaluator getEvaluator() { 314 return evaluator; 315 } 316 } 317 318 | Popular Tags |