All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.bigdata.rdf.sparql.ast.QueryBase Maven / Gradle / Ivy

/**

Copyright (C) SYSTAP, LLC DBA Blazegraph 2006-2016.  All rights reserved.

Contact:
     SYSTAP, LLC DBA Blazegraph
     2501 Calvert ST NW #106
     Washington, DC 20008
     [email protected]

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
package com.bigdata.rdf.sparql.ast;

import java.util.Map;
import java.util.Set;

import com.bigdata.bop.BOp;
import com.bigdata.bop.IVariable;
import com.bigdata.rdf.sparql.ast.QueryRoot.Annotations;

/**
 * Contains the projection clause, where clause, and solution modified clauses.
 * 
 * @see IGroupNode
 * @see ProjectionNode
 * @see GroupByNode
 * @see HavingNode
 * @see OrderByNode
 * @see SliceNode
 */
abstract public class QueryBase extends QueryNodeBase implements
        IBindingProducerNode, IGraphPatternContainer, IProjectionDecl {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public interface Annotations extends QueryNodeBase.Annotations,
            IGraphPatternContainer.Annotations, IProjectionDecl.Annotations {

        /**
         * The {@link QueryType}.
         */
        String QUERY_TYPE = "queryType";

        /**
         * The {@link ConstructNode} (optional).
         */
        String CONSTRUCT = "construct";

//        /**
//         * The {@link ProjectionNode} (optional). This is also used for DESCRIBE
//         * queries to capture the list of variables and IRIs which are then used
//         * to rewrite the DESCRIBE query into what amounts to a CONSTRUCT query.
//         * The resulting CONSTRUCT query will have a different
//         * {@link ProjectionNode} suitable for use with the generated
//         * {@link ConstructNode}.
//         */
//        String PROJECTION = "projection";

        /**
         * The {@link GroupByNode} (optional).
         */
        String GROUP_BY = "groupBy";

        /**
         * The {@link HavingNode} (optional).
         */
        String HAVING = "having";

        /**
         * The {@link OrderByNode} (optional).
         */
        String ORDER_BY = "orderBy";

        /**
         * The {@link SliceNode} (optional).
         */
        String SLICE = "slice";
        
        /**
         * When true inferred statements will not be stripped from
         * the access paths (default {@value #DEFAULT_INCLUDE_INFERRED}).
         */
        String INCLUDE_INFERRED = "includeInferred";
        
        boolean DEFAULT_INCLUDE_INFERRED = true;

        /**
         * The {@link Long} value giving the time limit for the query
         * (milliseconds).
         */
        String TIMEOUT = "timeout";

        long DEFAULT_TIMEOUT = Long.MAX_VALUE;

        /**
         * The BINDINGS clause (optional).
         */
        String BINDINGS_CLAUSE = "bindingsClause";
        
    }

    /**
     * Constructor is hidden to force people to declare the {@link QueryType}.
     */
    @SuppressWarnings("unused")
    private QueryBase() {
        
    }

    /**
     * Deep copy constructor.
     */
    public QueryBase(final QueryBase queryBase) {
    
        super(queryBase);
        
    }
    
    /**
     * Shallow copy constructor.
     */
    public QueryBase(final BOp[] args, final Map anns) {

        super(args, anns);
        
    }

    public QueryBase(final QueryType queryType) {
	    
        setQueryType(queryType);
	    
	}

    /**
     * Return the type of query. This provides access to information which may
     * otherwise be difficult to determine by inspecting the generated AST or
     * query plan.
     */
	public QueryType getQueryType() {
	    
        return (QueryType) getProperty(Annotations.QUERY_TYPE);

	}

    /**
     * Set the type of query.
     */
	public void setQueryType(final QueryType queryType) {
	    
        setProperty(Annotations.QUERY_TYPE, queryType);
	    
	}
	
    /**
     * Return the construction -or- null if there is no construction.
     */
    public ConstructNode getConstruct() {

        return (ConstructNode) getProperty(Annotations.CONSTRUCT);
        
    }
    
    /**
     * Set or clear the construction.
     * 
     * @param construction
     *            The construction (may be null).
     */
    public void setConstruct(final ConstructNode construct) {

        setProperty(Annotations.CONSTRUCT, construct);
        
        if (construct != null) {
        	
		   setQueryType(QueryType.CONSTRUCT);
		   
        }
        
    }
    
    @Override
    public void setProjection(final ProjectionNode projection) {

        setProperty(Annotations.PROJECTION, projection);

    }

    @Override
    public ProjectionNode getProjection() {

        return (ProjectionNode) getProperty(Annotations.PROJECTION);

    }
    
    @Override
    public Set> getProjectedVars(final Set> vars) {
        
        final ProjectionNode tmp = getProjection();
        
        if(tmp != null) {
            
            tmp.getProjectionVars(vars);
            
        }
        
        return vars;
        
    }

    /**
     * Return the set of variables on which the {@link ProjectionNode} for this
     * query depends (this is a NOP if there is no {@link ProjectionNode} for
     * the query, which can happen for an ASK query). This DOES NOT report the
     * variables which are projected OUT of the query, just those used by the
     * SELECT expressions.
     * 
     * @param vars
     *            The variables used by the select expressions are added to this
     *            set.
     * 
     * @return The caller's set.
     */
    public Set> getSelectExprVars(final Set> vars) {
        
        final ProjectionNode tmp = getProjection();
        
        if(tmp != null) {
            
            tmp.getSelectExprVars(vars);
            
        }
        
        return vars;
        
    }

    /**
     * Return the {@link GraphPatternGroup} for the WHERE clause.
     * 
     * @return The WHERE clause -or- null.
     */
    @SuppressWarnings({ "rawtypes" })
    public GraphPatternGroup getWhereClause() {

        // Note: Synonym for getGraphPattern.
        return getGraphPattern();

    }

    @Override
    @SuppressWarnings("unchecked")
    public GraphPatternGroup getGraphPattern() {
     
        return (GraphPatternGroup) getProperty(Annotations.GRAPH_PATTERN);
        
    }

    @Override
    public void setGraphPattern(
            final GraphPatternGroup graphPattern) {

        /*
         * Clear the parent reference on the new where clause.
         * 
         * Note: This handles cases where a join group is lifted into a named
         * subquery. If we do not clear the parent reference on the lifted join
         * group it will still point back to its parent in the original join
         * group.
         */
        graphPattern.setParent(null);
        
        super.setProperty(Annotations.GRAPH_PATTERN, graphPattern);

    }

    /**
     * Set the {@link GraphPatternGroup} for the WHERE clause.
     * 
     * @param whereClause
     *            The "WHERE" clause.
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void setWhereClause(final GraphPatternGroup whereClause) {

        // Note: synonym for setGraphPattern.
        setGraphPattern(whereClause);

    }
    
    /**
     * Return true if this query has a WHERE clause, false if not.
     */
    public boolean hasWhereClause() {
    	
    	return getProperty(Annotations.GRAPH_PATTERN) != null;
    	
    }
    
    /**
     * Return the {@link GroupByNode} -or- null if there is none.
     */
    public GroupByNode getGroupBy() {
        
        return (GroupByNode) getProperty(Annotations.GROUP_BY);
        
    }

    /**
     * Set or clear the {@link GroupByNode}.
     * 
     * @param groupBy
     *            The new value (may be null).
     */
    public void setGroupBy(final GroupByNode groupBy) {

        setProperty(Annotations.GROUP_BY, groupBy);
        
    }
    
    /**
     * Return the {@link HavingNode} -or- null if there is none.
     */
    public HavingNode getHaving() {
        
        return (HavingNode) getProperty(Annotations.HAVING);
        
    }

    /**
     * Set or clear the {@link HavingNode}.
     * 
     * @param having
     *            The new value (may be null).
     */
    public void setHaving(final HavingNode having) {

        setProperty(Annotations.HAVING, having);
        
    }

	/**
	 * Return the slice -or- null if there is no slice.
	 */
	public SliceNode getSlice() {
        
        return (SliceNode) getProperty(Annotations.SLICE);
	    
    }

    /**
     * Set or clear the slice.
     * 
     * @param slice
     *            The slice (may be null).
     */
    public void setSlice(final SliceNode slice) {

        setProperty(Annotations.SLICE, slice);
        
    }


    /**
     * Return true iff there is a {@link SliceNode} and either the
     * LIMIT and/or OFFSET has been specified with a non-default value.
     */
    public boolean hasSlice() {

        final SliceNode slice = getSlice();

        if (slice == null)
            return false;

        if (slice.getLimit() != SliceNode.Annotations.DEFAULT_LIMIT)
            return true;

        if (slice.getOffset() != SliceNode.Annotations.DEFAULT_OFFSET)
            return true;

        // The SLICE does not specify either LIMIT or OFFSET.
        return false;

    }

    /**
     * Return the order by clause -or- null if there is no order
     * by.
     */
    public OrderByNode getOrderBy() {
     
        return (OrderByNode) getProperty(Annotations.ORDER_BY);

    }

    /**
     * Set or clear the {@link OrderByNode}.
     * 
     * @param orderBy
     *            The order by (may be null).
     */
    public void setOrderBy(final OrderByNode orderBy) {
    
        setProperty(Annotations.ORDER_BY, orderBy);
        
    }

    /**
     * @see Annotations#INCLUDE_INFERRED
     */
    public boolean getIncludeInferred() {
        return getProperty(Annotations.INCLUDE_INFERRED,
                Annotations.DEFAULT_INCLUDE_INFERRED);
    }

    /**
     * @see Annotations#INCLUDE_INFERRED
     */
    public void setIncludeInferred(boolean includeInferred) {
        setProperty(Annotations.INCLUDE_INFERRED, includeInferred);
    }

    /**
     * @see Annotations#TIMEOUT
     */
    public long getTimeout() {
        return getProperty(Annotations.TIMEOUT, Annotations.DEFAULT_TIMEOUT);
    }

    /**
     * Set the timeout (milliseconds) for the query.
     * 
     * @see Annotations#TIMEOUT
     */
    public void setTimeout(long timeout) {
        setProperty(Annotations.TIMEOUT, timeout);
    }

    /**
     * Set the BINDINGS.
     * 
     * @param bindings
     */
    public void setBindingsClause(final BindingsClause bindings) {

        setProperty(Annotations.BINDINGS_CLAUSE, bindings);

    }

    /**
     * Return the BINDINGS.
     */
    public BindingsClause getBindingsClause() {

        return (BindingsClause) getProperty(Annotations.BINDINGS_CLAUSE);

    }
    
    @Override
	public String toString(final int indent) {
		
	    final String s = indent(indent);
	    
		final StringBuilder sb = new StringBuilder();

        final ConstructNode construct = getConstruct();
        final ProjectionNode projection = getProjection();
        @SuppressWarnings("unchecked")
        final IGroupNode whereClause = getWhereClause();
        final GroupByNode groupBy = getGroupBy();
        final HavingNode having = getHaving();
        final OrderByNode orderBy = getOrderBy();
        final SliceNode slice = getSlice();
        final BindingsClause bindings = getBindingsClause();

        if (getQueryType() != null) {

            sb.append("\n").append(s).append("QueryType: ")
                    .append(getQueryType().toString());

        }

        if (getProperty(Annotations.INCLUDE_INFERRED) != null) {
            sb.append("\n");
            sb.append(s);
            sb.append("includeInferred=" + getIncludeInferred());
        }

        if (getProperty(Annotations.TIMEOUT) != null) {
            sb.append("\n");
            sb.append(s);
            sb.append("timeout=" + getTimeout());
        }

        if (construct != null && !construct.isEmpty()) {

            sb.append(construct.toString(indent));
            
        }

        if (projection != null && !projection.isEmpty()) {

		    sb.append(projection.toString(indent));
		    
		}

        if (whereClause != null) {

            sb.append(whereClause.toString(indent + 1));

        }

        if (groupBy != null && !groupBy.isEmpty()) {

            sb.append(groupBy.toString(indent));

        }

        if (having != null && !having.isEmpty()) {

            sb.append(having.toString(indent));

        }

        if (orderBy != null && !orderBy.isEmpty()) {

            sb.append(orderBy.toString(indent));

        }

        if (slice != null) {

            sb.append(slice.toString(indent));

        }

        if (getQueryHints() != null && !getQueryHints().isEmpty()) {
            sb.append("\n");
            sb.append(indent(indent));
            sb.append(Annotations.QUERY_HINTS);
            sb.append("=");
            sb.append(getQueryHints().toString());
        }
        
        if (bindings != null) {

            sb.append(bindings.toString(indent + 1));

        }

        return sb.toString();

    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy