public void ProcessFilters(SqlString sql, ISessionImplementor session) { filteredParameterValues = new List<object>(); filteredParameterTypes = new List<IType>(); filteredParameterLocations = new List<int>(); if (session.EnabledFilters.Count == 0 || sql.ToString().IndexOf(ParserHelper.HqlVariablePrefix) < 0) { processedSQL = sql.Copy(); return; } Dialect.Dialect dialect = session.Factory.Dialect; string symbols = ParserHelper.HqlSeparators + dialect.OpenQuote + dialect.CloseQuote; var result = new SqlStringBuilder(); int originalParameterIndex = 0; // keep track of the positional parameter int newParameterIndex = 0; _adjustedParameterLocations = new Dictionary<int, int>(); foreach (var part in sql.Parts) { if (part is Parameter) { result.AddParameter(); // (?) can be a position parameter or a named parameter (already substituted by (?), // but only the positional parameters are available at this point. Adding them in the // order of appearance is best that can be done at this point of time, but if they // are mixed with named parameters, the order is still wrong, because values and // types for the named parameters are added later to the end of the list. // see test fixture NH-1098 _adjustedParameterLocations[originalParameterIndex] = newParameterIndex; originalParameterIndex++; newParameterIndex++; continue; } var tokenizer = new StringTokenizer((string) part, symbols, true); foreach (var token in tokenizer) { if (token.StartsWith(ParserHelper.HqlVariablePrefix)) { string filterParameterName = token.Substring(1); object value = session.GetFilterParameterValue(filterParameterName); IType type = session.GetFilterParameterType(filterParameterName); // If the value is not a value of the type but a collection of values... if (value != null && !type.ReturnedClass.IsAssignableFrom(value.GetType()) && // Added to fix NH-882 typeof (ICollection).IsAssignableFrom(value.GetType())) { var coll = (ICollection) value; int i = 0; foreach (var elementValue in coll) { i++; int span = type.GetColumnSpan(session.Factory); if (span > 0) { result.AddParameter(); filteredParameterTypes.Add(type); filteredParameterValues.Add(elementValue); filteredParameterLocations.Add(newParameterIndex); newParameterIndex++; if (i < coll.Count) { result.Add(", "); } } } } else { int span = type.GetColumnSpan(session.Factory); if (span > 0) { result.AddParameter(); filteredParameterTypes.Add(type); filteredParameterValues.Add(value); filteredParameterLocations.Add(newParameterIndex); newParameterIndex++; } } } else { result.Add(token); } } } processedSQL = result.ToSqlString(); }