Skip to main content
Participating Frequently
Aug 31, 2023 4:10 PM UTC
Question

QueryDeleteColumn errors out with java.lang.NegativeArraySizeException

I need help with an error I can't find an explanation for anywhere.

 

On ColdFusion 2021, I'm trying to delete a column from a query. The query for sure contains the column I am trying to delete, as you can see from the code snippet, which works otherwise when I comment QueryDeleteColumn.

 

<cftry>
	<cfset local.newColumnArray = ArrayNew(1)>
	<cfloop query="Data">
		<cfif len(Data.columName)>
			<cfset ArrayAppend(local.newColumnArray, Data.columName)>
		<cfelse>
			<cfset ArrayAppend(local.newColumnArray, otherMethod(Data.differentColumn))>
		</cfif>
	</cfloop>
	<cfset QueryAddColumn(Data,"newColumn","VarChar", local.newColumnArray)>
	<cfset QueryDeleteColumn(Data,"columName")>
<cfcatch type="any">
		<cf_mcabort message="xxx [line #cfcatch.tagContext[1].line#]: #CFCATCH.Message#"  except="#cfcatch#">
</cfcatch>
</cftry>

 

However, when I try do include that call, I get the following error:

java.lang.NegativeArraySizeException: -1
at coldfusion.sql.QueryTableMetaData.deleteColumnNameAndType(QueryTableMetaData.java:539)
at coldfusion.sql.imq.imqTable.deleteColumnnNameAndType(imqTable.java:321)
at coldfusion.sql.QueryTable.deleteColumn(QueryTable.java:705)
at coldfusion.runtime.QueryFunction.QueryDeleteColumn(QueryFunction.java:1025)
at coldfusion.runtime.CFPage.QueryDeleteColumn(CFPage.java:2508)
at cfTransactions2ecfc627721595$funcLOOKUPTRANSACTION.runFunction(xxxxxx:68)
at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:623)
at coldfusion.filter.SilentFilter.invoke(SilentFilter.java:47)
at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:516)
at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:95)
at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:463)
at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:438)
at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:681)
at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:980)
at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:762)
at coldfusion.filter.ComponentFilter.invoke(ComponentFilter.java:261)
at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:606)
at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:43)
at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
at coldfusion.filter.PathFilter.invoke(PathFilter.java:162)
at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:30)
at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:97)
at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:60)
at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
at coldfusion.xml.rpc.CFCServlet.invoke(CFCServlet.java:167)
at coldfusion.xml.rpc.CFCServlet.doGet(CFCServlet.java:318)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:311)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:46)
at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:47)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:377)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1743)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:829) 

 

My best guess is that this has to do with the query, as I use this method elsewhere with very similar code and it works fine. I've tried deleting different columns, including the one I dinamically add there, to no avail. I haven't figured out how, though.

    8 replies

    AlHolden
    Inspiring
    Feb 21, 2025 9:27 PM UTC

    It's been a year plus since the last reply, and I get the same error from an attempt to delete a column from a SP (sproc) generated cfprocresult set (Azure MS-SQL) in CF2021:

    <cfstoredproc procedure="Get_Centers" datasource="#application.datasource#" cachedwithin="#createTimespan(0,0,0,2)#">
    	<cfprocparam variable="IdClient" cfsqltype="CF_SQL_INTEGER" value="#val(struReturn.sessionStruct.client_id)#" />
    	<cfprocresult name="struReturn.data" />
    </cfstoredProc>
    <cfset queryDeleteColumn(struReturn.data,'SECRETCOL') /> <!--- NegativeArraySizeException ERROR --->

     

    My fix was a QoQ to "re-cast" the results as a query type - that CF apparently likes better:

     

    <cfstoredproc procedure="Get_Centers" datasource="#application.datasource#" cachedwithin="#createTimespan(0,0,0,2)#">
    	<cfprocparam variable="IdClient" cfsqltype="CF_SQL_INTEGER" value="#val(struReturn.sessionStruct.client_id)#" />
    	<cfprocresult name="qResults" />
    </cfstoredProc>
    <cfquery name="struReturn.data" dbtype="query">  <!--- DUMB BUT NEEDED --->
    	SELECT * FROM qResults
    </cfquery>
    <cfset queryDeleteColumn(struReturn.data,'SECRETCOL') /> <!--- WORKS --->

     

     

    Hope this helps someone.

    Translate
    BKBK
    Community Expert
    Community Expert
    Feb 22, 2025 4:14 PM UTC

    @AlHolden , With the error message

     

    java.lang.NegativeArraySizeException

     

    ColdFusion may be trying to tell you something. Chances are that, unknown to you, the query object is being modified by some underlying process.

     

    For example, your code contains an existential issue. The query object qResults is cached for just 2 seconds. So the code assumes that the query-of-query runs within 2 seconds after the stored procedure. That is a pretty tight timespan, hence an unrealistic assumption.

     

    There might be circumstances where the assumption is not true. Think, for example, of network latency between ColdFusion and the database server. There is then this fundamental question:

    • Which query object does the query of query refer to: the cached query or a newly generated query?

    That makes me ask what the point is of such a shortly lived cache. 

     

    In any case, I have already suggested a neat way to avoid any such misunderstanding. Before deleting a query-column, first test whether it exists.

     

    In your case, the code will be something like

     

    <!---
    Suggestion: Raise 'cachedWithin' to a more realistic value (10 seconds, say), to ensure that the same object is reused.
    Test whether a column exists before deleting it. If it unexpectedly doesn't exist, then an underlying process might have modified the query. 
    --->
    <cfstoredproc procedure="Get_Centers" datasource="#application.datasource#" cachedwithin="#createTimespan(0,0,0,10)#">
    	<cfprocparam variable="IdClient" cfsqltype="CF_SQL_INTEGER" value="#val(struReturn.sessionStruct.client_id)#" />
    	<cfprocresult name="qResults" />
    </cfstoredProc>
    
    <cfif queryKeyExists(qResults, "SECRETCOL")>
    	<cfset queryDeleteColumn(qResults,"SECRETCOL")>
    <cfelse>
        <!--- An underlying process has probably modified the query. Investigate. --->
        <!--- Dump any errors in the logs folder --->
        <cftry>
         <cfdump var="#qResults#" format="html" output="#server.coldfusion.rootDir#\logs\qResultsQueryDump.html">
        <cfcatch type="any">
            <cfdump var="#cfcatch#" format="html" output="#server.coldfusion.rootDir#\logs\qResultsCfcatch.html">
        </cfcatch>
        </cftry>
    </cfif>

     

     

     

    Translate
    AlHolden
    Inspiring
    Feb 22, 2025 8:38 PM UTC

    Wow, jumping in on a Satruday. Thanks @BKBK !

    Good catch, you are correct that the application of a cache appears to be the pivoting factor in this example's error.

    However, I'm not sure the time span of the cache is the issue. I've created a simplified standalone example which employs a full one day cache - and the error is still present, even when employing the "does it exist?" test first.

    Here is the "broken" version:

    <cfstoredproc procedure="Get_Centers" datasource="[redacted]" cachedwithin="#createTimespan(1,0,0,0)#">
    	<cfprocparam variable="IdClient" cfsqltype="CF_SQL_INTEGER" value="2" />
    	<cfprocresult name="qResults" />
    </cfstoredProc>
    
    <cfdump var="#qResults#" />
    <hr/>
    <cfdump var="#qResults.columnList#" />
    <hr/>
    <cfdump var="#queryKeyExists(qResults, "ADDED_IDUSERS")#" />
    <hr/>
    
    <cfif queryKeyExists(qResults, "ADDED_IDUSERS")>
    	<cfset queryDeleteColumn(qResults,'ADDED_IDUSERS') />
    </cfif>
    
    <hr/>
    <cfdump var="#qResults.columnList#" />

     Which produces this:

    Next, here is the "fixed" version:

    <cfstoredproc procedure="Get_Centers" datasource="[redacted]" cachedwithin="#createTimespan(1,0,0,0)#">
    	<cfprocparam variable="IdClient" cfsqltype="CF_SQL_INTEGER" value="2" />
    	<cfprocresult name="qResults" />
    </cfstoredProc>
    
    <!--- ADDED --->
    <cfquery name="qResults" dbtype="query">
    	SELECT * FROM qResults
    </cfquery>
    
    <cfdump var="#qResults#" />
    <hr/>
    <cfdump var="#qResults.columnList#" />
    <hr/>
    <cfdump var="#queryKeyExists(qResults, "ADDED_IDUSERS")#" />
    <hr/>
    
    <cfif queryKeyExists(qResults, "ADDED_IDUSERS")>
    	<cfset queryDeleteColumn(qResults,'ADDED_IDUSERS') />
    </cfif>
    
    <hr/>
    <cfdump var="#qResults.columnList#" />

    Here's the error-free result, after the ADDED interim step "turn this query into a query" step

    So to me, it seems a bit buggy.  The application of the cache seems to affect some internal column array, no matter how long the life span of the cache. The queryKeyExists function considers the column extant, while the queryDeleteColumn disagrees, perhaps using a different test.

    Can you audit my logic? Thanks again.

     

    Translate
    BKBK
    Community Expert
    Community Expert
    Mar 24, 2024 12:45 PM UTC

    The query is an object, and you have been manipulating it. So, before calling queryDeleteColumn, you have to first test for the existence of the column:

     

    <cfif queryKeyExists(Data, "columName")>
    	<cfset queryDeleteColumn(Data,"columName")>
    </cfif>
    Translate
    sharp_quirk16B6
    Inspiring
    Mar 11, 2024 3:02 PM UTC

    I received this exact same error message.  I am also using CF2021, fully patched.  Did you ever find a solution or workaround?

     

    In my case I am calling queryExecute() to run a SQL statement.  My T-SQL code utilizes OFFET-FETCH and CTEs to return the total number of records in a column named [totalCount].  From the CF side, this should be a basic query result.  I get the first value of [totalCount] and then try to delete that column before returning the results:

    local.data = queryExecute(sql=sql, params={ offset:arguments.offset, limit:arguments.limit })
    local.recordcount = local.data.totalCount
    queryDeleteColumn(local.data, "totalCount")

     

    Translate