Function [getColumnType] does not exist in the Array

Hi! Let me preface by saying I’m not a programmer. I am an unfortunate sysadmin stuck with the task of migrating a couple of simple, home-grown, internal-use web tools from an old ACF server to something else with a supported OS. We don’t have a programmer anymore to support this, the guy who wrote it left years ago.

The tool just queries a DB, and formats the result as a spreadsheet with headers. Other CF apps on the same server have run fine on Lucee, but this particular one wants to format the data. It seems to be tripping up on the TIMESTAMP/DataFormat area, specifically on cfif #rsAll.getColumnTypeName(metadata.getColumnType(index))#

Since this code works fine on the old ACF server, and even on newer ACF systems I was running under an eval, I’m guessing it’s one of the Lucee/ACF incompatibilities. I want to say it’s the arrays passing by value vs reference issue. But since the code isn’t calling cffunction anywhere, I don’t see where I’d put the cfargument to set the passby to value. Again, pretty out of my depth here.

The code makes a query (rsAll) which then gets passed to a loop to format the columns. It’s pretty simple, but can’t get it to work. I’d appreciate someone to point me at what I might be able to change in the code to make it compliant with Lucee. Code below, with the error under it.

Lucee 6.2 (although I tried 6.1 and 5.4, all the same issue) on Linux.

<cfquery name="rsAll" datasource="foo">
query snipped
</cfquery>
<cfset ColumnNames = ListToArray(rsAll.ColumnList)>
<cfset metadata = rsAll.getMetaData()>
<!--- Send the headers --->
<cfheader name="Content-type" value="text/xml">
<cfheader name="Pragma" value="public">
<cfheader name="Cache-control" value="private">
<cfheader name="Expires" value="-1">
<cfsetting enablecfoutputonly="no"><cfsetting enablecfoutputonly="no"><?xml version="1.0" encoding="utf-8"?>

<root>
  <cfoutput query="rsAll">
  <row>
    <cfloop from="1" to="#rsAll.getColumnCount()#" index="index"><cfset column = LCase(rsAll.getColumnName(index))><cfset value = rsAll[column][rsAll.CurrentRow]>
            <cfif #rsAll.getColumnTypeName(metadata.getColumnType(index))# equal "TIMESTAMP"><cfset value = DateFormat(value,"mm/dd/yyyy")&" "&TimeFormat(value,"HH:mm:ss")></cfif>
      <cfif value IS ""><#column# /><cfelse><#column# type="#rsAll.getColumnTypeName(metadata.getColumnType(index))#" name="#rsAll.getColumnName(index)#" ><![CDATA[#value#]]></#column#></cfif>
         </cfloop>
  </row>
    </cfoutput>
</root>

Error:

lucee.runtime.exp.ExpressionException: The function [getColumnType] does not exist in the Array. Available functions are [append, avg, clear, contains, containsNoCase, delete, deleteAt, deleteNoCase, duplicate, each, every, filter, find, findAll, findAllNoCase, findNoCase, first, getMetadata, indexExists, insertAt, isDefined, isEmpty, last, len, map, max, median, merge, mid, min, numberFormat, pop, prepend, push, reduce, removeDuplicates, resize, reverse, set, shift, slice, some, sort, splice, sum, swap, toJson, toList, toStruct, unshift].
 at lucee.runtime.type.util.MemberUtil.call(MemberUtil.java:190)
 at lucee.runtime.type.util.ArraySupport.call(ArraySupport.java:322)
 at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:797)
 at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:2050)
 at foo_cfm$cf$1.call(/bar/foo.cfm:63)
 at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1093)
 at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:987)
 at lucee.runtime.listener.ClassicAppListener._onRequest(ClassicAppListener.java:63)
 at lucee.runtime.listener.MixedAppListener.onRequest(MixedAppListener.java:42)
 at lucee.runtime.PageContextImpl.execute(PageContextImpl.java:2785)
 at lucee.runtime.PageContextImpl._execute(PageContextImpl.java:2772)
 at lucee.runtime.PageContextImpl.executeCFML(PageContextImpl.java:2743)
 at lucee.runtime.engine.Request.exe(Request.java:45)
 at lucee.runtime.engine.CFMLEngineImpl._service(CFMLEngineImpl.java:1099)
 at lucee.runtime.engine.CFMLEngineImpl.serviceCFML(CFMLEngineImpl.java:1056)
 at lucee.loader.engine.CFMLEngineWrapper.serviceCFML(CFMLEngineWrapper.java:97)
 at lucee.loader.servlet.CFMLServlet.service(CFMLServlet.java:51)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:623)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:199)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144)
 at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144)
 at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168)
 at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
 at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481)
 at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130)
 at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
 at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
 at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:346)
 at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:388)
 at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
 at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:928)
 at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1791)
 at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
 at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1190)
 at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
 at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
 at java.base/java.lang.Thread.run(Unknown Source)

try this

<cfscript>
    rsAll = queryNew("id,name,updated","numeric,varchar,timestamp");
    
    queryAddRow(rsall);
    querySetCell(rsAll, "id", 1);
    querySetCell(rsAll, "name", "Lucee");
    querySetCell(rsAll, "updated", now());
    dump(rsAll);
    
    meta = getMetaData(rsAll);
    dump(meta);
</cfscript>
<cfsavecontent variable="out">
    <root>
        <cfoutput query="rsAll">
            <cfloop array="#meta#" item="col">
                <cfset value=rsAll[col.name]>
            	<cfif col.typeName == "TIMESTAMP">
            		<cfset value = DateFormat( value ,"mm/dd/yyyy")&" "&TimeFormat(value,"HH:mm:ss")>
            	</cfif>
            	<cfif value IS "">
            		<#col.name#/>
            	<cfelse>
            		<#col.name# type="#col.typeName#" name="#col.name#" ><![CDATA[#value#]]></#col.name#>
            	</cfif>
            </cfloop>
        </cfoutput>
    </root>
</cfsavecontent>

<cfoutput>#htmlCodeFormat(out)#</cfoutput>
1 Like

Well, that’s progress for sure, thanks! It’s still not displaying anything on the screen, but at least now in the Chrome debug console I can see the results of the query are making it to the browser and it’s a 200 status code, versus the 500 it was getting when it was throwing the error. The data is there but something is off about the formatting so it won’t display. There’s another file that calls the one with the query in it I posted above, which sets the CSS. It might be expecting the results to look different. Let me poke around at that a bit more.

Here’s another thought: look closely at that data shown in the chrome “debugging” (do you mean perhaps the dev tools and its network tab?) Make sure you’re seeing ONLY xml as the result. You may be seeing some html also, like Lucee debug output…which maybe you’d not seen in cf if you’d not enabled it in the admin.

Since you say your goal is to show a spreadsheet as a result, that can indeed be done if the browser is configured to pass such an xml response to something like MS excel or Libre/Open Office Calc, which can render that xml as a spreadsheet. But it does need to be ONLY xml. :slight_smile:

All this just a guess, but let us know if it helps or maybe you’ll find it’s indeed something about css or the like.

Got it working fully! Evidently whatever was ingesting the XML that this generates, was expecting the column names to be lowercase. In my original code above you can see there’s a cfset to do that. I put that back into the code that works, and now everything displays the way it should.

And yes, I meant the dev tools/network tab.

Thanks again!

1 Like