1 23 24 package org.objectweb.medor.optim.lib; 25 26 import org.objectweb.medor.api.Field; 27 import org.objectweb.medor.api.MedorException; 28 import org.objectweb.medor.api.QueryNodeException; 29 import org.objectweb.medor.api.TupleStructure; 30 import org.objectweb.medor.expression.api.ExpressionException; 31 import org.objectweb.medor.expression.api.Operator; 32 import org.objectweb.medor.expression.api.Expression; 33 import org.objectweb.medor.filter.api.FieldOperand; 34 import org.objectweb.medor.optim.api.ExecPlanGenerator; 35 import org.objectweb.medor.query.api.CalculatedField; 36 import org.objectweb.medor.query.api.PropagatedField; 37 import org.objectweb.medor.query.api.QueryNode; 38 import org.objectweb.medor.query.api.QueryTree; 39 import org.objectweb.medor.query.api.TCQueryLeaf; 40 import org.objectweb.medor.query.rdb.lib.AggregateRdbQueryNode; 41 import org.objectweb.medor.tuple.lib.GeneralTupleLoader; 42 43 public class IndexesGenerator implements ExecPlanGenerator { 44 45 public QueryTree transform(QueryTree query) throws MedorException { 46 try { 48 generateIndexes(query); 49 } 50 catch (MedorException e) { 51 throw e; 52 } 53 catch (ExpressionException e) { 54 throw new MedorException(e); 55 } 56 return query; } 58 59 private void generateIndexes(QueryTree query) throws MedorException, ExpressionException { 60 if (query instanceof QueryNode) { 61 QueryNode qn = (QueryNode) query; 62 if (!(query instanceof AggregateRdbQueryNode)) { 63 setFilterIndexes(qn.getQueryFilter(), qn.getChildren()); 64 } 65 qn.setTupleLoader( 67 new GeneralTupleLoader( 68 computesFieldIndexes(qn.getTupleStructure(), qn.getChildren()), 69 query.getTupleStructure())); 70 QueryTree[] children = qn.getChildren(); 71 for (int cpt = 0; (cpt < children.length); cpt++) { 72 generateIndexes(children[cpt]); 73 } 74 } 76 else if (query instanceof TCQueryLeaf) { 77 TCQueryLeaf tcLeaf = (TCQueryLeaf) query; 79 TupleStructure ts = tcLeaf.getTupleStructure(); 80 boolean stop = false; 81 int cpt = 0; 82 int[] indexes = new int[ts.getSize()]; 83 while (cpt < ts.getSize() && !stop) { 84 indexes[cpt] = 85 tcLeaf.getTupleCollection().getMetaData().getFieldRank( 86 tcLeaf.getTupleCollection().getMetaData().getField( 87 ts.getField(cpt + 1).getName() 88 ) 89 ); 90 cpt++; 91 } 92 tcLeaf.setTupleLoader( 93 new GeneralTupleLoader(indexes, query.getTupleStructure())); 94 95 setTCQLFilterIndexes(tcLeaf.getQueryFilter(), tcLeaf); 97 } 98 } 99 100 public int[] computesFieldIndexes(TupleStructure ts, QueryTree[] nodes) 101 throws MedorException, ExpressionException { 102 Field[] ancestor = null; 103 Field current = null; 104 105 int[] indexes = new int[ts.getSize()]; 108 for (int i = 1; i <= ts.getSize(); i++) { 109 try { 110 current = ts.getField(i); 111 } 112 catch (MedorException me) { 113 } 115 if (current instanceof PropagatedField) { 116 ancestor = ((PropagatedField) current).getPreviousFields(); 117 for (int j = 0; j < ancestor.length; j++) { 118 int rank = 0; 119 int cpt = 0; 120 for (cpt = 0; 122 ((cpt < nodes.length) && 123 !containsField(nodes[cpt], ancestor[j])); 124 cpt++) { 125 rank = rank + nodes[cpt].getTupleStructure().getSize(); 126 } 127 if (cpt < nodes.length) { 129 indexes[i - 1] = rank + nodes[cpt].getTupleStructure().getFieldRank(nodes[cpt].getTupleStructure().getField(ancestor[j].getName())); 130 } 131 else { 132 throw new QueryNodeException( 133 "The previous field " + ancestor[j].getName() 134 + " must have a QueryTree which matches with one of children"); 135 } 136 } 137 } 138 else if (current instanceof CalculatedField) { 139 setFilterIndexes(((CalculatedField) current).getExpression(), nodes); 141 indexes[i - 1] = -1; } 143 150 else 151 throw new QueryNodeException( 152 "QueryNode fields error for field " + current.getName()); 153 } 154 return indexes; 158 } 159 160 167 public void setFilterIndexes(Expression e, QueryTree[] qts) 168 throws MedorException, ExpressionException { 169 if (e == null) 170 return; 171 e.compileExpression(); if (e instanceof Operator) { 173 for (int i = 0; i<((Operator) e).getOperandNumber(); i++) { 174 setFilterIndexes((Expression) ((Operator) e).getExpression(i), qts); 175 } 176 } 177 else if (e instanceof FieldOperand) { 178 int i; 179 184 int rank = 0; 185 for (i = 0; 186 i < qts.length && 187 !containsField(qts[i], ((FieldOperand) e).getField()); 188 rank = rank + qts[i].getTupleStructure().getSize(), i++) 189 ; 190 191 197 198 if (i != qts.length) { 199 ((FieldOperand) e).setIndex( 200 rank + qts[i].getTupleStructure().getFieldRank(qts[i].getTupleStructure().getField(((FieldOperand) e).getField().getName()))); 201 } 202 else { 203 throw new ExpressionException( 204 "Field not found in the subQueryTree: " 205 + ((FieldOperand) e).getField().getName()); 206 } 207 } 208 } 209 210 private void setTCQLFilterIndexes(Expression e, TCQueryLeaf tcLeaf) 211 throws MedorException,ExpressionException { 212 if (e == null) 213 return; 214 215 e.compileExpression(); if (e instanceof Operator) { 217 for (int i = 0; i<((Operator) e).getOperandNumber(); i++) { 218 setTCQLFilterIndexes((Expression) ((Operator) e).getExpression(i), tcLeaf); 219 } 220 } 221 else if (e instanceof FieldOperand) { 222 ((FieldOperand) e).setIndex( 223 tcLeaf.getTupleStructure().getFieldRank( 224 tcLeaf.getTupleStructure().getField( 225 ((FieldOperand) e).getField().getName() 226 ) 227 ) 228 ); 229 } 230 } 231 232 private boolean containsField(QueryTree qt, Field field) { 233 return qt.getTupleStructure().contains(field.getName()); 234 } 235 } 236 | Popular Tags |