Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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