1 23 package org.objectweb.medor.optim; 24 25 import org.objectweb.medor.lib.TestMedorHelper; 26 import org.objectweb.medor.lib.Log; 27 import org.objectweb.medor.query.rdb.api.RdbExpQueryLeaf; 28 import org.objectweb.medor.query.rdb.api.QualifiedTable; 29 import org.objectweb.medor.query.rdb.lib.BasicRdbExpQueryLeaf; 30 import org.objectweb.medor.query.rdb.lib.BasicQualifiedTable; 31 import org.objectweb.medor.query.api.QueryTree; 32 import org.objectweb.medor.query.api.QueryTreeField; 33 import org.objectweb.medor.query.api.QueryNode; 34 import org.objectweb.medor.query.lib.JoinProject; 35 import org.objectweb.medor.query.lib.QueryTreePrinter; 36 import org.objectweb.medor.query.TestQueryTreeHelper; 37 import org.objectweb.medor.datasource.api.DataStore; 38 import org.objectweb.medor.datasource.lib.ConnectionFactoryDataStore; 39 import org.objectweb.medor.api.MedorException; 40 import org.objectweb.medor.api.Field; 41 import org.objectweb.medor.expression.lib.And; 42 import org.objectweb.medor.expression.lib.Equal; 43 import org.objectweb.medor.filter.lib.BasicFieldOperand; 44 import org.objectweb.medor.expression.lib.Plus; 45 import org.objectweb.medor.expression.api.Expression; 46 import org.objectweb.medor.optim.lib.FlattenQueryTreeRule; 47 import org.objectweb.medor.optim.api.RewriteRule; 48 import org.objectweb.jorm.type.api.PTypeSpace; 49 import org.objectweb.jorm.type.api.PType; 50 import org.objectweb.util.monolog.api.BasicLevel; 51 import junit.textui.TestRunner; 52 import junit.framework.Test; 53 import junit.framework.TestSuite; 54 55 59 public class TestFlattenQueryTreeRule extends TestMedorHelper { 60 61 public final static String LOGGER_NAME = 62 Log.MEDOR_PREFIX + ".optim.flattenQueryTree"; 63 64 67 public static void main(String [] args) { 68 TestRunner.run(suite()); 69 } 70 71 74 public static Test suite() { 75 return new TestSuite(TestFlattenQueryTreeRule.class); 76 } 77 78 public TestFlattenQueryTreeRule() { 79 super("TestFlattenQueryTreeRule", LOGGER_NAME); 80 } 81 82 public TestFlattenQueryTreeRule(String testName) { 83 super(testName, LOGGER_NAME); 84 } 85 86 protected void setUp() { 87 } 88 89 protected void tearDown() { 90 } 91 92 public void testA() throws MedorException { 93 changeLogger(LOGGER_NAME + ".A"); 94 RdbExpQueryLeaf[] leaves = createLeaves("rdb", "table", 4, 95 new String []{"a", "b", "c"}, 96 new PType[]{PTypeSpace.BYTE, PTypeSpace.STRING, PTypeSpace.LONG}); 97 JoinProject j1 = join("", 98 leaves[0], new String []{"a0"}, leaves[1], new String []{"a1"}); 99 JoinProject j2 = join("", 100 leaves[2], new String []{"b2"}, leaves[3], new String []{"b3"}); 101 JoinProject init = join("", 102 j1, new String []{"c1"}, j2, new String []{"c2"}); 103 init.addCalculatedField("calc", PTypeSpace.LONG, getPlus(j1, "c0", j2, "c3")); 104 logger.log(BasicLevel.DEBUG, "Initial query tree:"); 105 QueryTreePrinter.printQueryTree(init, logger); 106 107 RewriteRule rule = new FlattenQueryTreeRule(); 108 QueryTree qt = rule.rewrite(init); 109 logger.log(BasicLevel.DEBUG, "Rewritten query tree:"); 110 QueryTreePrinter.printQueryTree(qt, logger); 111 112 RdbExpQueryLeaf[] leaves2 = createLeaves("rdb", "table", 4, 113 new String []{"a", "b", "c"}, 114 new PType[]{PTypeSpace.BYTE, PTypeSpace.STRING, PTypeSpace.LONG}); 115 JoinProject expected = new JoinProject(""); 116 propagateField(leaves2[0], expected); 117 propagateField(leaves2[1], expected); 118 propagateField(leaves2[2], expected); 119 propagateField(leaves2[3], expected); 120 expected.addCalculatedField("calc", PTypeSpace.LONG, 121 getPlus(leaves2[0], "c0", leaves2[3], "c3")); 122 Expression filter = getEqual(leaves2[1], "c1", leaves2[2], "c2"); 123 filter = new And(filter, getEqual(leaves2[0], "a0", leaves2[1], "a1")); 124 filter = new And(filter, getEqual(leaves2[2], "b2", leaves2[3], "b3")); 125 expected.setQueryFilter(filter); 126 logger.log(BasicLevel.DEBUG, "Expected query tree:"); 127 QueryTreePrinter.printQueryTree(expected, logger); 128 129 TestQueryTreeHelper.equals("", expected, qt, logger); 130 } 131 132 public void testB() throws MedorException { 133 changeLogger(LOGGER_NAME + ".B"); 134 RdbExpQueryLeaf[] leaves = createLeaves("rdb", "table", 4, 135 new String []{"a", "b", "c"}, 136 new PType[]{PTypeSpace.BYTE, PTypeSpace.STRING, PTypeSpace.LONG}); 137 JoinProject j1 = join("", 138 leaves[0], new String []{"a0"}, leaves[1], new String []{"a1"}); 139 JoinProject j2 = join("", 140 j1, new String []{"b1"}, leaves[2], new String []{"b2"}); 141 JoinProject init = join("", 142 j2, new String []{"c2"}, leaves[3], new String []{"c3"}); 143 init.addCalculatedField("calc", PTypeSpace.LONG, getPlus(j2, "c0", leaves[3], "c3")); 144 145 RewriteRule rule = new FlattenQueryTreeRule(); 146 QueryTree qt = rule.rewrite(init); 147 logger.log(BasicLevel.DEBUG, "Rewritten query tree:"); 148 QueryTreePrinter.printQueryTree(qt, logger); 149 150 RdbExpQueryLeaf[] leaves2 = createLeaves("rdb", "table", 4, 151 new String []{"a", "b", "c"}, 152 new PType[]{PTypeSpace.BYTE, PTypeSpace.STRING, PTypeSpace.LONG}); 153 JoinProject expected = new JoinProject(""); 154 propagateField(leaves2[0], expected); 155 propagateField(leaves2[1], expected); 156 propagateField(leaves2[2], expected); 157 propagateField(leaves2[3], expected); 158 expected.addCalculatedField("calc", PTypeSpace.LONG, 159 getPlus(leaves2[0], "c0", leaves2[3], "c3")); 160 Expression filter = getEqual(leaves2[2], "c2", leaves2[3], "c3"); 161 filter = new And(filter, getEqual(leaves2[1], "b1", leaves2[2], "b2")); 162 filter = new And(filter, getEqual(leaves2[0], "a0", leaves2[1], "a1")); 163 expected.setQueryFilter(filter); 164 logger.log(BasicLevel.DEBUG, "Expected query tree:"); 165 QueryTreePrinter.printQueryTree(expected, logger); 166 TestQueryTreeHelper.equals("", expected, qt, logger); 167 } 168 169 public void testC() throws MedorException { 170 changeLogger(LOGGER_NAME + ".C"); 171 RdbExpQueryLeaf[] leaves = createLeaves("rdb", "table", 4, 172 new String []{"a", "b", "c"}, 173 new PType[]{PTypeSpace.BYTE, PTypeSpace.STRING, PTypeSpace.LONG}); 174 JoinProject init = new JoinProject(""); 175 propagateField(leaves[0], init); 176 propagateField(leaves[1], init); 177 propagateField(leaves[2], init); 178 propagateField(leaves[3], init); 179 init.addCalculatedField("calc", PTypeSpace.LONG, 180 getPlus(leaves[0], "c0", leaves[3], "c3")); 181 Expression filter = getEqual(leaves[2], "c2", leaves[3], "c3"); 182 filter = new And(filter, getEqual(leaves[1], "b1", leaves[2], "b2")); 183 filter = new And(filter, getEqual(leaves[0], "a0", leaves[1], "a1")); 184 init.setQueryFilter(filter); 185 186 RewriteRule rule = new FlattenQueryTreeRule(); 187 QueryTree qt = rule.rewrite(init); 188 logger.log(BasicLevel.DEBUG, "Rewritten query tree:"); 189 QueryTreePrinter.printQueryTree(qt, logger); 190 191 RdbExpQueryLeaf[] leaves2 = createLeaves("rdb", "table", 4, 192 new String []{"a", "b", "c"}, 193 new PType[]{PTypeSpace.BYTE, PTypeSpace.STRING, PTypeSpace.LONG}); 194 JoinProject expected = new JoinProject(""); 195 propagateField(leaves2[0], expected); 196 propagateField(leaves2[1], expected); 197 propagateField(leaves2[2], expected); 198 propagateField(leaves2[3], expected); 199 expected.addCalculatedField("calc", PTypeSpace.LONG, 200 getPlus(leaves2[0], "c0", leaves2[3], "c3")); 201 filter = getEqual(leaves2[2], "c2", leaves2[3], "c3"); 202 filter = new And(filter, getEqual(leaves2[1], "b1", leaves2[2], "b2")); 203 filter = new And(filter, getEqual(leaves2[0], "a0", leaves2[1], "a1")); 204 expected.setQueryFilter(filter); 205 logger.log(BasicLevel.DEBUG, "Expected query tree:"); 206 QueryTreePrinter.printQueryTree(expected, logger); 207 TestQueryTreeHelper.equals("", expected, qt, logger); 208 } 209 210 private JoinProject join(String nodeName, 211 QueryTree qt1, String [] fields1, 212 QueryTree qt2, String [] fields2) throws MedorException { 213 JoinProject res = new JoinProject(nodeName); 214 join(res, qt1, fields1, qt2, fields2); 215 return res; 216 } 217 218 private void join(JoinProject join, 219 QueryTree qt1, String [] fields1, 220 QueryTree qt2, String [] fields2) throws MedorException { 221 if (fields1.length > 0) { 222 Expression filter = join.getQueryFilter(); 223 for (int i = 0; i < fields1.length; i++) { 224 Equal eq = getEqual(qt1, fields1[i], qt2, fields2[i]); 225 if (filter == null) { 226 filter = eq; 227 } 228 else { 229 filter = new And(filter, eq); 230 } 231 } 232 join.setQueryFilter(filter); 233 } 234 propagateField(qt1, join); 235 propagateField(qt2, join); 236 } 237 238 private Equal getEqual(QueryTree qt1, String field1, 239 QueryTree qt2, String field2) throws MedorException { 240 Field f1 = qt1.getTupleStructure().getField(field1); 241 Field f2 = qt2.getTupleStructure().getField(field2); 242 return new Equal(new BasicFieldOperand(f1), new BasicFieldOperand(f2)); 243 } 244 245 private Plus getPlus(QueryTree qt1, String field1, 246 QueryTree qt2, String field2) throws MedorException { 247 Field f1 = qt1.getTupleStructure().getField(field1); 248 Field f2 = qt2.getTupleStructure().getField(field2); 249 return new Plus(new BasicFieldOperand(f1), new BasicFieldOperand(f2)); 250 } 251 252 private void propagateField(QueryTree source, QueryNode dest) 253 throws MedorException { 254 Field[] children = source.getTupleStructure().getFields(); 255 for (int i = 0; i < children.length; i++) { 256 if (!dest.getTupleStructure().contains(children[i].getName())) { 257 dest.addPropagatedField(children[i].getName(), 258 children[i].getType(), 259 new QueryTreeField[]{(QueryTreeField) children[i]}); 260 } 261 } 262 } 263 264 private RdbExpQueryLeaf[] createLeaves(String nodeName, 265 String tableName, 266 int nbLeaves, 267 String [] fieldNames, 268 PType[] fieldTypes) throws MedorException { 269 DataStore ds = new ConnectionFactoryDataStore( 270 DataStore.JDBC_STORE, "postgres", null, this); 271 RdbExpQueryLeaf[] res = new RdbExpQueryLeaf[nbLeaves]; 272 for (int i = 0; i < nbLeaves; i++) { 273 String [] fns = new String [fieldNames.length]; 274 for (int j = 0; j < fieldNames.length; j++) { 275 fns[j] = fieldNames[j] + i; 276 } 277 res[i] = createLeaf(nodeName + i, tableName + i, ds, fns, fieldTypes); 278 } 279 return res; 280 } 281 282 private RdbExpQueryLeaf createLeaf(String nodeName, 283 String tableName, 284 DataStore ds, 285 String [] fieldNames, 286 PType[] fieldTypes) throws MedorException { 287 QualifiedTable t = new BasicQualifiedTable(tableName, null); 288 RdbExpQueryLeaf res = new BasicRdbExpQueryLeaf( 289 ds, new QualifiedTable[]{t}, nodeName); 290 for (int i = 0; i < fieldNames.length; i++) { 291 res.addRdbField(fieldNames[i], fieldTypes[i], fieldNames[i], t); 292 } 293 return res; 294 } 295 } 296 | Popular Tags |