1 23 package org.objectweb.medor.optim.jorm; 24 25 import org.objectweb.medor.api.Field; 26 import org.objectweb.medor.api.MedorException; 27 import org.objectweb.medor.api.TupleStructure; 28 import org.objectweb.medor.expression.api.Expression; 29 import org.objectweb.medor.expression.api.UnaryOperator; 30 import org.objectweb.medor.filter.api.FieldOperand; 31 import org.objectweb.medor.filter.lib.ExpressionPrinter; 32 import org.objectweb.medor.optim.api.RewriteRule; 33 import org.objectweb.medor.optim.lib.DropUnusedProjFieldsRule; 34 import org.objectweb.medor.query.api.CalculatedField; 35 import org.objectweb.medor.query.api.PropagatedField; 36 import org.objectweb.medor.query.api.QueryNode; 37 import org.objectweb.medor.query.api.QueryTree; 38 import org.objectweb.medor.query.api.QueryTreeField; 39 import org.objectweb.medor.query.lib.Nest; 40 import org.objectweb.medor.query.lib.QueryTreePrinter; 41 import org.objectweb.medor.query.rdb.lib.AggregateRdbQueryNode; 42 import org.objectweb.medor.query.rdb.lib.BasicRdbExpQueryLeaf; 43 import org.objectweb.util.monolog.api.BasicLevel; 44 45 import java.util.ArrayList ; 46 47 55 public class Jorm2Rdb extends JormRule { 56 57 public Jorm2Rdb() { 58 super("Jorm2Rdb"); 59 } 60 61 private RewriteRule jormRule = new JormFlatten2Rdb(); 62 63 public QueryTree rewrite(QueryTree qt, QueryNode parent) 64 throws MedorException { 65 log.log(BasicLevel.DEBUG, "Jorm2Rdb: Input query tree:"); 66 QueryTreePrinter.printQueryTree(qt, log, BasicLevel.DEBUG); 67 68 if (qt instanceof Nest) { 69 QueryTree qtInter = 70 jormRule.rewrite(((QueryNode)qt).getChildren()[0], 71 (QueryNode) qt); 72 log.log(BasicLevel.DEBUG, "Jorm2Rdb: intermediate query tree:"); 73 QueryTreePrinter.printQueryTree(qtInter, log); 76 RewriteRule dropProj = new DropUnusedProjFieldsRule(); 80 QueryTree qt2 = dropProj.rewrite(qt, parent); 81 log.log(BasicLevel.DEBUG, "Jorm2Rdb: intermediate query tree after dropping unused projections:"); 82 QueryTreePrinter.printQueryTree(qt2, log); 83 qt = qt2; 84 if ((qtInter instanceof QueryNode) && !(qtInter instanceof Nest) 86 && (noCalculatedField((QueryNode)qtInter)) ) { 87 Field[] fs = qtInter.getTupleStructure().getFields(); 89 for (int i = 0; i < fs.length; i++) { 90 if (fs[i] instanceof PropagatedField) { 91 log.log(BasicLevel.DEBUG, "PropagatedField " + ((PropagatedField) fs[i]).getPreviousFields()[0]); 92 QueryTreeField qtf = (QueryTreeField) 93 ((PropagatedField) fs[i]).getPreviousFields()[0]; 94 log.log(BasicLevel.DEBUG, "PF name " + qtf.getName()); 95 } 96 } 97 log.log(BasicLevel.DEBUG, "NestedField " +((Nest)qt).getNestedField()); 99 Field[] tmpQT = ((Nest)qt).getNestedField().getFields(); 100 ArrayList tmpQT2 = new ArrayList (); 101 for (int jj = 0; jj < tmpQT.length; jj++) { 102 log.log(BasicLevel.DEBUG, "containing " +tmpQT[jj] + " " 103 + tmpQT[jj].getName() + " (" + (QueryTreeField) 104 (((PropagatedField)tmpQT[jj]). 105 getPreviousFields()[0]) + ") of node " + 106 ((QueryTreeField) 107 (((PropagatedField)tmpQT[jj]). 108 getPreviousFields()[0])).getQueryTree()); 109 if (!tmpQT2.contains( 110 (((PropagatedField)tmpQT[jj]). 111 getPreviousFields()[0]))) { 112 tmpQT2.add( 113 (((PropagatedField)tmpQT[jj]). 114 getPreviousFields()[0])); 115 } 116 } 117 BasicRdbExpQueryLeaf theLeaf = (BasicRdbExpQueryLeaf) 118 ((QueryNode)qtInter).getChildren()[0]; 119 QueryNode qtNew = 120 new AggregateRdbQueryNode( 121 (QueryTreeField[]) (tmpQT2.toArray(new QueryTreeField[] {})), 122 ((Nest)qt).getNestedField().getName(), 123 replaceGroupByFields((Nest)qt), 125 theLeaf, 126 theLeaf.getDataStore(), qt.getName()); 127 qtNew.setDistinct(qtInter.getDistinct()); 128 Field[] otherFields = qt.getTupleStructure().getFields(); 130 for (int fl = 0; fl < otherFields.length; fl++) { 131 log.log(BasicLevel.DEBUG, "Handling other field " + otherFields[fl]); 132 if (otherFields[fl] instanceof CalculatedField) { 133 CalculatedField cf = (CalculatedField) otherFields[fl]; 134 replaceAggregatedField(cf.getExpression()); 135 136 qtNew.addCalculatedField( 137 cf.getName().substring( 139 cf.getName().indexOf(qt.getName()) 140 + qt.getName().length() + 1), 141 cf.getType(), 142 cf.getExpression()); 143 log.log(BasicLevel.DEBUG, "Adding CalculatedField " + cf + " (" + ExpressionPrinter.e2str(cf.getExpression()) + ")"); 144 } else if (otherFields[fl] instanceof PropagatedField) { 145 log.log(BasicLevel.DEBUG, "Adding PropagatedField from " + otherFields[fl]); 147 QueryTreeField previousField = 148 (QueryTreeField) 149 ((PropagatedField) 150 ((PropagatedField)otherFields[fl]).getPreviousFields()[0]) 151 .getPreviousFields()[0]; 152 log.log(BasicLevel.DEBUG, "Previous field is " + previousField + " of node " + previousField.getQueryTree()); 153 qtNew.addPropagatedField(previousField.getName(), 154 previousField.getType(), 155 new QueryTreeField[] {previousField}); 156 } else { 157 log.log(BasicLevel.DEBUG, "Doing nothing"); 158 } 159 } 160 log.log(BasicLevel.DEBUG, "Jorm2Rdb: final query tree:"); 162 QueryTreePrinter.printQueryTree(qtNew, log); 163 return qtNew; 164 } else { 165 168 log.log(BasicLevel.DEBUG, "Jorm2Rdb: some calculated fields: keeping input query tree"); 169 return qt; 170 } 171 } 172 else return jormRule.rewrite(qt, parent); 173 } 174 175 private void replaceAggregatedField(Expression e) { 176 UnaryOperator op = (UnaryOperator) e; 177 FieldOperand fo = (FieldOperand) op.getExpression(0); 178 fo.setField(((PropagatedField) fo.getField()).getPreviousFields()[0]); 179 } 180 181 private QueryTreeField[] replaceGroupByFields(Nest nest) { 182 log.log(BasicLevel.DEBUG, "Jorm2Rdb: replacing GroupBy fields"); 183 QueryTreeField[] groupBy = (nest).getNestingFields(); 184 QueryTreeField[] newGroupBy = new QueryTreeField[groupBy.length]; 185 188 for (int i = 0; i < groupBy.length; i++) { 189 log.log(BasicLevel.DEBUG, "Jorm2Rdb: examining GroupBy field " + groupBy[i]); 190 newGroupBy[i] = 191 (QueryTreeField) 192 ((PropagatedField)groupBy[i]).getPreviousFields()[0]; 193 log.log(BasicLevel.DEBUG, "new GroupBy field " + i + ": " 194 + newGroupBy[i] + " of node " + newGroupBy[i].getQueryTree()); 195 } 196 return newGroupBy; 197 } 198 204 private boolean noCalculatedField(QueryNode qn) throws MedorException { 205 boolean noCCF = true; 206 TupleStructure ts = qn.getTupleStructure(); 207 for (int i = 0; i < ts.getSize(); i++) { 208 if (ts.getField(i+1) instanceof CalculatedField) { 209 log.log(BasicLevel.DEBUG, "Found CalculatedField " + ts.getField(i+1).getName()); 210 noCCF = false; 211 } 212 } 213 return noCCF; 214 } 215 } 216 | Popular Tags |