Github user DaveBirdsall commented on a diff in the pull request:

    https://github.com/apache/incubator-trafodion/pull/132#discussion_r42405465
  
    --- Diff: core/sql/optimizer/ItemExpr.cpp ---
    @@ -14906,3 +14906,80 @@ NABoolean LOBoper::isCovered
       return FALSE;
     }
     
    +// Compute the exprssion at compile time. Assume all operands are 
constants.
    +// Return NULL if the computation fails and CmpCommon::diags() may be 
side-affected.
    +ConstValue* ItemExpr::compute(CollHeap* heap)
    +{
    +  ValueIdList exprs;
    +  exprs.insert(getValueId());
    +
    +  const NAType& dataType = getValueId().getType();
    +
    +  Lng32 decodedValueLen = dataType.getNominalSize() + 
dataType.getSQLnullHdrSize();
    +
    +  char staticDecodeBuf[200];
    +  Lng32 staticDecodeBufLen = 200;
    +
    +  char* decodeBuf = staticDecodeBuf;
    +  Lng32 decodeBufLen = staticDecodeBufLen;
    +
    +  // For character types, multiplying by 8 to deal with conversions between
    +  // any two known character sets supported.  
    +  Lng32 factor = (DFS2REC::isAnyCharacter(dataType.getFSDatatype())) ? 8 : 
1;
    +
    +  if ( staticDecodeBufLen < decodedValueLen * factor) {
    +    decodeBufLen = decodedValueLen * factor;
    +    decodeBuf = new (STMTHEAP) char[decodeBufLen];
    +  }
    +
    +  Lng32 resultLength = 0;
    +  Lng32 resultOffset = 0;
    +
    +  // Produce the decoded key. Refer to 
    +  // ex_function_encode::decodeKeyValue() for the 
    +  // implementation of the decoding logic.
    +  ex_expr::exp_return_type rc = exprs.evalAtCompileTime
    +    (0, ExpTupleDesc::SQLARK_EXPLODED_FORMAT, decodeBuf, decodeBufLen,
    +     &resultLength, &resultOffset, CmpCommon::diags()
    +     );
    +
    +
    +  ConstValue* result = NULL;
    +
    +  if ( rc == ex_expr::EXPR_OK ) {
    +    CMPASSERT(resultOffset == dataType.getPrefixSizeWithAlignment());
    +    // expect the decodeBuf to have this layout
    +    // | null ind. | varchar length ind. | alignment | result |
    +    // |<---getPrefixSizeWithAlignment-------------->|
    +    // |<----getPrefixSize-------------->|
    +
    +    // The method getPrefixSizeWithAlignment(), the diagram above,
    +    // and this code block assumes that varchar length ind. is
    +    // 2 bytes if present. If it is 4 bytes we should fail the 
    +    // previous assert
    +
    +    // Next we get rid of alignment bytes by prepending the prefix
    +    // (null ind. + varlen ind.) to the result. ConstValue constr.
    +    // will process prefix + result. The assert above ensures that 
    +    // there are no alignment fillers at the beginning of the 
    +    // buffer. Given the previous assumption about size
    +    // of varchar length indicator, alignment bytes will be used by
    +    // expression evaluator only if column is of nullable type.
    +    // For a description of how alignment is computed, please see
    +    // ExpTupleDesc::sqlarkExplodedOffsets() in exp/exp_tuple_desc.cpp
    +
    +    if (dataType.getSQLnullHdrSize() > 0)
    +      memmove(&decodeBuf[resultOffset - dataType.getPrefixSize()], 
    --- End diff --
    
    The source and target fields seem to overlap? How long is the null 
indicator? Two bytes? Does memmove move a byte at a time?


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at [email protected] or file a JIRA ticket
with INFRA.
---

Reply via email to