/** * Returns true if the constraint is associated with the given FromElement. * * @param constraint the constraint in question * @param fromElement the FromElement to check * @return true if associated */ public static boolean isRelatedTo(Constraint constraint, FromElement fromElement) { if (isAssociatedWith(constraint, fromElement)) { return true; } // also want to find out if this is referred to in a Contains or Subquery // constraint that is associated with another fromElement. if (constraint instanceof ContainsConstraint) { if (fromElement == ((ContainsConstraint) constraint).getQueryClass()) { return true; } } else if (constraint instanceof SubqueryConstraint) { if (fromElement == ((SubqueryConstraint) constraint).getQuery()) { return true; } } else if (constraint instanceof SimpleConstraint) { SimpleConstraint sc = (SimpleConstraint) constraint; Set<QueryField> qFields = getQueryFields(sc.getArg1()); qFields.addAll(getQueryFields(sc.getArg2())); for (QueryField qf : qFields) { if (fromElement == qf.getFromElement()) { return true; } } } return false; }
/** * Returns true if the constraint is associated with the given FromElement. Associated with means * relating directly to a field of the QueryClass but NOT a cross-reference contraint (which * compares two arbitrary fields of different QueryClasses. * * @param constraint the constraint in question * @param fromElement the FromElement to check * @return true if associated */ public static boolean isAssociatedWith(Constraint constraint, FromElement fromElement) { Object left = getLeftArgument(constraint); Object right = getRightArgument(constraint); // ignore cross-references if (left instanceof QueryEvaluable && !(isCrossReference(constraint))) { // not a cross-reference -> at most one QueryClass. find it. QueryClass qc = null; // TODO test for a bug here? left not assoc by right is if (getQueryFields((QueryEvaluable) left).iterator().hasNext()) { QueryField qf = getQueryFields((QueryEvaluable) left).iterator().next(); qc = (QueryClass) qf.getFromElement(); } else if (getQueryFields((QueryEvaluable) right).iterator().hasNext()) { QueryField qf = getQueryFields((QueryEvaluable) right).iterator().next(); qc = (QueryClass) qf.getFromElement(); } else { return false; // does not relate to any QueryClass } return (fromElement == qc); } else if (left instanceof QueryClass && right instanceof QueryClass) { return (fromElement == left || fromElement == right); } else if (left instanceof QueryClass) { return (fromElement == left); } else if (left instanceof QueryReference) { return (fromElement == ((QueryReference) left).getQueryClass()); } else if (right instanceof Query) { return (fromElement == right); } return false; }
/** * Returns true if the Constraint is a cross-reference between two QueryClasses. A constraint is * deemed to be a cross-reference if it compares fields of two different QueryClasses, either * directly or via QueryExpressions. * * @param constraint the contraint to test * @return true if the contraint is a cross-reference */ public static boolean isCrossReference(Constraint constraint) { if (constraint instanceof SimpleConstraint) { // if QueryField exposed part of a subquery QueryField.getFromElement() // returns a query, does not cause any problem. Set<FromElement> qcs = new HashSet<FromElement>(); for (QueryField qf : getQueryFields(((SimpleConstraint) constraint).getArg1())) { qcs.add(qf.getFromElement()); } for (QueryField qf : getQueryFields(((SimpleConstraint) constraint).getArg2())) { qcs.add(qf.getFromElement()); } if (qcs.size() > 1) { return true; } } return false; }
public String toString(ValueContext vc) { valid = false; if (queryDefn == null) return "Query Definition is NULL"; StringBuffer errorMsg = new StringBuffer(); if (queryDefn.getErrors() != null) { List errors = queryDefn.getErrors(); for (int i = 0; i < errors.size(); i++) errorMsg.append(errors.get(i) + ".\n"); } if (select == null) { errorMsg.append("Query select is NULL."); } else { if (select.getErrors() != null) { List errors = select.getErrors(); for (int i = 0; i < errors.size(); i++) errorMsg.append(errors.get(i) + ".\n"); } } if (errorMsg.length() > 0) return errorMsg.toString(); List showFields = select.getReportFields(); int showFieldsCount = showFields.size(); for (int sf = 0; sf < showFieldsCount; sf++) { QueryField field = (QueryField) showFields.get(sf); String selClauseAndLabel = field.getSelectClauseExprAndLabel(); if (selClauseAndLabel != null) selectClause.add(field.getSelectClauseExprAndLabel()); addJoin(field); } QueryConditions allSelectConditions = select.getConditions(); QueryConditions usedSelectConditions = allSelectConditions.getUsedConditions(this, vc); // add join tables which have the auto-include flag set and their respective conditions to the // from and where clause lists. If the join is already in the 'joins' list, no need to add it // in. List autoIncJoinList = this.queryDefn.getAutoIncJoins(); for (Iterator it = autoIncJoinList.iterator(); it.hasNext(); ) { this.addJoin((QueryJoin) it.next()); } StringBuffer sql = new StringBuffer(); int selectCount = selectClause.size(); int selectLast = selectCount - 1; sql.append("select "); if (select.distinctRowsOnly()) sql.append("distinct \n"); else sql.append("\n"); for (int sc = 0; sc < selectCount; sc++) { sql.append(" " + selectClause.get(sc)); if (sc != selectLast) sql.append(", "); sql.append("\n"); } int fromCount = fromClause.size(); int fromLast = fromCount - 1; sql.append("from \n"); for (int fc = 0; fc < fromCount; fc++) { sql.append(" " + fromClause.get(fc)); if (fc != fromLast) sql.append(", "); sql.append("\n"); } boolean haveJoinWheres = false; int whereCount = whereJoinClause.size(); int whereLast = whereCount - 1; if (whereCount > 0) { sql.append("where\n (\n"); for (int wc = 0; wc < whereCount; wc++) { sql.append(" " + whereJoinClause.get(wc)); if (wc != whereLast) sql.append(" and "); sql.append("\n"); } sql.append(" )"); haveJoinWheres = true; } boolean haveCondWheres = false; int usedCondsCount = usedSelectConditions.size(); if (usedCondsCount > 0) { if (haveJoinWheres) sql.append(" and (\n"); else sql.append("where\n (\n"); usedSelectConditions.createSql(this, vc, usedSelectConditions, sql); sql.append(" )\n"); haveCondWheres = true; } List whereExprs = select.getWhereExpressions(); if (whereExprs != null && whereExprs.size() > 0) { int whereExprsLast = whereExprs.size() - 1; boolean first = false; if (!haveJoinWheres && !haveCondWheres) { sql.append("where\n (\n"); first = true; } int whereExprsCount = whereExprs.size(); for (int we = 0; we < whereExprsCount; we++) { SqlWhereExpression expr = (SqlWhereExpression) whereExprs.get(we); if (first) first = false; else sql.append(expr.getConnectorSql()); sql.append(" ("); sql.append(expr.getWhereCondExpr(this)); sql.append(" )\n"); } } List groupBys = select.getGroupBy(); int groupBysCount = groupBys.size(); if (groupBysCount > 0) { int groupByLast = groupBysCount - 1; sql.append("group by\n"); for (int gb = 0; gb < groupBysCount; gb++) { QueryField field = (QueryField) groupBys.get(gb); sql.append(" " + field.getQualifiedColName()); if (gb != groupByLast) { sql.append(", "); } sql.append("\n"); } } List orderBys = select.getOrderBy(); int orderBysCount = orderBys.size(); int orderBysLast = orderBysCount - 1; if (orderBysCount > 0) { sql.append("order by\n"); for (int ob = 0; ob < orderBysCount; ob++) { QuerySortFieldRef sortRef = (QuerySortFieldRef) orderBys.get(ob); QueryField[] fields = sortRef.getFields(vc); if (fields == null) { return "Order by field '" + sortRef.getFieldName().getId() + "' did not evaluate to an appropriate QueryField.\n"; } else { int lastField = fields.length - 1; for (int i = 0; i < fields.length; i++) { QueryField field = fields[i]; if (field == null) return "Order by field [" + i + "] in '" + sortRef.getFieldName().getId() + "' did not evaluate to an appropriate QueryField.\n"; sql.append(" " + field.getOrderByClauseExpr()); if (sortRef.isDescending()) sql.append(" desc"); if (i != lastField) { sql.append(", "); sql.append("\n"); } } } if (ob != orderBysLast) sql.append(", "); sql.append("\n"); } } valid = true; return sql.toString(); }
public void addJoin(QueryField field) { if (field == null) throw new RuntimeException("Null field"); QueryJoin join = field.getJoin(); this.addJoin(join); }