Merge pull request #11771 from Budibase/fix/more-less-than-sql

More/less than SQL fix
This commit is contained in:
Michael Drury 2023-09-14 18:02:30 +01:00 committed by GitHub
commit a5e79207ea
7 changed files with 62 additions and 43 deletions

View File

@ -25,6 +25,13 @@ jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Maximize build space
uses: easimon/maximize-build-space@master
with:
root-reserve-mb: 35000
swap-size-mb: 1024
remove-android: 'true'
remove-dotnet: 'true'
- name: Checkout repo and submodules - name: Checkout repo and submodules
uses: actions/checkout@v3 uses: actions/checkout@v3
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase' if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase'

View File

@ -18,7 +18,6 @@ import {
import sdk from "../../../sdk" import sdk from "../../../sdk"
import * as utils from "./utils" import * as utils from "./utils"
import { dataFilters } from "@budibase/shared-core" import { dataFilters } from "@budibase/shared-core"
import { removeEmptyFilters } from "./utils"
export async function handleRequest( export async function handleRequest(
operation: Operation, operation: Operation,
@ -27,7 +26,7 @@ export async function handleRequest(
) { ) {
// make sure the filters are cleaned up, no empty strings for equals, fuzzy or string // make sure the filters are cleaned up, no empty strings for equals, fuzzy or string
if (opts && opts.filters) { if (opts && opts.filters) {
opts.filters = utils.removeEmptyFilters(opts.filters) opts.filters = sdk.rows.removeEmptyFilters(opts.filters)
} }
if ( if (
!dataFilters.hasFilters(opts?.filters) && !dataFilters.hasFilters(opts?.filters) &&

View File

@ -146,32 +146,3 @@ export async function validate({
} }
return { valid: Object.keys(errors).length === 0, errors } return { valid: Object.keys(errors).length === 0, errors }
} }
// don't do a pure falsy check, as 0 is included
// https://github.com/Budibase/budibase/issues/10118
export function removeEmptyFilters(filters: SearchFilters) {
for (let filterField of NoEmptyFilterStrings) {
if (!filters[filterField]) {
continue
}
for (let filterType of Object.keys(filters)) {
if (filterType !== filterField) {
continue
}
// don't know which one we're checking, type could be anything
const value = filters[filterType] as unknown
if (typeof value === "object") {
for (let [key, value] of Object.entries(
filters[filterType] as object
)) {
if (value == null || value === "") {
// @ts-ignore
delete filters[filterField][key]
}
}
}
}
}
return filters
}

View File

@ -1,4 +1,8 @@
import { Knex, knex } from "knex" import { Knex, knex } from "knex"
import { db as dbCore } from "@budibase/backend-core"
import { QueryOptions } from "../../definitions/datasource"
import { isIsoDateString, SqlClient } from "../utils"
import SqlTableQueryBuilder from "./sqlTable"
import { import {
Operation, Operation,
QueryJson, QueryJson,
@ -6,11 +10,8 @@ import {
SearchFilters, SearchFilters,
SortDirection, SortDirection,
} from "@budibase/types" } from "@budibase/types"
import { db as dbCore } from "@budibase/backend-core"
import { QueryOptions } from "../../definitions/datasource"
import { isIsoDateString, SqlClient } from "../utils"
import SqlTableQueryBuilder from "./sqlTable"
import environment from "../../environment" import environment from "../../environment"
import { isValidFilter } from "../utils"
const envLimit = environment.SQL_MAX_ROWS const envLimit = environment.SQL_MAX_ROWS
? parseInt(environment.SQL_MAX_ROWS) ? parseInt(environment.SQL_MAX_ROWS)
@ -261,15 +262,17 @@ class InternalBuilder {
if (isEmptyObject(value.high)) { if (isEmptyObject(value.high)) {
value.high = "" value.high = ""
} }
if (value.low && value.high) { const lowValid = isValidFilter(value.low),
highValid = isValidFilter(value.high)
if (lowValid && highValid) {
// Use a between operator if we have 2 valid range values // Use a between operator if we have 2 valid range values
const fnc = allOr ? "orWhereBetween" : "whereBetween" const fnc = allOr ? "orWhereBetween" : "whereBetween"
query = query[fnc](key, [value.low, value.high]) query = query[fnc](key, [value.low, value.high])
} else if (value.low) { } else if (lowValid) {
// Use just a single greater than operator if we only have a low // Use just a single greater than operator if we only have a low
const fnc = allOr ? "orWhere" : "where" const fnc = allOr ? "orWhere" : "where"
query = query[fnc](key, ">", value.low) query = query[fnc](key, ">", value.low)
} else if (value.high) { } else if (highValid) {
// Use just a single less than operator if we only have a high // Use just a single less than operator if we only have a high
const fnc = allOr ? "orWhere" : "where" const fnc = allOr ? "orWhere" : "where"
query = query[fnc](key, "<", value.high) query = query[fnc](key, "<", value.high)

View File

@ -1,6 +1,11 @@
import { SourceName, SqlQuery, Datasource, Table } from "@budibase/types" import { SqlQuery, Table, SearchFilters } from "@budibase/types"
import { DocumentType, SEPARATOR } from "../db/utils" import { DocumentType, SEPARATOR } from "../db/utils"
import { FieldTypes, BuildSchemaErrors, InvalidColumns } from "../constants" import {
FieldTypes,
BuildSchemaErrors,
InvalidColumns,
NoEmptyFilterStrings,
} from "../constants"
import { helpers } from "@budibase/shared-core" import { helpers } from "@budibase/shared-core"
const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}` const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
@ -343,3 +348,36 @@ export function getPrimaryDisplay(testValue: unknown): string | undefined {
} }
return testValue as string return testValue as string
} }
export function isValidFilter(value: any) {
return value != null && value !== ""
}
// don't do a pure falsy check, as 0 is included
// https://github.com/Budibase/budibase/issues/10118
export function removeEmptyFilters(filters: SearchFilters) {
for (let filterField of NoEmptyFilterStrings) {
if (!filters[filterField]) {
continue
}
for (let filterType of Object.keys(filters)) {
if (filterType !== filterField) {
continue
}
// don't know which one we're checking, type could be anything
const value = filters[filterType] as unknown
if (typeof value === "object") {
for (let [key, value] of Object.entries(
filters[filterType] as object
)) {
if (value == null || value === "") {
// @ts-ignore
delete filters[filterField][key]
}
}
}
}
}
return filters
}

View File

@ -3,6 +3,7 @@ import { isExternalTable } from "../../../integrations/utils"
import * as internal from "./search/internal" import * as internal from "./search/internal"
import * as external from "./search/external" import * as external from "./search/external"
import { Format } from "../../../api/controllers/view/exporters" import { Format } from "../../../api/controllers/view/exporters"
export { isValidFilter, removeEmptyFilters } from "../../../integrations/utils"
export interface ViewParams { export interface ViewParams {
calculation: string calculation: string

View File

@ -1,8 +1,8 @@
import * as utils from "../utils" import * as search from "../../app/rows/search"
describe("removeEmptyFilters", () => { describe("removeEmptyFilters", () => {
it("0 should not be removed", () => { it("0 should not be removed", () => {
const filters = utils.removeEmptyFilters({ const filters = search.removeEmptyFilters({
equal: { equal: {
column: 0, column: 0,
}, },
@ -11,7 +11,7 @@ describe("removeEmptyFilters", () => {
}) })
it("empty string should be removed", () => { it("empty string should be removed", () => {
const filters = utils.removeEmptyFilters({ const filters = search.removeEmptyFilters({
equal: { equal: {
column: "", column: "",
}, },