1 22 23 package org.xquark.extractor.runtime; 24 25 import java.io.StringReader ; 26 import java.util.ArrayList ; 27 import java.util.List ; 28 29 import org.apache.commons.logging.Log; 30 import org.apache.commons.logging.LogFactory; 31 import org.xquark.extractor.algebra.*; 32 import org.xquark.extractor.common.*; 33 import org.xquark.extractor.metadata.MetaDataManager; 34 import org.xquark.extractor.runtime.Query.SQLExecutionInfo; 35 import org.xquark.extractor.sql.AbstractGenSqlVisitor; 36 import org.xquark.extractor.sql.SqlExpression; 37 import org.xquark.xml.xdbc.XMLDBCException; 38 import org.xquark.xml.xdbc.XMLDBCNotSupportedException; 39 import org.xquark.xquery.metadata.VarCounter; 40 import org.xquark.xquery.metadata.resolver.MetadataAccess; 41 import org.xquark.xquery.normalize.DependNode; 42 import org.xquark.xquery.normalize.TransformXQueryExpression; 43 import org.xquark.xquery.parser.*; 44 import org.xquark.xquery.typing.*; 45 46 49 public abstract class QueryFactory { 50 51 private static Log log = LogFactory.getLog(QueryFactory.class); 52 53 protected XQueryParser _parser = null; 54 protected GenAlgebraVisitor _genAlgebraVisitor = null; 55 protected AlgebraTypeVisitor _algebraTypeVisitor = null; 56 protected RemoveIntermediateProjectVisitor _removeProjectVisitor = null; 57 protected BuildReferredAttributes _brav = null; 58 protected AnalyzePredicateVisitor _apv = null; 59 protected AbstractGenSqlVisitor _genSqlVisitor = null; 60 protected String _baseURI = null; 61 protected MetaDataManager _metadataManager = null; 62 protected MetadataAccess _metadata = null; 63 protected ExtractorStatement _stmt = null; 64 65 66 protected AliasIDGenerator _attIDProvider = new AliasIDGenerator(); 67 protected AliasIDGenerator _relIDProvider = new AliasIDGenerator(); 68 69 public QueryFactory(MetaDataManager metadataManager, MetadataAccess metadata) throws XMLDBCException { 70 try { 71 _metadataManager = metadataManager; 72 _metadata = metadata; 73 createParser(); 74 createVisitors(); 75 } catch (ParseException ex) { 76 throw new XMLDBCException("Can not create statement", ex); 77 } catch (TypeException ex) { 78 throw new XMLDBCException("Can not create statement", ex); 79 } 80 } 81 82 86 public Query createCompiledQuery(String query) throws XMLDBCException { 87 XQueryModule module = parseXQuery(query); 88 return new Query(query, this, compileQuery(module), module); 89 } 90 91 public void setStatement(ExtractorStatement stmt) { 92 _stmt = stmt; 93 } 94 95 public void setBaseURI(String baseURI) { 96 _baseURI = baseURI; 97 } 98 99 public String getBaseURI() { 100 return _baseURI; 101 } 102 103 protected void createParser() throws ParseException, TypeException { 104 _parser = new XQueryParser(new StringReader ("dummy")); 105 _parser.setFactory("org.xquark.xquery.parser.ParserFactory"); 106 } 107 108 abstract protected void createVisitors(); 109 110 111 public List compileQuery(XQueryModule module) throws XMLDBCException { 112 List exprList = module.getExpressions(); 113 List cExpressions = new ArrayList (); 114 115 if (exprList != null) 116 for (int i = 0; i < exprList.size(); i++) { 117 cExpressions.add(compileQuery((XQueryExpression) exprList.get(i))); 118 } 119 return cExpressions; 120 } 121 122 protected Query.CompiledExpression compileQuery(XQueryExpression xExpr) throws XMLDBCException { 123 Query.CompiledExpression retVal = null; 124 125 try { 126 127 128 TransformXQueryExpression transformExpr = xExpr.getParentModule().canonize(xExpr, _parser.getTypeVisitor()); 129 130 139 143 ArrayList idVarList = transformExpr.getIdVarList(); 144 List Qdb = transformExpr.getQDB(); 145 146 if (log.isDebugEnabled()) { 147 log.debug("=================< QMEM >================="); 148 log.debug(transformExpr.getQMEM().toString(true, false, true)); 149 log.debug("=================< QDBs >================="); 150 for (int i = 0; i < Qdb.size(); i++) 151 log.debug(((Variable) Qdb.get(i)).getExpression().toString(true, false, true)); 152 } 153 154 Query.SQLExecutionInfo jdbcExecInfo = null; 155 ArrayList root = transformExpr.getDependMap(); 156 157 if (Qdb.size() > 1) { 158 if (root != null) { if (root.size() == 1) 160 jdbcExecInfo = compileSOU((DependNode) root.get(0), idVarList); 161 else { 162 FLWRExpression xQuery = null; 166 ArrayList idVarLists = new ArrayList (root.size()); 167 168 int rootIndex = -1; 169 int idIndex = 0; 170 ArrayList tmpList = new ArrayList (); 171 for (int i = 0; i < Qdb.size() || idIndex < idVarList.size(); i++) { 172 xQuery = (FLWRExpression) ((Variable) Qdb.get(i)).getExpression(); 173 if (rootIndex + 1 < root.size() && ((DependNode) root.get(rootIndex + 1)).getExpression() == xQuery) { 174 rootIndex++; 175 tmpList = new ArrayList (); 176 idVarLists.add(tmpList); 177 } 178 while (idIndex < idVarList.size() && xQuery.getVariables().contains(idVarList.get(idIndex)) && !tmpList.contains(idVarList.get(idIndex))) { 179 tmpList.add(idVarList.get(idIndex)); 180 idIndex++; 181 } 182 } 183 184 jdbcExecInfo = new Query.SQLExecutionInfo(); 185 Query.SQLExecutionInfo subQuery = null; 186 for (int m = 0; m < root.size(); m++) { 187 xQuery = (FLWRExpression) ((Variable) Qdb.get(m)).getExpression(); 188 subQuery = compileSOU((DependNode) root.get(m), (ArrayList ) idVarLists.get(m)); 189 subQuery.idCount = ((ArrayList ) idVarLists.get(m)).size(); 190 jdbcExecInfo.addChild(subQuery); 191 } 192 } 193 } else { 195 FLWRExpression xQuery = null; 199 int[] idCounts = new int[Qdb.size()]; 200 int idCount = idVarList.size(); 201 int wQdb = 0; 202 203 for (int i = 0; i < idCount; i++) { 204 xQuery = (FLWRExpression) ((Variable) Qdb.get(wQdb)).getExpression(); 205 if (xQuery.getVariables().contains(idVarList.get(i))) 206 idCounts[wQdb]++; 207 else { 208 wQdb++; 209 i--; 210 } 211 } 212 213 jdbcExecInfo = new Query.SQLExecutionInfo(); 214 Query.SQLExecutionInfo subQuery = null; 215 for (int m = 0; m < Qdb.size(); m++) { 216 xQuery = (FLWRExpression) ((Variable) Qdb.get(m)).getExpression(); 217 subQuery = compileSingleQDB(xQuery, true); 218 subQuery.idCount = idCounts[m]; 219 jdbcExecInfo.addChild(subQuery); 220 } 221 } 222 } else if (Qdb.size() == 1) { jdbcExecInfo = compileSingleQDB(((Variable) Qdb.get(0)).getExpression(), false); 224 } 225 retVal = new Query.CompiledExpression(jdbcExecInfo, transformExpr); 226 } catch (NotSupport ex) { 227 throw new XMLDBCNotSupportedException(ex.getMessage(), ex); 228 } catch (SqlWrapperException ex) { 229 throw new XMLDBCException(ex.getMessage(), ex); 230 } catch (AssertionException ex) { 231 throw new XMLDBCException(MessageLibrary.getMessage("G_INT_LOG_ERR", ex.getMessage()), ex); 232 } catch (ParseException ex) { 233 throw new XMLDBCException(ex.getMessage(), ex); 234 } catch (TypeException ex) { 235 throw new XMLDBCException(ex.getMessage(), ex); 236 } catch (XQueryException ex) { 237 throw new XMLDBCException(ex.getMessage(), ex); 238 } 239 return retVal; 240 } 241 242 252 protected Query.SQLExecutionInfo compileSOU(DependNode node, List idVarList) throws XQueryException, XMLDBCException { 253 254 FLWRExpression xQuery = node.getExpression(); 255 256 257 ArrayList newSortExprList = new ArrayList (); 258 List varLevels = node.varLevels(); 259 List varsOfCurrentLevel = null; 260 List sortExprLevels = node.sortExprLevels(); 261 List sortExprsOfCurrentLevel = null; 262 int levelNumber = varLevels.size(); 263 for (int i = 0; i < levelNumber; i++) { 264 sortExprsOfCurrentLevel = (List ) sortExprLevels.get(i); 265 if (sortExprsOfCurrentLevel != null) 266 newSortExprList.addAll(sortExprsOfCurrentLevel); 267 varsOfCurrentLevel = (List ) varLevels.get(i); 268 newSortExprList.add(new PlaceHolder(varsOfCurrentLevel)); 269 } 270 xQuery.setOrderBy(newSortExprList); 271 272 Query.SQLExecutionInfo jdbcExecInfo = compileSingleQDB(xQuery, true); 273 274 275 jdbcExecInfo.idPosition = calculateIdPosition(node.getExpression().getVariables(), idVarList); 276 277 278 List childQueryList = node.getSons(); 279 if (null != childQueryList && !childQueryList.isEmpty()) { 280 for (int i = 0; i < childQueryList.size(); i++) { 281 jdbcExecInfo.addChild(compileSOU((DependNode) childQueryList.get(i), idVarList)); 282 } 283 } 284 285 return jdbcExecInfo; 286 } 287 288 protected Query.SQLExecutionInfo compileSingleQDB(XQueryExpression xQuery, boolean keyNeeded) throws XQueryException, XMLDBCException { 289 290 Expression algebraTree = null; 291 292 293 _genAlgebraVisitor.reinit(); 294 295 296 _attIDProvider.reset(); 297 _relIDProvider.reset(); 298 299 if (keyNeeded) { List souArgList = new ArrayList (); 301 souArgList.add(xQuery); 302 _genAlgebraVisitor.noticSortedOuterUnion(souArgList); 303 } 304 xQuery.accept(_genAlgebraVisitor); 305 algebraTree = _genAlgebraVisitor.getAlgebraTree(); 306 307 _removeProjectVisitor.reinit(); 310 algebraTree.accept(_removeProjectVisitor); 311 312 algebraTree.accept(_brav); 313 314 315 _apv.reinit(); 316 algebraTree.accept(_apv); 317 318 _algebraTypeVisitor.reinit(); 319 algebraTree.accept(_algebraTypeVisitor); 320 321 _genSqlVisitor.reinit(); 322 SqlExpression sql = algebraTree.accept(_genSqlVisitor); 323 324 325 sql.generateRequestList(); 326 return new SQLExecutionInfo(sql, algebraTree.getMapper()); 327 } 328 329 public XQueryModule parseXQuery(String xquery) throws XMLDBCException { 330 331 _parser.ReInit(new StringReader (xquery)); 332 _parser.setBaseURI(_baseURI); 333 334 XQueryModule result = null; 335 try { 336 result = _parser.Start(_metadata, _metadata.getSchemaManager(), _metadata.getModuleManager(), new VarCounter()); 338 result.normalize(_parser.getTypeVisitor()); 339 } catch (ParseException ex) { 340 throw new XMLDBCException(ex.getMessage(), ex); 341 } catch (XQueryException ex) { 342 throw new XMLDBCException(ex.getMessage(), ex); 343 } 344 _parser.ReInit(new StringReader (xquery)); 345 346 return result; 347 } 348 349 355 private int[] calculateIdPosition(List varList, List idVarList) { 356 int[] retVal = new int[idVarList.size()]; 357 int idNum = -1; 358 int idPosition = 0; 359 int idVarIndex = -1; 360 361 Object var = null; 362 for (int i = 0; i < varList.size(); i++) { 363 var = varList.get(i); 364 idPosition = (int) idVarList.indexOf(var); 365 if (-1 != idPosition) { 366 367 idNum++; 368 retVal[idNum] = idPosition; 369 } 370 } 371 372 return retVal; 373 } 374 375 protected class AliasIDGenerator implements IDProvider { 376 private int counter = 0; 377 378 public String getID() { 379 return String.valueOf(counter++); 380 } 381 382 public void reset() { 383 counter = 0; 384 } 385 } 386 387 protected class TempTableIDGenerator implements IDProvider { 388 private int counter = 0; 389 390 public TempTableIDGenerator() { 391 } 392 393 public String getID() { 394 return String.valueOf(_stmt.getStatementId()) + '_' + String.valueOf(counter++); 395 } 396 397 public void reset() { 398 counter = 0; 399 } 400 } 401 } 402 | Popular Tags |