Hi Dave,

As you say,
        However I just tried such an example but observed that the error was 
returned (see below). So the error is returned in spite of 
MdamColumn::buildDisjunct() not         reporting it via a return code. I will 
guess that instead higher level code looks for the presence of errors in 
ComDiagsArea.

        Perhaps the issue is we don't respond to the error quickly enough?

You are right, a ComDiagsArea has been newed and then higher level detects it.

So is no return code a problem? Is it necessary to trace it in jira?

-----邮件原件-----
发件人: Dave Birdsall <[email protected]> 
发送时间: 2018年8月16日 5:26
收件人: [email protected]
主题: RE: problems in ExHbaseAccessTcb and MdamColumn

Hi Qifan,

I explained the CAST business poorly.

Actually, in the compiler we are generating a Narrow node. This is a 
non-standard node that casts a value from a larger data type to a smaller one.

It is necessary for MDAM in order to properly populate key buffers. Key buffers 
have the data type of the key, which may be smaller than the value the key is 
being compared against.

It is perfectly fine in ANSI SQL to issue a query such as SELECT * FROM T WHERE 
X > 100000, given a SMALLINT column X. Such a query should always return zero 
rows as the predicate can never be true for a SMALLINT.

If we choose a non-key access path, the compiler internally will convert X > 
100000 to CAST(X TO INTEGER) > 100000. And the predicate will evaluate just 
fine.

For a key access path however we need to make 100000 smaller, rather than 
making X bigger, for the aforementioned reason. Hence the Narrow node.

The Narrow node has the property that it has two outputs, one being the value 
being converted and the other being a "data conversion error" flag. That flag 
can then be used to manipulate inclusion/exclusion on a key predicate. So, for 
example, X < 100000 can be changed at run time to X <= 32767 if X is SMALLINT 
SIGNED.

So, no, we do not want to raise a SQL error in this case. Ironically, to do so 
would make us non-standard.

Dave

-----Original Message-----
From: Qifan Chen <[email protected]> 
Sent: Wednesday, August 15, 2018 2:13 PM
To: [email protected]
Subject: Re: problems in ExHbaseAccessTcb and MdamColumn

Hi Dave,


Thanks a lot for the good explanation on the MDAM code.


On the data conversion error you gave as an example, it seems the best 
treatment is to raise it as a SQL error, per SQL standard quoted below.  
Perhaps we are already doing it?


Thanks --Qifan


ISO/IEC 9075-2:2003 (E)

6.12

<cast specification>

yielding value TVEi.

d) If TD is an array type, then let TC be the maximum cardinality of TD. Case:

i) If SC is greater than TC, then an exception condition is raised: data 
exception - array data, right truncation.

ii) Otherwise, TV is the array with elements TVEi, 1 (one) ≤ i ≤ SC.

e) If TD is a multiset type, then TV is the multiset with elements TVEi, 1 
(one) ≤ i ≤ SC.

If SD is a row type, then:

a) For i varying from 1 (one) to DSD, the <cast specification> is applied:

CAST ( FSDi AS TFTDi ) yielding a value TVEi.

b) TV is ROW ( TVE1, TVE2, ..., TVEDSD ).

If TD is exact numeric, then Case:

a) If SD is exact numeric or approximate numeric, then

Case:

i) If there is a representation of SV in the data type TD that does not lose 
any leading significant digits after rounding or truncating if necessary, then 
TV is that representation. The choice of whether to round or truncate is 
implementation-defined.

ii) Otherwise, an exception condition is raised: data exception - numeric value 
out of range.

________________________________
From: Dave Birdsall <[email protected]>
Sent: Wednesday, August 15, 2018 1:03:43 PM
To: [email protected]
Subject: RE: problems in ExHbaseAccessTcb and MdamColumn

Hi,

My previous answer was incorrect.

The code at hand is execution time code, not compile time code.

When a predicate of the form X > 100000 for a SMALLINT column X is executed, 
predPtr->getValue(atp0,workAtp) returns ex_expr::EXPR_OK; the data conversion 
error of converting 100000 to a SMALLINT is reflected instead in 
dataConvErrorFlag.

So, I am guessing that the problem you are trying to solve is that the 
expression evaluator is returning a genuine error, one that does not involve 
data conversions.

However I just tried such an example but observed that the error was returned 
(see below). So the error is returned in spite of MdamColumn::buildDisjunct() 
not reporting it via a return code. I will guess that instead higher level code 
looks for the presence of errors in ComDiagsArea.

Perhaps the issue is we don't respond to the error quickly enough?

Thanks,

Dave



>>showddl tmdam;

CREATE TABLE TRAFODION.SEABASE.TMDAM
  (
    A                                INT NO DEFAULT NOT NULL NOT DROPPABLE NOT
      SERIALIZED
  , B                                INT NO DEFAULT NOT NULL NOT DROPPABLE NOT
      SERIALIZED
  , C                                INT DEFAULT NULL NOT SERIALIZED
  , PRIMARY KEY (A ASC, B ASC)
  )
 ATTRIBUTES ALIGNED FORMAT
;

-- GRANT SELECT, INSERT, DELETE, UPDATE, REFERENCES ON TRAFODION.SEABASE.TMDAM 
TO DB__ROOT WITH GRANT OPTION;

--- SQL operation complete.
>>log example.txt;
>>showddl tmdam;

CREATE TABLE TRAFODION.SEABASE.TMDAM
  (
    A                                INT NO DEFAULT NOT NULL NOT DROPPABLE NOT
      SERIALIZED
  , B                                INT NO DEFAULT NOT NULL NOT DROPPABLE NOT
      SERIALIZED
  , C                                INT DEFAULT NULL NOT SERIALIZED
  , PRIMARY KEY (A ASC, B ASC)
  )
 ATTRIBUTES ALIGNED FORMAT
;

-- GRANT SELECT, INSERT, DELETE, UPDATE, REFERENCES ON TRAFODION.SEABASE.TMDAM 
TO DB__ROOT WITH GRANT OPTION;

--- SQL operation complete.
>>showstats for table tmdam on existing columns;

Histogram data for Table TRAFODION.SEABASE.TMDAM Table ID: 8581215122595296219

   Hist ID # Ints    Rowcount         UEC Colname(s)
========== ====== =========== =========== ===========================
1638572183     24       16384          24 C
1638572188     48       16384        8192 B
1638572193      2       16384           2 A
1638572198      1       16384       16384 A, B


--- SQL operation complete.
>>prepare s2 from select * from tmdam where b = 'abc';

--- SQL command prepared.
>>showshape select * from tmdam where b = 'abc';
control query shape scan(path 'TRAFODION.SEABASE.TMDAM', forward , 
blocks_per_access 4 , mdam forced, mdam_columns all(dense, sparse));

--- SQL operation complete.
>>execute s2;

Breakpoint 2, MdamPred::getValue_ (this=0x7ffff7eec520, value=...,
    atp0=0x7ffff7eb7390, atp1=0x7ffff7eb6cf8) at ../comexe/ComKeyMDAM.cpp:600
600       ex_expr::exp_return_type returnExpReturnType = ex_expr::EXPR_OK;
(gdb) c
Continuing.

*** ERROR[8413] The string argument contains characters that cannot be 
converted. Source data(in hex): 616263

--- 0 row(s) selected.
>>



-----Original Message-----
From: Dave Birdsall
Sent: Wednesday, August 15, 2018 9:37 AM
To: [email protected]
Subject: RE: problems in ExHbaseAccessTcb and MdamColumn

Hi,

Could you elaborate on what problem you are trying to solve?

I think I might have written this code, but it was over 20 years ago. I'll try 
to refresh my memory to explain what is going on in this code.

Looking at the code:

587        ex_expr::exp_return_type errorCode = predPtr->getValue(atp0,workAtp);
588
589        Int32 dcErrFlag1 = dataConvErrorFlag;
590        Int32 dcErrFlag2 = 0;
591        if (errorCode == ex_expr::EXPR_OK &&
592            predPtr->getPredType() == MdamPred::MDAM_BETWEEN)
593          {
594            dataConvErrorFlag = 0;
595            errorCode = predPtr->getValue2(atp0,workAtp);
596            dcErrFlag2 = dataConvErrorFlag;
597          }
598
599        MdamPred::MdamPredType predType = MdamPred::MDAM_RETURN_FALSE;
600        // Next 2 used only for MDAM_BETWEEN.
601        MdamEnums::MdamInclusion startInclusion = 
predPtr->getStartInclusion();
602        MdamEnums::MdamInclusion endInclusion   = predPtr->getEndInclusion();
603        if (errorCode == ex_expr::EXPR_OK)
604          predType = predPtr->getTransformedPredType(dcErrFlag1, dcErrFlag2,
605                                                     startInclusion, 
endInclusion);

errorCode is set at line 587. It is checked at line 591; if everything is OK we 
go ahead and process the second value if it is a BETWEEN. Then errCode is again 
set at line 595.

At line 599, we are pessimistic; we set predType to FALSE. Then if there were 
no errors at line 603, we then compute the predType at line 604.

If I remember correctly, the point is that when processing certain key 
predicates (MDAM predicates are key predicates) we expect to get certain 
errors. For example, if we have a SMALLINT column X, and we have a predicate X 
> 100000, the compiler will down-cast the 100000 for the comparison. So when we 
get here the predicate is transformed to X < CAST(100000 AS SMALLINT). This 
CAST results in an error, because 100000 is greater than any possible SMALLINT 
value. So in this case, we want the predicate to always evaluate as FALSE.

And that is precisely what this code does.

The handling of errorCode locally in this procedure is quite intentional.

If we change this code to instead pass the error up to the caller, we may get 
compile time errors for a predicate that is perfectly OK.

Thanks,

Dave


-----Original Message-----
From: Zhu, Wen-Jun <[email protected]>
Sent: Tuesday, August 14, 2018 9:10 PM
To: [email protected]
Subject: problems in ExHbaseAccessTcb and MdamColumn

Hi,

in MdamColumn::buildDisjunct() at ../executor/ex_mdam.cpp:
587         ex_expr::exp_return_type errorCode = 
predPtr->getValue(atp0,workAtp);
588
589         Int32 dcErrFlag1 = dataConvErrorFlag;
590         Int32 dcErrFlag2 = 0;
591         if (errorCode == ex_expr::EXPR_OK &&
592             predPtr->getPredType() == MdamPred::MDAM_BETWEEN)
593           {
594             dataConvErrorFlag = 0;
595             errorCode = predPtr->getValue2(atp0,workAtp);
596             dcErrFlag2 = dataConvErrorFlag;
597           }
when errorCode is not OK on line 587, it is not checked immediately and is then 
reused.

So I suggest to change the interface of function MdamColumn::buildDisjunct(), 
making the return value type from NABoolean to int, to distingush the normal 
value and error code.

And in function keyMdamEx::buildNetwork(), which calls buildDisjunct(), the 
current logic requires the returned value must be true, why?
If there is an error occurred, we can ignore that ex_assert() and just return 
the errorCode, right?





Another problem, ExHbaseAccessTcb::initNextKeyRange() in 
core/sql/executor/ExHbaseAccess.cpp:
2430 Lng32 ExHbaseAccessTcb::initNextKeyRange(sql_buffer_pool *pool,
2431                          atp_struct * atp)
2432 {
2433   if (keyExeExpr())
2434     keyExeExpr()->initNextKeyRange(pool, atp);
2435   else
2436     return -1;
2437
2438   return 0;
2439 }
which does not check the returned value of initNextKeyRange(), so if there is 
something wrong in it, but keyExeExpr() is fine, this function returns 0, 
indicating success.


Regards,
Wenjun Zhu

Reply via email to