class CachedRunningQuery extends AbstractRunningQuery {

    public String generateSql(String view, String fields, String conditions, String grouping, String order, String user, Connection connection)
                    throws SQLException {
        CachedResultsParameters.validate(view);
        StringBuilder buf = new StringBuilder();
        if (StringUtils.isEmpty(StringUtils.trimToNull(fields)))
            fields = "*";
        if (StringUtils.isEmpty(StringUtils.trimToNull(conditions)))
            conditions = null;
        if (StringUtils.isEmpty(StringUtils.trimToNull(order)))
            order = null;
        if (StringUtils.isEmpty(StringUtils.trimToNull(grouping)))
            grouping = null;
        
        if (null == this.viewColumnNames)
            this.viewColumnNames = this.getViewColumnNames(connection, view);
        
        if (!fields.equals("*")) {
            LinkedHashSet<String> fieldSet = new LinkedHashSet<>();
            String[] result = tokenizeOutsideParens(fields, ',');
            
            LinkedHashSet<String> requestedFieldSet = new LinkedHashSet<>();
            
            for (String s : result) {
                s = s.replace("`", "").trim();
                s = quoteField(s);
                requestedFieldSet.add(s);
            }
            
            if (requestedFieldSet.contains("*") == true) {
                // make sure that * is in front
                requestedFieldSet.remove("*");
                fieldSet.add("*");
            } else {
                // make sure that all fixed columns are included in the SELECT
                fieldSet.addAll(CacheableQueryRow.getFixedColumnSet());
            }
            fieldSet.addAll(requestedFieldSet);
            
            fields = StringUtils.join(fieldSet, ",");
        }
        
        if (null != conditions) {
            // quote fields that are known columns
            StringBuilder newConditions = new StringBuilder();
            String[] conditionsSplit = conditions.split(" ");
            for (String s : conditionsSplit) {
                String field = s.replace("`", "").trim();
                if (variableFields.contains(field) || isFunction(field)) {
                    newConditions.append(quoteField(field)).append(SPACE);
                } else {
                    newConditions.append(s).append(SPACE);
                }
            }
            if (newConditions.toString().trim().isEmpty()) {
                conditions = null;
            } else {
                conditions = newConditions.toString().trim();
            }
        }
        
        order = buildOrderClause(order);
        
        if (null != grouping) {
            // quote fields in the group by
            List<String> newGroup = new ArrayList<>();
            String[] groupSplit = grouping.split(",");
            for (String s : groupSplit) {
                s = s.replace("`", "").trim();
                // add quoted field
                newGroup.add(quoteField(s));
            }
            if (newGroup.isEmpty()) {
                grouping = null;
            } else {
                grouping = StringUtils.join(newGroup, ",");
            }
            
        }
        
        if (conditions == null || conditions.isEmpty()) {
            // create the condition
            conditions = "_user_ = '" + user + "'";
        } else {
            // add it to the existing conditions
            conditions = "_user_ = '" + user + "' AND (" + conditions + ")";
        }
        
        buf.append("SELECT ").append(fields).append(" FROM ").append(view);
        if (null != conditions)
            buf.append(" WHERE ").append(conditions);
        if (null != grouping)
            buf.append(" GROUP BY ").append(grouping);
        if (null != order)
            buf.append(" ORDER BY ").append(order);
        
        if (log.isTraceEnabled()) {
            log.trace("sqlQuery: " + buf);
        }
        
        if (CachedRunningQuery.isSqlSafe(buf.toString()) == false) {
            throw new IllegalArgumentException("Illegal arguments found");
        }
        return buf.toString();
    }

    private  CachedRunningQuery(QueryMetricFactory metricFactory);
    public  CachedRunningQuery(Query query, QueryLogic<?> queryLogic, String queryId, String alias, String user, String view, int pagesize,
                    String originalQueryId, Set<String> variableFields, Set<String> fixedFieldsInEvent, QueryMetricFactory metricFactory);
    public  CachedRunningQuery(Connection connection, Query query, QueryLogic<?> queryLogic, String queryId, String alias, String user, String view,
                    String fields, String conditions, String grouping, String order, int pagesize, Set<String> variableFields, Set<String> fixedFieldsInEvent,
                    QueryMetricFactory metricFactory);

}