Space missing when cfquery in function

Description

Odd error with white space in cfquery when called from a function in a cfc. This example dumps a table with no problem:

<cfdump var="#getQuery(orderby="lock_name",sortOrder="asc")#" > <cffunction name="getQuery" access="public" output="false" returntype="query"> <cfargument name="orderby" type="string" required="false" /> <cfargument name="sortDirection" type="string" required="false" default="asc" /> <cfquery name="qList" datasource="testDSN"> SELECT * FROM tbllock WHERE 0=0 <cfif structKeyExists(arguments, "orderby") and len(arguments.orderBy)> ORDER BY #arguments.orderby# #arguments.sortDirection# </cfif> </cfquery> <cfreturn qList /> </cffunction>

Put the function in a cfc and call it from a cfm and it seems to strip the white space between orderby and sortDirection which gives a sql error “Unknown column 'lock_nameasc' in 'order clause'“

test.cfm

<cfset newTest = createObject("test")> <cfdump var="#newTest.getQuery(orderby="lock_name",sortOrder="asc")#" >

test.cfc

<cfcomponent singleton displayname="test" output="false"> <cffunction name="getQuery" access="public" output="false" returntype="query"> <cfargument name="orderby" type="string" required="false" /> <cfargument name="sortDirection" type="string" required="false" default="asc" /> <cfquery name="qList" datasource="testDSN"> SELECT * FROM tbllock WHERE 0=0 <cfif structKeyExists(arguments, "orderby") and len(arguments.orderBy)> ORDER BY #arguments.orderby# #arguments.sortDirection# </cfif> </cfquery> <cfreturn qList /> </cffunction> </cfcomponent>
ortus.boxlang.runtime.types.exceptions.DatabaseException: Unknown column 'lock_nameasc' in 'order clause' at ortus.boxlang.runtime.jdbc.PendingQuery.executeStatement(PendingQuery.java:626) at ortus.boxlang.runtime.jdbc.PendingQuery.execute(PendingQuery.java:572) at ortus.boxlang.runtime.jdbc.PendingQuery.execute(PendingQuery.java:534) at ortus.boxlang.runtime.components.jdbc.Query._invoke(Query.java:148) at ortus.boxlang.runtime.components.Component.invoke(Component.java:145) at ortus.boxlang.runtime.components.ComponentDescriptor.invoke(ComponentDescriptor.java:224) at ortus.boxlang.runtime.context.BaseBoxContext.invokeComponent(BaseBoxContext.java:506) at boxgenerated.boxclass.testsuite.Test$cfc$Func_getQuery._invoke(/app/survey/webroot/testSuite/test.cfc:7) at ortus.boxlang.runtime.types.Function.invoke(Function.java:198) at ortus.boxlang.runtime.runnables.BoxClassSupport.dereferenceAndInvoke(BoxClassSupport.java:443) at boxgenerated.boxclass.testsuite.Test$cfc.dereferenceAndInvoke(/app/survey/webroot/testSuite/test.cfc) at ortus.boxlang.runtime.interop.DynamicInteropService.dereferenceAndInvoke(DynamicInteropService.java:2076) at ortus.boxlang.runtime.interop.DynamicInteropService.dereferenceAndInvoke(DynamicInteropService.java:2052) at ortus.boxlang.runtime.dynamic.Referencer.getAndInvoke(Referencer.java:136) at boxgenerated.templates.testsuite.Test$cfm._invoke(/app/survey/webroot/testSuite/test.cfm:17) at ortus.boxlang.runtime.runnables.BoxTemplate.invoke(BoxTemplate.java:60) at ortus.boxlang.runtime.context.BaseBoxContext.includeTemplate(BaseBoxContext.java:641) at ortus.boxlang.runtime.application.ApplicationClassListener.onRequest(ApplicationClassListener.java:105) at ortus.boxlang.web.WebRequestExecutor.execute(WebRequestExecutor.java:129) at ortus.boxlang.servlet.BoxLangServlet.service(BoxLangServlet.java:113) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129) at runwar.servlet.RegexPathInfoFilter.doFilter(RegexPathInfoFilter.java:57) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:67) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at com.intergral.fusionreactor.j2ee.jakarta.filterchain.WrappedFilterChain.doFilter(WrappedFilterChain.java:132) at com.intergral.fusionreactor.j2ee.jakarta.filter.FusionReactorRequestHandler.doNext(FusionReactorRequestHandler.java:705) at com.intergral.fusionreactor.j2ee.jakarta.filter.FusionReactorRequestHandler.doHttpServletRequest(FusionReactorRequestHandler.java:263) at com.intergral.fusionreactor.j2ee.jakarta.filter.FusionReactorRequestHandler.doFusionRequest(FusionReactorRequestHandler.java:126) at com.intergral.fusionreactor.j2ee.jakarta.filter.FusionReactorRequestHandler.handle(FusionReactorRequestHandler.java:743) at com.intergral.fusionreactor.j2ee.jakarta.filter.FusionReactorCoreFilter.doFilter(FusionReactorCoreFilter.java:35) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at com.intergral.fusionreactor.j2ee.jakarta.filterchain.WrappedFilterChain.doFilter(WrappedFilterChain.java:69) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) at java.base/java.lang.reflect.Method.invoke(Method.java:580) at com.intergral.fusionreactor.agent.filter.FusionReactorStaticFilter.doFilterJakarta(FusionReactorStaticFilter.java:282) at com.intergral.fusionreactor.agent.pointcuts.jakarta.JakartaNewFilterChainPointCut$1.invoke(JakartaNewFilterChainPointCut.java:48) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at runwar.undertow.SSLCertHeaderHandler.handleRequest(SSLCertHeaderHandler.java:171) at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:117) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77) at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.SendErrorPageHandler.handleRequest(SendErrorPageHandler.java:52) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:276) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135) at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:132) at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48) at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:256) at io.undertow.servlet.handlers.ServletInitialHandler.handleRequest(ServletInitialHandler.java:176) at io.undertow.server.handlers.HttpContinueReadHandler.handleRequest(HttpContinueReadHandler.java:69) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at runwar.undertow.WelcomeFileHandler.handleRequest(WelcomeFileHandler.java:49) at io.undertow.server.handlers.PathHandler.handleRequest(PathHandler.java:104) at runwar.undertow.SiteDeployment$1.handleRequest(SiteDeployment.java:169) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:141) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:141) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.DisallowedMethodsHandler.handleRequest(DisallowedMethodsHandler.java:62) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.SetHeaderHandler.handleRequest(SetHeaderHandler.java:90) at io.undertow.predicate.PredicatesHandler.handleRequest(PredicatesHandler.java:113) at io.undertow.server.handlers.encoding.EncodingHandler.handleRequest(EncodingHandler.java:72) at runwar.undertow.LifecyleHandler.handleRequest(LifecyleHandler.java:148) at runwar.undertow.SiteDeployment$4.handleRequest(SiteDeployment.java:360) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:393) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:859) at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18) at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513) at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1538) at org.xnio.XnioWorker$WorkerThreadFactory$1$1.run(XnioWorker.java:1282) at java.base/java.lang.Thread.run(Thread.java:1583) Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'lock_nameasc' in 'order clause' at mysql//com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:112) at mysql//com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:113) at mysql//com.mysql.cj.jdbc.StatementImpl.executeInternal(StatementImpl.java:829) at mysql//com.mysql.cj.jdbc.StatementImpl.execute(StatementImpl.java:686) at com.intergral.fusionreactor.jdbc.StatementSurrogate.execute(StatementSurrogate.java:70) at com.zaxxer.hikari.pool.ProxyStatement.execute(ProxyStatement.java:103) at com.zaxxer.hikari.pool.HikariProxyStatement.execute(HikariProxyStatement.java) at ortus.boxlang.runtime.jdbc.PendingQuery.executeStatement(PendingQuery.java:605) ... 108 more

Activity

Brad WoodMarch 14, 2025 at 6:23 PM

Oops, good catch. I was looking for the first ancestor AST node of type “Component” and checking the name to see if it was a query, document, or savecontent. But the loop component was the closest ancestor of type component and insulated the whitespace so it didn’t “see” the query. I modified this logic to keep climbing the ancestors in the tree.

Doug CainMarch 14, 2025 at 10:56 AM

Looks like there are some more variations that break, we have a cfquery with a loop in it which errors with Unknown column 'lock_nameasc' in 'order clause'

test.cfm

<cfset newTest = createObject("test")> <cfdump var="#newTest.getQuery(orderby="lock_name,lock_timestamp",sortOrder="asc")#" >

test.cfc

<cfcomponent singleton displayname="test" output="true"> <cffunction name="getQuery" returntype="query"> <cfargument name="orderby" type="string" required="false" /> <cfargument name="sortDirection" type="string" required="false" default="asc" /> <cfquery name="qList" datasource="rubix_any3survey"> SELECT * FROM tbllock WHERE 0=0 ORDER BY lock_status DESC, <cfif structKeyExists(arguments, "orderby") and len(arguments.orderBy)> <cfloop list="#arguments.orderby#" item="item"> #trim(item)# #arguments.sortOrder#, </cfloop> </cfif> id </cfquery> <cfreturn qList /> </cffunction> </cfcomponent>

Doug CainMarch 14, 2025 at 9:16 AM

sounds like a tricky one to track down, thanks for sorting brad.

Brad WoodMarch 13, 2025 at 11:30 PM

This was due to an attempt at optimizing the AST by removing stand-alone buffer output nodes which had nothing but whitespace in them. In this case, the code

#arguments.orderby# #arguments.sortDirection#

is the buffer output nodes (we can’t combine them, or they will get appended out of order if the expressions also emit output to the buffer).

  • order by

  • the space

  • sort direction

So the space was getting discarded because it was in a class and only had whitespace. This optimization was made for the box pretty printer class and since we convert classes to script in BoxLang and didn’t want a bunch of writeOutput( " " ) calls output nothing but the whitespace from the original tag code.

I added in some caveats for blank buffer output nodes inside of cfquery, cfsavecontent, and cfdocument, but this still prolly still need further work in future for CF code that has functions that output actual HTML from inside of functions.

Doug CainMarch 13, 2025 at 8:51 AM

I set whitespaceManagement": "false" in cfconfig and same problem - is there another way of setting white space management in boxlang?

Fixed
Pinned fields
Click on the next to a field label to start pinning.

Details

Assignee

Reporter

Fix versions

Priority

Sentry

Created March 11, 2025 at 10:16 PM
Updated March 14, 2025 at 6:24 PM
Resolved March 13, 2025 at 11:30 PM

Flag notifications