sqlutils
sqlutils copied to clipboard
Non set SQL user variables `:=` leads to error
It seems that when setting multiple :=
to use user variables within SELECT in MySQL the getSQL function will throw the following error:
Error in if (!is.null(params) & length(params[params$param == v, "default"]) > :
argument is of length zer
The reason is that the getParameters function only looks for ":" and then takes everything in between without any further test.
Taking an example here:
SELECT source,
MIN(value) AS min,
MAX(value) AS max,
SUM(value) AS sum,
CAST(AVG(value) AS DECIMAL(20, 2)) AS avg
FROM (
SELECT @series := @series + (COALESCE(@source <> source, 0)) AS series,
@source := source AS newsource,
q.*
FROM (
SELECT @series := 1, @source := NULL
) vars
STRAIGHT_JOIN
(
SELECT 1 AS id, 1 AS source, 10 AS value
UNION ALL
SELECT 2 AS id, 1 AS source, 20 AS value
UNION ALL
SELECT 3 AS id, 2 AS source, 15 AS value
UNION ALL
SELECT 4 AS id, 2 AS source, 25 AS value
UNION ALL
SELECT 5 AS id, 1 AS source, 45 AS value
UNION ALL
SELECT 6 AS id, 3 AS source, 50 AS value
UNION ALL
SELECT 7 AS id, 3 AS source, 35 AS value
UNION ALL
SELECT 8 AS id, 1 AS source, 40 AS value
UNION ALL
SELECT 9 AS id, 1 AS source, 10 AS value
) q
ORDER BY
id
) q
GROUP BY
series
When using the sqlutils::getSQL
function this will throw an error as it will consider:
- "= @series + (COALESCE(@source <> source, 0)) AS series, @source"
- "= 1, @source "
as being parameters.
My suggestion would be to replace here:
pos = gregexpr(":", sql)
by
pos = gregexpr(":(?!=)", sql, perl = T)
or even
pos = gregexpr("(?<=[@\\b\\s]):(?!=)", sql, perl = T)
I understand that another solution for this example would be to use sqlutils::getSQLRaw(query) however it would not allow users to add any extra parameters.
I can help with a PR if you want.