JPQL report groovy preprocess error

There is probably problem with AbstractDbDataLoader.processQueryTemplate, which is using GStringTemplateEngine shared for both SQL and JPQL query preprocessing.
When you are using JPQL report type you are querying against metaclasses eg.

select e.login as login from sec$User e where e.id = ${userId}

When you check

preprocess query as Groovy template

This query is being processed by mentioned function, which is looking for $ signs, it leads to transforming metaclass name such as sec$User. If you dont have parameter User it will lead to

No such property: User for class: groovy.lang.Binding

Otherwise if you have such parameter it will transform eg.

User parameter = ‘Joe’
sec$User -> secJoe

Tested on 6.5, 6.8, 6.9 framework.

Am I doing something wrong ?

Hi,

You need to add escapes since groovy pre-processing is on:
select e.login as login from sec\$User e where e.id = \${userId}
It is seems more like a normal behavior for groovy-template.

2 Likes

According to docs

The resulting query will be processed by GStringTemplateEngine that will have access to:

the report parameters: ${<parameter_name>},

values from parent bands: ${<band_name>.<parameter_name>}.

In fact this is not true.
Imho there should be machanism to escape $ without leading {.
Or change in docs.

Escape mechanism is quite simple

          \\ lookbehind backslash, lookahead {
           Matcher m =  Pattern.compile("(?<!\\\\)[$](?!\\{)").matcher(query);
            StringBuffer sb = new StringBuffer();
            \\replace non-escaped, non-parameter $ with escaped \$
            String repString = "\\\\\\$"; 
            while (m.find()) {
                m.appendReplacement(sb, repString);
            }
            m.appendTail(sb);
            query = sb.toString();
            query = engine.createTemplate(query).make(queryParams).toString();

Hi Michal,

Escaping $ manually is the normal behavior:

select e.login as "login" from sec\$User e where e.id = \${userId}

or

select e.LOGIN as login from SEC_USER e where e.id = \${userId}

As the $ symbol can be a part of any Groovy variable, not only starting with ${, escaping it everywhere implicitly by default is not implemened.

1 Like

Thank you for explanation, when I went through groovy docs they really mapped tons of features to dollar sign and escaping it would be really inappropriate.

1 Like