Repository: hazelcast/hazelcast (language: java)

Issue:
com.hazelcast.mapstore.mssql.MSSQLGenericMapStoreTest [HZ-2963]
_master_ (commit a06bee6a20c0f5136793b2c9998001f250d93282)
Failed on ibm-11: https://jenkins.hazelcast.com/job/Hazelcast-master-Openj9-11-nightly/118/testReport/junit/com.hazelcast.mapstore.mssql/MSSQLGenericMapStoreTest/
<details><summary>Stacktrace:</summary>

```
com.hazelcast.sql.HazelcastSqlException: com.hazelcast.jet.JetException: Execution on a member failed: com.hazelcast.jet.JetException: Exception in ProcessorTasklet{0a5a-21cc-0b95-0001/sinkProcessor([people_o_12f364e6_0c96_4175_b002_7d78dda8f489])#1}: com.hazelcast.jet.JetException: java.sql.BatchUpdateException: Invalid column name 'person'.
	at com.hazelcast.sql.impl.CoreQueryUtils.toPublicException(CoreQueryUtils.java:62)
	at com.hazelcast.sql.impl.SqlServiceImpl.execute(SqlServiceImpl.java:221)
	at com.hazelcast.sql.impl.SqlServiceImpl.execute(SqlServiceImpl.java:172)
	at com.hazelcast.sql.impl.SqlServiceImpl.execute(SqlServiceImpl.java:168)
	at com.hazelcast.sql.impl.SqlServiceImpl.execute(SqlServiceImpl.java:164)
	at com.hazelcast.sql.SqlService.execute(SqlService.java:89)
	at com.hazelcast.mapstore.GenericMapStore.store(GenericMapStore.java:73)
	at com.hazelcast.mapstore.GenericMapStoreTest.whenStore_thenTableContainsRow(GenericMapStoreTest.java:165)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at com.hazelcast.test.FailOnTimeoutStatement$CallableStatement.call(FailOnTimeoutStatement.java:115)
	at com.hazelcast.test.FailOnTimeoutStatement$CallableStatement.call(FailOnTimeoutStatement.java:107)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: java.util.concurrent.CompletionException: com.hazelcast.jet.JetException: Execution on a member failed: com.hazelcast.jet.JetException: Exception in ProcessorTasklet{0a5a-21cc-0b95-0001/sinkProcessor([people_o_12f364e6_0c96_4175_b002_7d78dda8f489])#1}: com.hazelcast.jet.JetException: java.sql.BatchUpdateException: Invalid column name 'person'.
	at java.base/java.util.concurrent.CompletableFuture.reportJoin(CompletableFuture.java:412)
	at java.base/java.util.concurrent.CompletableFuture.join(CompletableFuture.java:2044)
	at com.hazelcast.jet.Job.join(Job.java:80)
	at com.hazelcast.jet.sql.impl.PlanExecutor.execute(PlanExecutor.java:615)
	at com.hazelcast.jet.sql.impl.SqlPlanImpl$DmlPlan.execute(SqlPlanImpl.java:1214)
	at com.hazelcast.sql.impl.SqlServiceImpl.query0(SqlServiceImpl.java:266)
	at com.hazelcast.sql.impl.SqlServiceImpl.execute(SqlServiceImpl.java:204)
	... 18 more
Caused by: com.hazelcast.jet.JetException: Execution on a member failed: com.hazelcast.jet.JetException: Exception in ProcessorTasklet{0a5a-21cc-0b95-0001/sinkProcessor([people_o_12f364e6_0c96_4175_b002_7d78dda8f489])#1}: com.hazelcast.jet.JetException: java.sql.BatchUpdateException: Invalid column name 'person'.
	at com.hazelcast.jet.impl.LightMasterContext.findError(LightMasterContext.java:351)
	at com.hazelcast.jet.impl.LightMasterContext.lambda$createContext$2(LightMasterContext.java:178)
	at com.hazelcast.jet.impl.LightMasterContext.lambda$invokeOnParticipant$8(LightMasterContext.java:322)
	at com.hazelcast.spi.impl.AbstractInvocationFuture$WhenCompleteNode.lambda$execute$0(AbstractInvocationFuture.java:1570)
	at com.hazelcast.test.TestLoggingUtils$CustomTestNameAwareForkJoinPool$TestNameAwareRunnable.run(TestLoggingUtils.java:104)
	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: com.hazelcast.jet.JetException: Exception in ProcessorTasklet{0a5a-21cc-0b95-0001/sinkProcessor([people_o_12f364e6_0c96_4175_b002_7d78dda8f489])#1}: com.hazelcast.jet.JetException: java.sql.BatchUpdateException: Invalid column name 'person'.
	at com.hazelcast.jet.impl.execution.TaskletExecutionService.handleTaskletExecutionError(TaskletExecutionService.java:290)
	at com.hazelcast.jet.impl.execution.TaskletExecutionService$BlockingWorker.run(TaskletExecutionService.java:329)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:840)
Caused by: com.hazelcast.jet.impl.execution.TaskletExecutionException: Exception in ProcessorTasklet{0a5a-21cc-0b95-0001/sinkProcessor([people_o_12f364e6_0c96_4175_b002_7d78dda8f489])#1}: com.hazelcast.jet.JetException: java.sql.BatchUpdateException: Invalid column name 'person'.
	at com.hazelcast.jet.impl.execution.TaskletExecutionService.handleTaskletExecutionError(TaskletExecutionService.java:289)
	... 6 more
Caused by: com.hazelcast.jet.JetException: java.sql.BatchUpdateException: Invalid column name 'person'.
	at com.hazelcast.jet.impl.util.ExceptionUtil.peeledAndUnchecked(ExceptionUtil.java:145)
	at com.hazelcast.jet.impl.util.ExceptionUtil.rethrow(ExceptionUtil.java:156)
	at com.hazelcast.jet.impl.connector.WriteJdbcP.process(WriteJdbcP.java:234)
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.lambda$processInbox$2f647568$2(ProcessorTasklet.java:490)
	at com.hazelcast.jet.function.RunnableEx.run(RunnableEx.java:31)
	at com.hazelcast.jet.impl.util.Util.doWithClassLoader(Util.java:551)
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.processInbox(ProcessorTasklet.java:490)
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.stateMachineStep(ProcessorTasklet.java:341)
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.stateMachineStep(ProcessorTasklet.java:336)
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.stateMachineStep(ProcessorTasklet.java:328)
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.call(ProcessorTasklet.java:291)
	at com.hazelcast.jet.impl.execution.TaskletExecutionService$BlockingWorker.run(TaskletExecutionService.java:319)
	... 5 more
Caused by: java.sql.BatchUpdateException: Invalid column name 'person'.
	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeBatch(SQLServerPreparedStatement.java:2231)
	at com.hazelcast.shaded.com.zaxxer.hikari.pool.ProxyStatement.executeBatch(ProxyStatement.java:127)
	at com.hazelcast.shaded.com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeBatch(HikariProxyPreparedStatement.java)
	at com.hazelcast.jet.impl.connector.WriteJdbcP.executeBatch(WriteJdbcP.java:315)
	at com.hazelcast.jet.impl.connector.WriteJdbcP.process(WriteJdbcP.java:220)
	... 14 more

```

</details>

<details><summary>Standard output:</summary>

```
Finished Running Test: givenRow_whenLoadAllKeys_thenReturnKeys in 0.219 seconds.
Started Running Test: whenStore_thenTableContainsRow
10:02:31,553 DEBUG || - [GenericMapLoader] hz.MSSQLGenericMapStoreTest_youthful_mendel.cached.thread-6 - [127.0.0.1]:5701 [dev] [5.4.0-SNAPSHOT] Initializing for map people_o_12f364e6_0c96_4175_b002_7d78dda8f489
10:02:31,615  INFO || - [TaskletExecutionService] hz.MSSQLGenericMapStoreTest_youthful_mendel.jet.blocking.thread-0 - [127.0.0.1]:5701 [dev] [5.4.0-SNAPSHOT] Exception in ProcessorTasklet{0a5a-21cc-0b95-0001/sinkProcessor([people_o_12f364e6_0c96_4175_b002_7d78dda8f489])#1}
com.hazelcast.jet.JetException: java.sql.BatchUpdateException: Invalid column name 'person'.
	at com.hazelcast.jet.impl.util.ExceptionUtil.peeledAndUnchecked(ExceptionUtil.java:145) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.util.ExceptionUtil.rethrow(ExceptionUtil.java:156) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.connector.WriteJdbcP.process(WriteJdbcP.java:234) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.lambda$processInbox$2f647568$2(ProcessorTasklet.java:490) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.function.RunnableEx.run(RunnableEx.java:31) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.util.Util.doWithClassLoader(Util.java:551) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.processInbox(ProcessorTasklet.java:490) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.stateMachineStep(ProcessorTasklet.java:341) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.stateMachineStep(ProcessorTasklet.java:336) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.stateMachineStep(ProcessorTasklet.java:328) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.execution.ProcessorTasklet.call(ProcessorTasklet.java:291) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.execution.TaskletExecutionService$BlockingWorker.run(TaskletExecutionService.java:319) [hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) [?:?]
	at java.util.concurrent.FutureTask.run(FutureTask.java:264) [?:?]
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) [?:?]
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) [?:?]
	at java.lang.Thread.run(Thread.java:840) [?:?]
Caused by: java.sql.BatchUpdateException: Invalid column name 'person'.
	at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.executeBatch(SQLServerPreparedStatement.java:2231) ~[mssql-jdbc-12.4.0.jre8-preview.jar:?]
	at com.hazelcast.shaded.com.zaxxer.hikari.pool.ProxyStatement.executeBatch(ProxyStatement.java:127) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.shaded.com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeBatch(HikariProxyPreparedStatement.java) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.connector.WriteJdbcP.executeBatch(WriteJdbcP.java:315) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	at com.hazelcast.jet.impl.connector.WriteJdbcP.process(WriteJdbcP.java:220) ~[hazelcast-5.4.0-SNAPSHOT.jar:5.4.0-SNAPSHOT]
	... 14 more
10:02:31,714  INFO |whenStore_thenTableContainsRow| - [SqlTestSupport] Time-limited test - Removing 1 cached plans in SqlTestSupport.@After
10:02:31,714  INFO |whenStore_thenTableContainsRow| - [SqlTestSupport] Time-limited test - Removing 0 cached plans in SqlTestSupport.@After
10:02:31,714  INFO || - [GenericMapLoader] hz.MSSQLGenericMapStoreTest_youthful_mendel.cached.thread-9 - [127.0.0.1]:5701 [dev] [5.4.0-SNAPSHOT] Dropping mapping __map-store.people_o_12f364e6_0c96_4175_b002_7d78dda8f489
10:02:31,715  INFO |whenStore_thenTableContainsRow| - [SimpleTestInClusterSupport] Time-limited test - Ditching 0 jobs in SimpleTestInClusterSupport.@After: []
10:02:31,715  INFO |whenStore_thenTableContainsRow| - [SimpleTestInClusterSupport] Time-limited test - Destroying 1 distributed objects in SimpleTestInClusterSupport.@After: [hz:impl:mapService/__sql.catalog]
10:02:31,716  INFO |whenStore_thenTableContainsRow| - [HazelcastTestSupport] Time-limited test - Shutting down node factory as @After action
BuildInfo right after whenStore_thenTableContainsRow(com.hazelcast.mapstore.mssql.MSSQLGenericMapStoreTest): BuildInfo{version='5.4.0-SNAPSHOT', build='20230821', buildNumber=20230821, revision=a06bee6, enterprise=false, serializationVersion=1}
Hiccups measured while running test 'whenStore_thenTableContainsRow(com.hazelcast.mapstore.mssql.MSSQLGenericMapStoreTest):'
10:02:30, accumulated pauses: 91 ms, max pause: 75 ms, pauses over 1000 ms: 0


No metrics recorded during the test

```

</details>

Standard output can be found here - https://s3.console.aws.amazon.com/s3/buckets/j-artifacts/Hazelcast-master-Openj9-11-nightly/118/



Discussion / hints:
Failed again on _master_ with 

- zing-11: https://jenkins.hazelcast.com/job/Hazelcast-master-ZingJDK11-nightly/46/testReport/junit/com.hazelcast.mapstore.mssql/MSSQLGenericMapStoreTest/
- oracle-11 (force-offload): https://jenkins.hazelcast.com/job/Hazelcast-master-nightly-force-offload/62/testReport/junit/com.hazelcast.mapstore.mssql/MSSQLGenericMapStoreTest/
- openjdk-sts (openjdk-20): https://jenkins.hazelcast.com/job/Hazelcast-master-OpenJDK-sts-nightly/43/testReport/junit/com.hazelcast.mapstore.mssql/MSSQLGenericMapStoreTest/
- oracle-11 (little-endian): https://jenkins.hazelcast.com/job/Hazelcast-master-nightly-little-endian/40/testReport/junit/com.hazelcast.mapstore.mssql/MSSQLGenericMapStoreTest/
- zing-17: https://jenkins.hazelcast.com/job/Hazelcast-master-ZingJDK17-nightly/39/testReport/junit/com.hazelcast.mapstore.mssql/MSSQLGenericMapStoreTest/
Internal Jira issue: [HZ-2963](https://hazelcast.atlassian.net//browse/HZ-2963)

Fix patch:
diff --git a/hazelcast-sql/src/main/java/com/hazelcast/jet/sql/impl/connector/jdbc/mssql/MSSQLUpsertQueryBuilder.java b/hazelcast-sql/src/main/java/com/hazelcast/jet/sql/impl/connector/jdbc/mssql/MSSQLUpsertQueryBuilder.java
index 42bc3cf6ec854..bbb45f2265ca7 100644
--- a/hazelcast-sql/src/main/java/com/hazelcast/jet/sql/impl/connector/jdbc/mssql/MSSQLUpsertQueryBuilder.java
+++ b/hazelcast-sql/src/main/java/com/hazelcast/jet/sql/impl/connector/jdbc/mssql/MSSQLUpsertQueryBuilder.java
@@ -59,7 +59,7 @@ void appendValuesClause(StringBuilder sb) {
     void appendMatchedClause(StringBuilder sb) {
         sb.append("WHEN MATCHED THEN ");
         sb.append("UPDATE ");
-        sb.append(" SET");
+        sb.append("SET");
         Iterator<String> it = jdbcTable.dbFieldNames().iterator();
         while (it.hasNext()) {
             String dbFieldName = it.next();
@@ -83,10 +83,10 @@ void appendPrimaryKeys(StringBuilder sb) {
         for (int i = 0; i < pkFields.size(); i++) {
             String field = pkFields.get(i);
             dialect.quoteIdentifier(sb, jdbcTable.getExternalNameList());
-            sb.append(".")
-                    .append(field)
-                    .append(" = source.")
-                    .append(field);
+            sb.append(".");
+            dialect.quoteIdentifier(sb, field);
+            sb.append(" = source.");
+            dialect.quoteIdentifier(sb, field);
             if (i < pkFields.size() - 1) {
                 sb.append(" AND ");
             }


Test patch:
diff --git a/hazelcast-sql/src/test/java/com/hazelcast/jet/sql/impl/connector/jdbc/mssql/MSSQLUpsertQueryBuilderTest.java b/hazelcast-sql/src/test/java/com/hazelcast/jet/sql/impl/connector/jdbc/mssql/MSSQLUpsertQueryBuilderTest.java
index c4dcd91d276cb..7a308a0de8614 100644
--- a/hazelcast-sql/src/test/java/com/hazelcast/jet/sql/impl/connector/jdbc/mssql/MSSQLUpsertQueryBuilderTest.java
+++ b/hazelcast-sql/src/test/java/com/hazelcast/jet/sql/impl/connector/jdbc/mssql/MSSQLUpsertQueryBuilderTest.java
@@ -61,7 +61,7 @@ public void appendMergeClause() {
         StringBuilder sb = new StringBuilder();
         builder.appendMergeClause(sb);
         String mergeClause = sb.toString();
-        assertThat(mergeClause).isEqualTo("MERGE [table1] USING (VALUES (?, ?)) AS source ([field1], [field2]) ON [table1].pk1 = source.pk1 AND [table1].pk2 = source.pk2");
+        assertThat(mergeClause).isEqualTo("MERGE [table1] USING (VALUES (?, ?)) AS source ([field1], [field2]) ON [table1].[pk1] = source.[pk1] AND [table1].[pk2] = source.[pk2]");
     }
 
     @Test
@@ -82,7 +82,7 @@ public void appendMatchedClause() {
 
         String matchedClause = sb.toString();
         assertThat(matchedClause).isEqualTo(
-                "WHEN MATCHED THEN UPDATE  SET [field1] = source.[field1], [field2] = source.[field2] "
+                "WHEN MATCHED THEN UPDATE SET [field1] = source.[field1], [field2] = source.[field2] "
                         + "WHEN NOT MATCHED THEN INSERT ([field1], [field2]) VALUES(source.[field1], source.[field2]);");
     }
 
@@ -91,8 +91,8 @@ public void query() {
         MSSQLUpsertQueryBuilder builder = new MSSQLUpsertQueryBuilder(jdbcTable, dialect);
         String result = builder.query();
         assertThat(result).isEqualTo(
-                "MERGE [table1] USING (VALUES (?, ?)) AS source ([field1], [field2]) ON [table1].pk1 = source.pk1 AND [table1].pk2 = source.pk2 "
-                        + "WHEN MATCHED THEN UPDATE  SET [field1] = source.[field1], [field2] = source.[field2] "
+                "MERGE [table1] USING (VALUES (?, ?)) AS source ([field1], [field2]) ON [table1].[pk1] = source.[pk1] AND [table1].[pk2] = source.[pk2] "
+                        + "WHEN MATCHED THEN UPDATE SET [field1] = source.[field1], [field2] = source.[field2] "
                         + "WHEN NOT MATCHED THEN INSERT ([field1], [field2]) VALUES(source.[field1], source.[field2]);"
         );
     }