[ 
https://issues.apache.org/jira/browse/PHOENIX-3469?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

chenglei updated PHOENIX-3469:
------------------------------
    Description: 
This problem can be reproduced as following:

{code:borderStyle=solid} 
       CREATE TABLE  DESC_TEST (
          ORGANIZATION_ID VARCHAR,
          CONTAINER_ID VARCHAR,
          ENTITY_ID VARCHAR NOT NULL,
          CONSTRAINT TEST_PK PRIMARY KEY ( 
                        ORGANIZATION_ID DESC,
                        CONTAINER_ID DESC,
                        ENTITY_ID
                        ))

      UPSERT INTO DESC_TEST VALUES ('a',null,'11')")
      UPSERT INTO DESC_TEST VALUES (null,'2','22')")
      UPSERT INTO DESC_TEST VALUES ('c','3','33')")
{code} 

For the following sql:
{code:borderStyle=solid}
      SELECT CONTAINER_ID,ORGANIZATION_ID FROM DESC_TEST  order by CONTAINER_ID 
ASC NULLS LAST
{code} 
the expecting result is:
{code:borderStyle=solid}
     2,   null 
     3,    c   
    null,  a
{code} 
but the actual result is:
{code:borderStyle=solid}
      null,  a     
      2,   null 
      3,    c     
{code} 

By debug the source code,I found the ScanPlan passes the OrderByExpression to 
both the ScanRegionObserver and MergeSortTopNResultIterator,but the 
OrderByExpression 's "isNullsLast" property is false, while my sql is "order by 
CONTAINER_ID ASC NULLS LAST", the "isNullsLast" property should be true.

{code:borderStyle=solid}
 90    private ScanPlan(StatementContext context, FilterableStatement 
statement, TableRef table, RowProjector projector, Integer limit, Integer 
offset, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory, 
boolean allowPageFilter, Expression dynamicFilter) throws SQLException {
     ......   
95      boolean isOrdered = !orderBy.getOrderByExpressions().isEmpty();
96     if (isOrdered) { // TopN
97           int thresholdBytes = 
context.getConnection().getQueryServices().getProps().getInt(
98           QueryServices.SPOOL_THRESHOLD_BYTES_ATTRIB, 
QueryServicesOptions.DEFAULT_SPOOL_THRESHOLD_BYTES);    
99           ScanRegionObserver.serializeIntoScan(context.getScan(),
  thresholdBytes, 
100          limit == null ? -1 : QueryUtil.getOffsetLimit(limit, offset),  
orderBy.getOrderByExpressions(),
101   projector.getEstimatedRowByteSize());
102   }

......

231        } else if (isOrdered) {
232            scanner = new MergeSortTopNResultIterator(iterators, limit, 
offset, orderBy.getOrderByExpressions());

{code} 

so the problem is caused by the OrderByCompiler, in line 144, it should not 
negative the "isNullsLast",because the "isNullsLast" should take effect no 
matter the SortOrder is DESC or ASC:

{code:borderStyle=solid}
142              if (expression.getSortOrder() == SortOrder.DESC) {
143                     isAscending = !isAscending;
144                     isNullsLast = !isNullsLast;
145             }
{code} 



  was:
This problem can be reproduced as following:

{code:borderStyle=solid} 
    CREATE TABLE  DESC_TEST (
          ORGANIZATION_ID VARCHAR,
          CONTAINER_ID VARCHAR,
          ENTITY_ID VARCHAR NOT NULL,
          CONSTRAINT TEST_PK PRIMARY KEY ( 
                        ORGANIZATION_ID DESC,
                        CONTAINER_ID DESC,
                        ENTITY_ID
                        ))

                UPSERT INTO DESC_TEST VALUES ('a',null,'11')")
                UPSERT INTO DESC_TEST VALUES (null,'2','22')")
                UPSERT INTO DESC_TEST VALUES ('c','3','33')")
{code} 

For the following sql:
{code:borderStyle=solid}
      SELECT CONTAINER_ID,ORGANIZATION_ID FROM DESC_TEST  order by CONTAINER_ID 
ASC NULLS LAST
{code} 
the expecting result is:
{code:borderStyle=solid}
     2,   null 
     3,    c   
    null,  a
{code} 
but the actual result is:
{code:borderStyle=solid}
      null,  a     
      2,   null 
      3,    c     
{code} 

By debug the source code,I found the ScanPlan passes the OrderByExpression to 
both the ScanRegionObserver and MergeSortTopNResultIterator,but the 
OrderByExpression 's "isNullsLast" property is false, while my sql is "order by 
CONTAINER_ID ASC NULLS LAST", the "isNullsLast" property should be true.

{code:borderStyle=solid}
 90    private ScanPlan(StatementContext context, FilterableStatement 
statement, TableRef table, RowProjector projector, Integer limit, Integer 
offset, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory, 
boolean allowPageFilter, Expression dynamicFilter) throws SQLException {
     ......   
95      boolean isOrdered = !orderBy.getOrderByExpressions().isEmpty();
96     if (isOrdered) { // TopN
97           int thresholdBytes = 
context.getConnection().getQueryServices().getProps().getInt(
98           QueryServices.SPOOL_THRESHOLD_BYTES_ATTRIB, 
QueryServicesOptions.DEFAULT_SPOOL_THRESHOLD_BYTES);    
99           ScanRegionObserver.serializeIntoScan(context.getScan(),
  thresholdBytes, 
100          limit == null ? -1 : QueryUtil.getOffsetLimit(limit, offset),  
orderBy.getOrderByExpressions(),
101   projector.getEstimatedRowByteSize());
102   }

......

231        } else if (isOrdered) {
232            scanner = new MergeSortTopNResultIterator(iterators, limit, 
offset, orderBy.getOrderByExpressions());

{code} 

so the problem is caused by the OrderByCompiler, in line 144, it should not 
negative the "isNullsLast",because the "isNullsLast" should take effect no 
matter the SortOrder is DESC or ASC:

{code:borderStyle=solid}
142              if (expression.getSortOrder() == SortOrder.DESC) {
143                     isAscending = !isAscending;
144                     isNullsLast = !isNullsLast;
145             }
{code} 




> Once a column in primary key or index is DESC, the corresponding order by  
> NULLS LAST/NULLS FIRST may work incorrectly
> ----------------------------------------------------------------------------------------------------------------------
>
>                 Key: PHOENIX-3469
>                 URL: https://issues.apache.org/jira/browse/PHOENIX-3469
>             Project: Phoenix
>          Issue Type: Bug
>    Affects Versions: 4.8.0
>            Reporter: chenglei
>
> This problem can be reproduced as following:
> {code:borderStyle=solid} 
>        CREATE TABLE  DESC_TEST (
>         ORGANIZATION_ID VARCHAR,
>         CONTAINER_ID VARCHAR,
>         ENTITY_ID VARCHAR NOT NULL,
>         CONSTRAINT TEST_PK PRIMARY KEY ( 
>                       ORGANIZATION_ID DESC,
>                       CONTAINER_ID DESC,
>                       ENTITY_ID
>                       ))
>       UPSERT INTO DESC_TEST VALUES ('a',null,'11')")
>       UPSERT INTO DESC_TEST VALUES (null,'2','22')")
>       UPSERT INTO DESC_TEST VALUES ('c','3','33')")
> {code} 
> For the following sql:
> {code:borderStyle=solid}
>       SELECT CONTAINER_ID,ORGANIZATION_ID FROM DESC_TEST  order by 
> CONTAINER_ID ASC NULLS LAST
> {code} 
> the expecting result is:
> {code:borderStyle=solid}
>      2,   null 
>      3,    c   
>     null,  a
> {code} 
> but the actual result is:
> {code:borderStyle=solid}
>       null,  a     
>       2,   null 
>       3,    c     
> {code} 
> By debug the source code,I found the ScanPlan passes the OrderByExpression to 
> both the ScanRegionObserver and MergeSortTopNResultIterator,but the 
> OrderByExpression 's "isNullsLast" property is false, while my sql is "order 
> by CONTAINER_ID ASC NULLS LAST", the "isNullsLast" property should be true.
> {code:borderStyle=solid}
>  90    private ScanPlan(StatementContext context, FilterableStatement 
> statement, TableRef table, RowProjector projector, Integer limit, Integer 
> offset, OrderBy orderBy, ParallelIteratorFactory parallelIteratorFactory, 
> boolean allowPageFilter, Expression dynamicFilter) throws SQLException {
>      ......   
> 95      boolean isOrdered = !orderBy.getOrderByExpressions().isEmpty();
> 96     if (isOrdered) { // TopN
> 97           int thresholdBytes = 
> context.getConnection().getQueryServices().getProps().getInt(
> 98           QueryServices.SPOOL_THRESHOLD_BYTES_ATTRIB, 
> QueryServicesOptions.DEFAULT_SPOOL_THRESHOLD_BYTES);    
> 99           ScanRegionObserver.serializeIntoScan(context.getScan(),
>   thresholdBytes, 
> 100          limit == null ? -1 : QueryUtil.getOffsetLimit(limit, offset),  
> orderBy.getOrderByExpressions(),
> 101   projector.getEstimatedRowByteSize());
> 102   }
> ......
> 231        } else if (isOrdered) {
> 232            scanner = new MergeSortTopNResultIterator(iterators, limit, 
> offset, orderBy.getOrderByExpressions());
> {code} 
> so the problem is caused by the OrderByCompiler, in line 144, it should not 
> negative the "isNullsLast",because the "isNullsLast" should take effect no 
> matter the SortOrder is DESC or ASC:
> {code:borderStyle=solid}
> 142              if (expression.getSortOrder() == SortOrder.DESC) {
> 143                     isAscending = !isAscending;
> 144                     isNullsLast = !isNullsLast;
> 145             }
> {code} 



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to