issue with DbFunctionCall wrong type of parameter in generated query

Posts   
 
    
MarcinK
User
Posts: 1
Joined: 13-Nov-2014
# Posted on: 13-Nov-2014 11:56:11   

Hello

I'm creating the following code:


var timeFilter = new EntityField2("timeEnd", new DbFunctionCall("({0} + {1} *'1 second'::interval)", new object[] { BackgroundTasksQueueFields.ModifiedAt, BackgroundTasksQueueFields.ValidityTime }), typeof(DateTime));

IRelationPredicateBucket filter = new RelationPredicateBucket(
                    BackgroundTasksQueueFields.IdBackgroundQueueState =='BQS_RUN'
                    & timeFilter < DateTime.utcNow);

BackgroundTasksQueueEntity updateEntity = new BackgroundTasksQueueEntity();

updateEntity.ExecuteAfter = DateTime.UtcNow.AddMinutes(2);
updateEntity.IdBackgroundQueueState = 'BQS_QUEU';

UpdateEntitiesDirectly(adapter, entity, filter);


For this code LLBLGen create following query:


Query: UPDATE "queue"."background_tasks_queue" SET "execute_after"=:p1, "id_background_queue_state"=:p2 WHERE ( ( ( "queue"."background_tasks_queue"."id_background_queue_state" = :p3 AND ("queue"."background_tasks_queue"."modified_at" + "queue"."background_tasks_queue"."validity_time" *'1 second'::interval) < :p5)))
    Parameter: :p1 : DateTime. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 2014-11-13T10:39:22.1845828.
    Parameter: :p2 : String. Length: 1073741824. Precision: 0. Scale: 0. Direction: Input. Value: "BQS_QUEU".
    Parameter: :p3 : String. Length: 1073741824. Precision: 0. Scale: 0. Direction: Input. Value: "BQS_RUN".
    Parameter: :p5 : Date. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 2014-11-13 00:00:00.

In my opinion the created query is incorrect. Why parameter p5 have type Date? It should be DateTime because I want filter by date with time.

Maybe I do something wrong?

I'm using LLBLGen ver: 4.2 with Postgresql 9.29.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39888
Joined: 17-Aug-2003
# Posted on: 13-Nov-2014 18:14:30   

It does the following: a fieldcomparevalue predicate is created, with the expression on one side and the value (the utcNow datetime) on the other. It ignores the field's type the expression is on, as it could be the expression is simply set on a field with a different type: the field is simply a placeholder, not used in the actual output.

Because of this, it passes the value to compare with to the parameter creator and by default it picks 'Date' for a datetime value on postgresql as in general that's the right choice, however not for your situation.

We can't change the way it ignores the field's type, as that will definitely break code. The way you could change it is by deriving a class from FieldCompareValuePredicate and in that class override ToQueryText(bool) and make sure the parameter's DbType property is set to DateTime, not Date. Then use in your code this derived class instead of the timeFilter < DateTime.utcNow predicate, by calling its ctor.

Please let us know whether this works for you or not.

Frans Bouma | Lead developer LLBLGen Pro