//// (c) 2005 Andreas Harth //package org.semanticweb.yars.engine; // //import java.util.ArrayList; //import java.util.SortedMap; //import java.util.logging.Logger; // //import org.semanticweb.yars.api.n3.Quad; //import org.semanticweb.yars.api.n3.Variable; //import org.semanticweb.yars.api.rdf.Resource; //import org.semanticweb.yars.engine.exec.local.DifferenceIterator; //import org.semanticweb.yars.engine.exec.local.DistinctIterator; //import org.semanticweb.yars.engine.exec.local.ExecIterator; //import org.semanticweb.yars.engine.exec.local.FilterIneq; //import org.semanticweb.yars.engine.exec.local.JoinINLIterator; //import org.semanticweb.yars.engine.exec.local.KeywordIterator; //import org.semanticweb.yars.engine.exec.local.OIDIterator; //import org.semanticweb.yars.engine.exec.local.ProjectBAIterator; //import org.semanticweb.yars.engine.exec.local.SelectIterator; //import org.semanticweb.yars.engine.exec.local.TemplateIterator; //import org.semanticweb.yars.engine.exec.local.ValuesIterator; //import org.semanticweb.yars.engine.exec.local.ValuesListIterator; //import org.semanticweb.yars.engine.relational.ConstructOp; //import org.semanticweb.yars.engine.relational.DifferenceOp; //import org.semanticweb.yars.engine.relational.JoinOp; //import org.semanticweb.yars.engine.relational.ProjectOp; //import org.semanticweb.yars.engine.relational.SelectOp; //import org.semanticweb.yars.index.DataStore; // ///** // * Converts from relational algebra plans to physical access plans. // * // * @author aharth // */ //public class Relational2Exec implements LogicalOlapOperatorQueryPlanVisitor { // // the new root node // ExecIterator _root; // // the physical access plans need access to the data store component // DataStore _ds; // // logging // private static Logger _log = Logger.getLogger("org.semanticweb.yars.engine.Relational2Exec"); // // the select clause... // private ExecIterator _result; // // list of variables for return values // private ArrayList _boundvars; // // select variables // private ArrayList _selectvars; // // // private ArrayList _template; // // // private ArrayList _ineqfilter; // // check whether the thing is distinct // private boolean _distinct = false; // // // private int _resultformat; // // final private static int PROJECT = 1; // final private static int PROJECTFILTER = 2; // final private static int CONSTRUCT = 4; // // /** // * Constructor. // * // * @param ds // */ // public Relational2Exec(DataStore ds) { // _ds = ds; // _boundvars = new ArrayList(); // _resultformat = 0; // } // // /** // * A visitor object. // * // * takes an node in the relational algebra tree and // * converts it to a node in the physical access tree. // * // * @param o // */ // public void visit(Object o) throws QueryException { // if (o instanceof SelectOp) { // ExecIterator bi = null; // SelectOp so = (SelectOp)o; // // // remote context? no, not yet, not here // /* // if (!(so._q.getContext() instanceof Variable)) { // _root = new org.semanticweb.yars.engine.remote.SelectIterator(so._q); // _variables.addAll(so._q.getVariables()); // } else { // */ // // // keyword query? // if (so._q.isKeywordQuad()) { // // generate the keyword iterator // KeywordIterator keyit = new KeywordIterator(_ds.getTextIndex(), so._q.getObject().toString()); // // // build variable list as we go // _boundvars.addAll(getVariables(so._q, DataStore.TEXT)); // // _root = keyit; // } else { // // find out index // int indexNo = whichIndex(so._q); // // construct the appropriate key for the query // SortedMap bt = _ds.getQuadIndex().getIndex(indexNo); // // OIDIterator oit = new OIDIterator(_ds.getLexicon(), so._q); // // _boundvars.addAll(getVariables(so._q, indexNo)); // // bi = new SelectIterator(bt, indexNo, oit); // //ProjectIterator pi = new ProjectIterator(bi, getMask(indexNo)); // _root = bi; // } // } else if (o instanceof ConstructOp) { // // if there's a construct operator, just visit the children // ConstructOp cop = (ConstructOp)o; // // _template = cop._template; // //_result = new TemplateIterator(null, cop._template); // _resultformat = CONSTRUCT; // // cop._o.accept(this); // } else if (o instanceof ProjectOp) { // // if there's a project operator, just visit the children // ProjectOp po = (ProjectOp)o; // // _selectvars = po.getVariableList(); // // _ineqfilter = po.getIneqFilter(); // _distinct = po.getDistinct(); // // if (_ineqfilter != null) { // _resultformat = PROJECTFILTER; // } else // _resultformat = PROJECT; // // po._o.accept(this); // } else if (o instanceof JoinOp) { // ExecIterator bi = null; // JoinOp jo = (JoinOp)o; // long rpos = 0; // long spos = 0; // // jo._left.accept(this); // // // replace the join condition with a non-variable // // that we can figure out the right index // Quad s = new Quad(jo._right._q); // // if (s.getSubject() == jo._var) { // s.setSubject(new Resource("joinie")); // spos = 0l; // } else if (s.getPredicate() == jo._var) { // s.setPredicate(new Resource("joinie")); // spos = 1l; // } else if (s.getObject() == jo._var) { // s.setObject(new Resource("joinie")); // spos = 2l; // } else if (s.getContext() == jo._var) { // s.setContext(new Resource("joinie")); // spos = 3l; // } // // int indexNo = whichIndex(s); // // SelectIterator si = new SelectIterator(_ds.getQuadIndex().getIndex(indexNo), // indexNo, // new OIDIterator(_ds.getLexicon(), jo._right._q)); // // rpos = _boundvars.indexOf(jo._var); // // // construct join iterator, note that spos and rpos are not masks // // by merely the position in the array // bi = new JoinINLIterator(_root, si, rpos, spos); // // // build variable list as we go // _boundvars.addAll(getVariables(s, indexNo)); // // _root = bi; // } else if (o instanceof DifferenceOp) { // ExecIterator bi = null; // DifferenceOp dio = (DifferenceOp)o; // long rpos = 0; // long spos = 0; // // dio._left.accept(this); // // // replace the join condition with a non-variable // // that we can figure out the right index // Quad s = new Quad(dio._right._q); // // if (s.getSubject() == dio._var) { // s.setSubject(new Resource("diffie")); // spos = 0l; // } else if (s.getPredicate() == dio._var) { // s.setPredicate(new Resource("diffie")); // spos = 1l; // } else if (s.getObject() == dio._var) { // s.setObject(new Resource("diffie")); // spos = 2l; // } else if (s.getContext() == dio._var) { // s.setContext(new Resource("diffie")); // spos = 3l; // } // // int indexNo = whichIndex(s); // // SelectIterator si = new SelectIterator(_ds.getQuadIndex().getIndex(indexNo), // indexNo, // new OIDIterator(_ds.getLexicon(), dio._right._q)); // // rpos = _boundvars.indexOf(dio._var); // // // construct join iterator, note that spos and rpos are not masks // // by merely the position in the array // bi = new DifferenceIterator(_root, si, rpos, spos); // // // build variable list as we go // // no, not for difference _variables.addAll(getVariables(s, indexNo)); // // _root = bi; // } // } // // /** // * Return a new root node. // */ // public Object getNewRoot() { // // XXX the iterators should be stupid, all transformations should // // be made here (e.g. constructing the template, constructing the // // mapping etc. // // System.out.println("bound variables " + _boundvars); // System.out.println("select variables " + _selectvars); // // if (_resultformat == PROJECT || _resultformat == PROJECTFILTER) { // // mapping has a mapping from the _variables to the select specification // // i.e. which indexes of the _variables should be used in the real result // // mapping from _variables to po._varlist // // int mapping[] = new int[_selectvars.size()]; // // for (int i=0; i<_selectvars.size(); i++) { // mapping[i] = _boundvars.indexOf(_selectvars.get(i)); // } // // if (_resultformat == PROJECT) { // if (_distinct == true) { // _result = new ValuesListIterator(_ds.getLexicon(), new DistinctIterator(new ProjectBAIterator(_root, mapping, _selectvars)), _boundvars); // } else { // _result = new ValuesListIterator(_ds.getLexicon(), new ProjectBAIterator( _root, mapping, _selectvars), _boundvars); // } // } else { // int[] ineq = new int[2]; // // ineq[0] = _boundvars.indexOf(_ineqfilter.get(0)); // ineq[1] = _boundvars.indexOf(_ineqfilter.get(1)); // // _result = new ValuesListIterator(_ds.getLexicon(), new ProjectBAIterator(new FilterIneq(_root, ineq), mapping, _selectvars), _boundvars); // } // } else if (_resultformat == CONSTRUCT) { // // FIXME XXX should project out stuff earlier to // // not do the unncesssary join with the lexicon for // // nodes that are projected out lateron anyways // // // get the variables from the template and provide a mapping // _selectvars = new ArrayList(); // // for (int i=0; i < _template.size(); i++) { // if (_template.get(i) instanceof Quad) { // Quad q = (Quad)_template.get(i); // //Variable v = (Variable)_template.get(i); // _selectvars.add(q.getVariables()); // } // } // // _log.info("selectvars " + _selectvars + " tempalte " + _template + " boundvars " + _boundvars); // // // mapping has a mapping from the _variables to the select specification // // i.e. which indexes of the _variables should be used in the real result // // mapping from _variables to po._varlist // // int mapping[] = new int[_selectvars.size()]; // // for (int i=0; i<_selectvars.size(); i++) { // mapping[i] = _boundvars.indexOf(_selectvars.get(i)); // } // // if (_distinct == true) { // throw new ClassCastException("distinct not yet supported for triples"); // } else { // _result = new TemplateIterator(new ValuesIterator(_ds.getLexicon(), _root, _boundvars), _template); // //_result = new TemplateIterator(new ValuesIterator(_ds.getLexicon(), new ProjectBAIterator(_root, mapping, _selectvars), _selectvars), _template); // } // //_result = new TemplateIterator(new ValuesIterator(_ds.getLexicon(), _root, _boundvars), _template); // } else { // throw new ClassCastException("result iterator is neither project nor template!"); // } // // return _result; // } // // /** // * Get variables out of the adornments and index no // * @param adornments // * @return // */ // private ArrayList getVariables(Quad stmt, int indexNo) { // ArrayList variables = new ArrayList(); // // switch (indexNo) { // case DataStore.NIL: // variables.add(stmt.getSubject()); // variables.add(stmt.getPredicate()); // variables.add(stmt.getObject()); // variables.add(stmt.getContext()); // break; // case DataStore.S: // variables.add(stmt.getPredicate()); // variables.add(stmt.getObject()); // variables.add(stmt.getContext()); // break; // case DataStore.SP: // variables.add(stmt.getObject()); // variables.add(stmt.getContext()); // break; // case DataStore.SPO: // variables.add(stmt.getContext()); // break; // case DataStore.SPOC: // break; // case DataStore.O: // variables.add(stmt.getContext()); // variables.add(stmt.getSubject()); // variables.add(stmt.getPredicate()); // break; // case DataStore.OC: // variables.add(stmt.getSubject()); // variables.add(stmt.getPredicate()); // break; // case DataStore.OCS: // variables.add(stmt.getPredicate()); // break; // case DataStore.P: // variables.add(stmt.getObject()); // variables.add(stmt.getContext()); // variables.add(stmt.getSubject()); // break; // case DataStore.PO: // variables.add(stmt.getContext()); // variables.add(stmt.getSubject()); // break; // case DataStore.POC: // variables.add(stmt.getSubject()); // break; // case DataStore.C: // variables.add(stmt.getPredicate()); // variables.add(stmt.getObject()); // variables.add(stmt.getSubject()); // break; // case DataStore.CS: // variables.add(stmt.getPredicate()); // variables.add(stmt.getObject()); // break; // case DataStore.CSP: // variables.add(stmt.getObject()); // break; // case DataStore.CP: // variables.add(stmt.getObject()); // variables.add(stmt.getSubject()); // break; // case DataStore.OS: // variables.add(stmt.getContext()); // variables.add(stmt.getPredicate()); // break; // case DataStore.TEXT: // variables.add(stmt.getSubject()); // break; // } // // return variables; // } // // // project out the variables based on index no // // XXX FIXME that's strange, shouldn't project mask specify what's left, not what's removed? // // that seems inconsistent with the join stuff where equality is determined on the masks // // that stay // /* // private long _mask[] = {15l, 14l, 14l, 12l, 14l, 12l, 12l, 8l, 14l, 12l, 12l, 8l, 12l, 8l, 8l, 0l}; // // private long getMask(int indexNo) { // return _mask[indexNo]; // } // */ // // /** // * Figure out what index to use for retrieval // * of a non-ground quad (or spoc for ground quads). // */ // private int whichIndex(Quad query) { // // check which things are variables // boolean s = query.getSubject() instanceof Variable; // boolean p = query.getPredicate() instanceof Variable; // boolean o = query.getObject() instanceof Variable; // boolean c = query.getContext() instanceof Variable; // // _log.fine("s var: " + s + " p var: " + p + " o var: " + o + " c var: " + c); // // // calculate what index to use // int indexNo = c ? 0 : 1; // indexNo += o ? 0 : 2; // indexNo += p ? 0 : 4; // indexNo += s ? 0 : 8; // // return indexNo; // } //}