Skip to content

Commit

Permalink
bugfix: insert sql primary key value support type. (apache#2349)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsbxyyx committed Mar 31, 2020
1 parent 6c46de7 commit b71d84e
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,16 @@
import io.seata.common.exception.ShouldNeverHappenException;
import io.seata.common.util.CollectionUtils;
import io.seata.common.util.StringUtils;

import io.seata.rm.datasource.PreparedStatementProxy;
import io.seata.rm.datasource.StatementProxy;
import io.seata.rm.datasource.sql.struct.ColumnMeta;
import io.seata.rm.datasource.sql.struct.TableRecords;

import io.seata.sqlparser.SQLInsertRecognizer;
import io.seata.sqlparser.SQLRecognizer;
import io.seata.sqlparser.struct.Null;
import io.seata.sqlparser.struct.SqlMethodExpr;
import io.seata.sqlparser.struct.SqlSequenceExpr;
import io.seata.sqlparser.util.JdbcConstants;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -175,10 +172,6 @@ protected List<Object> getPkValuesByColumn() throws SQLException {
if (!pkValues.isEmpty() && pkValues.get(0) instanceof SqlSequenceExpr) {
pkValues = getPkValuesBySequence(pkValues.get(0));
}
// pk auto generated while single insert primary key is expression
else if (pkValues.size() == 1 && pkValues.get(0) instanceof SqlMethodExpr) {
pkValues = getPkValuesByAuto();
}
// pk auto generated while column exists and value is null
else if (!pkValues.isEmpty() && pkValues.get(0) instanceof Null) {
pkValues = getPkValuesByAuto();
Expand Down Expand Up @@ -251,29 +244,54 @@ protected int getPkIndex() {
/**
* check pk values
* @param pkValues
* @return true support false not support
* @return true: support. false: not support.
*/
private boolean checkPkValues(List<Object> pkValues) {
boolean pkParameterHasNull = false;
boolean pkParameterHasNotNull = false;
boolean pkParameterHasExpr = false;
if (pkValues.size() == 1) {
return true;
}
protected boolean checkPkValues(List<Object> pkValues) {
/*
-----------------------------------------------
one more
null O O
value O O
method X X
sequence O X
-----------------------------------------------
null value method sequence
null O X X X
value X O X X
method X X X X
sequence X X X X
-----------------------------------------------
*/
int n = 0, v = 0, m = 0, s = 0;
for (Object pkValue : pkValues) {
if (pkValue instanceof Null) {
pkParameterHasNull = true;
n++;
continue;
}
pkParameterHasNotNull = true;
if (pkValue instanceof SqlMethodExpr) {
pkParameterHasExpr = true;
m++;
break;
}
if (pkValue instanceof SqlSequenceExpr) {
s++;
continue;
}
v++;
}
if (pkParameterHasExpr) {
// not support sql primary key is function.
if (m > 0) {
return false;
}
return !pkParameterHasNull || !pkParameterHasNotNull;
if (n > 0 && v == 0 && s == 0) {
return true;
}
if (n == 0 && v > 0 && s == 0) {
return true;
}
if (n == 0 && v == 0 && s == 1) {
return true;
}
return false;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import io.seata.rm.datasource.sql.struct.Row;
import io.seata.rm.datasource.sql.struct.TableMeta;
import io.seata.rm.datasource.sql.struct.TableRecords;
import io.seata.sqlparser.struct.SqlMethodExpr;
import io.seata.sqlparser.struct.SqlSequenceExpr;
import io.seata.sqlparser.util.JdbcConstants;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -315,6 +317,91 @@ public void test_getPkIndex() {
Assertions.assertEquals(0, insertExecutor.getPkIndex());
}

@Test
public void test_checkPkValues() {
// one parameters.
// pk is null support
List<Object> pkValues = new ArrayList<>();
pkValues.add(Null.get());
Assertions.assertTrue(insertExecutor.checkPkValues(pkValues));

// pk is sequence support.
pkValues = new ArrayList<>();
pkValues.add(new SqlSequenceExpr());
Assertions.assertTrue(insertExecutor.checkPkValues(pkValues));

// pk is specify value support.
pkValues = new ArrayList<>();
pkValues.add(1);
Assertions.assertTrue(insertExecutor.checkPkValues(pkValues));

// pk is sql function not support.
pkValues = new ArrayList<>();
pkValues.add(new SqlMethodExpr());
Assertions.assertFalse(insertExecutor.checkPkValues(pkValues));

// more parameters.
// pk is specify value support.
pkValues = new ArrayList<>();
pkValues.add(1);
pkValues.add(2);
Assertions.assertTrue(insertExecutor.checkPkValues(pkValues));

// pk is null support.
pkValues = new ArrayList<>();
pkValues.add(Null.get());
pkValues.add(Null.get());
Assertions.assertTrue(insertExecutor.checkPkValues(pkValues));

// pk is sql function not support.
pkValues = new ArrayList<>();
pkValues.add(new SqlMethodExpr());
pkValues.add(new SqlMethodExpr());
Assertions.assertFalse(insertExecutor.checkPkValues(pkValues));

// pk is sql sequence not support.
pkValues = new ArrayList<>();
pkValues.add(new SqlSequenceExpr());
pkValues.add(new SqlSequenceExpr());
Assertions.assertFalse(insertExecutor.checkPkValues(pkValues));

// pk is specify value and null not support.
pkValues = new ArrayList<>();
pkValues.add(1);
pkValues.add(Null.get());
Assertions.assertFalse(insertExecutor.checkPkValues(pkValues));

// pk is specify value and sql function not support.
pkValues = new ArrayList<>();
pkValues.add(1);
pkValues.add(new SqlMethodExpr());
Assertions.assertFalse(insertExecutor.checkPkValues(pkValues));

// pk is specify value and sequence not support.
pkValues = new ArrayList<>();
pkValues.add(1);
pkValues.add(new SqlSequenceExpr());
Assertions.assertFalse(insertExecutor.checkPkValues(pkValues));

// pk is null and sql function not support.
pkValues = new ArrayList<>();
pkValues.add(Null.get());
pkValues.add(new SqlMethodExpr());
Assertions.assertFalse(insertExecutor.checkPkValues(pkValues));

// pk is null and sequence not support.
pkValues = new ArrayList<>();
pkValues.add(Null.get());
pkValues.add(new SqlSequenceExpr());
Assertions.assertFalse(insertExecutor.checkPkValues(pkValues));

// pk is sql function and sequence not support.
pkValues = new ArrayList<>();
pkValues.add(new SqlMethodExpr());
pkValues.add(new SqlSequenceExpr());
Assertions.assertFalse(insertExecutor.checkPkValues(pkValues));
}

private List<String> mockInsertColumns() {
List<String> columns = new ArrayList<>();
columns.add(ID_COLUMN);
Expand Down

0 comments on commit b71d84e

Please sign in to comment.