Package com.hp.hpl.jena.sparql.expr

Source Code of com.hp.hpl.jena.sparql.expr.ExprLib$ExprUnstable

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.hp.hpl.jena.sparql.expr;

import com.hp.hpl.jena.sparql.ARQInternalErrorException ;
import com.hp.hpl.jena.sparql.algebra.optimize.ExprTransformConstantFold ;
import com.hp.hpl.jena.sparql.core.Var ;

public class ExprLib
{
    /** Attempt to fold any sub-expressions of the Expr.
     * Return an expression that is euqivalent to the argument but maybe simpler.   
     * @param expr
     * @return Expression
     */
    public static Expr foldConstants(Expr expr) {
        return ExprTransformer.transform(new ExprTransformConstantFold(), expr) ;
    }

    /** transform an expression that may involve aggregates into one that just uses the variable for the aggregate */ 

    public static Expr replaceAggregateByVariable(Expr expr)
    {
        return ExprTransformer.transform(replaceAgg, expr) ;
    }

    /** transform expressions that may involve aggregates into one that just uses the variable for the aggregate */ 
    public static ExprList replaceAggregateByVariable(ExprList exprs)
    {
        return ExprTransformer.transform(replaceAgg, exprs) ;
    }
   
    private static ExprTransform replaceAgg = new ExprTransformCopy()
    {
        @Override
        public Expr transform(ExprAggregator eAgg)      
        { return eAgg.getAggVar()  ; }
    } ;
   
    /** Decide whether an expression is safe for using a a graph substitution.
     * Need to be careful about value-like tests when the graph is not
     * matched in a value fashion.
     */

    public static boolean isAssignmentSafeEquality(Expr expr)
    {
        return isAssignmentSafeEquality(expr, false, false) ;
    }
   
    /**
     * @param graphHasStringEquality    True if the graph triple matching equates xsd:string and plain literal
     * @param graphHasNumercialValueEquality    True if the graph triple matching equates numeric values
     */
   
    public static boolean isAssignmentSafeEquality(Expr expr, boolean graphHasStringEquality, boolean graphHasNumercialValueEquality)
    {
        if ( !(expr instanceof E_Equals) && !(expr instanceof E_SameTerm) )
            return false ;

        // Corner case: sameTerm is false for string/plain literal,
        // but true in the graph.
       
        ExprFunction2 eq = (ExprFunction2)expr ;
        Expr left = eq.getArg1() ;
        Expr right = eq.getArg2() ;
        Var var = null ;
        NodeValue constant = null ;

        if ( left.isVariable() && right.isConstant() )
        {
            var = left.asVar() ;
            constant = right.getConstant() ;
        }
        else if ( right.isVariable() && left.isConstant() )
        {
            var = right.asVar() ;
            constant = left.getConstant() ;
        }

        // Not between a variable and a constant
        if ( var == null || constant == null )
            return false ;

        if ( ! constant.isLiteral() )
            // URIs, bNodes.  Any bNode will have come from a substitution - not legal syntax in filters
            return true ;
       
        if (expr instanceof E_SameTerm)
        {
            if ( graphHasStringEquality && constant.isString() )
                // Graph is not same term
                return false ;
            if ( graphHasNumercialValueEquality && constant.isNumber() )
                return false ;
            return true ;
        }
       
        // Final check for "=" where a FILTER = can do value matching when the graph does not.
        if ( expr instanceof E_Equals )
        {
            if ( ! graphHasStringEquality && constant.isString() )
                return false ;
            if ( ! graphHasNumercialValueEquality && constant.isNumber() )
                return false ;
            return true ;
        }
        // Unreachable.
        throw new ARQInternalErrorException() ;
    }
   
    /** Some "functions" are non-deterministic (unstable) -
     * calling them with the same arguments
     * does not yields the same answer each time.
     * Therefore how and when they are called
     * matters.
     *
     * Functions: RAND, UUID, StrUUID, BNode
     *
     * NOW() is safe.
     */
    public static boolean isStable(Expr expr) {
        try {
            ExprWalker.walk(exprVisitorCheckForNonFunctions, expr) ;
            return true ;
        } catch ( ExprUnstable ex ) {
            return false ;
        }
    }

    private static ExprVisitor exprVisitorCheckForNonFunctions = new ExprVisitorBase() {
        @Override
        public void visit(ExprFunction0 func) {
            if ( func instanceof E_Random ||
                func instanceof E_UUID ||
                func instanceof E_StrUUID)
                throw new ExprUnstable() ;
        }
        @Override
        public void visit(ExprFunctionN func) {
            if (func instanceof E_BNode )
                throw new ExprUnstable() ;
        }
    } ;
   
    private static class ExprUnstable extends ExprException {}
}
TOP

Related Classes of com.hp.hpl.jena.sparql.expr.ExprLib$ExprUnstable

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.