<cfsilent>
	<!--- build query filter string --->
	<!--- пустые и некорректные значения параметров вызвыают пропуск параметра --->
	<cfparam name="ATTRIBUTES.filter" type="struct"/>
	
	<cfif thisTag.executionMode IS "end" OR !thisTag.hasEndTag>

		<cfset queryFilter="">
		<cfloop collection=#ATTRIBUTES.filter# item="item">
		
			<cftry>
				<cfset fltr=structFind(ATTRIBUTES.filter,item)>
				
				<!--- checks and preformatting --->
				<cfset skip=false><!--- *** неуклюжая имитация continue --->
				
				<cfswitch expression=#fltr.ftype#>
					<cfcase value="numeric">
						<cfif NOT isNumeric(fltr.val)><cfset skip=true></cfif>
						<cfset val=fltr.val>
					</cfcase>
					
					<cfcase value="date">
						<cfif NOT isDate(fltr.val)><cfset skip=true></cfif>
						<cfset val=fltr.val>
					</cfcase>
					
					<cfcase value="string">
						<!--- special case --->
						<!--- escape single quotes for security--->
						<cfset val=replace(fltr.val,"'","''", "ALL")>
						<!--- elclose in single quotes --->
						<cfif NOT fltr.compare EQ "LIKE%"><!---*** криво --->
						<cfset val="'#val#'">
						</cfif>
					</cfcase>
					
					<cfcase value="list"><!--- *** для простоты листы разных типов не различаются, что не есть хорошо, повышается риск инъекциии --->		
						<!--- данные списка хранятся в виде массива, чтобы исключить проблемы с запятыми--->
						<cfif arrayLen(fltr.val) EQ 0>
							<cfset skip=true>
						<cfelse>
							<cfset isNumericList=true>
							
							<!--- test: maybe list is of numbers--->
							<cfloop array=#fltr.val# index="item">	
								<cfif NOT isNumeric(#item#)>
									<cfset isNumericList=false/>
									<cfbreak/>
								</cfif>
							</cfloop>
							<!---<cfoutput>#isNumericList#</cfoutput>--->
							
							<cfset lst="">			
							<cfif isNumericList>
								<cfloop array=#fltr.val# index="item">
									<cfset lst=listAppend(lst, item)><!---<cfoutput>**#item#</cfoutput>	--->		
								</cfloop>	
							<cfelse>				
								<cfloop array=#fltr.val# index="item"><!--- escape single quotes to prevent SQL injection --->
									<cfset cleanItem=replace(item, "'", "''", "ALL")>
									<cfset lst=listAppend(lst, "'#cleanItem#'")><cfoutput>#item#</cfoutput>
								</cfloop>
							</cfif>
							<cfset val=lst> 
							<!---<cfoutput>#val#</cfoutput>--->
						</cfif>	
					</cfcase>
					
					<cfdefaultcase>
						<cfset skip=true>
					</cfdefaultcase>
				</cfswitch>
			
				<!--- query building --->
				<!--- потенциально опасно --->
				<!--- *** протестировать на sql injection --->
				<cfif NOT skip> 
					<cfif structKeyExists(fltr,"expression") AND len(fltr.expression)>
						<cfset cmpExpr=replace(fltr.expression,"?","#val#","ALL")/>						
					<cfelse>	
						<cfswitch expression=#fltr.compare#>
							<cfcase value="EQ">
								<cfset cmpExpr="#fltr.field#=#val#">
							</cfcase>
							<cfcase value="NE,NEQ">
								<cfset cmpExpr="NOT #fltr.field#=#val#">
							</cfcase>
							<cfcase value="LE">
								<cfset cmpExpr="#fltr.field#<=#val#">
							</cfcase>
							<cfcase value="LT">
								<cfset cmpExpr="#fltr.field#<#val#">
							</cfcase>
							<cfcase value="GE">
								<cfset cmpExpr="#fltr.field#>=#val#">
							</cfcase>
							<cfcase value="GT">
								<cfset cmpExpr="#fltr.field#>#val#">
							</cfcase>
							<cfcase value="IN">
								<cfset cmpExpr="#fltr.field# IN (#val#)">
							</cfcase>
							<cfcase value="LIKE">
								<cfset cmpExpr="#fltr.field# LIKE #val#">
							</cfcase>
							<cfcase value="LIKE%">
								<cfset cmpExpr="#fltr.field# LIKE '%#val#%'">
							</cfcase>
							<cfdefaultcase>
								<cfset skip=true>
							</cfdefaultcase>
						</cfswitch>	
					</cfif>
				</cfif>
				<cfif NOT skip>
					<cfset queryFilter="#queryFilter# AND #cmpExpr#"> 
				</cfif>			
							
				<cfcatch type="ANY"></cfcatch>				
			</cftry>
		</cfloop>

		<cfif isDefined("ATTRIBUTES.output")>
			<cfset "CALLER.#ATTRIBUTES.output#"=preserveSingleQuotes(queryFilter)/>
		<cfelse>
			<cfset thisTag.generatedContent=preserveSingleQuotes(queryFilter)/>
		</cfif>

	</cfif>
</cfsilent>