trafodion-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Eric Owhadi <eric.owh...@esgyn.com>
Subject question on ValueIdSet::isNotNullable
Date Wed, 06 Jan 2016 01:39:36 GMT
Hi Trafodioneers,

Not sure if the author of this isNotNullable function is still active, but
since this is the only part in the code I am about to submit that will not
be cqd protected, I would like to ask if I am exposing trafodion to some
side effect. Basically running L1 testing, I discovered that doing:

Select an from t140 where an between 20 and 30

Would not optimize the column returned, and incorrectly add a key column to
satisfy NULLs (an being a nullable column).

However, given the predicate an cannot be null, therefore there should not
be any additional column retrieved.



The issue is in the original  NABoolean ValueIdSet::isNotNullable(const
ValueId& opd)



It is assuming that predicates are a bunch of ANDed together stuff in the
ValueIdSet.

However, in my case, the resulting stuff is a single valueId in the
valueIdSet, that has as first operator and ITM_AND.

So I believe the correct implementation taking care of both cases of AND
should be the one bellow. Does that make sense?



Or should I CQD protect this to only be the behavior with the predicate
push down V2. I don’t think so, but cannot be 100% certain…

The original code is simply the same removing the line between ~~EO begin
and ~~EO end.





//~~EO begin

//helper function for isNotNullable recusivity on AND

NABoolean isNotNullableRecurse(const ValueId& vid, const ValueId& opd)

{

                ItemExpr *iePtr = vid.getItemExpr();

                switch (iePtr->getOperatorType()) {

                    case ITM_AND:

                                return
isNotNullableRecurse(iePtr->child(0)->castToItemExpr()->getValueId(),opd) ||


isNotNullableRecurse(iePtr->child(1)->castToItemExpr()->getValueId(),opd);

                                break;

                    case ITM_IS_NOT_NULL:

                      if (iePtr->child(0)->containsTheGivenValue( opd )) {

                        // found "opd IS NOT NULL" predicate conjunct

                        return TRUE; // opd is not null

                      }

                      break; // keep looking

                    case ITM_EQUAL:

                    case ITM_NOT_EQUAL:

                    case ITM_LESS:

                    case ITM_LESS_EQ:

                    case ITM_GREATER:

                    case ITM_GREATER_EQ:

                      if (iePtr->child(0)->containsTheGivenValue( opd ) ||

                          iePtr->child(1)->containsTheGivenValue( opd )) {

                        // found "opd compop expr" predicate conjunct

                        return TRUE; // opd is not null

                      }

                      break; // keep looking

                    case ITM_IS_NULL:

                      if (iePtr->child(0)->containsTheGivenValue( opd )) {

                        // found "opd IS NULL" predicate conjunct

                        return FALSE; // opd is null

                      }

                      break;

                    default:

                      break; // keep looking



                  }

                  return FALSE;

}

//~~EO end

// --------------------------------------------------------------------

// return true iff ValueIdSet has predicates that guarantee

// that opd is not nullable

// --------------------------------------------------------------------

NABoolean ValueIdSet::isNotNullable(const ValueId& opd)

{

  // if opd's type is not nullable then return TRUE

  if (!opd.getType().supportsSQLnullLogical()) {

    return TRUE;

  }

  // opd's type is nullable.



  // search ValueIdSet for a predicate conjunct

  // that can guarantee that opd is not null

  for (ValueId vid = init(); next(vid); advance(vid) ) {

    // predicates are implicitly connected by AND

    ItemExpr *iePtr = vid.getItemExpr();

    switch (iePtr->getOperatorType()) {

//~~EO begin

    case ITM_AND:

                return
isNotNullableRecurse(iePtr->child(0)->castToItemExpr()->getValueId(),opd) ||


isNotNullableRecurse(iePtr->child(1)->castToItemExpr()->getValueId(),opd);

                break;

//~~EO end

    case ITM_IS_NOT_NULL:

      if (iePtr->child(0)->containsTheGivenValue( opd )) {

        // found "opd IS NOT NULL" predicate conjunct

        return TRUE; // opd is not null

      }

      break; // keep looking

    case ITM_EQUAL:

    case ITM_NOT_EQUAL:

    case ITM_LESS:

    case ITM_LESS_EQ:

    case ITM_GREATER:

    case ITM_GREATER_EQ:

      if (iePtr->child(0)->containsTheGivenValue( opd ) ||

          iePtr->child(1)->containsTheGivenValue( opd )) {

        // found "opd compop expr" predicate conjunct

        return TRUE; // opd is not null

      }

      break; // keep looking

    case ITM_IS_NULL:

      if (iePtr->child(0)->containsTheGivenValue( opd )) {

        // found "opd IS NULL" predicate conjunct

        return FALSE; // opd is null

      }

      break;

    default:

      break; // keep looking

    }

  }

  return FALSE;

}

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message