Bitmask filters on select

Posts   
 
    
rparkins
User
Posts: 66
Joined: 04-May-2005
# Posted on: 22-Jun-2006 16:04:04   

Hi Guys,

sorry marked as done previously by accident

Again another quickie as I am struggling to find what is wrong with my code and if I am using this bitmask stuff properly. I need to select rows which bit 0 and bit 1 set in column: Cop_checkoptions. I have 2 rows that satisy this requirement but I only get the first row that satisfies this requirement. The code I use to generate the filter is as follows, is this correct? Interestingly on an update of rows I use this code with no problems... and I have checked the column values visually so I am pretty sure its not me being stupid! (ahem)

for(int i=0; i < 32; i++) { uint bit = (uint)System.Math.Pow(2, i);

if ((bit & CheckedOptions) > 0) {
    filter.Add(new FieldCompareExpressionPredicate(
                        CustomerOptionFields.Cop_checkoptions, ComparisonOperator.Equal,
                        new Expression(CustomerOptionFields.Cop_checkoptions, ExOp.BitwiseAnd, (bit & (uint)0x7FFF))));
}

}

Many thanks

Richard

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 22-Jun-2006 16:19:31   

To help us understand your goal correctly, would you please post your target sql statement?

Also a data layout of the 2 rows that should satisfy the requirement. And what's the difference between the returned row, and the "should-have-been" returned row ?

rparkins
User
Posts: 66
Joined: 04-May-2005
# Posted on: 22-Jun-2006 17:12:30   

Sorry to be dumb, but is there a quick way to get the target sql? I have seen somewhere while debugging an object but cant remember where rage

The column I have is a bigint and each bit is an option for the user (to 32 bit values).

ie for the 1st bit I current have 2 rows that have this set to 1, however I only receive 1 row on the filter shown above.

Thanks for your reply please let me know if you need more info

Rich

Walaa wrote:

To help us understand your goal correctly, would you please post your target sql statement?

Also a data layout of the 2 rows that should satisfy the requirement. And what's the difference between the returned row, and the "should-have-been" returned row ?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 22-Jun-2006 18:17:59   

See troubleshooting and debugging in the docs -> DQE tracing for debugging generated SQL

Frans Bouma | Lead developer LLBLGen Pro
rparkins
User
Posts: 66
Joined: 04-May-2005
# Posted on: 23-Jun-2006 09:56:15   

Ah, many thanks for your pointers, that helps massively I have used llbgen for a couple of years now and havn;t needed the tracing info. I think I can see what the issue is now and it is something to do with how I generate the filter. The genareted SLQ as follows:

Query: SELECT DISTINCT [mallett_WMS01].[Customer].[c_id] AS [C_id], [mallett_WMS01].[Customer].[c_guid] AS [C_guid], [mallett_WMS01].[CustomerOption].[cop_checkoptions] AS [Cop_checkoptions], [mallett_WMS01].[CustomerOption].[c_id] AS [C_id_] FROM (( [mallett_WMS01].[CustomerType] INNER JOIN [mallett_WMS01].[Customer] ON [mallett_WMS01].[CustomerType].[ct_id]=[mallett_WMS01].[Customer].[ct_id]) INNER JOIN [mallett_WMS01].[CustomerOption] ON [mallett_WMS01].[Customer].[c_id]=[mallett_WMS01].[CustomerOption].[c_id]) WHERE ( [mallett_WMS01].[CustomerOption].[cop_checkoptions] = [mallett_WMS01].[CustomerOption].[cop_checkoptions] & @LO22121)

The where clause is obviously wrong, I will investigate why 22121 is passed across as it should be 000001. I need something like

Where [mallett_WMS01].[CustomerOption].[cop_checkoptions] & 8 = 8,

and I think the solution is something to do with creating 2 fields and adding them to a predicate? As you can tell I havn;t quite got my head around generating compex filters, so again an pointers would be appreciated.

Again great product and many thanks

Richard

Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 23-Jun-2006 16:42:27   

I think the following may do the trick, please try it:

filter.Add(new FieldCompareExpressionPredicate(
                EntityFieldFactory.Create(CustomerOptionFieldIndex.Cop_checkoptions), null,
                ComparisonOperator.Equal,
                new Expression(EntityFieldFactory.Create(CustomerOptionFieldIndex.Cop_checkoptions), ExOp.BitwiseAnd, 8)));

rparkins
User
Posts: 66
Joined: 04-May-2005
# Posted on: 24-Jun-2006 02:17:58   

Hi

Thanks for the reply. The code failed with an exception object null. I removed the null parameter and the code completed but with the following SQL, which didn;t seem to be different from my version, (the where clause being the same). I can see how to create an expression but cant see how to compare an expression to a static number instead of another expression or field,

FYI I am using self servicing.

Query: SELECT COUNT(*) AS NumberOfRows FROM (SELECT DISTINCT [mallett_WMS01].[Customer].[c_id] AS [C_id], [mallett_WMS01].[Customer].[c_guid] AS [C_guid], [mallett_WMS01].[Customer].[c_title] AS [C_title], [mallett_WMS01].[Customer].[c_firstname] AS [C_firstname], [mallett_WMS01].[Customer].[c_surname] AS [C_surname], [mallett_WMS01].[Customer].[c_email] AS [C_email], [mallett_WMS01].[Customer].[c_phone] AS [C_phone], [mallett_WMS01].[Customer].[c_mobile] AS [C_mobile], [mallett_WMS01].[Customer].[c_created] AS [C_created], [mallett_WMS01].[Customer].[c_notes] AS [C_notes], [mallett_WMS01].[Customer].[c_update_requested] AS [C_update_requested], [mallett_WMS01].[Customer].[ct_id] AS [Ct_id], [mallett_WMS01].[CustomerType].[ct_id] AS [Ct_id], [mallett_WMS01].[CustomerType].[ct_ref] AS [Ct_ref], [mallett_WMS01].[CustomerType].[ct_description] AS [Ct_description], [mallett_WMS01].[CustomerOption].[cop_id] AS [Cop_id], [mallett_WMS01].[CustomerOption].[cop_checkoptions] AS [Cop_checkoptions], [mallett_WMS01].[CustomerOption].[cp_searchoption1] AS [Cp_searchoption1], [mallett_WMS01].[CustomerOption].[cp_searchoption2] AS [Cp_searchoption2], [mallett_WMS01].[CustomerOption].[cp_searchoption3] AS [Cp_searchoption3], [mallett_WMS01].[CustomerOption].[cp_searchoption4] AS [Cp_searchoption4], [mallett_WMS01].[CustomerOption].[cp_searchoption5] AS [Cp_searchoption5], [mallett_WMS01].[CustomerOption].[cp_searchoption6] AS [Cp_searchoption6], [mallett_WMS01].[CustomerOption].[c_id] AS [C_id] FROM (( [mallett_WMS01].[CustomerType] INNER JOIN [mallett_WMS01].[Customer] ON [mallett_WMS01].[CustomerType].[ct_id]=[mallett_WMS01].[Customer].[ct_id]) INNER JOIN [mallett_WMS01].[CustomerOption] ON [mallett_WMS01].[Customer].[c_id]=[mallett_WMS01].[CustomerOption].[c_id]) WHERE ( [mallett_WMS01].[CustomerOption].[cop_checkoptions] = [mallett_WMS01].[CustomerOption].[cop_checkoptions] & @LO23821))

Walaa wrote:

I think the following may do the trick, please try it:

filter.Add(new FieldCompareExpressionPredicate(
                EntityFieldFactory.Create(CustomerOptionFieldIndex.Cop_checkoptions), null,
                ComparisonOperator.Equal,
                new Expression(EntityFieldFactory.Create(CustomerOptionFieldIndex.Cop_checkoptions), ExOp.BitwiseAnd, 8)));

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 25-Jun-2006 12:36:40   

rparkins wrote:

Hi Guys,

sorry marked as done previously by accident

Again another quickie as I am struggling to find what is wrong with my code and if I am using this bitmask stuff properly. I need to select rows which bit 0 and bit 1 set in column: Cop_checkoptions. I have 2 rows that satisy this requirement but I only get the first row that satisfies this requirement. The code I use to generate the filter is as follows, is this correct? Interestingly on an update of rows I use this code with no problems... and I have checked the column values visually so I am pretty sure its not me being stupid! (ahem)

for(int i=0; i < 32; i++) { uint bit = (uint)System.Math.Pow(2, i);

if ((bit & CheckedOptions) > 0) {
    filter.Add(new FieldCompareExpressionPredicate(
                        CustomerOptionFields.Cop_checkoptions, ComparisonOperator.Equal,
                        new Expression(CustomerOptionFields.Cop_checkoptions, ExOp.BitwiseAnd, (bit & (uint)0x7FFF))));
}

}

Many thanks

Richard

This will lead to WHERE (Cop_checkoptions = (Cop_checkoptions & (0x1)) AND (Cop_checkoptions = (Cop_checkoptions & (0x2)) etc..

which of course fails. (as Cop_checkoptions has more bits set probably)

If you want to check if Cop_checkoptions has bit 0 and 1 set, you should do: WHERE (Cop_checkoptions & 0x3) = 0x3

so you should do: filter.Add(CustomerOptionFields.Cop_checkoptions.SetExpression(new Expression(CustomerOptionFields.Cop_checkoptions, ExOp.BitwiseAnd, 0x3)) = 3);

Frans Bouma | Lead developer LLBLGen Pro
rparkins
User
Posts: 66
Joined: 04-May-2005
# Posted on: 25-Jun-2006 16:17:03   

Hi Otis,

Just a quick one before I watch England beat Equador (I hope)! I am conscious that you may be writing my code for me, but the sample of code you sent does not compile as it says it cant convert argument 1 from EntityField to Predicate.. Sorry if this is a silly problem, but would appreciate another sample from you.. Thanks once again for your replies

Many thanks

Richard

Otis wrote:

rparkins wrote:

Hi Guys,

sorry marked as done previously by accident

Again another quickie as I am struggling to find what is wrong with my code and if I am using this bitmask stuff properly. I need to select rows which bit 0 and bit 1 set in column: Cop_checkoptions. I have 2 rows that satisy this requirement but I only get the first row that satisfies this requirement. The code I use to generate the filter is as follows, is this correct? Interestingly on an update of rows I use this code with no problems... and I have checked the column values visually so I am pretty sure its not me being stupid! (ahem)

for(int i=0; i < 32; i++) { uint bit = (uint)System.Math.Pow(2, i);

if ((bit & CheckedOptions) > 0) {
    filter.Add(new FieldCompareExpressionPredicate(
                        CustomerOptionFields.Cop_checkoptions, ComparisonOperator.Equal,
                        new Expression(CustomerOptionFields.Cop_checkoptions, ExOp.BitwiseAnd, (bit & (uint)0x7FFF))));
}

}

Many thanks

Richard

This will lead to WHERE (Cop_checkoptions = (Cop_checkoptions & (0x1)) AND (Cop_checkoptions = (Cop_checkoptions & (0x2)) etc..

which of course fails. (as Cop_checkoptions has more bits set probably)

If you want to check if Cop_checkoptions has bit 0 and 1 set, you should do: WHERE (Cop_checkoptions & 0x3) = 0x3

so you should do: filter.Add(CustomerOptionFields.Cop_checkoptions.SetExpression(new Expression(CustomerOptionFields.Cop_checkoptions, ExOp.BitwiseAnd, 0x3)) = 3);

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 25-Jun-2006 17:05:41   

rparkins wrote:

Hi Otis,

Just a quick one before I watch England beat Equador (I hope)! I am conscious that you may be writing my code for me, but the sample of code you sent does not compile as it says it cant convert argument 1 from EntityField to Predicate.. Sorry if this is a silly problem, but would appreciate another sample from you.. Thanks once again for your replies

Many thanks

Richard

Oh, my bad! flushed

filter.Add(CustomerOptionFields.Cop_checkoptions.SetExpression(new Expression(CustomerOptionFields.Cop_checkoptions, ExOp.BitwiseAnd, 0x3)) ==3);

I wrote an assignment, not a compare statement.

(offtopic: I hope we both can cheer tonight if both our teams have won wink )

Frans Bouma | Lead developer LLBLGen Pro
Walaa avatar
Walaa
Support Team
Posts: 14995
Joined: 21-Aug-2005
# Posted on: 25-Jun-2006 21:18:35   

offtopic:

(offtopic: I hope we both can cheer tonight if both our teams have won )

If this happens, then you will play against each other (England vs The Netherlands) next Saturday.

rparkins
User
Posts: 66
Joined: 04-May-2005
# Posted on: 25-Jun-2006 21:39:23   

Hope things go well, at the mo its Portugal 1 Netherlands 0... I'm cheering for Holland.. Honestly! simple_smile Thanks for the reply, will try later

rparkins wrote:

Hi Otis,

Just a quick one before I watch England beat Equador (I hope)! I am conscious that you may be writing my code for me, but the sample of code you sent does not compile as it says it cant convert argument 1 from EntityField to Predicate.. Sorry if this is a silly problem, but would appreciate another sample from you.. Thanks once again for your replies

Many thanks

Richard

Oh, my bad! flushed

filter.Add(CustomerOptionFields.Cop_checkoptions.SetExpression(new Expression(CustomerOptionFields.Cop_checkoptions, ExOp.BitwiseAnd, 0x3)) ==3);

I wrote an assignment, not a compare statement.

(offtopic: I hope we both can cheer tonight if both our teams have won wink )

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 25-Jun-2006 23:02:46   

sob cry

10 against 9, and then still no win. Horrible.. cry

Frans Bouma | Lead developer LLBLGen Pro
rparkins
User
Posts: 66
Joined: 04-May-2005
# Posted on: 25-Jun-2006 23:10:24   

Sorry, too many beers after the game, I now have recompilation and will close out after I test.

Cheers

Rich

Sorry about the result rage We'll sort them for you... simple_smile

On another tack I tried your new sample code and I think its the same as the previous you defined... I still get E:\ASP_Projects\Mallett\BusinessLayer\Session\CustomerSearchParemeters.cs(136): Argument '1': cannot convert from 'SD.LLBLGen.Pro.ORMSupportClasses.EntityField' to 'SD.LLBLGen.Pro.ORMSupportClasses.IPredicate'

Better luck in Euro 2008, Holland are a great team and with a decent referee I think you would have gone far.. Once again we meet Scolari!

Rich

Otis wrote:

sob cry

10 against 9, and then still no win. Horrible.. cry

rparkins
User
Posts: 66
Joined: 04-May-2005
# Posted on: 26-Jun-2006 11:05:25   

Hi Otis,

The saga continues... I now have a where statement that looks fine, if i run it in Query Analyzer I get the rows I expect but through the application I am getting zero rows rage

I include the where clause and the parameter info. I am setting the paremeters specifically to 0x01 to eliminate other issues.

Also can I add... If I do use my ulong value instead of hardcoding the parameters to 0x01 they are passed as ansi strings (but still no rows), so both techniques return zero rows rage

Below is the 0x01 hardcoded SQL

WHERE ( [mallett_WMS01].[CustomerOption].[cop_checkoptions] & @LO8082 = @Cop_checkoptions1) Parameter: @Cop_checkoptions1 : Int32. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 1. Parameter: @LO8082 : Int32. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 1.

Below is the ulong values passed in from the loop:

WHERE ( [mallett_WMS01].[CustomerOption].[cop_checkoptions] & @LO6422 = @Cop_checkoptions1) Parameter: @Cop_checkoptions1 : AnsiString. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 1. Parameter: @LO6422 : AnsiString. Length: 0. Precision: 0. Scale: 0. Direction: Input. Value: 1.

Cheers

Richard

Oh, my bad! flushed

filter.Add(CustomerOptionFields.Cop_checkoptions.SetExpression(new Expression(CustomerOptionFields.Cop_checkoptions, ExOp.BitwiseAnd, 0x3)) ==3);

I wrote an assignment, not a compare statement.

(offtopic: I hope we both can cheer tonight if both our teams have won wink )

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39928
Joined: 17-Aug-2003
# Posted on: 26-Jun-2006 14:59:38   
Frans Bouma | Lead developer LLBLGen Pro