Hi,
Assuming those queries which are all the same except the UPPER calls:
# Case (1) SELECT COUNT($1) FROM com.lexware.vereinsverwaltung.verein.mitglied.Mitglied $1 LEFT JOIN $1.mitgliedschaft $2 LEFT JOIN $1.profile $3 LEFT JOIN $3.organisation $4 LEFT JOIN $1.postalAddresses $5 LEFT JOIN $1.communication $6 WHERE (((NOT (($2 IS NOT NULL) AND ($2.austritt IS NOT NULL) AND ($2.austritt<=CURRENT_DATE)))) AND (((($3 IS NOT NULL) AND ($4 IS NOT NULL) AND ($4.name IS NOT NULL) AND ($4.name LIKE '%81%')) OR (($5 IS NOT NULL) AND ($5.postalCode IS NOT NULL) AND ($5.postalCode LIKE '%81%')) OR (($5 IS NOT NULL) AND ($5.streetNumber IS NOT NULL) AND ($5.streetNumber LIKE '%81%')) OR (($6 IS NOT NULL) AND ($6.cellphone IS NOT NULL) AND ($6.cellphone LIKE '%81%')) OR (($5 IS NOT NULL) AND ($5.street IS NOT NULL) AND ($5.street LIKE '%81%')) OR (($5 IS NOT NULL) AND ($5.city IS NOT NULL) AND ($5.city LIKE '%81%')) OR (($3 IS NOT NULL) AND ($3.lastName IS NOT NULL) AND ($3.lastName LIKE '%81%')) OR (($6 IS NOT NULL) AND ($6.email IS NOT NULL) AND ($6.email LIKE '%81%')) OR (($3 IS NOT NULL) AND ($3.firstName IS NOT NULL) AND ($3.firstName LIKE '%81%')) OR (($6 IS NOT NULL) AND ($6.fax IS NOT NULL) AND ($6.fax LIKE '%81%')) OR (($6 IS NOT NULL) AND ($6.phone IS NOT NULL) AND ($6.phone LIKE '%81%'))))) # Case (2) SELECT COUNT($1) FROM com.lexware.vereinsverwaltung.verein.mitglied.Mitglied $1 LEFT JOIN $1.mitgliedschaft $2 LEFT JOIN $1.profile $3 LEFT JOIN $3.organisation $4 LEFT JOIN $1.postalAddresses $5 LEFT JOIN $1.communication $6 WHERE (((NOT (($2 IS NOT NULL) AND ($2.austritt IS NOT NULL) AND ($2.austritt<=CURRENT_DATE)))) AND (((($3 IS NOT NULL) AND ($4 IS NOT NULL) AND ($4.name IS NOT NULL) AND (UPPER($4.name) LIKE UPPER('%81%'))) OR (($5 IS NOT NULL) AND ($5.postalCode IS NOT NULL) AND (UPPER($5.postalCode) LIKE UPPER('%81%'))) OR (($5 IS NOT NULL) AND ($5.streetNumber IS NOT NULL) AND (UPPER($5.streetNumber) LIKE UPPER('%81%'))) OR (($6 IS NOT NULL) AND ($6.cellphone IS NOT NULL) AND (UPPER($6.cellphone) LIKE UPPER('%81%'))) OR (($5 IS NOT NULL) AND ($5.street IS NOT NULL) AND (UPPER($5.street) LIKE UPPER('%81%'))) OR (($5 IS NOT NULL) AND ($5.city IS NOT NULL) AND (UPPER($5.city) LIKE UPPER('%81%'))) OR (($3 IS NOT NULL) AND ($3.lastName IS NOT NULL) AND (UPPER($3.lastName) LIKE UPPER('%81%'))) OR (($6 IS NOT NULL) AND ($6.email IS NOT NULL) AND (UPPER($6.email) LIKE UPPER('%81%'))) OR (($3 IS NOT NULL) AND ($3.firstName IS NOT NULL) AND (UPPER($3.firstName) LIKE UPPER('%81%'))) OR (($6 IS NOT NULL) AND ($6.fax IS NOT NULL) AND (UPPER($6.fax) LIKE UPPER('%81%'))) OR (($6 IS NOT NULL) AND ($6.phone IS NOT NULL) AND (UPPER($6.phone) LIKE UPPER('%81%')))))) # Case (3) SELECT COUNT($1) FROM com.lexware.vereinsverwaltung.verein.mitglied.Mitglied $1 LEFT JOIN $1.mitgliedschaft $2 LEFT JOIN $1.profile $3 LEFT JOIN $3.organisation $4 LEFT JOIN $1.postalAddresses $5 LEFT JOIN $1.communication $6 WHERE (((NOT (($2 IS NOT NULL) AND ($2.austritt IS NOT NULL) AND ($2.austritt<=CURRENT_DATE)))) AND (((($3 IS NOT NULL) AND ($4 IS NOT NULL) AND ($4.name IS NOT NULL) AND ($4.name LIKE '%81%')) OR (($5 IS NOT NULL) AND ($5.postalCode IS NOT NULL) AND ($5.postalCode LIKE '%81%')) OR (($5 IS NOT NULL) AND ($5.streetNumber IS NOT NULL) AND ($5.streetNumber LIKE '%81%')) OR (($6 IS NOT NULL) AND ($6.cellphone IS NOT NULL) AND (UPPER($6.cellphone) LIKE UPPER('%81%'))) OR (($5 IS NOT NULL) AND ($5.street IS NOT NULL) AND (UPPER($5.street) LIKE UPPER('%81%'))) OR (($5 IS NOT NULL) AND ($5.city IS NOT NULL) AND (UPPER($5.city) LIKE UPPER('%81%'))) OR (($3 IS NOT NULL) AND ($3.lastName IS NOT NULL) AND (UPPER($3.lastName) LIKE UPPER('%81%'))) OR (($6 IS NOT NULL) AND ($6.email IS NOT NULL) AND (UPPER($6.email) LIKE UPPER('%81%'))) OR (($3 IS NOT NULL) AND ($3.firstName IS NOT NULL) AND (UPPER($3.firstName) LIKE UPPER('%81%'))) OR (($6 IS NOT NULL) AND ($6.fax IS NOT NULL) AND (UPPER($6.fax) LIKE UPPER('%81%'))) OR (($6 IS NOT NULL) AND ($6.phone IS NOT NULL) AND (UPPER($6.phone) LIKE UPPER('%81%'))))))
What happens is this:
Case (1) -> all is ok, it returns a count of one which is correct, the query is equal to Case (2) & (3) except the missing UPPER() calls everywhere
Case (2) -> fails badly and suddenly returns doubled results and weird counts (the total count of ALL available Rows is 100 though this returns 149!!!). The difference between this and Case (1) which works is the use of UPPER everywhere
Case (3) -> is a copy+paste of Case(2) with all UPPER removed from the beginning of the query until it started suddenly working again correctly as it should
Please help out, this looks very weird.. especially.. for this case, using or not using UPPER shouldn't make ANY difference as we're testing for a number as well...
All fields that are tested are strings
Here're the query stack traces from the explorer for each case. Attached you can also find my database for testing hope that helps, we'd need an eager fix to this issue to be able to do ignore-case queries..
# Case (1) Query Plan Description ====================== Step 1: Process Mitglied ($1) instances --------------------------------------- [Step 1a] Scan type com.lexware.vereinsverwaltung.verein.api.model.mitglied.Mitglied locating all the Mitglied ($1) instances. [Step 1b] Evaluate fields in Mitglied ($1) instances. Step 2: Process IndividualProfile ($3) instances (for every result of step 1) ------------------------------------------------ Iterate over all the instances ($3) in $1.profile. Step 3: Extract field values ---------------------------- Retrieve fields in IndividualProfile ($3) instances. Step 4: Process OrganisationContact ($4) instances (for every result tuple of the steps above) -------------------------------------------------- Iterate over all the instances ($4) in $3.organisation. Step 5: Process IndividualPostalAddress ($5) instances (for every result tuple of the steps above) ------------------------------------------------------ Iterate over all the instances ($5) in $1.postalAddresses. Step 6: Extract field values ---------------------------- Retrieve fields in IndividualPostalAddress ($5) instances. Step 7: Extract field values ---------------------------- Retrieve fields in OrganisationContact ($4) instances. Step 8: Process IndividualCommunicationInfo ($6) instances (for every result tuple of the steps above) ---------------------------------------------------------- [Step 8a] Iterate over all the instances ($6) in $1.communication. [Step 8b] Retrieve fields in IndividualCommunicationInfo ($6) instances. [Step 8c] Filter the results of step 8b retaining only results that satisfy: or(and(like($6.phone,'%81%'),($6.phone!=null),($6!=null)),and(like($6.fax,'%81%'),($6.fax!=null),($6!=null)),and(like($3.firstName,'%81%'),($3.firstName!=null),($3!=null)),and(like($6.email,'%81%'),($6.email!=null),($6!=null)),and(like($3.lastName,'%81%'),($3.lastName!=null),($3!=null)),and(like($5.city,'%81%'),($5.city!=null),($5!=null)),and(like($5.street,'%81%'),($5.street!=null),($5!=null)),and(like($6.cellphone,'%81%'),($6.cellphone!=null),($6!=null)),and(like($5.streetNumber,'%81%'),($5.streetNumber!=null),($5!=null)),and(like($5.postalCode,'%81%'),($5.postalCode!=null),($5!=null)),and(like($4.name,'%81%'),($4.name!=null),($4!=null),($3!=null))). Step 9: Process Mitgliedschaft ($2) instances (for every result tuple of the steps above) --------------------------------------------- [Step 9a] Iterate over all the instances ($2) in $1.mitgliedschaft. [Step 9b] Retrieve fields in Mitgliedschaft ($2) instances. [Step 9c] Filter the results of step 9b retaining only results that satisfy: not(and(($2.austritt<=current-java.sql.Date),($2.austritt!=null),($2!=null))). Step 10: Group results --------------------- Evaluate aggregate expressions: count($1). Step 11: Apply selection ----------------------- Apply selection and prepare final results. # Case (2) Query Plan Description ====================== Step 1: Process Mitglied ($1) instances --------------------------------------- [Step 1a] Scan type com.lexware.vereinsverwaltung.verein.api.model.mitglied.Mitglied locating all the Mitglied ($1) instances. [Step 1b] Evaluate fields in Mitglied ($1) instances. Step 2: Process IndividualProfile ($3) instances (for every result of step 1) ------------------------------------------------ Iterate over all the instances ($3) in $1.profile. Step 3: Process IndividualPostalAddress ($5) instances (for every result tuple of the steps above) ------------------------------------------------------ Iterate over all the instances ($5) in $1.postalAddresses. Step 4: Process IndividualCommunicationInfo ($6) instances (for every result tuple of the steps above) ---------------------------------------------------------- Iterate over all the instances ($6) in $1.communication. Step 5: Extract field values ---------------------------- Retrieve fields in IndividualCommunicationInfo ($6) instances. Step 6: Extract field values ---------------------------- Retrieve fields in IndividualPostalAddress ($5) instances. Step 7: Extract field values ---------------------------- Retrieve fields in IndividualProfile ($3) instances. Step 8: Process OrganisationContact ($4) instances (for every result tuple of the steps above) -------------------------------------------------- Step 8a: Handle a constant expression ------------------------------------ [Step 8a1] If or(or(or(or(or(or(or(or(or(and(like(toUpper($5.postalCode),toUpper('%81%')),($5.postalCode!=null),($5!=null)),and(like(toUpper($5.streetNumber),toUpper('%81%')),($5.streetNumber!=null),($5!=null))),and(like(toUpper($6.cellphone),toUpper('%81%')),($6.cellphone!=null),($6!=null))),and(like(toUpper($5.street),toUpper('%81%')),($5.street!=null),($5!=null))),and(like(toUpper($5.city),toUpper('%81%')),($5.city!=null),($5!=null))),and(like(toUpper($3.lastName),toUpper('%81%')),($3.lastName!=null),($3!=null))),and(like(toUpper($6.email),toUpper('%81%')),($6.email!=null),($6!=null))),and(like(toUpper($3.firstName),toUpper('%81%')),($3.firstName!=null),($3!=null))),and(like(toUpper($6.fax),toUpper('%81%')),($6.fax!=null),($6!=null))),and(like(toUpper($6.phone),toUpper('%81%')),($6.phone!=null),($6!=null))) is true - execute only step 8a2. If or(or(or(or(or(or(or(or(or(and(like(toUpper($5.postalCode),toUpper('%81%')),($5.postalCode!=null),($5!=null)),and(like(toUpper($5.streetNumber),toUpper('%81%')),($5.streetNumber!=null),($5!=null))),and(like(toUpper($6.cellphone),toUpper('%81%')),($6.cellphone!=null),($6!=null))),and(like(toUpper($5.street),toUpper('%81%')),($5.street!=null),($5!=null))),and(like(toUpper($5.city),toUpper('%81%')),($5.city!=null),($5!=null))),and(like(toUpper($3.lastName),toUpper('%81%')),($3.lastName!=null),($3!=null))),and(like(toUpper($6.email),toUpper('%81%')),($6.email!=null),($6!=null))),and(like(toUpper($3.firstName),toUpper('%81%')),($3.firstName!=null),($3!=null))),and(like(toUpper($6.fax),toUpper('%81%')),($6.fax!=null),($6!=null))),and(like(toUpper($6.phone),toUpper('%81%')),($6.phone!=null),($6!=null))) is false - execute only step 8a3. [Step 8a2] Scan type com.quasado.foundation.contact.api.model.organisation.OrganisationContact locating all the OrganisationContact ($4) instances. Step 8a3: Handle a constant expression ------------------------------------ [Step 8a3a] If ($3!=null) is true - execute only step 8a3e. If ($3!=null) is false - execute only step 8a3f. [Step 8a3b] Scan type com.quasado.foundation.contact.api.model.organisation.OrganisationContact locating OrganisationContact ($4) instances that satisfy: ($4!=null). [Step 8a3c] Evaluate fields in OrganisationContact ($4) instances. [Step 8a3d] Filter the results of step 8a3c retaining only results that satisfy: like(toUpper($4.name),toUpper('%81%')). [Step 8a3e] Filter the results of step 8a3d retaining only results that satisfy: ($4.name!=null). [Step 8a3f] Prepare an empty result set. [Step 8b] Filter the results of step 8a retaining only results that satisfy: ($3.organisation left-join $4). Step 9: Process Mitgliedschaft ($2) instances (for every result tuple of the steps above) --------------------------------------------- [Step 9a] Iterate over all the instances ($2) in $1.mitgliedschaft. [Step 9b] Retrieve fields in Mitgliedschaft ($2) instances. [Step 9c] Filter the results of step 9b retaining only results that satisfy: not(and(($2.austritt<=current-java.sql.Date),($2.austritt!=null),($2!=null))). Step 10: Group results --------------------- Evaluate aggregate expressions: count($1). Step 11: Apply selection ----------------------- Apply selection and prepare final results. # Case (3) Query Plan Description ====================== Step 1: Process Mitglied ($1) instances --------------------------------------- [Step 1a] Scan type com.lexware.vereinsverwaltung.verein.api.model.mitglied.Mitglied locating all the Mitglied ($1) instances. [Step 1b] Evaluate fields in Mitglied ($1) instances. Step 2: Process IndividualProfile ($3) instances (for every result of step 1) ------------------------------------------------ Iterate over all the instances ($3) in $1.profile. Step 3: Extract field values ---------------------------- Retrieve fields in IndividualProfile ($3) instances. Step 4: Process OrganisationContact ($4) instances (for every result tuple of the steps above) -------------------------------------------------- Iterate over all the instances ($4) in $3.organisation. Step 5: Process IndividualPostalAddress ($5) instances (for every result tuple of the steps above) ------------------------------------------------------ Iterate over all the instances ($5) in $1.postalAddresses. Step 6: Extract field values ---------------------------- Retrieve fields in IndividualPostalAddress ($5) instances. Step 7: Extract field values ---------------------------- Retrieve fields in OrganisationContact ($4) instances. Step 8: Process IndividualCommunicationInfo ($6) instances (for every result tuple of the steps above) ---------------------------------------------------------- [Step 8a] Iterate over all the instances ($6) in $1.communication. [Step 8b] Retrieve fields in IndividualCommunicationInfo ($6) instances. [Step 8c] Filter the results of step 8b retaining only results that satisfy: or(and(like(toUpper($6.phone),toUpper('%81%')),($6.phone!=null),($6!=null)),and(like(toUpper($6.fax),toUpper('%81%')),($6.fax!=null),($6!=null)),and(like(toUpper($3.firstName),toUpper('%81%')),($3.firstName!=null),($3!=null)),and(like(toUpper($6.email),toUpper('%81%')),($6.email!=null),($6!=null)),and(like(toUpper($3.lastName),toUpper('%81%')),($3.lastName!=null),($3!=null)),and(like(toUpper($5.city),toUpper('%81%')),($5.city!=null),($5!=null)),and(like(toUpper($5.street),toUpper('%81%')),($5.street!=null),($5!=null)),and(like(toUpper($6.cellphone),toUpper('%81%')),($6.cellphone!=null),($6!=null)),and(like($5.streetNumber,'%81%'),($5.streetNumber!=null),($5!=null)),and(like($5.postalCode,'%81%'),($5.postalCode!=null),($5!=null)),and(like($4.name,'%81%'),($4.name!=null),($4!=null),($3!=null))). Step 9: Process Mitgliedschaft ($2) instances (for every result tuple of the steps above) --------------------------------------------- [Step 9a] Iterate over all the instances ($2) in $1.mitgliedschaft. [Step 9b] Retrieve fields in Mitgliedschaft ($2) instances. [Step 9c] Filter the results of step 9b retaining only results that satisfy: not(and(($2.austritt<=current-java.sql.Date),($2.austritt!=null),($2!=null))). Step 10: Group results --------------------- Evaluate aggregate expressions: count($1). Step 11: Apply selection ----------------------- Apply selection and prepare final results.