1 9 package mondrian.rolap; 10 11 import java.sql.Connection ; 12 import java.sql.SQLException ; 13 import java.util.ArrayList ; 14 import java.util.List ; 15 import java.util.Map ; 16 17 import javax.sql.DataSource ; 18 19 import mondrian.olap.*; 20 import mondrian.rolap.sql.SqlQuery; 21 import mondrian.rolap.sql.TupleConstraint; 22 import mondrian.rolap.sql.SqlQuery.Dialect; 23 24 31 public class RolapNativeTopCount extends RolapNativeSet { 32 33 boolean ascending; 34 35 public RolapNativeTopCount() { 36 super.setEnabled(MondrianProperties.instance().EnableNativeTopCount.get()); 37 } 38 39 class TopCountConstraint extends SetConstraint { 40 String orderByExpr; 41 42 public TopCountConstraint(CrossJoinArg[] args, RolapEvaluator evaluator, String orderByExpr) { 43 super(args, evaluator, true); 44 this.orderByExpr = orderByExpr; 45 } 46 47 51 protected boolean isJoinRequired() { 52 return true; 53 } 54 55 public void addConstraint( 56 SqlQuery sqlQuery, 57 Map <RolapLevel, RolapStar.Column> levelToColumnMap) { 58 if (orderByExpr != null) { 59 Dialect dialect = sqlQuery.getDialect(); 60 if (dialect.requiresOrderByAlias()) { 61 String alias = sqlQuery.nextColumnAlias(); 62 alias = dialect.quoteIdentifier(alias); 63 sqlQuery.addSelect(orderByExpr, alias); 64 sqlQuery.addOrderBy(alias, ascending, true, false); 65 } else { 66 sqlQuery.addOrderBy(orderByExpr, ascending, true, false); 67 } 68 } 69 super.addConstraint(sqlQuery, levelToColumnMap); 70 } 71 72 public Object getCacheKey() { 73 List <Object > key = new ArrayList <Object >(); 74 key.add(super.getCacheKey()); 75 key.add(orderByExpr); 76 key.add(ascending); 77 return key; 78 } 79 } 80 81 protected boolean isStrict() { 82 return true; 83 } 84 85 NativeEvaluator createEvaluator(RolapEvaluator evaluator, FunDef fun, Exp[] args) { 86 if (!isEnabled()) 87 return null; 88 if (!TopCountConstraint.isValidContext(evaluator)) { 89 return null; 90 } 91 92 String funName = fun.getName(); 94 if ("TopCount".equalsIgnoreCase(funName)) { 95 ascending = false; 96 } else if ("BottomCount".equalsIgnoreCase(funName)) { 97 ascending = true; 98 } else { 99 return null; 100 } 101 if (args.length < 2 || args.length > 3) { 102 return null; 103 } 104 CrossJoinArg[] cargs = checkCrossJoinArg(args[0]); 106 if (cargs == null) { 107 return null; 108 } 109 if (isPreferInterpreter(cargs)) { 110 return null; 111 } 112 113 if (!(args[1] instanceof Literal)) { 115 return null; 116 } 117 int count = ((Literal) args[1]).getIntValue(); 118 119 SchemaReader schemaReader = evaluator.getSchemaReader(); 121 DataSource ds = schemaReader.getDataSource(); 122 123 SqlQuery sqlQuery = SqlQuery.newQuery(ds, "NativeTopCount"); 125 RolapNativeSql sql = new RolapNativeSql(sqlQuery); 126 String orderByExpr = null; 127 if (args.length == 3) { 128 orderByExpr = sql.generateTopCountOrderBy(args[2]); 129 if (orderByExpr == null) { 130 return null; 131 } 132 } 133 LOGGER.debug("using native topcount"); 134 evaluator = overrideContext(evaluator, cargs, sql.getStoredMeasure()); 135 136 TupleConstraint constraint = new TopCountConstraint(cargs, evaluator, orderByExpr); 137 SetEvaluator sev = new SetEvaluator(cargs, schemaReader, constraint); 138 sev.setMaxRows(count); 139 return sev; 140 } 141 } 142 143 | Popular Tags |