wingkingbobo opened a new issue, #17888:
URL: https://github.com/apache/shardingsphere/issues/17888

   ## Bug Report
   
   ### Which version of ShardingSphere did you use?
   5.1.1
   
   ### Which project did you use? ShardingSphere-JDBC or ShardingSphere-Proxy?
   ShardingSphere-Proxy
   
   ### Expected behavior
   execute prepareStatement like `INSERT INTO remark (userid, content, `time`) 
VALUES (?, ?, ?) `
   
   ### Actual behavior
   ```
   com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error 
in your SQL syntax; check the manual that corresponds to your MySQL server 
version for the right syntax to use near 
'org.apache.shardingsphere.sharding.rewrite.token.pojo.ShardingInsertValuesToken@'
 at line 1
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at 
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at 
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)
        at com.mysql.jdbc.Util.getInstance(Util.java:408)
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:944)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3978)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3914)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2530)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2683)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2495)
        at 
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1903)
        at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1242)
        at 
com.wingkingbobo.splitdb.service.RemarkServiceImpl.testInsert(RemarkServiceImpl.java:107)
   ```
   
   ### Reason analyze (If you can)
   
   ### Steps to reproduce the behavior, such as: SQL to execute, sharding rule 
configuration, when exception occur etc.
   * steps
     * create database `p`, `p1` by create table statement.
     * run demo
       * `jdbcUrl=JDBC_URL_MYSQL`: OK
       * `jdbcUrl=JDBC_URL_MYSQL`: throw `MySQLSyntaxErrorException`
   * demo
   ```java
   
       private static final String JDBC_URL_MYSQL = 
"jdbc:mysql://localhost:3306/p1?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai";
       private static final String JDBC_URL_SHARDING_PROXY = 
"jdbc:mysql://localhost:3307/sharding_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai";
   
       public static void main(String[] args) {
           String jdbcUrl = JDBC_URL_SHARDING_PROXY;
           try {
               testInsert(createRemarkList(1).get(0), jdbcUrl);
               // testBatchInsert(createRemarkList(1).get(0), jdbcUrl);
           } catch(Exception e) {
               e.printStacktrace();
           }
           
       }
   
       private List<RemarkPO> createRemarkList(int count) {
           List<RemarkPO> remarks = new ArrayList<>();
   
           for (int i = 0; i < count; i++) {
               RemarkPO remark = new RemarkPO();
               remark.setUserId(4);
               remark.setContent("test"+i);
               remark.setTime(new Date());
               remarks.add(remark);
           }
   
           return remarks;
       }
   
       private boolean testInsert(RemarkPO remark, String jdbcUrl) throws 
Exception{
           DriverManager.registerDriver(new Driver());
           Connection connection = DriverManager.getConnection(jdbcUrl, "root", 
"123456");
   
           String sql = "INSERT INTO remark(userid, content, `time`) VALUES (?, 
?, ?)";
           PreparedStatement statement = connection.prepareStatement(sql);
           statement.setLong(1, remark.getUserId());
           statement.setString(2, remark.getContent());
           statement.setDate(3, toSqlDate(remark.getTime()));
           statement.execute();
           return true;
       }
   
       private boolean testBatchInsert(List<RemarkPO> remarks, String jdbcUrl) 
throws Exception {
           if (remarks.isEmpty()) {
               return false;
           }
           DriverManager.registerDriver(new Driver());
           Connection connection = DriverManager.getConnection(jdbcUrl, "root", 
"123456");
   
           StringBuilder sb = new StringBuilder("INSERT INTO remark(userid, 
content, `time`) VALUES ");
           for (int i = 0; i < remarks.size(); i++) {
               if (i != 0) {
                   sb.append(",");
               }
               sb.append(" (?, ?, ?)");
           }
           String sql = sb.toString();
           PreparedStatement statement = connection.prepareStatement(sql);
           int stride = 3;
           for (int i = 0; i < remarks.size(); i++) {
               int offset = stride * i;
               RemarkPO remark = remarks.get(i);
               statement.setLong(1 + offset, remark.getUserId());
               statement.setString(2 + offset, remark.getContent());
               statement.setDate(3 + offset, toSqlDate(remark.getTime()));
           }
   
           statement.execute();
   
           return true;
       }
   
       private java.sql.Date toSqlDate(Date date) {
           return new java.sql.Date(date.getTime());
       }
   ```
   ```java
   package com.test.po;
   
   import java.util.Date;
   
   public class RemarkPO {
       private long id;
       private long userId;
       private String content;
       private Date time;
   
       public long getId() {
           return id;
       }
   
       public void setId(long id) {
           this.id = id;
       }
   
       public long getUserId() {
           return userId;
       }
   
       public void setUserId(long userId) {
           this.userId = userId;
       }
   
       public String getContent() {
           return content;
       }
   
       public void setContent(String content) {
           this.content = content;
       }
   
       public Date getTime() {
           return time;
       }
   
       public void setTime(Date time) {
           this.time = time;
       }
   }
   
   ```
   * server.yaml
   ```yaml
   mode:
     type: Cluster
     repository:
       type: ZooKeeper
       props:
         namespace: governance_ds
         server-lists: localhost:2182
         retryIntervalMilliseconds: 500
         timeToLiveSeconds: 60
         maxRetries: 3
         operationTimeoutMilliseconds: 500
     overwrite: false
   
   rules:
     - !AUTHORITY
       users:
         - root@%:123456
       provider:
         type: ALL_PRIVILEGES_PERMITTED
     - !TRANSACTION
       defaultType: LOCAL
       props:
         recoveryStoreUrl: jdbc:mysql://127.0.0.1:3306/jbossts
         recoveryStoreDataSource: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
         recoveryStoreUser: root
         recoveryStorePassword: 12345678
     - !SQL_PARSER
       sqlCommentParseEnabled: true
       sqlStatementCache:
         initialCapacity: 2000
         maximumSize: 65535
         concurrencyLevel: 4
       parseTreeCache:
         initialCapacity: 128
         maximumSize: 1024
         concurrencyLevel: 4
   
   props:
     max-connections-size-per-query: 1
     kernel-executor-size: 16 
     proxy-frontend-flush-threshold: 128 
     proxy-hint-enabled: false
     sql-show: true
     check-table-metadata-enabled: false
     show-process-list-enabled: false
     proxy-backend-query-fetch-size: -1
     check-duplicate-table-enabled: false
     proxy-frontend-executor-size: 0
     proxy-backend-executor-suitable: OLAP
     proxy-frontend-max-connections: 0 
     sql-federation-enabled: false
     proxy-backend-driver-type: JDBC
   
   ```
   
   * config-sharding.yaml
   ```yaml
   schemaName: sharding_db
   
   dataSources:
     p:
       url: 
jdbc:mysql://localhost:3306/p?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
       username: root
       password: 123456
       connectionTimeoutMilliseconds: 30000
       idleTimeoutMilliseconds: 60000
       maxLifetimeMilliseconds: 1800000
       maxPoolSize: 50
       minPoolSize: 1
     p1:
       url: 
jdbc:mysql://localhost:3306/p1?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
       username: root
       password: 123456
       connectionTimeoutMilliseconds: 30000
       idleTimeoutMilliseconds: 60000
       maxLifetimeMilliseconds: 1800000
       maxPoolSize: 50
       minPoolSize: 1
   
   rules:
     - !SHARDING
       tables:
         remark:
           actualDataNodes: p.remark,p$->{1..1}.remark
           databaseStrategy:
             standard:
               shardingColumn: userid
               shardingAlgorithmName: database_inline
       shardingAlgorithms:
         database_inline:
           type: INLINE
           props:
             algorithm-expression: 
p$->{userid<3?"":(String)((int)((userid-3)/2)+1)}
   ```
   * create table statement
   ```sql
   /*
    Navicat Premium Data Transfer
   
    Source Server         : localhost
    Source Server Type    : MySQL
    Source Server Version : 50708
    Source Host           : localhost:3306
    Source Schema         : p
   
    Target Server Type    : MySQL
    Target Server Version : 50708
    File Encoding         : 65001
   
    Date: 12/05/2022 16:42:31
   */
   
   SET NAMES utf8mb4;
   SET FOREIGN_KEY_CHECKS = 0;
   
   -- ----------------------------
   -- Table structure for remark
   -- ----------------------------
   DROP TABLE IF EXISTS `remark`;
   CREATE TABLE `remark`  (
     `id` int(11) NOT NULL AUTO_INCREMENT,
     `userid` int(11) NOT NULL,
     `content` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
     `time` datetime NOT NULL,
     PRIMARY KEY (`id`) USING BTREE
   ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = 
utf8_general_ci ROW_FORMAT = COMPACT;
   
   SET FOREIGN_KEY_CHECKS = 1;
   
   ```
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: 
[email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to