We had an interesting problem when migrating to the PS2 version of jdeveloper. All of our QBE table filters that previously were case insensitive became case sensitive.
ADF supports case-insensitive queries but it relies on use of the UPPER() function to wrap the criteria and column selection. We made design decisions a long time ago, that (A) the business data would not be converted to all upper case, and (B) the application search screens would not convert user criteria to upper case. To make all searches case-insensitive, the application use Oracle’s case-insensitive string comparison feature NLS_COMP=LINGUISTIC and NLS_SORT=BINARY_CI (where CI means case-insensitive). Further, to support indexed case-insensitive searches, the data modeler added linguist-sort indexes on all indexed character strings. That works fine for the “=” operator but we found out it does not work for the LIKE operator. I understand that this has been fixed in the 11g database. Unfortunately our 11G front-end is connected to a 10g database so filtering using the like operator will invalidate the indexes and produce a full table scan. Furthermore, the use of the UPPER() function on the table column will invalidate the linguistic sort index so we can't use the ADF way of making filters be case insensitive.
The reason filters on tables became case sensitive in PS2 was that even though the database was case insensitive by default, ADF would perform an in-memory filter immediately after executing the query and the in-memory filter, being case sensitive would remove all of the non-matching rows from the result set. The fix for this was a little tricky. All of our view objects inherit from a custom base class we created. In this class we have overridden the getViewCriteraClause(boolean forQuery) method. This method is called whenever ADF is about to apply view criteria (i.e. filter) for either a database or a in-memory query. It conveniently lets you know which type (forQuery) it is requesting. So now all we need to do is return null when forQuery==false and no criteria will be applied to in-memory filters. But what if we actually want to perform in-memory filtering? Well, we can check the query mode to determine if the query is a "database only" query and no in-memory filtering should be performed. The problem caused in PS2 was because ADF was performing this in-memory filter even though the query mode had not been set to do so. Therefore we can detect this condition and only allow in-memory filtering when the view's query mode is set to do so.
In the example code below, I'm allowing the in-memory filter to occur but simply calling vc.setUpperColumns(true); to put the UPPER() clause around the in-memory filter making it case insensitive. I want to do just the opposite when the query is bound for the database. There is one section of code added there to support date filters where we skip the in-memory filter all together by returning null. I'll talk about that in a later blog.