protected static void rewriteFilterItem(StringBuilder sb, FilterItem filterItem) throws UnsupportedOperationException { if (filterItem.isCompoundFilter()) { FilterItem[] childrend = filterItem.getChildItems(); boolean firstChild = true; sb.append('('); for (FilterItem child : childrend) { if (firstChild) { firstChild = false; } else { sb.append(' '); sb.append(filterItem.getLogicalOperator().toString()); sb.append(' '); } rewriteFilterItem(sb, child); } sb.append(')'); return; } final SelectItem selectItem = filterItem.getSelectItem(); validateSoqlSupportedSelectItem(selectItem); final Column column = selectItem.getColumn(); sb.append(column.getName()); sb.append(' '); final OperatorType operator = filterItem.getOperator(); if (OperatorType.IN.equals(operator)) { throw new UnsupportedOperationException("IN operator not supported: " + filterItem); } sb.append(operator.toSql()); sb.append(' '); final Object operand = filterItem.getOperand(); if (operand == null) { sb.append("null"); } else if (operand instanceof String) { sb.append('\''); String str = operand.toString(); str = str.replaceAll("\'", "\\\\'"); str = str.replaceAll("\"", "\\\\\""); str = str.replaceAll("\r", "\\\\r"); str = str.replaceAll("\n", "\\\\n"); str = str.replaceAll("\t", "\\\\t"); sb.append(str); sb.append('\''); } else if (operand instanceof Number) { sb.append(operand); } else if (operand instanceof Date) { final SimpleDateFormat dateFormat; ColumnType expectedColumnType = selectItem.getExpectedColumnType(); if (expectedColumnType == ColumnType.DATE) { // note: we don't apply the timezone for DATE fields, since they // don't contain time-of-day information. dateFormat = new SimpleDateFormat(SOQL_DATE_FORMAT_OUT); } else if (expectedColumnType == ColumnType.TIME) { dateFormat = new SimpleDateFormat(SOQL_TIME_FORMAT_OUT, Locale.ENGLISH); dateFormat.setTimeZone(SOQL_TIMEZONE); } else { dateFormat = new SimpleDateFormat(SOQL_DATE_TIME_FORMAT_OUT, Locale.ENGLISH); dateFormat.setTimeZone(SOQL_TIMEZONE); } String str = dateFormat.format((Date) operand); logger.debug("Date '{}' formatted as: {}", operand, str); sb.append(str); } else if (operand instanceof Column) { sb.append(((Column) operand).getName()); } else if (operand instanceof SelectItem) { SelectItem operandSelectItem = (SelectItem) operand; validateSoqlSupportedSelectItem(operandSelectItem); sb.append(operandSelectItem.getColumn().getName()); } else { throw new UnsupportedOperationException("Unsupported operand: " + operand); } }
@Override public DataSet executeQuery(Query query) { final List<FromItem> fromItems = query.getFromClause().getItems(); if (fromItems.size() != 1) { // not a simple SELECT ... FROM [table] ... query, we need to use // query post processing. return super.executeQuery(query); } final Table table = fromItems.get(0).getTable(); if (table == null) { return super.executeQuery(query); } if (!query.getGroupByClause().isEmpty()) { return super.executeQuery(query); } if (!query.getHavingClause().isEmpty()) { return super.executeQuery(query); } final List<SelectItem> selectItems = query.getSelectClause().getItems(); final StringBuilder sb = new StringBuilder(); try { sb.append("SELECT "); int i = 0; final Column[] columns = new Column[selectItems.size()]; for (SelectItem selectItem : selectItems) { validateSoqlSupportedSelectItem(selectItem); columns[i] = selectItem.getColumn(); if (i != 0) { sb.append(", "); } sb.append(columns[i].getName()); i++; } sb.append(" FROM "); sb.append(table.getName()); boolean firstWhere = true; for (FilterItem filterItem : query.getWhereClause().getItems()) { if (firstWhere) { sb.append(" WHERE "); firstWhere = false; } else { sb.append(" AND "); } rewriteFilterItem(sb, filterItem); } i = 0; final List<OrderByItem> items = query.getOrderByClause().getItems(); for (OrderByItem orderByItem : items) { if (i == 0) { sb.append(" ORDER BY "); } else { sb.append(", "); } final SelectItem selectItem = orderByItem.getSelectItem(); validateSoqlSupportedSelectItem(selectItem); final Column column = selectItem.getColumn(); sb.append(column.getName()); sb.append(' '); sb.append(orderByItem.getDirection()); i++; } final Integer firstRow = query.getFirstRow(); final Integer maxRows = query.getMaxRows(); if (maxRows != null && maxRows > 0) { if (firstRow != null) { // add first row / offset to avoid missing some records. sb.append(" LIMIT " + (maxRows + firstRow - 1)); } else { sb.append(" LIMIT " + maxRows); } } final QueryResult result = executeSoqlQuery(sb.toString()); DataSet dataSet = new SalesforceDataSet(columns, result, _connection); if (firstRow != null) { // OFFSET is still only a developer preview feature of SFDC. See // http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_calls_soql_select_offset.htm dataSet = new FirstRowDataSet(dataSet, firstRow.intValue()); } return dataSet; } catch (UnsupportedOperationException e) { logger.debug( "Failed to rewrite query to SOQL, falling back to regular query post-processing", e); return super.executeQuery(query); } }