Saturday, July 4, 2009

QoQ: Invalid Column Name Hack

I saw a question the other day about how to rename query columns with invalid names. Now in the poster's case, renaming really was not needed. Like most query ills it was solved with a simple bit of array notation: #queryName["column-name"][rowNumber]#

But in the process I did stumble upon another way to rename a column. In a pinch, you can use QueryAddColumn() to make a copy of it under a new name. Just pass in a reference to the query column in place of the array of values. Though this verges on the undocumented, it does work with both MX7 and CF8:

<cfset queryAddColumn(myQuery, "BetterColumnName", myQuery["Awful-Column-Name"]) />

Why does it work?
When you add a column with the QueryAddColumn() function, the values are passed in as an array. If you take a look at that function internally, you will see that the argument type is actually a java.util.List

<cfset funcObject = createObject("java", "coldfusion.runtime.QueryFunction")>
<cfdump var="#funcObject#" label="Query Functions">

Since ColdFusion arrays are java.util.List objects internally, that makes sense. But that also means that you can pass in any java.util.List object.

Now if you create a query, and examine one of its columns, you will discover the query column is also a java.util.List object. That means the QueryAddColumn() function will accept it the same way it would a ColdFusion array object.

<cfset myQuery = QueryNew("SomeColumn")/>

<b>Query Column Class:</b> #myQuery.SomeColumn.getClass().name#<br/>
<cfset interfaces = myQuery.SomeColumn.getClass().getInterfaces() />
<!--- Show the interfaces this class impements --->
<cfloop array="#interfaces#" index="inter">
Implements: <cfdump var="#inter.getName()#" label="Interface"/><br/>

So there you have it. Again, this is not documented behavior. But I thought it was an interesting find nonetheless.

Related Entry: QoQ: Invalid column Name Hack (Follow-up)


  © Blogger templates The Professional Template by 2008

Header image adapted from atomicjeep