apache / shardingsphere

Distributed SQL transaction & query engine for data sharding, scaling, encryption, and more - on any database.
Apache License 2.0
19.88k stars 6.73k forks source link

problem in SQLServerStatementSQLVisitor.class #32354

Open JINWANDALAOHU250 opened 2 months ago

JINWANDALAOHU250 commented 2 months ago

Bug Report

Which version of ShardingSphere did you use?

 <dependency>
  <groupId>org.apache.shardingsphere</groupId>
  <artifactId>shardingsphere-jdbc-core</artifactId>
  <version>5.3.2</version>
</dependency>

Which project did you use? ShardingSphere-JDBC or ShardingSphere-Proxy?

ShardingSphere-JDBC

Expected behavior

execute sql like

SELECT
    * 
FROM
    message_mst 
WHERE
    readed = 0 
ORDER BY
    msg.create_dt DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY

then parse to

Actual SQL: slave :::
SELECT
    * 
FROM
    message_mst 
WHERE
    readed = 0 
ORDER BY
    msg.create_dt DESC OFFSET ? ROWS FETCH NEXT ? ROWS ONLY

::: [10, 5]

Actual behavior

### Cause: java.sql.SQLException: Unknown exception: Index: 2, Size: 2
; uncategorized SQLException for SQL []; SQL state [HY000]; error code [30000]; Unknown exception: Index: 2, Size: 2; nested exception is java.sql.SQLException: Unknown exception: Index: 2, Size: 2

Reason analyze (If you can)

In class SQLServerStatementSQLVisitor.class#visitOrderBy ,offset paramIndex and rowcount paramIndex not right, caused PaginationContext get param in List params out of bounds.

// SQLServerStatementSQLVisitor
... line 788
                // param index is 'parameterMarkerSegments.size() - 1'
                offset = new ParameterMarkerLimitValueSegment(ctx.expr(0).start.getStartIndex(), ctx.expr(0).stop.getStopIndex(), parameterMarkerSegments.size());
...
...
                // param index is 'parameterMarkerSegments.size() - 1'
                rowcount = new ParameterMarkerLimitValueSegment(ctx.expr(1).start.getStartIndex(), ctx.expr(1).stop.getStopIndex(), parameterMarkerSegments.size());
...

// PaginationContext
...line 56
// getParameterIndex() caused Unknown exception: Index: 2, Size: 2
Object obj = null == params || params.isEmpty() ? 0L : params.get(((ParameterMarkerPaginationValueSegment) paginationValueSegment).getParameterIndex());
...

Steps to reproduce the behavior, such as: SQL to execute, sharding rule configuration, when exception occur etc.

SpringBoot + Mybatis + Similar to the sql mentioned above

Example codes for reproduce this issue (such as a github link).

terrymanu commented 2 months ago

No plan to enhance with SQLServer for now, does any one want to do it?

JINWANDALAOHU250 commented 2 months ago

Is it that I want to be simple, I think it should only take parameterMarkerSegments.size() - 1 to solve this problem

terrymanu commented 2 months ago

I cannot suggest without investigate. Please try.