[ https://issues.apache.org/jira/browse/IGNITE-24514?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17927082#comment-17927082 ]
Sergey Korotkov edited comment on IGNITE-24514 at 2/17/25 9:09 AM: ------------------------------------------------------------------- The immediate reason is a bug in H2 which is fixed in [https://github.com/h2database/h2database/commit/36350d2ecc58880bc17b36fdd6ab8c2b5ab38c70] Remove from the Session#localTempTables is done without check for null. *** In our case the temporary view created for the CTE is bound to the "T2" table. And H2 session used during query does have the not null localTempTables containing reference to this view. However during the table drop another H2 session is used (from the another H2 connection taken from pool). This new session may have null localTempTables. This causes the NPE. was (Author: JIRAUSER279895): The immediate reason is a bug in H2 which is fixed in https://github.com/h2database/h2database/commit/36350d2ecc58880bc17b36fdd6ab8c2b5ab38c70 > SQL query with WITH clause prevents table drop and causes node crash on table > recreate > -------------------------------------------------------------------------------------- > > Key: IGNITE-24514 > URL: https://issues.apache.org/jira/browse/IGNITE-24514 > Project: Ignite > Issue Type: Bug > Reporter: Sergey Korotkov > Assignee: Sergey Korotkov > Priority: Major > Labels: ise > Time Spent: 10m > Remaining Estimate: 0h > > SQL query with the WITH clause (AKA Common Table Expressions - CTEs) can > leave the H2 sql query engine in the state that the following bad things can > happen: > - Table can not be dropped correctly. Call to {{ignite.destroyCache}} or > "DROP TABLE" SQL succseed. Ignite cache is removed but not the table. > - Table can not be recreated (it fails saying table already exists) > - If table has index and created via the Ignite API and {{QueryEntity}}'s > the ignite node crashes with AsserionError. > > The problem is reproduced both the invalid or correct queries like: > {code:sql} > WITH cte AS (SELECT id FROM T2) > SELECT * FROM absent_table_to_emulate_statement_parse_failure > {code} > or > {code:sql} > WITH cte AS (SELECT id FROM T2) > SELECT * FROM T1 > {code} > After such a query the drop table fails leaving the below WARNING in the > ignite node log. Reason is that the temporary view created for the CTE is > still bound to the "T2" table. It wasn't removed after query parsing failure. > *Note that NO error will be reported to user application*. It fails > silently. > {noformat} > [2025-02-13T22:31:07,203][WARN > ][exchange-worker-#92%query.SqlFailedCteQueryTest%][SchemaManager$CompoundSchemaChangeListener] > Failed to notify listener (will ignore): Failed to drop database table > [type=T2, table="PUBLIC"."T2"] > org.apache.ignite.internal.processors.query.IgniteSQLException: Failed to > drop database table [type=T2, table="PUBLIC"."T2"] > at > org.apache.ignite.internal.processors.query.h2.H2SchemaManager.dropTable(H2SchemaManager.java:213) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.h2.H2SchemaManager.onSqlTypeDropped(H2SchemaManager.java:183) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager$CompoundSchemaChangeListener.lambda$onSqlTypeDropped$10(SchemaManager.java:1397) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager$CompoundSchemaChangeListener.executeSafe(SchemaManager.java:1459) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager$CompoundSchemaChangeListener.lambda$onSqlTypeDropped$11(SchemaManager.java:1397) > ~[classes/:?] > at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) ~[?:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager$CompoundSchemaChangeListener.onSqlTypeDropped(SchemaManager.java:1397) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager.onCacheStopped(SchemaManager.java:446) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.onCacheStop0(GridQueryProcessor.java:2462) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.onCacheStop(GridQueryProcessor.java:1322) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.stopCache(GridCacheProcessor.java:1041) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.prepareCacheStop(GridCacheProcessor.java:2610) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.prepareCacheStop(GridCacheProcessor.java:2589) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.lambda$processCacheStopRequestOnExchangeDone$a1367cb0$1(GridCacheProcessor.java:2830) > ~[classes/:?] > at > org.apache.ignite.internal.util.IgniteUtils.doInParallel(IgniteUtils.java:11624) > [classes/:?] > at > org.apache.ignite.internal.util.IgniteUtils.doInParallel(IgniteUtils.java:11526) > [classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.processCacheStopRequestOnExchangeDone(GridCacheProcessor.java:2804) > [classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.onExchangeDone(GridCacheProcessor.java:2956) > [classes/:?] > at > org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onDone(GridDhtPartitionsExchangeFuture.java:2467) > [classes/:?] > at > org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.finishExchangeOnCoordinator(GridDhtPartitionsExchangeFuture.java:3945) > [classes/:?] > at > org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onAllReceived(GridDhtPartitionsExchangeFuture.java:3717) > [classes/:?] > at > org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.distributedExchange(GridDhtPartitionsExchangeFuture.java:1768) > [classes/:?] > at > org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.init(GridDhtPartitionsExchangeFuture.java:1049) > [classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$ExchangeWorker.body0(GridCachePartitionExchangeManager.java:3170) > [classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$ExchangeWorker.body(GridCachePartitionExchangeManager.java:3004) > [classes/:?] > at > org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:125) > [classes/:?] > at java.base/java.lang.Thread.run(Thread.java:829) [?:?] > Caused by: org.h2.jdbc.JdbcSQLException: General error: > "java.lang.NullPointerException"; SQL statement: > DROP TABLE IF EXISTS "PUBLIC"."T2" [50000-197] > at org.h2.message.DbException.getJdbcSQLException(DbException.java:357) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.message.DbException.get(DbException.java:168) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.message.DbException.convert(DbException.java:307) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.command.Command.executeUpdate(Command.java:274) > ~[h2-1.4.197.jar:1.4.197] > at > org.h2.jdbc.JdbcStatement.executeUpdateInternal(JdbcStatement.java:169) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.jdbc.JdbcStatement.executeUpdate(JdbcStatement.java:126) > ~[h2-1.4.197.jar:1.4.197] > at > org.apache.ignite.internal.processors.query.h2.H2SchemaManager.dropTable(H2SchemaManager.java:209) > ~[classes/:?] > ... 26 more > Caused by: java.lang.NullPointerException > at org.h2.engine.Session.removeLocalTempTable(Session.java:407) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.engine.Database.removeSchemaObject(Database.java:1884) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.table.Table.removeChildrenAndResources(Table.java:531) > ~[h2-1.4.197.jar:1.4.197] > at > org.apache.ignite.internal.processors.query.h2.opt.GridH2Table.removeChildrenAndResources(GridH2Table.java:614) > ~[classes/:?] > at org.h2.engine.Database.removeSchemaObject(Database.java:1918) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.command.ddl.DropTable.executeDrop(DropTable.java:119) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.command.ddl.DropTable.update(DropTable.java:130) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.command.CommandContainer.update(CommandContainer.java:102) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.command.Command.executeUpdate(Command.java:261) > ~[h2-1.4.197.jar:1.4.197] > at > org.h2.jdbc.JdbcStatement.executeUpdateInternal(JdbcStatement.java:169) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.jdbc.JdbcStatement.executeUpdate(JdbcStatement.java:126) > ~[h2-1.4.197.jar:1.4.197] > at > org.apache.ignite.internal.processors.query.h2.H2SchemaManager.dropTable(H2SchemaManager.java:209) > ~[classes/:?] > ... 26 more > {noformat} > If try to recreate table with SQL the following error will be returned: > {noformat} > class org.apache.ignite.internal.processors.query.IgniteSQLException: Table > already exists: T2 > at > org.apache.ignite.internal.processors.query.QueryUtils.convert(QueryUtils.java:1710) > at > org.apache.ignite.internal.processors.query.h2.CommandProcessor.runCommandH2(CommandProcessor.java:435) > at > org.apache.ignite.internal.processors.query.h2.CommandProcessor.runCommand(CommandProcessor.java:162) > at > org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.executeCommand(IgniteH2Indexing.java:900) > at > org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.querySqlFields(IgniteH2Indexing.java:985) > at > org.apache.ignite.internal.processors.query.GridQueryProcessor$2.applyx(GridQueryProcessor.java:3135) > at > org.apache.ignite.internal.processors.query.GridQueryProcessor$2.applyx(GridQueryProcessor.java:3075) > at > org.apache.ignite.internal.util.lang.IgniteOutClosureX.apply(IgniteOutClosureX.java:36) > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuery(GridQueryProcessor.java:3861) > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.lambda$querySqlFields$3(GridQueryProcessor.java:3152) > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.executeQuerySafe(GridQueryProcessor.java:3289) > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:3071) > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2995) > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.querySqlFields(GridQueryProcessor.java:2968) > at > org.apache.ignite.internal.processors.query.SqlFailedCteQueryTest.sql(SqlFailedCteQueryTest.java:166) > at > org.apache.ignite.internal.processors.query.SqlFailedCteQueryTest.testFailedCteQueryDoesNotPreventTableRecreate(SqlFailedCteQueryTest.java:140) > 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:50) > at > org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) > at > org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) > at > org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) > at > org.apache.ignite.testframework.junits.GridAbstractTest$6.run(GridAbstractTest.java:2506) > at java.base/java.lang.Thread.run(Thread.java:829) > Caused by: SchemaOperationException [code=3, msg=Table already exists: T2] > at > org.apache.ignite.internal.processors.query.h2.CommandProcessor.runCommandH2(CommandProcessor.java:255) > ... 24 more > {noformat} > *Ignite node would crash* if try to recreate table via Ignite API and > {{QueryEntity}}'s with index configured say like > {code:java} > new CacheConfiguration<>("T2") > .setQueryEntities(Collections.singletonList( > new QueryEntity("java.lang.String", "T2") > .addQueryField("id", String.class.getName(), null) > .setIndexes(List.of( > new QueryIndex("id", false, "id_idx"))) > .setKeyFieldName("id"))) > .setSqlSchema(SCHEMA); > {code} > {noformat} > [2025-02-13T22:47:55,394][ERROR][exchange-worker-#92%query.SqlFailedCteQueryTest%][IgniteTestResources] > Critical system error detected. Will be handled accordingly to configured > handler > [hnd=o.a.i.i.processors.query.SqlFailedCteQueryTest$TestFailureHandler@c35172e, > failureCtx=FailureContext [type=SYSTEM_WORKER_TERMINATION, > err=java.lang.AssertionError]] > java.lang.AssertionError: null > at > org.apache.ignite.internal.processors.query.h2.opt.GridH2Table.commitUserIndex(GridH2Table.java:851) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.h2.opt.GridH2Table.addIndex(GridH2Table.java:750) > ~[classes/:?] > at org.h2.command.ddl.CreateIndex.update(CreateIndex.java:107) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.command.CommandContainer.update(CommandContainer.java:102) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.command.Command.executeUpdate(Command.java:261) > ~[h2-1.4.197.jar:1.4.197] > at > org.h2.jdbc.JdbcStatement.executeUpdateInternal(JdbcStatement.java:169) > ~[h2-1.4.197.jar:1.4.197] > at org.h2.jdbc.JdbcStatement.executeUpdate(JdbcStatement.java:126) > ~[h2-1.4.197.jar:1.4.197] > at > org.apache.ignite.internal.processors.query.h2.ConnectionManager.executeStatement(ConnectionManager.java:160) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.h2.H2SchemaManager.onIndexCreated(H2SchemaManager.java:308) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager$CompoundSchemaChangeListener.lambda$onIndexCreated$12(SchemaManager.java:1407) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager$CompoundSchemaChangeListener.executeSafe(SchemaManager.java:1459) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager$CompoundSchemaChangeListener.lambda$onIndexCreated$13(SchemaManager.java:1407) > ~[classes/:?] > at java.base/java.util.ArrayList.forEach(ArrayList.java:1541) ~[?:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager$CompoundSchemaChangeListener.onIndexCreated(SchemaManager.java:1407) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager.addIndex(SchemaManager.java:750) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager.createIndex0(SchemaManager.java:630) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.schema.management.SchemaManager.onCacheTypeCreated(SchemaManager.java:389) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.registerCache0(GridQueryProcessor.java:2400) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.onCacheStart0(GridQueryProcessor.java:1215) > ~[classes/:?] > at > org.apache.ignite.internal.processors.query.GridQueryProcessor.onCacheStart(GridQueryProcessor.java:1287) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.prepareCacheStart(GridCacheProcessor.java:1928) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.lambda$prepareStartCaches$55a0e703$1(GridCacheProcessor.java:1798) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.lambda$prepareStartCachesIfPossible$17(GridCacheProcessor.java:1768) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.prepareStartCaches(GridCacheProcessor.java:1795) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCacheProcessor.prepareStartCachesIfPossible(GridCacheProcessor.java:1766) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.CacheAffinitySharedManager.processCacheStartRequests(CacheAffinitySharedManager.java:994) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.CacheAffinitySharedManager.onCacheChangeRequest(CacheAffinitySharedManager.java:880) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.onCacheChangeRequest(GridDhtPartitionsExchangeFuture.java:1449) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionsExchangeFuture.init(GridDhtPartitionsExchangeFuture.java:975) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$ExchangeWorker.body0(GridCachePartitionExchangeManager.java:3170) > ~[classes/:?] > at > org.apache.ignite.internal.processors.cache.GridCachePartitionExchangeManager$ExchangeWorker.body(GridCachePartitionExchangeManager.java:3004) > [classes/:?] > at > org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:125) > [classes/:?] > at java.base/java.lang.Thread.run(Thread.java:829) [?:?] > {noformat} -- This message was sent by Atlassian Jira (v8.20.10#820010)