Search in sources :

Example 36 with NucleusException

use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.

the class ListGetMethod method getExpression.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
     */
public SQLExpression getExpression(SQLStatement stmt, SQLExpression expr, List<SQLExpression> args) {
    if (args == null || args.size() == 0 || args.size() > 1) {
        throw new NucleusException(Localiser.msg("060016", "get", "CollectionExpression", 1));
    }
    CollectionExpression listSqlExpr = (CollectionExpression) expr;
    AbstractMemberMetaData mmd = listSqlExpr.getJavaTypeMapping().getMemberMetaData();
    if (mmd == null) {
        // TODO Cater for the List being an input parameter
        throw new NucleusException(Localiser.msg("060020", "indexOf", listSqlExpr.getClass().getName()));
    }
    if (!List.class.isAssignableFrom(mmd.getType())) {
        throw new UnsupportedOperationException("Query contains " + expr + ".get(int) yet the field is not a List!");
    } else if (mmd.getOrderMetaData() != null && !mmd.getOrderMetaData().isIndexedList()) {
        throw new UnsupportedOperationException("Query contains " + expr + ".get(int) yet the field is not an 'indexed' List!");
    }
    SQLExpression idxExpr = args.get(0);
    if (idxExpr instanceof SQLLiteral) {
        if (!(((SQLLiteral) idxExpr).getValue() instanceof Number)) {
            throw new UnsupportedOperationException("Query contains " + expr + ".get(int) yet the index is not a numeric literal so not yet supported");
        }
    } else {
        throw new UnsupportedOperationException("Query contains " + expr + ".get(int) yet the index is not a numeric literal so not yet supported");
    }
    if (listSqlExpr instanceof CollectionLiteral && idxExpr instanceof SQLLiteral) {
        CollectionLiteral lit = (CollectionLiteral) expr;
        if (lit.getValue() == null) {
            return new NullLiteral(stmt, null, null, null);
        }
        return lit.invoke("get", args);
    }
    if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.FILTER) {
        return getAsInnerJoin(stmt, listSqlExpr, idxExpr);
    } else if (stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.ORDERING || stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.RESULT || stmt.getQueryGenerator().getCompilationComponent() == CompilationComponent.HAVING) {
        return getAsSubquery(stmt, listSqlExpr, idxExpr);
    }
    throw new NucleusException("List.get() is not supported for " + listSqlExpr + " with argument " + idxExpr + " for query component " + stmt.getQueryGenerator().getCompilationComponent());
}
Also used : CollectionLiteral(org.datanucleus.store.rdbms.sql.expression.CollectionLiteral) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) SQLLiteral(org.datanucleus.store.rdbms.sql.expression.SQLLiteral) List(java.util.List) CollectionExpression(org.datanucleus.store.rdbms.sql.expression.CollectionExpression) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData) NullLiteral(org.datanucleus.store.rdbms.sql.expression.NullLiteral)

Example 37 with NucleusException

use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.

the class CoalesceFunction method getExpression.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
     */
public SQLExpression getExpression(SQLStatement stmt, SQLExpression expr, List<SQLExpression> args) {
    if (expr == null) {
        // Find expression type that this handles - all expressions need to be consistent in our implementation
        Class exprType = null;
        Class cls = null;
        int clsLevel = 0;
        for (int i = 0; i < args.size(); i++) {
            SQLExpression argExpr = args.get(i);
            if (exprType == null) {
                if (argExpr instanceof NumericExpression) {
                    exprType = NumericExpression.class;
                    cls = Integer.class;
                } else if (argExpr instanceof StringExpression) {
                    exprType = StringExpression.class;
                    cls = String.class;
                } else if (argExpr instanceof TemporalExpression) {
                    exprType = TemporalExpression.class;
                    cls = argExpr.getJavaTypeMapping().getJavaType();
                } else {
                    exprType = argExpr.getClass();
                    cls = argExpr.getJavaTypeMapping().getJavaType();
                }
            } else {
                if (!exprType.isAssignableFrom(argExpr.getClass())) {
                    throw new NucleusUserException("COALESCE invocation first argument of type " + exprType.getName() + " yet subsequent argument of type " + argExpr.getClass().getName());
                }
            }
            if (exprType == NumericExpression.class) {
                // Priority order is Double, Float, BigDecimal, BigInteger, Long, Integer
                Class argType = argExpr.getJavaTypeMapping().getJavaType();
                if (clsLevel < 5 && (argType == double.class || argType == Double.class)) {
                    cls = Double.class;
                    clsLevel = 5;
                } else if (clsLevel < 4 && (argType == float.class || argType == Float.class)) {
                    cls = Float.class;
                    clsLevel = 4;
                } else if (clsLevel < 3 && argType == BigDecimal.class) {
                    cls = BigDecimal.class;
                    clsLevel = 3;
                } else if (clsLevel < 2 && argType == BigInteger.class) {
                    cls = BigInteger.class;
                    clsLevel = 2;
                } else if (clsLevel < 1 && (argType == long.class || argType == Long.class)) {
                    cls = Long.class;
                    clsLevel = 1;
                }
            }
        }
        SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
        if (exprType == NumericExpression.class) {
            return new NumericExpression(stmt, exprFactory.getMappingForType(cls, true), "COALESCE", args);
        } else if (exprType == StringExpression.class) {
            return new StringExpression(stmt, exprFactory.getMappingForType(cls, true), "COALESCE", args);
        } else if (exprType == TemporalExpression.class) {
            return new TemporalExpression(stmt, exprFactory.getMappingForType(cls, true), "COALESCE", args);
        } else {
            return new ObjectExpression(stmt, exprFactory.getMappingForType(cls, true), "COALESCE", args);
        }
    }
    throw new NucleusException(Localiser.msg("060002", "COALESCE", expr));
}
Also used : TemporalExpression(org.datanucleus.store.rdbms.sql.expression.TemporalExpression) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) NucleusUserException(org.datanucleus.exceptions.NucleusUserException) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) BigDecimal(java.math.BigDecimal) StringExpression(org.datanucleus.store.rdbms.sql.expression.StringExpression) BigInteger(java.math.BigInteger) NucleusException(org.datanucleus.exceptions.NucleusException) ObjectExpression(org.datanucleus.store.rdbms.sql.expression.ObjectExpression)

Example 38 with NucleusException

use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.

the class CurrentTimeFunction method getExpression.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
     */
public SQLExpression getExpression(SQLStatement stmt, SQLExpression expr, List<SQLExpression> args) {
    if (expr == null) {
        // Assume that we have something like "CURRENT_DATE()"
        SQLExpression dateExpr = new TemporalExpression(stmt, stmt.getSQLExpressionFactory().getMappingForType(getClassForMapping(), true), getFunctionName(), args);
        // Update the SQL manually since the default is to add brackets after the name
        dateExpr.toSQLText().clearStatement();
        dateExpr.toSQLText().append(getFunctionName());
        return dateExpr;
    }
    throw new NucleusException(Localiser.msg("060002", getFunctionName(), expr));
}
Also used : TemporalExpression(org.datanucleus.store.rdbms.sql.expression.TemporalExpression) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) NucleusException(org.datanucleus.exceptions.NucleusException)

Example 39 with NucleusException

use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.

the class ListIndexOfMethod method getExpression.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
     */
public SQLExpression getExpression(SQLStatement stmt, SQLExpression expr, List<SQLExpression> args) {
    SQLExpression collSqlExpr = null;
    SQLExpression elemSqlExpr = null;
    if (expr != null) {
        if (args == null || args.size() == 0 || args.size() > 1) {
            throw new NucleusException(Localiser.msg("060016", "indexOf", "CollectionExpression", 1));
        }
        elemSqlExpr = args.get(0);
        collSqlExpr = expr;
    } else {
        if (args == null || args.size() != 2) {
            throw new NucleusException(Localiser.msg("060016", "indexOf", "CollectionExpression", 2));
        }
        elemSqlExpr = args.get(0);
        collSqlExpr = args.get(1);
    }
    AbstractMemberMetaData mmd = collSqlExpr.getJavaTypeMapping().getMemberMetaData();
    if (mmd == null) {
        // TODO Cater for the List being an input parameter
        throw new NucleusException(Localiser.msg("060020", "indexOf", collSqlExpr.getClass().getName()));
    }
    if (!mmd.hasCollection()) {
        throw new NucleusException("List.indexOf expression for field " + mmd.getFullFieldName() + " does not represent a collection!");
    } else if (!mmd.getOrderMetaData().isIndexedList()) {
        throw new NucleusException("List.indexOf expression for field " + mmd.getFullFieldName() + " does not represent an indexed list!");
    }
    JavaTypeMapping orderMapping = null;
    SQLTable orderTable = null;
    Table joinTbl = stmt.getRDBMSManager().getTable(mmd);
    if (joinTbl != null) {
        // 1-N via join table
        CollectionTable collTable = (CollectionTable) joinTbl;
        orderTable = stmt.getTableForDatastoreContainer(collTable);
        if (orderTable == null) {
            // TODO Allow control over the join type? the alias?
            orderTable = stmt.join(JoinType.LEFT_OUTER_JOIN, collSqlExpr.getSQLTable(), collSqlExpr.getSQLTable().getTable().getIdMapping(), collTable, null, collTable.getOwnerMapping(), null, null);
        }
        orderMapping = collTable.getOrderMapping();
    } else {
        // 1-N via FK
        orderTable = elemSqlExpr.getSQLTable();
        orderMapping = ((ClassTable) elemSqlExpr.getSQLTable().getTable()).getExternalMapping(mmd, MappingType.EXTERNAL_INDEX);
    }
    return new NumericExpression(stmt, orderTable, orderMapping);
}
Also used : CollectionTable(org.datanucleus.store.rdbms.table.CollectionTable) Table(org.datanucleus.store.rdbms.table.Table) ClassTable(org.datanucleus.store.rdbms.table.ClassTable) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) CollectionTable(org.datanucleus.store.rdbms.table.CollectionTable) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) SQLTable(org.datanucleus.store.rdbms.sql.SQLTable) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Example 40 with NucleusException

use of org.datanucleus.exceptions.NucleusException in project datanucleus-rdbms by datanucleus.

the class ArrayContainsMethod method getExpression.

/* (non-Javadoc)
     * @see org.datanucleus.store.rdbms.sql.method.SQLMethod#getExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression, java.util.List)
     */
public SQLExpression getExpression(SQLStatement stmt, SQLExpression expr, List<SQLExpression> args) {
    if (args == null || args.size() != 1) {
        throw new NucleusException("Incorrect arguments for Array.contains(SQLExpression)");
    }
    ClassLoaderResolver clr = stmt.getQueryGenerator().getClassLoaderResolver();
    SQLExpressionFactory exprFactory = stmt.getSQLExpressionFactory();
    ArrayExpression arrExpr = (ArrayExpression) expr;
    SQLExpression elemExpr = args.get(0);
    if (elemExpr.isParameter()) {
        // Element is a parameter so make sure its type is set
        AbstractMemberMetaData mmd = arrExpr.getJavaTypeMapping().getMemberMetaData();
        if (mmd != null) {
            stmt.getQueryGenerator().bindParameter(elemExpr.getParameterName(), mmd.getType().getComponentType());
        }
    }
    if (expr instanceof ArrayLiteral) {
        if (elemExpr instanceof UnboundExpression) {
            Class elemCls = clr.classForName(arrExpr.getJavaTypeMapping().getType()).getComponentType();
            elemExpr = stmt.getQueryGenerator().bindVariable((UnboundExpression) elemExpr, elemCls);
        }
        ArrayLiteral lit = (ArrayLiteral) expr;
        Object array = lit.getValue();
        JavaTypeMapping m = exprFactory.getMappingForType(boolean.class, true);
        if (array == null || Array.getLength(array) == 0) {
            return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
        }
        if (arrExpr.isParameter()) {
            stmt.getQueryGenerator().useParameterExpressionAsLiteral((ArrayLiteral) arrExpr);
        }
        boolean useInExpression = false;
        List<SQLExpression> collElementExprs = lit.getElementExpressions();
        if (collElementExprs != null && !collElementExprs.isEmpty()) {
            // Make sure the the collection element(s) are compatible with the elemExpr
            boolean incompatible = true;
            Class elemtype = clr.classForName(elemExpr.getJavaTypeMapping().getType());
            Iterator<SQLExpression> collElementExprIter = collElementExprs.iterator();
            while (collElementExprIter.hasNext()) {
                SQLExpression collElementExpr = collElementExprIter.next();
                Class collElemType = clr.classForName(collElementExpr.getJavaTypeMapping().getType());
                if (elementTypeCompatible(elemtype, collElemType)) {
                    incompatible = false;
                    break;
                }
            }
            if (incompatible) {
                // The provided element type isn't assignable to any of the input collection elements!
                return exprFactory.newLiteral(stmt, m, true).eq(exprFactory.newLiteral(stmt, m, false));
            }
            // Check if we should compare using an "IN (...)" expression
            SQLExpression collElementExpr = collElementExprs.get(0);
            if (collElementExpr instanceof StringExpression || collElementExpr instanceof NumericExpression || collElementExpr instanceof TemporalExpression || collElementExpr instanceof CharacterExpression || collElementExpr instanceof EnumExpression) {
                useInExpression = true;
            }
        }
        if (useInExpression) {
            // Return "elem IN (val1, val2, ...)"
            SQLExpression[] exprs = (collElementExprs != null ? collElementExprs.toArray(new SQLExpression[collElementExprs.size()]) : null);
            return new InExpression(elemExpr, exprs);
        }
        // TODO If elemExpr is a parameter and collExpr is derived from a parameter ?
        BooleanExpression bExpr = null;
        List<SQLExpression> elementExprs = lit.getElementExpressions();
        for (int i = 0; i < elementExprs.size(); i++) {
            SQLExpression arrElemExpr = elementExprs.get(i);
            if (bExpr == null) {
                bExpr = arrElemExpr.eq(elemExpr);
            } else {
                bExpr = bExpr.ior(arrElemExpr.eq(elemExpr));
            }
        }
        if (bExpr != null) {
            bExpr.encloseInParentheses();
        }
        return bExpr;
    } else if (arrExpr.getElementExpressions() != null) {
        if (elemExpr instanceof UnboundExpression) {
            Class elemCls = clr.classForName(arrExpr.getJavaTypeMapping().getType()).getComponentType();
            elemExpr = stmt.getQueryGenerator().bindVariable((UnboundExpression) elemExpr, elemCls);
        }
        // Array defined in query that has some expressions for elements, so just do OR chain
        BooleanExpression bExpr = null;
        List<SQLExpression> elementExprs = arrExpr.getElementExpressions();
        for (int i = 0; i < elementExprs.size(); i++) {
            SQLExpression arrElemExpr = elementExprs.get(i);
            if (bExpr == null) {
                bExpr = arrElemExpr.eq(elemExpr);
            } else {
                bExpr = bExpr.ior(arrElemExpr.eq(elemExpr));
            }
        }
        if (bExpr != null) {
            bExpr.encloseInParentheses();
        }
        return bExpr;
    } else {
        // TODO Support inner join variant
        return containsAsSubquery(stmt, arrExpr, elemExpr);
    }
}
Also used : TemporalExpression(org.datanucleus.store.rdbms.sql.expression.TemporalExpression) SQLExpressionFactory(org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory) SQLExpression(org.datanucleus.store.rdbms.sql.expression.SQLExpression) JavaTypeMapping(org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping) InExpression(org.datanucleus.store.rdbms.sql.expression.InExpression) ClassLoaderResolver(org.datanucleus.ClassLoaderResolver) NumericExpression(org.datanucleus.store.rdbms.sql.expression.NumericExpression) UnboundExpression(org.datanucleus.store.rdbms.sql.expression.UnboundExpression) EnumExpression(org.datanucleus.store.rdbms.sql.expression.EnumExpression) ArrayLiteral(org.datanucleus.store.rdbms.sql.expression.ArrayLiteral) CharacterExpression(org.datanucleus.store.rdbms.sql.expression.CharacterExpression) BooleanExpression(org.datanucleus.store.rdbms.sql.expression.BooleanExpression) StringExpression(org.datanucleus.store.rdbms.sql.expression.StringExpression) ArrayExpression(org.datanucleus.store.rdbms.sql.expression.ArrayExpression) DatastoreClass(org.datanucleus.store.rdbms.table.DatastoreClass) List(java.util.List) NucleusException(org.datanucleus.exceptions.NucleusException) AbstractMemberMetaData(org.datanucleus.metadata.AbstractMemberMetaData)

Aggregations

NucleusException (org.datanucleus.exceptions.NucleusException)326 NucleusUserException (org.datanucleus.exceptions.NucleusUserException)71 SQLExpression (org.datanucleus.store.rdbms.sql.expression.SQLExpression)67 JavaTypeMapping (org.datanucleus.store.rdbms.mapping.java.JavaTypeMapping)62 ParameterExpression (org.datanucleus.query.expression.ParameterExpression)53 PrimaryExpression (org.datanucleus.query.expression.PrimaryExpression)52 ArrayList (java.util.ArrayList)48 Literal (org.datanucleus.query.expression.Literal)47 AbstractMemberMetaData (org.datanucleus.metadata.AbstractMemberMetaData)44 SQLExpressionFactory (org.datanucleus.store.rdbms.sql.expression.SQLExpressionFactory)43 InvokeExpression (org.datanucleus.query.expression.InvokeExpression)40 AbstractClassMetaData (org.datanucleus.metadata.AbstractClassMetaData)37 ClassLoaderResolver (org.datanucleus.ClassLoaderResolver)36 StringExpression (org.datanucleus.store.rdbms.sql.expression.StringExpression)35 DatastoreClass (org.datanucleus.store.rdbms.table.DatastoreClass)35 Expression (org.datanucleus.query.expression.Expression)32 HashMap (java.util.HashMap)31 SelectStatement (org.datanucleus.store.rdbms.sql.SelectStatement)31 VariableExpression (org.datanucleus.query.expression.VariableExpression)26 RDBMSStoreManager (org.datanucleus.store.rdbms.RDBMSStoreManager)26