using SUBQUERY to remove nulls

  • I have a property, 'meaning' on my objects in a core data model. It's optional. I need to find all the meanings which contain a certain string (not terribly efficient but a fairly rare search).

    I started out with this predicate

    [ NSPredicate predicateWithFormat:@"meaning CONTAINS %@", searchString ];

    but it crashes with a EXC_BAD_ACCESS deep down in the SQLLite execution trying to evaluate CFStringGetLength on a zero pointer. My assumption here is that it's finding an object with a null meaning, so I want to filter them out. So I tried

    [ NSPredicate predicateWithFormat:@"( meaning != NULL ) AND ( meaning CONTAINS %@ )", searchString ];

    and a few variants thereof, but they crash the same way, leading me to think perhaps both parts of the AND are evaluated whether or not the first part succeeds, ie not like C's guaranteed shortcut, and perhaps I shouldn't expect it to be.

    I could split this into two, and will try that, but I was trying to figure out how to use the SUBQUERY() syntax to do it in one. The documentation is a little weak on this, does anyone have some serious NSPredicate skills and knows how to do it?
  • On Jun 5, 2013, at 7:50 AM, Roland King wrote:

    > I have a property, 'meaning' on my objects in a core data model. It's optional. I need to find all the meanings which contain a certain string (not terribly efficient but a fairly rare search).
    >
    > I started out with this predicate
    >
    > [ NSPredicate predicateWithFormat:@"meaning CONTAINS %@", searchString ];
    >
    > but it crashes with a EXC_BAD_ACCESS deep down in the SQLLite execution trying to evaluate CFStringGetLength on a zero pointer. My assumption here is that it's finding an object with a null meaning, so I want to filter them out. So I tried
    >
    > [ NSPredicate predicateWithFormat:@"( meaning != NULL ) AND ( meaning CONTAINS %@ )", searchString ];
    >
    > and a few variants thereof, but they crash the same way, leading me to think perhaps both parts of the AND are evaluated whether or not the first part succeeds, ie not like C's guaranteed shortcut, and perhaps I shouldn't expect it to be.

    I would not jump to an issue with NULL values since NULL handing is fundamental to any SQL-aware API. I would instead consider a memory issue first. Turn on zombies and see if you get a different response. Post the backtrace if you want potentially better feedback. In any case, it is highly unlikely to be the predicate or underlying SQL machinery that is causing this crash.

    HTH,

    Keary Suska
    Esoteritech, Inc.
  • On 6 Jun, 2013, at 5:34 AM, Keary Suska <cocoa-dev...> wrote:

    > On Jun 5, 2013, at 7:50 AM, Roland King wrote:
    >
    >> I have a property, 'meaning' on my objects in a core data model. It's optional. I need to find all the meanings which contain a certain string (not terribly efficient but a fairly rare search).
    >>
    >> I started out with this predicate
    >>
    >> [ NSPredicate predicateWithFormat:@"meaning CONTAINS %@", searchString ];
    >>
    >> but it crashes with a EXC_BAD_ACCESS deep down in the SQLLite execution trying to evaluate CFStringGetLength on a zero pointer. My assumption here is that it's finding an object with a null meaning, so I want to filter them out. So I tried
    >>
    >> [ NSPredicate predicateWithFormat:@"( meaning != NULL ) AND ( meaning CONTAINS %@ )", searchString ];
    >>
    >> and a few variants thereof, but they crash the same way, leading me to think perhaps both parts of the AND are evaluated whether or not the first part succeeds, ie not like C's guaranteed shortcut, and perhaps I shouldn't expect it to be.
    >
    > I would not jump to an issue with NULL values since NULL handing is fundamental to any SQL-aware API. I would instead consider a memory issue first. Turn on zombies and see if you get a different response. Post the backtrace if you want potentially better feedback. In any case, it is highly unlikely to be the predicate or underlying SQL machinery that is causing this crash.
    >
    > HTH,
    >
    > Keary Suska
    > Esoteritech, Inc.
    >
    >

    Thanks for the reply Keary. Very sure it wasn't a memory issue, I'm using ARC (not a guarantee of course but it's been very reliable thus far) and I checked the registers at the point of failure, with the help of a few goggled articles, and confirmed this was CFStringGetLength() sent to a NULL pointer.

    I did split the query into two and weed out the NULLs, then filter the rest, that worked. That also showed me that I hardly had any instances which didn't supply a 'meaning' (it was optional hence it could be nil), so I changed it to non-optional and made the default the empty string, upgraded the database and the original query worked fine again.

    I'd agree SQL is great with NULLs and I think that part of the API is handing the NULL just fine, but that then it's passed to the filtering code which uses a CFString() call on it and it crashes there when it's optional and not supplied.

    It's working happily now with the non-optional parameter and for the sake of a few extra bytes in the database, the predicate is simpler too so I probably ended up at a better solution.
previous month june 2013 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today