Skip to content

NullPointerException when running MERGE statement with correlated subquery in ON clause #4198

@lukaseder

Description

@lukaseder

Check out this reproducer:

CREATE TABLE u (i int PRIMARY KEY, j int);
CREATE TABLE v (i int PRIMARY KEY REFERENCES u);

MERGE INTO u
USING (
  VALUES (1, 1)
) t (i, j)
ON (
  u.i = t.i
  AND (
    SELECT v.i
    FROM v 
    WHERE u.i = v.i
  ) = 2
)
WHEN MATCHED THEN UPDATE SET
  u.j = 2
;

It produces this error:

org.jkiss.dbeaver.model.sql.DBSQLException: SQL Error [50000] [HY000]: General error: "java.lang.NullPointerException: Cannot invoke ""java.util.HashSet.add(Object)"" because ""this.outerResolvers"" is null" [50000-232]
	at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.executeStatement(JDBCStatementImpl.java:133)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.executeStatement(SQLQueryJob.java:615)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.lambda$2(SQLQueryJob.java:506)
	at org.jkiss.dbeaver.model.exec.DBExecUtils.tryExecuteRecover(DBExecUtils.java:192)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.executeSingleQuery(SQLQueryJob.java:525)
	at org.jkiss.dbeaver.ui.editors.sql.execute.SQLQueryJob.extractData(SQLQueryJob.java:977)
	at org.jkiss.dbeaver.ui.editors.sql.SQLEditor$QueryResultsContainer.readData(SQLEditor.java:4176)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetJobDataRead.lambda$0(ResultSetJobDataRead.java:123)
	at org.jkiss.dbeaver.model.exec.DBExecUtils.tryExecuteRecover(DBExecUtils.java:192)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetJobDataRead.run(ResultSetJobDataRead.java:121)
	at org.jkiss.dbeaver.ui.controls.resultset.ResultSetViewer$ResultSetDataPumpJob.run(ResultSetViewer.java:5154)
	at org.jkiss.dbeaver.model.runtime.AbstractJob.run(AbstractJob.java:117)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)
Caused by: org.h2.jdbc.JdbcSQLNonTransientException: General error: "java.lang.NullPointerException: Cannot invoke ""java.util.HashSet.add(Object)"" because ""this.outerResolvers"" is null" [50000-232]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:566)
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:489)
	at org.h2.message.DbException.get(DbException.java:212)
	at org.h2.message.DbException.convert(DbException.java:407)
	at org.h2.message.DbException.toSQLException(DbException.java:379)
	at org.h2.message.TraceObject.logAndConvert(TraceObject.java:365)
	at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:233)
	at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.execute(JDBCStatementImpl.java:330)
	at org.jkiss.dbeaver.model.impl.jdbc.exec.JDBCStatementImpl.executeStatement(JDBCStatementImpl.java:131)
	... 12 more
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.HashSet.add(Object)" because "this.outerResolvers" is null
	at org.h2.expression.Subquery.mapColumns(Subquery.java:92)
	at org.h2.expression.condition.Comparison.mapColumns(Comparison.java:546)
	at org.h2.expression.condition.ConditionAndOr.mapColumns(ConditionAndOr.java:290)
	at org.h2.table.TableFilter$MapColumnsVisitor.accept(TableFilter.java:1317)
	at org.h2.table.TableFilter.visit(TableFilter.java:1260)
	at org.h2.table.TableFilter.addJoin(TableFilter.java:639)
	at org.h2.command.dml.MergeUsing.doPrepare(MergeUsing.java:202)
	at org.h2.command.dml.DataChangeStatement.prepare(DataChangeStatement.java:37)
	at org.h2.command.Parser.prepareCommand(Parser.java:489)
	at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:645)
	at org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:561)
	at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1164)
	at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:245)
	at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:231)
	... 14 more

This seems to be an equivalent query that doesn't produce the problem:

MERGE INTO u
USING (
  VALUES (1, 1)
) t (i, j)
ON (
  u.i = t.i
  AND EXISTS (
    SELECT v.i
    FROM v 
    WHERE u.i = v.i
    AND v.i = 2
  )
)
WHEN MATCHED THEN UPDATE SET
  u.j = 2
;

This one also works:

MERGE INTO u
USING (
  VALUES (1, 1)
) t (i, j)
ON (
  u.i = t.i
  AND 2 IN (
    SELECT v.i
    FROM v 
    WHERE u.i = v.i
  )
)
WHEN MATCHED THEN UPDATE SET
  u.j = 2
;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions