fix: Native filter dynamic numeric search (#24418)

This commit is contained in:
John Bodley 2023-06-21 09:45:15 -07:00 committed by GitHub
parent 92e2ee9d07
commit 652bf6454e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 25 deletions

View File

@ -97,7 +97,7 @@ describe('Select buildQuery', () => {
expect(query.orderby).toEqual([['my_col', false]]);
});
it('should add text search parameter to query filter', () => {
it('should add text search parameter for string to query filter', () => {
const queryContext = buildQuery(formData, {
ownState: {
search: 'abc',
@ -111,7 +111,7 @@ describe('Select buildQuery', () => {
]);
});
it('should add numeric search parameter to query filter', () => {
it('should add text search parameter for numeric to query filter', () => {
const queryContext = buildQuery(formData, {
ownState: {
search: '123',
@ -120,6 +120,8 @@ describe('Select buildQuery', () => {
});
expect(queryContext.queries.length).toEqual(1);
const [query] = queryContext.queries;
expect(query.filters).toEqual([{ col: 'my_col', op: '>=', val: 123 }]);
expect(query.filters).toEqual([
{ col: 'my_col', op: 'ILIKE', val: '%123%' },
]);
});
});

View File

@ -39,22 +39,16 @@ const buildQuery: BuildQuery<PluginFilterSelectQueryFormData> = (
if (search) {
columns.filter(isPhysicalColumn).forEach(column => {
const label = getColumnLabel(column);
if (coltypeMap[label] === GenericDataType.STRING) {
if (
coltypeMap[label] === GenericDataType.STRING ||
(coltypeMap[label] === GenericDataType.NUMERIC &&
!Number.isNaN(Number(search)))
) {
extraFilters.push({
col: column,
op: 'ILIKE',
val: `%${search}%`,
});
} else if (
coltypeMap[label] === GenericDataType.NUMERIC &&
!Number.isNaN(Number(search))
) {
// for numeric columns we apply a >= where clause
extraFilters.push({
col: column,
op: '>=',
val: Number(search),
});
}
});
}

View File

@ -439,7 +439,14 @@ class BaseDatasource(
if isinstance(value, str):
value = value.strip("\t\n")
if target_generic_type == utils.GenericDataType.NUMERIC:
if (
target_generic_type == utils.GenericDataType.NUMERIC
and operator
not in {
utils.FilterOperator.ILIKE,
utils.FilterOperator.LIKE,
}
):
# For backwards compatibility and edge cases
# where a column data type might have changed
return utils.cast_to_num(value)

View File

@ -1173,7 +1173,14 @@ class ExploreMixin: # pylint: disable=too-many-public-methods
if isinstance(value, str):
value = value.strip("\t\n")
if target_generic_type == utils.GenericDataType.NUMERIC:
if (
target_generic_type == utils.GenericDataType.NUMERIC
and operator
not in {
utils.FilterOperator.ILIKE,
utils.FilterOperator.LIKE,
}
):
# For backwards compatibility and edge cases
# where a column data type might have changed
return utils.cast_to_num(value)
@ -1744,10 +1751,7 @@ class ExploreMixin: # pylint: disable=too-many-public-methods
tbl_column=col_obj, template_processor=template_processor
)
col_type = col_obj.type if col_obj else None
col_spec = db_engine_spec.get_column_spec(
native_type=col_type,
# db_extra=self.database.get_extra(),
)
col_spec = db_engine_spec.get_column_spec(native_type=col_type)
is_list_target = op in (
utils.FilterOperator.IN.value,
utils.FilterOperator.NOT_IN.value,
@ -1766,7 +1770,6 @@ class ExploreMixin: # pylint: disable=too-many-public-methods
target_native_type=col_type,
is_list_target=is_list_target,
db_engine_spec=db_engine_spec,
# db_extra=self.database.get_extra(),
)
if (
col_advanced_data_type != ""
@ -1848,10 +1851,17 @@ class ExploreMixin: # pylint: disable=too-many-public-methods
where_clause_and.append(sqla_col >= eq)
elif op == utils.FilterOperator.LESS_THAN_OR_EQUALS.value:
where_clause_and.append(sqla_col <= eq)
elif op == utils.FilterOperator.LIKE.value:
where_clause_and.append(sqla_col.like(eq))
elif op == utils.FilterOperator.ILIKE.value:
where_clause_and.append(sqla_col.ilike(eq))
elif op in {
utils.FilterOperator.ILIKE,
utils.FilterOperator.LIKE,
}:
if target_generic_type != GenericDataType.STRING:
sqla_col = sa.cast(sqla_col, sa.String)
if utils.FilterOperator.LIKE.value:
where_clause_and.append(sqla_col.like(eq))
else:
where_clause_and.append(sqla_col.ilike(eq))
elif (
op == utils.FilterOperator.TEMPORAL_RANGE.value
and isinstance(eq, str)