Skip to content
Permalink
Browse files
fix: support insert ... on conflict...update for reWriteBatchedInsert…
…s=true (#1130)

pgjdbc will avoid rewriting the query if a bind is identified after values(...)

That is ON CONFLICT... DO update set x=? is NOT rewrite-compatible, and update set x='default' is rewrite-compatible

"reported" here: https://stackoverflow.com/questions/47664889/jdbc-batch-operations-understanding/48349524?noredirect=1#comment84691562_48349524
  • Loading branch information
vlsi committed Mar 8, 2018
1 parent 45c32bc commit 1ca0c5864a8b6c575b32aee03e2e1e8848fee143
@@ -4,6 +4,8 @@ Notable changes since version 42.0.0, read the complete [History of Changes](htt
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).

## [Unreleased]
### Fixed
- Avoid failure for `insert ... on conflict...update` for `reWriteBatchedInserts=true` case [PR#1130](https://github.com/pgjdbc/pgjdbc/pull/1130)

## [42.2.1] (2018-01-25)
### Changed
@@ -149,6 +149,13 @@
nativeQueries = new ArrayList<NativeQuery>();
}

if (!isValuesFound || !isCurrentReWriteCompatible || valuesBraceClosePosition == -1
|| (bindPositions != null
&& valuesBraceClosePosition < bindPositions.get(bindPositions.size() - 1))) {
valuesBraceOpenPosition = -1;
valuesBraceClosePosition = -1;
}

nativeQueries.add(new NativeQuery(nativeSql.toString(),
toIntArray(bindPositions), false,
SqlCommand.createStatementTypeInfo(
@@ -236,10 +243,10 @@
}
}
}
if (!isValuesFound) {
isCurrentReWriteCompatible = false;
}
if (!isCurrentReWriteCompatible) {

if (!isValuesFound || !isCurrentReWriteCompatible || valuesBraceClosePosition == -1
|| (bindPositions != null
&& valuesBraceClosePosition < bindPositions.get(bindPositions.size() - 1))) {
valuesBraceOpenPosition = -1;
valuesBraceClosePosition = -1;
}
@@ -171,6 +171,22 @@ public void insertBatchedReWriteOnConflict() throws SQLException {
Assert.assertEquals(44, command.getBatchRewriteValuesBraceClosePosition());
}

@Test
public void insertBatchedReWriteOnConflictUpdateBind() throws SQLException {
String query = "insert into test(id, name) values (?,?) ON CONFLICT (id) UPDATE SET name=?";
List<NativeQuery> qry = Parser.parseJdbcSql(query, true, true, true, true);
SqlCommand command = qry.get(0).getCommand();
Assert.assertFalse("update set name=? is NOT compatible with insert rewrite", command.isBatchedReWriteCompatible());
}

@Test
public void insertBatchedReWriteOnConflictUpdateConstant() throws SQLException {
String query = "insert into test(id, name) values (?,?) ON CONFLICT (id) UPDATE SET name='default'";
List<NativeQuery> qry = Parser.parseJdbcSql(query, true, true, true, true);
SqlCommand command = qry.get(0).getCommand();
Assert.assertTrue("update set name='default' is compatible with insert rewrite", command.isBatchedReWriteCompatible());
}

@Test
public void insertMultiInsert() throws SQLException {
String query =
@@ -148,4 +148,46 @@ public void testMultiValuedUpsertBatch() throws SQLException {
TestUtil.closeQuietly(ps);
}
}

@Test
public void testSingleValuedUpsertUpdateBatch() throws SQLException {
PreparedStatement ps = null;
try {
ps = con.prepareStatement(
"insert into test_statement(i, t) values (?,?) ON CONFLICT (i) DO update set t=?");
ps.setInt(1, 50);
ps.setString(2, "50U");
ps.setString(3, "50U");
ps.addBatch();
ps.setInt(1, 53);
ps.setString(2, "53U");
ps.setString(3, "53U");
ps.addBatch();
int[] actual = ps.executeBatch();
BatchExecuteTest.assertSimpleInsertBatch(2, actual);
} finally {
TestUtil.closeQuietly(ps);
}
}

@Test
public void testSingleValuedUpsertUpdateConstantBatch() throws SQLException {
PreparedStatement ps = null;
try {
// For reWriteBatchedInserts=YES the following is expected
// FE=> Parse(stmt=null,query="insert into test_statement(i, t) values ($1,$2),($3,$4) ON CONFLICT (i) DO update set t='DEF'",oids={23,1043,23,1043})
ps = con.prepareStatement(
"insert into test_statement(i, t) values (?,?) ON CONFLICT (i) DO update set t='DEF'");
ps.setInt(1, 50);
ps.setString(2, "50");
ps.addBatch();
ps.setInt(1, 53);
ps.setString(2, "53");
ps.addBatch();
int[] actual = ps.executeBatch();
BatchExecuteTest.assertSimpleInsertBatch(2, actual);
} finally {
TestUtil.closeQuietly(ps);
}
}
}

0 comments on commit 1ca0c58

Please sign in to comment.