[ https://issues.apache.org/jira/browse/IGNITE-24514?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Sergey Korotkov updated IGNITE-24514: ------------------------------------- Fix Version/s: 2.18 > 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 > Fix For: 2.18 > > Time Spent: 40m > 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)