Fix for #5242 - string interpolation in SQL queries was too wide, it was combining parts of multiple strings, rather than searching for bindings within distinct strings.

This commit is contained in:
mike12345567 2022-04-04 19:08:56 +01:00
parent d152635e25
commit cad32631a4
1 changed files with 14 additions and 7 deletions

View File

@ -9,6 +9,8 @@ const {
const { doInAppContext, getAppDB } = require("@budibase/backend-core/context") const { doInAppContext, getAppDB } = require("@budibase/backend-core/context")
const { isSQL } = require("../integrations/utils") const { isSQL } = require("../integrations/utils")
const CONST_CHAR_REGEX = new RegExp("'[^']*'", "g")
class QueryRunner { class QueryRunner {
constructor(input, flags = { noRecursiveQuery: false }) { constructor(input, flags = { noRecursiveQuery: false }) {
this.datasource = input.datasource this.datasource = input.datasource
@ -37,17 +39,22 @@ class QueryRunner {
arrays = [] arrays = []
for (let binding of bindings) { for (let binding of bindings) {
// look for array/list operations in the SQL statement, which will need handled later // look for array/list operations in the SQL statement, which will need handled later
const listRegex = new RegExp(`(in|IN|In|iN)( )+[(]?${binding}[)]?`) const listRegexMatch = sql.match(
const listRegexMatch = sql.match(listRegex) new RegExp(`(in|IN|In|iN)( )+[(]?${binding}[)]?`)
)
// check if the variable was used as part of a string concat e.g. 'Hello {{binding}}' // check if the variable was used as part of a string concat e.g. 'Hello {{binding}}'
const charConstRegex = new RegExp(`'[^']*${binding}[^']*'`) // start by finding all the instances of const character strings
const charConstMatch = sql.match(charConstRegex) const charConstMatch = sql.match(CONST_CHAR_REGEX) || []
if (charConstMatch) { // now look within them to see if a binding is used
let [part1, part2] = charConstMatch[0].split(binding) const charConstBindingMatch = charConstMatch.find(string =>
string.match(new RegExp(`'[^']*${binding}[^']*'`))
)
if (charConstBindingMatch) {
let [part1, part2] = charConstBindingMatch.split(binding)
part1 = `'${part1.substring(1)}'` part1 = `'${part1.substring(1)}'`
part2 = `'${part2.substring(0, part2.length - 1)}'` part2 = `'${part2.substring(0, part2.length - 1)}'`
sql = sql.replace( sql = sql.replace(
charConstMatch[0], charConstBindingMatch,
integration.getStringConcat([ integration.getStringConcat([
part1, part1,
integration.getBindingIdentifier(), integration.getBindingIdentifier(),