Class QueryToSQLMapper

  • All Implemented Interfaces:
    org.datanucleus.query.expression.ExpressionEvaluator, QueryGenerator

    public class QueryToSQLMapper
    extends org.datanucleus.query.expression.AbstractExpressionEvaluator
    implements QueryGenerator
    Class which maps a compiled (generic) query to an SQL query for RDBMS datastores. Takes in an SQLStatement, and use of compile() will update the SQLStatement to reflect the filter, result, grouping, having, ordering etc.

    Supports the following extensions currently :-

    • datanucleus.query.jdoql.{varName}.join defines the join type for that alias. This only currently applies if the variable is (finally) bound using the equality operator (e.g var.field == this.field). The extension should be set to "LEFTOUTERJOIN", "INNERJOIN"

    TODO This class currently takes in an SQLStatement and updates it with filter, result, from etc. If the input statement is a UNION of statements it tries to update the statement by applying the filter, result etc across all UNIONs. This can cause problems in some situations, particularly around looking up tables when using COMPLETE_TABLE inheritance, or with TYPE/instanceOf operations. We currently work around these by some fixes to getSQLTableMappingForPrimaryExpression, and by manually going around the UNIONs. What may be a better long term solution would be to run this class on each of the UNIONed statements separately and merge them.

    • Constructor Detail

      • QueryToSQLMapper

        public QueryToSQLMapper​(SQLStatement stmt,
                                org.datanucleus.query.compiler.QueryCompilation compilation,
                                Map parameters,
                                StatementClassMapping resultDefForClass,
                                StatementResultMapping resultDef,
                                org.datanucleus.metadata.AbstractClassMetaData cmd,
                                boolean subclasses,
                                org.datanucleus.FetchPlan fetchPlan,
                                org.datanucleus.ExecutionContext ec,
                                org.datanucleus.util.Imports importsDefinition,
                                Set<String> options,
                                Map<String,​Object> extensions)
        Constructor.
        Parameters:
        stmt - SQL Statement to update with the query contents.
        compilation - The generic query compilation
        parameters - Parameters needed
        resultDefForClass - Definition of results for the statement (populated here)
        resultDef - Definition of results if we have a result clause (populated here)
        cmd - Metadata for the candidate class
        subclasses - Whether to include subclasses
        fetchPlan - Fetch Plan to apply
        ec - execution context
        importsDefinition - Import definition to use in class lookups (optional)
        options - Options controlling behaviour
        extensions - Any query extensions that may define compilation behaviour
    • Method Detail

      • getQueryLanguage

        public String getQueryLanguage()
        Accessor for the query language that this query pertains to. Can be used to decide how to handle the input.
        Specified by:
        getQueryLanguage in interface QueryGenerator
        Returns:
        The query language
      • getClassLoaderResolver

        public org.datanucleus.ClassLoaderResolver getClassLoaderResolver()
        Description copied from interface: QueryGenerator
        Accessor for the ClassLoader resolver to use when looking up classes.
        Specified by:
        getClassLoaderResolver in interface QueryGenerator
        Returns:
        The classloader resolver
      • getCompilationComponent

        public org.datanucleus.query.compiler.CompilationComponent getCompilationComponent()
        Description copied from interface: QueryGenerator
        Accessor for the current query component being compiled.
        Specified by:
        getCompilationComponent in interface QueryGenerator
        Returns:
        Component being compiled (if any)
      • getExecutionContext

        public org.datanucleus.ExecutionContext getExecutionContext()
        Description copied from interface: QueryGenerator
        Accessor for the ExecutionContext for this query.
        Specified by:
        getExecutionContext in interface QueryGenerator
        Returns:
        ExecutionContext
      • getProperty

        public Object getProperty​(String name)
        Description copied from interface: QueryGenerator
        Accessor for a property affecting the query compilation. This can be something like whether there is an OR in the filter, which can then impact on the type of SQL used.
        Specified by:
        getProperty in interface QueryGenerator
        Parameters:
        name - The property name
        Returns:
        Its value
      • isPrecompilable

        public boolean isPrecompilable()
        Accessor for whether the query is precompilable (doesn't need to know parameter values to be able to compile it).
        Returns:
        Whether the query is precompilable and hence cacheable
      • setNotPrecompilable

        protected void setNotPrecompilable()
      • getParameterNameByPosition

        public Map<Integer,​String> getParameterNameByPosition()
        Convenience accessor for a map of the parameter name keyed by its position. This is only available after
        compile
        is called.
        Returns:
        Map of parameter name keyed by position
      • compile

        public void compile()
        Method to update the supplied SQLStatement with the components of the specified query. During the compilation process this updates the SQLStatement "compileComponent" to the component of the query being compiled.
      • compileFrom

        protected void compileFrom()
        Method to compile the FROM clause of the query into the SQLStatement.
      • compileFilter

        protected void compileFilter()
        Method to compile the WHERE clause of the query into the SQLStatement.
      • compileResult

        protected void compileResult​(SelectStatement stmt)
        Method to compile the result clause of the query into the SQLStatement. Note that this also compiles queries of the candidate (no specified result), selecting the candidate field(s).
        Parameters:
        stmt - SELECT statement
      • getStatementMappingForNewObjectExpression

        protected StatementNewObjectMapping getStatementMappingForNewObjectExpression​(NewObjectExpression expr,
                                                                                      SelectStatement stmt)
        Convenience method to convert a NewObjectExpression into a StatementNewObjectMapping. Handles recursive new object calls (where a new object is an argument to a new object construction).
        Parameters:
        expr - The NewObjectExpression
        stmt - SelectStatement
        Returns:
        The mapping for the new object
      • compileUpdate

        protected void compileUpdate​(UpdateStatement stmt)
        Method to compile the result clause of the query into the SQLStatement.
        Parameters:
        stmt - UPDATE statement
      • validateExpressionForResult

        protected void validateExpressionForResult​(SQLExpression sqlExpr)
        Method that validates that the specified expression is valid for use in a result clause. Throws a NucleusUserException if it finds a multi-value mapping selected (collection, map).
        Parameters:
        sqlExpr - The SQLExpression
      • compileGrouping

        protected void compileGrouping​(SelectStatement stmt)
        Method to compile the grouping clause of the query into the SQLStatement.
        Parameters:
        stmt - SELECT statement
      • compileHaving

        protected void compileHaving​(SelectStatement stmt)
        Method to compile the having clause of the query into the SQLStatement.
        Parameters:
        stmt - SELECT statement
      • compileOrdering

        protected void compileOrdering​(SelectStatement stmt)
        Method to compile the ordering clause of the query into the SQLStatement.
        Parameters:
        stmt - SELECT statement
      • compileFromClassExpression

        protected void compileFromClassExpression​(org.datanucleus.query.expression.ClassExpression clsExpr)
        Method to take a ClassExpression (in a FROM clause) and process the candidate and any linked JoinExpression(s), adding joins to the SQLStatement as required.
        Parameters:
        clsExpr - The ClassExpression
      • processFromClauseSubquery

        protected void processFromClauseSubquery​(org.datanucleus.query.expression.ClassExpression clsExpr,
                                                 SQLTable candSqlTbl,
                                                 org.datanucleus.metadata.MetaDataManager mmgr)
        Method to process a ClassExpression where it represents a subquery. User defined the candidate of the subquery as an implied join to the outer query, for example "SELECT c FROM Customer c WHERE EXISTS (SELECT o FROM c.orders o ...)" so this method will add the join(s) to the outer query.
        Parameters:
        clsExpr - The ClassExpression
        candSqlTbl - Candidate SQL Table
        mmgr - MetaData Manager
      • processAndExpression

        protected Object processAndExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processAndExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processOrExpression

        protected Object processOrExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processOrExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processBitAndExpression

        protected Object processBitAndExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processBitAndExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processBitOrExpression

        protected Object processBitOrExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processBitOrExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processBitXorExpression

        protected Object processBitXorExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processBitXorExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processEqExpression

        protected Object processEqExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processEqExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processNoteqExpression

        protected Object processNoteqExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processNoteqExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processGteqExpression

        protected Object processGteqExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processGteqExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processGtExpression

        protected Object processGtExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processGtExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processLteqExpression

        protected Object processLteqExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processLteqExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processLtExpression

        protected Object processLtExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processLtExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processLiteral

        protected Object processLiteral​(org.datanucleus.query.expression.Literal expr)
        Overrides:
        processLiteral in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • getSQLLiteralForLiteralValue

        protected SQLExpression getSQLLiteralForLiteralValue​(Object litValue)
      • processPrimaryExpression

        protected Object processPrimaryExpression​(org.datanucleus.query.expression.PrimaryExpression expr)
        Overrides:
        processPrimaryExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processParameterExpression

        protected Object processParameterExpression​(org.datanucleus.query.expression.ParameterExpression expr)
        Overrides:
        processParameterExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processParameterExpression

        protected Object processParameterExpression​(org.datanucleus.query.expression.ParameterExpression expr,
                                                    boolean asLiteral)
        Method to process a parameter expression. The optional argument controls whether we should create this as a parameter or as a literal (i.e the param value is known etc). If the parameter doesn't have its value defined then returns ParameterLiteral otherwise we get an XXXLiteral of the (declared) type of the parameter
        Parameters:
        expr - The ParameterExpression
        asLiteral - Whether to create a SQLLiteral rather than a parameter literal
        Returns:
        The processed expression
      • getInvokedSqlExpressionForInvokeExpression

        protected SQLExpression getInvokedSqlExpressionForInvokeExpression​(org.datanucleus.query.expression.InvokeExpression expr)
      • processInvokeExpression

        protected Object processInvokeExpression​(org.datanucleus.query.expression.InvokeExpression expr)
        Overrides:
        processInvokeExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processInvokeExpression

        protected SQLExpression processInvokeExpression​(org.datanucleus.query.expression.InvokeExpression expr,
                                                        SQLExpression invokedSqlExpr)
        Internal method to handle the processing of an InvokeExpression.
        Parameters:
        expr - The InvokeExpression
        invokedSqlExpr - The SQLExpression that we are invoking the method on.
        Returns:
        The resultant SQLExpression
      • processSubqueryExpression

        protected Object processSubqueryExpression​(org.datanucleus.query.expression.SubqueryExpression expr)
        Overrides:
        processSubqueryExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processAddExpression

        protected Object processAddExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processAddExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processDivExpression

        protected Object processDivExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processDivExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processMulExpression

        protected Object processMulExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processMulExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processSubExpression

        protected Object processSubExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processSubExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processDistinctExpression

        protected Object processDistinctExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processDistinctExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processComExpression

        protected Object processComExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processComExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processModExpression

        protected Object processModExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processModExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processNegExpression

        protected Object processNegExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processNegExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processNotExpression

        protected Object processNotExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processNotExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processCastExpression

        protected Object processCastExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processCastExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processCaseExpression

        protected Object processCaseExpression​(org.datanucleus.query.expression.CaseExpression expr)
        Overrides:
        processCaseExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processCaseExpression

        protected Object processCaseExpression​(org.datanucleus.query.expression.CaseExpression expr,
                                               SQLExpression typeExpr)
      • processIsExpression

        protected Object processIsExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processIsExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processIsnotExpression

        protected Object processIsnotExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processIsnotExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processInExpression

        protected Object processInExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processInExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processNotInExpression

        protected Object processNotInExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processNotInExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processCreatorExpression

        protected Object processCreatorExpression​(org.datanucleus.query.expression.CreatorExpression expr)
        Overrides:
        processCreatorExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processLikeExpression

        protected Object processLikeExpression​(org.datanucleus.query.expression.Expression expr)
        Overrides:
        processLikeExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • processVariableExpression

        protected Object processVariableExpression​(org.datanucleus.query.expression.VariableExpression expr)
        Overrides:
        processVariableExpression in class org.datanucleus.query.expression.AbstractExpressionEvaluator
      • useParameterExpressionAsLiteral

        public void useParameterExpressionAsLiteral​(SQLLiteral paramLiteral)
        Description copied from interface: QueryGenerator
        Method to instruct the generator to convert the provided parameter expression to just be a literal using the value of the parameter (hence the statement cannot be precompilable since the value needs to be known).
        Specified by:
        useParameterExpressionAsLiteral in interface QueryGenerator
        Parameters:
        paramLiteral - The parameter expression
      • hasExtension

        public boolean hasExtension​(String key)
        Description copied from interface: QueryGenerator
        Accessor for whether the query being generated has the specified extension.
        Specified by:
        hasExtension in interface QueryGenerator
        Parameters:
        key - Extension name
        Returns:
        Whether it is present
      • getValueForExtension

        public Object getValueForExtension​(String key)
        Description copied from interface: QueryGenerator
        Accessor for the value of the specified query extension (or null if not defined).
        Specified by:
        getValueForExtension in interface QueryGenerator
        Parameters:
        key - Extension name
        Returns:
        The value for the extension
      • getRequiredJoinTypeForAlias

        public SQLJoin.JoinType getRequiredJoinTypeForAlias​(String alias)
        Convenience method to return the required join type for the specified alias. If the table has a join type defined as an extension "datanucleus.query.jdoql.{alias}.join" then this returns the type. Otherwise returns null.
        Parameters:
        alias - The alias
        Returns:
        The join type required (if any)
      • getValueForObjectField

        protected Object getValueForObjectField​(Object obj,
                                                String fieldName)
        Convenience method to return the value of a field of the supplied object. If the object is null then returns null for the field.
        Parameters:
        obj - The object
        fieldName - The field name
        Returns:
        The field value
      • getSQLTableMappingForAlias

        protected org.datanucleus.store.rdbms.query.QueryToSQLMapper.SQLTableMapping getSQLTableMappingForAlias​(String alias)
      • getAliasForSQLTableMapping

        public String getAliasForSQLTableMapping​(org.datanucleus.store.rdbms.query.QueryToSQLMapper.SQLTableMapping tblMapping)
      • getAliasForSQLTable

        public String getAliasForSQLTable​(SQLTable tbl)
        Returns the alias used for the specified SQLTable. If we have a variable "var1" and there is an access to a field also, then we may have entries for "var1" and "var1.field". In this case we return the shortest.
        Parameters:
        tbl - The table
        Returns:
        The query name alias for this table
      • setSQLTableMappingForAlias

        protected void setSQLTableMappingForAlias​(String alias,
                                                  org.datanucleus.store.rdbms.query.QueryToSQLMapper.SQLTableMapping mapping)
      • hasSQLTableMappingForAlias

        protected boolean hasSQLTableMappingForAlias​(String alias)
      • bindVariable

        public void bindVariable​(String varName,
                                 org.datanucleus.metadata.AbstractClassMetaData cmd,
                                 SQLTable sqlTbl,
                                 JavaTypeMapping mapping)
        Method to bind the specified variable to the table and mapping.
        Specified by:
        bindVariable in interface QueryGenerator
        Parameters:
        varName - Variable name
        cmd - Metadata for this variable type
        sqlTbl - Table for this variable
        mapping - The mapping of this variable in the table
      • bindVariable

        public SQLExpression bindVariable​(UnboundExpression expr,
                                          Class type)
        Method to bind the specified unbound variable (as cross join) on the assumption that the type is a persistable class.
        Specified by:
        bindVariable in interface QueryGenerator
        Parameters:
        expr - Unbound expression
        type - The type to bind as
        Returns:
        The bound expression to use instead
      • bindParameter

        public void bindParameter​(String paramName,
                                  Class type)
        Method to bind the specified parameter to the defined type. If the parameter is already bound (declared in the query perhaps, or bound via an earlier usage) then does nothing.
        Specified by:
        bindParameter in interface QueryGenerator
        Parameters:
        paramName - Name of the parameter
        type - The type (or subclass)
      • getTypeOfVariable

        public Class getTypeOfVariable​(String varName)
        Accessor for the type of a variable if already known (declared?).
        Specified by:
        getTypeOfVariable in interface QueryGenerator
        Parameters:
        varName - Name of the variable
        Returns:
        The type if it is known
      • hasExplicitJoins

        public boolean hasExplicitJoins()
        Accessor for whether the query has explicit variables. If not then has implicit variables, meaning that they could potentially be rebound later if prematurely bound in a particular way.
        Specified by:
        hasExplicitJoins in interface QueryGenerator
        Returns:
        Whether the query has explicit variables
      • getBooleanExpressionForUseInFilter

        protected BooleanExpression getBooleanExpressionForUseInFilter​(BooleanExpression expr)
        Convenience method to return a boolean expression suitable for using in a filter. Will return the input expression unless it is simply a reference to a field of a class such as in a filter clause like
        myBoolField
        . In that case we return a boolean like
        myBoolField == TRUE
        .
        Parameters:
        expr - The expression to check
        Returns:
        The expression valid for use in the filter
      • resolveClass

        public Class resolveClass​(String className)
        Convenience method to resolve a class name.
        Specified by:
        resolveClass in interface QueryGenerator
        Parameters:
        className - The class name
        Returns:
        The class it relates to (if found)