Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL generation fix for EOKeyValueQualifiers when key is key path with derived attribute #829

Merged
merged 1 commit into from
Mar 21, 2017

Conversation

rparada
Copy link
Contributor

@rparada rparada commented Mar 19, 2017

Overview

This bug fix can be disabled by setting the er.extensions.KeyValueQualifierSQLGenerationSupport.handlesKeyPathWithDerivedAttribute property to false and everything works just like before. Only one method is overriden and the rest are helper methods.

Basically, it overrides sqlStringForSQLExpression() in KeyValueQualifierSQLGenerationSupport which is responsible for generating SQL for key value qualifiers. It does this by first checking for the special case. If it is the special case then it calls the helper method to handle the SQL generation which calls other helper methods. On the other hand, If it is not the special case then it works just like before.

The special case fixes SQL generation support for EOKeyValueQualifiers when the key consists of two or more keys and the last key references a derived attribute.

Example #1:

The the key in the key-value qualifier is patient.fullNameReversed and the last key fullNameReversed is defined as: lastName || ', ' || firstName.

Example #2:

A more complex example I tested involves a key-value qualifier with the key claim.patientAge where patientAge is a derived attribute that is defined as TRUNC(MONTHS_BETWEEN(dateOfService,patient.birthDate)/12,0). My object model has a Claim entity, a LineItem entity and a Patient entity.

My test:

This test uses both patient.fullNameReversed and claim.patientAge

EOEditingContext ec = ERXEC.newEditingContext();
EOQualifier q = Claim.USER_GROUP_ID.is(4)
		.and(Claim.REFERENCE1.is("349069"))
		.and(Claim.PATIENT_AGE.greaterThan(30))
		.and(Claim.PATIENT.dot(Patient.FULL_NAME_REVERSED.likeInsensitive("wilson*")));
		
NSArray<Claim> claims = Claim.fetchClaims(ec, q, null);
q = LineItem.USER_GROUP_ID.is(4).and(LineItem.CLAIM.prefix(q));
NSArray<LineItem> items = LineItem.fetchLineItems(ec, q, null);
System.out.println(claims);
System.out.println(items);
if (claims.count() == 1 && items.count() == 5) {
	System.out.println("Success");
}

Without the fix, EOF throws an exception.
With the fix, the SQL is generated perfectly as follows:

Output

KeyValueQualifierSQLGenerationSupport handled edge case for key-value qualifier with key path referencing a derived attribute: Claim.patientAge
   Key value qualifier: (claim.patientAge > 30)
   Key path: claim.patientAge
   Attribute patientAge is defined as: TRUNC(MONTHS_BETWEEN(dateOfService, patient.birthDate)/12,0)
   SQL generated: TRUNC(MONTHS_BETWEEN(T1.DATE_OF_SERVICE, T2.BIRTH_DATE)/12,0) > ?

KeyValueQualifierSQLGenerationSupport handled edge case for key-value qualifier with key path referencing a derived attribute: Patient.fullNameReversed
   Key value qualifier: (claim.patient.fullNameReversed caseinsensitivelike 'wilson*')
   Key path: claim.patient.fullNameReversed
   Attribute fullNameReversed is defined as: lastName || ', ' || firstName
   SQL generated: UPPER(T2.LAST_NAME || ', ' || T2.FIRST_NAME) LIKE UPPER(?) ESCAPE '\'

 === Begin Internal Transaction
 evaluateExpression: <com.webobjects.jdbcadaptor.EROracleExpression: "SELECT t0.CLAIM_ID, t0.CPT_CODE, t0.LINE_ITEM_ID, t0.USER_GROUP_ID FROM LINE_ITEM t0, PATIENT T2, CLAIM T1 WHERE T1.PATIENT_ID = T2.PATIENT_ID AND t0.CLAIM_ID = T1.CLAIM_ID AND (t0.USER_GROUP_ID = ? AND (T1.USER_GROUP_ID = ? AND T1.REFERENCE1 = ? AND TRUNC(MONTHS_BETWEEN(T1.DATE_OF_SERVICE, T2.BIRTH_DATE)/12,0) > ? AND UPPER(T2.LAST_NAME || ', ' || T2.FIRST_NAME) LIKE UPPER(?) ESCAPE '\'))" withBindings: 1:4(userGroupID), 2:4(userGroupID), 3:"349069"(reference1), 4:30(patientAge), 5:"wilson%"(fullNameReversed)>
5 row(s) processed
 === Commit Internal Transaction

(<your.app.model.Claim pk:"111454491">)
(
  <your.app.model.LineItem pk:"180693217">, 
  <your.app.model.LineItem pk:"180693218">, 
  <your.app.model.LineItem pk:"180693216">, 
  <your.app.model.LineItem pk:"180693219">, 
  <your.app.model.LineItem pk:"180693215">
)
Success

where the key is a key path (with two or more keys) and the last key
is a derived attribute.  For example, "customer.fullName" where the
last key fullName is defined as: 'firstName || ' ' || lastName.
@rparada rparada changed the title Added SQL generation fix for EOKeyValueQualifiers in an edge case SQL generation fix for EOKeyValueQualifiers when key is key path with derived attribute Mar 19, 2017
@darkv darkv merged commit bee51ac into wocommunity:master Mar 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants