SQL query result 'url' object not string?

Should I open a lucce JIRA ?

I would expect a query to return strings or numbers , not the java object that it does when a column is named “url”

I’m porting legacy CF11 to lucee , one application has an Oracle query that SELECTs a column “url” , in the CF11 result set “url” type is a string. Later in the code, we interpolate the url string. In Lucee, the “url” type is a lucee.runtime.type.scope.URLImpl. When we try to interpolate it, an exception is thrown to the effect that you can’t interoplate a complex struct

CODE:

<cfquery name="url_as_object" datasource="admin_console">
        SELECT url FROM content WHERE ROWNUM <= 1
</cfquery>
<cfset my_str="a string">
<cfloop query="url_as_object">
<cfoutput>
<pre>
        expected data for url:     #getMetadata(my_str)#
        actual meta data for url: #getMetadata(url)#
</pre>
</cfoutput>
</cfloop>

OUTPUT:

	expected data for url:     class java.lang.String 
	actual meta data for url: class lucee.runtime.type.scope.URLImpl

OS: ubuntu 22.04n
Java Version: OpenJDK Runtime Environment (build 11.0.21+9-post-Ubuntu-0ubuntu122.04)
Tomcat Version: 9.0.58-1ubuntu0.1
Lucee Version: 5.4.4.38

While I’ll let others debate whether you should open a ticket, I’ll share something to save others saying it or looking into it. I also offer a workaround (that you may already have considered), as well as a trycf gist to demonstrate the issue and workaround.

First, I’ll note that this code Dan offers returns string for that URL var not only in CF11 but even 2023. Is that a bug in CF?

As some will want to note, url is indeed a reserved word in CFML, referring to the url variable scope. But note that Dan is referring to it within the cfloop over a query, which has url as a column name.

THAT is in fact the different behavior CF has which Lucee currently does not implement: it switches (only while in such a query loop) to letting that variable name implicitly refer to the query column. I’d never noticed this before, but again I have now confirmed it.

It may be worth noting, Dan, that CF would ALSO treat that url var differently outside the loop (whether before OR AFTER it), where the getmetadata would show it to have a similar “type” for that URL reference: class coldfusion.filter.UrlScope. (And a dump of it would show any querystring passed in to the request.)

As for the workaround, until Lucee may change the behavior to suit his previous experience with CF, you can solve the problem by changing the select statement to use an alias for the url col (select url as url2). Then if you refer to THAT url2 var you’ll find it renders as the string you expect.

Finally, here is that trycf gist that has his code, modified to use a simulated query versus a real DSN (done via a querynew and QofQ which doesn’t even need a row of data to demonstrate the issue). And FWIW I show the dumps and getmetadata’s before/after the query loop to demonstrate my point above. I also offer the proposed workaround in comments.

HTH

2 Likes

Great post. Thanks @carehart. I’d also think about what happens if you use a columname such as “SELECT variables, application, request, form FROM someTable”? I have always tried to avoid such reserved names everywhere, but the name url is such a name to be easily used as a varaible name anywhere else.

Use #url_as_object.url# instead of #url#.

<cfloop query=“url_as_object”>
#url_as_object.url#<br>
</cfloop>

1 Like

Michele, it seems you’re posing that as a stylistic preference, right? Not as having some impact on the concern Dan was raisng?

And thanks, Andreas, for the kind regards and follow-up.

Scoping the variable reference, as Michele suggested, should result in the reference resolving to the column’s value, not the global url scope. I haven’t tried it, but I’m pretty sure it is another valid workaround.

2 Likes

I confirm that the suggestion of @Michele_Scaletta solves the problem. @Dan_MacNeil you should try it.

I also recommend always scoping the columns in the loop with the variable name (e.g. myQuery.myColumn). In addition to avoiding this kind of problem with reserved words, it is much clearer for the developer to see where the variable comes from. For example, if in the loop we display a column coming from the query and another variable defined previously, we clearly see the origin of each.

2 Likes

@TonyMonast

Thanks for the nudge, Before posting I changed “SELECT url” to “SELECT url_str” and moved on to the next thing which worked and seems clearest, so I’m all set.

I probably should have updated thread, but erred on the side of keeping the noise low.

1 Like