Skip to content
11 changes: 11 additions & 0 deletions api/src/org/labkey/api/data/CompareType.java
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,10 @@ public Pair<SQLFragment, SQLFragment> getSqlFragments(Map<FieldKey, ? extends Co
return null;

ColumnInfo colInfo = columnMap != null ? columnMap.get(_fieldKey) : null;

if (colInfo != null && colInfo.getJdbcType() != JdbcType.ARRAY)
throw new RuntimeSQLException(new SQLGenerationException("Invalid filter type for column '" + _fieldKey.toDisplayString() + "'."));

var alias = SimpleFilter.getAliasForColumnFilter(dialect, colInfo, _fieldKey);

SQLFragment valuesFragment = dialect.array_construct(paramValues);
Expand Down Expand Up @@ -1040,6 +1044,10 @@ public ArrayIsEmptyClause(@NotNull FieldKey fieldKey)
public SQLFragment toSQLFragment(Map<FieldKey, ? extends ColumnInfo> columnMap, SqlDialect dialect)
{
ColumnInfo colInfo = columnMap != null ? columnMap.get(_fieldKey) : null;

if (colInfo != null && colInfo.getJdbcType() != JdbcType.ARRAY)
throw new RuntimeSQLException(new SQLGenerationException("Invalid filter type for column '" + _fieldKey.toDisplayString() + "'."));

var alias = SimpleFilter.getAliasForColumnFilter(dialect, colInfo, _fieldKey);

SQLFragment columnFragment = new SQLFragment().appendIdentifier(alias);
Expand Down Expand Up @@ -1747,6 +1755,9 @@ protected String toURLParamValue()
public SQLFragment toSQLFragment(Map<FieldKey, ? extends ColumnInfo> columnMap, SqlDialect dialect)
{
ColumnInfo colInfo = columnMap != null ? columnMap.get(_fieldKey) : null;
if (colInfo != null && colInfo.getJdbcType() == JdbcType.ARRAY)
throw new RuntimeSQLException(new SQLGenerationException("Invalid filter type for column '" + _fieldKey.toDisplayString() + "'."));

var alias = SimpleFilter.getAliasForColumnFilter(dialect, colInfo, _fieldKey);

SQLFragment fragment = toWhereClause(dialect, alias);
Expand Down
4 changes: 2 additions & 2 deletions api/src/org/labkey/api/data/DataRegion.java
Original file line number Diff line number Diff line change
Expand Up @@ -2654,7 +2654,7 @@ private void prepareFilters(RenderContext ctx)
StringBuilder msg;
if (ignoredColumns.size() == 1)
{
msg = new StringBuilder("Ignoring filter/sort on column '" + ignoredColumns.iterator().next().toDisplayString() + "' because it does not exist.");
msg = new StringBuilder("Ignoring filter/sort on column '" + ignoredColumns.iterator().next().toDisplayString() + "' because it does not exist or the filter type is invalid.");
}
else
{
Expand All @@ -2666,7 +2666,7 @@ private void prepareFilters(RenderContext ctx)
sep = ", ";
msg.append("'").append(fieldKey.toDisplayString()).append("'");
}
msg.append(" because they do not exist.");
msg.append(" because they do not exist or the filter types are invalid.");
}

addMessage(new Message(msg.toString(), MessageType.WARNING, "filter"));
Expand Down
50 changes: 42 additions & 8 deletions query/src/org/labkey/query/QueryServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.json.JSONObject;
import org.junit.Assert;
import org.junit.Test;
import org.labkey.api.action.ApiUsageException;
import org.labkey.api.assay.AssayService;
import org.labkey.api.audit.AbstractAuditHandler;
import org.labkey.api.audit.AuditHandler;
Expand Down Expand Up @@ -1902,7 +1903,7 @@ public List<ColumnInfo> ensureRequiredColumns(@NotNull TableInfo table, @NotNull
continue;
for (FieldKey fieldKey : set)
{
ColumnInfo col = resolveFieldKey(fieldKey, table, columnMap, unresolvedColumns, manager);
ColumnInfo col = resolveFieldKey(fieldKey, table, columnMap, unresolvedColumns, manager, null);
if (col != null)
ret.putIfAbsent(col.getFieldKey(),col);
}
Expand All @@ -1911,19 +1912,37 @@ public List<ColumnInfo> ensureRequiredColumns(@NotNull TableInfo table, @NotNull

if (filter != null)
{
for (FieldKey fieldKey : filter.getWhereParamFieldKeys())
if (filter instanceof SimpleFilter simpleFilter)
{
ColumnInfo col = resolveFieldKey(fieldKey, table, columnMap, unresolvedColumns, manager);
if (col != null)
ret.putIfAbsent(col.getFieldKey(),col);
Map<FieldKey, List<SimpleFilter.FilterClause>> clausesByField = new HashMap<>();
for (SimpleFilter.FilterClause clause : simpleFilter.getClauses())
{
for (FieldKey fk : clause.getFieldKeys())
clausesByField.computeIfAbsent(fk, k -> new ArrayList<>()).add(clause);
}
for (FieldKey fieldKey : simpleFilter.getWhereParamFieldKeys())
{
ColumnInfo col = resolveFieldKey(fieldKey, table, columnMap, unresolvedColumns, manager, clausesByField.get(fieldKey));
if (col != null)
ret.putIfAbsent(col.getFieldKey(), col);
}
}
else
{
for (FieldKey fieldKey : filter.getWhereParamFieldKeys())
{
ColumnInfo col = resolveFieldKey(fieldKey, table, columnMap, unresolvedColumns, manager, null);
if (col != null)
ret.putIfAbsent(col.getFieldKey(), col);
}
}
}

if (sort != null)
{
for (Sort.SortField field : sort.getSortList())
{
ColumnInfo col = resolveFieldKey(field.getFieldKey(), table, columnMap, unresolvedColumns, manager);
ColumnInfo col = resolveFieldKey(field.getFieldKey(), table, columnMap, unresolvedColumns, manager, null);
if (col != null)
{
ret.putIfAbsent(col.getFieldKey(),col);
Expand Down Expand Up @@ -1970,7 +1989,7 @@ private void resolveSortColumns(ColumnInfo col, Map<FieldKey, ColumnInfo> column

for (FieldKey key : sortFieldKeys)
{
ColumnInfo sortCol = resolveFieldKey(key, col.getParentTable(), columnMap, null, manager);
ColumnInfo sortCol = resolveFieldKey(key, col.getParentTable(), columnMap, null, manager, null);
if (sortCol != null)
{
toAdd.add(sortCol);
Expand Down Expand Up @@ -2002,7 +2021,7 @@ private void resolveSortColumns(ColumnInfo col, Map<FieldKey, ColumnInfo> column
}
}

private ColumnInfo resolveFieldKey(FieldKey fieldKey, TableInfo table, Map<FieldKey, ColumnInfo> columnMap, Set<FieldKey> unresolvedColumns, AliasManager manager)
private ColumnInfo resolveFieldKey(FieldKey fieldKey, TableInfo table, Map<FieldKey, ColumnInfo> columnMap, Set<FieldKey> unresolvedColumns, AliasManager manager, @Nullable List<SimpleFilter.FilterClause> filterClauses)
{
if (fieldKey == null) // TODO: Can this resolve "selectionMethods/selectionMethodId$Sname"?
return null;
Expand Down Expand Up @@ -2030,6 +2049,21 @@ private ColumnInfo resolveFieldKey(FieldKey fieldKey, TableInfo table, Map<Field
assert Table.checkColumn(table, column, "ensureRequiredColumns():");
assert fieldKey.getTable() == null || columnMap.containsKey(fieldKey);

if (filterClauses != null)
{
boolean isArrayColumn = column.getJdbcType() == JdbcType.ARRAY;
for (SimpleFilter.FilterClause clause : filterClauses)
{
boolean isArrayFilter = clause instanceof CompareType.ArrayClause;
boolean invalidArrayFilter = (isArrayFilter && !isArrayColumn) || (!isArrayFilter && isArrayColumn);
if (invalidArrayFilter)
{
unresolvedColumns.add(fieldKey);
return column; // return column, but mark as unresolvedColumns to drop filters
}
}
}

// getColumn() might return a column with a different field key than we asked for!
if (!column.getFieldKey().equals(fieldKey))
{
Expand Down
Loading