diff --git a/packages/server/src/threads/query.js b/packages/server/src/threads/query.js index aee3ddb205..d6089567b8 100644 --- a/packages/server/src/threads/query.js +++ b/packages/server/src/threads/query.js @@ -9,6 +9,8 @@ const { const { doInAppContext, getAppDB } = require("@budibase/backend-core/context") const { isSQL } = require("../integrations/utils") +const CONST_CHAR_REGEX = new RegExp("'[^']*'", "g") + class QueryRunner { constructor(input, flags = { noRecursiveQuery: false }) { this.datasource = input.datasource @@ -37,17 +39,22 @@ class QueryRunner { arrays = [] for (let binding of bindings) { // 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(listRegex) + const listRegexMatch = sql.match( + new RegExp(`(in|IN|In|iN)( )+[(]?${binding}[)]?`) + ) // check if the variable was used as part of a string concat e.g. 'Hello {{binding}}' - const charConstRegex = new RegExp(`'[^']*${binding}[^']*'`) - const charConstMatch = sql.match(charConstRegex) - if (charConstMatch) { - let [part1, part2] = charConstMatch[0].split(binding) + // start by finding all the instances of const character strings + const charConstMatch = sql.match(CONST_CHAR_REGEX) || [] + // now look within them to see if a binding is used + const charConstBindingMatch = charConstMatch.find(string => + string.match(new RegExp(`'[^']*${binding}[^']*'`)) + ) + if (charConstBindingMatch) { + let [part1, part2] = charConstBindingMatch.split(binding) part1 = `'${part1.substring(1)}'` part2 = `'${part2.substring(0, part2.length - 1)}'` sql = sql.replace( - charConstMatch[0], + charConstBindingMatch, integration.getStringConcat([ part1, integration.getBindingIdentifier(),