I am using Core Data based time series (entity/table) which consists of the following attributes / columns:
dateTime mc nd re
Based on the formula result = (mc + nd) / re
I would like to calculate the result for each row and return the results (dateTime + value) in an array.
I tried the following code to perform the calculations on the database level but do get wrong results in my result array (multiple dateTime values per row, wrong calculation results). However, the NSExpressionDescription
returns the correct formula when NSLogging it.
Do you have any idea on what might be wrong with my code?
NSString *divisorKeyPath = @"revenue"
NSExpression *marketCapExpression = [NSExpression expressionForKeyPath:@"mc"];
NSExpression *netDebtExpression = [NSExpression expressionForKeyPath:@"nd"];
NSExpression *divisorExpression = [NSExpression expressionForKeyPath:
divisorKeyPath];
NSExpression *evExpression = [NSExpression expressionForFunction:
@"add:to:"
arguments:@[marketCapExpression,netDebtExpression]];
NSExpression *divisionExpression = [NSExpression expressionForFunction:
@"divide:by:"
arguments:@[evExpression, divisorExpression]];
NSString *divisionExpressionName = @"division";
NSExpressionDescription *divisionDescription = [[NSExpressionDescription alloc] init];
divisionDescription.name = divisionExpressionName;
divisionDescription.expression = divisionExpression;
divisionDescription.expressionResultType = NSDoubleAttributeType;
NSFetchRequest *divisionRequest = [NSFetchRequest fetchRequestWithEntityName:
NSStringFromClass([SharePrice class])];
divisionRequest.propertiesToFetch = @[@"dateTime",divisionDescription];
divisionRequest.resultType = NSDictionaryResultType;
NSSortDescriptor *sortDescriptor = [NSSortDescriptor
sortDescriptorWithKey:@"dateTime" ascending:YES];
divisionRequest.sortDescriptors = @[sortDescriptor];
NSError *error;
NSArray *divisionResults = [self.managedDocument.managedObjectContext
executeFetchRequest:divisionRequest error:&error];
NSLog(@"results: %@",divisionResults);
This seems to be a bug in Core Data. If you set the launch argument "-com.apple.CoreData.SQLDebug 3" then you can see that the expression description is translated to the SQLite query
SELECT t0.ZDATETIME, t0.ZMARKETCAP + t0.ZNETDEBT / t0.ZREVENUE FROM ZENTITY t0 ORDER BY t0.ZDATETIME
and not
SELECT t0.ZDATETIME, (t0.ZMARKETCAP + t0.ZNETDEBT) / t0.ZREVENUE FROM ZENTITY t0 ORDER BY t0.ZDATETIME
as it should be.
The divisionExpression
itself is correct. If you apply it to a single sharePrice
object of your entity, using
NSNumber *x = [expression expressionValueWithObject:sharePrice context: nil];
it returns the expected result.