diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index 8a7238c359f..bbf3aba1438 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -211,7 +211,7 @@ fi
 
 max_no_embedded_configs="$SSL_LIBRARY --with-plugins=max"
 max_no_qc_configs="$SSL_LIBRARY --with-plugins=max --without-query-cache"
-max_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-libevent --without-plugin=plugin_file_key_management --with-plugin-rocksdb=dynamic --with-plugin-test_sql_discovery=DYNAMIC"
+max_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-libevent --without-plugin=plugin_file_key_management --with-plugin-rocksdb=dynamic --without-plugin-tokudb --with-plugin-test_sql_discovery=DYNAMIC"
 all_configs="$SSL_LIBRARY --with-plugins=max --with-embedded-server --with-innodb_plugin --with-libevent"
 
 #
diff --git a/mysql-test/suite/sql_sequence/default.result b/mysql-test/suite/sql_sequence/default.result
index 37d536d9020..2f048c9e4e2 100644
--- a/mysql-test/suite/sql_sequence/default.result
+++ b/mysql-test/suite/sql_sequence/default.result
@@ -185,3 +185,13 @@ ALTER TABLE t1 add column d int default next value for s_not_exits;
 ERROR 42S02: Table 'test.s_not_exits' doesn't exist
 drop table t1;
 drop sequence s1;
+#
+# MDEV 22785 Crash with prepared statements and NEXTVAL()
+#
+CREATE SEQUENCE s;
+CREATE TABLE t1 (id int NOT NULL DEFAULT NEXTVAL(s), PRIMARY KEY (id));
+PREPARE stmt FROM " INSERT INTO t1 () values ()";
+INSERT INTO t1 () values ();
+EXECUTE stmt;
+DROP TABLE t1;
+DROP SEQUENCE s;
diff --git a/mysql-test/suite/sql_sequence/default.test b/mysql-test/suite/sql_sequence/default.test
index 017165c1a80..e7c13211013 100644
--- a/mysql-test/suite/sql_sequence/default.test
+++ b/mysql-test/suite/sql_sequence/default.test
@@ -123,3 +123,15 @@ ALTER TABLE t1 add column c int;
 ALTER TABLE t1 add column d int default next value for s_not_exits;
 drop table t1;
 drop sequence s1;
+
+--echo #
+--echo # MDEV 22785 Crash with prepared statements and NEXTVAL()
+--echo #
+CREATE SEQUENCE s;
+CREATE TABLE t1 (id int NOT NULL DEFAULT NEXTVAL(s), PRIMARY KEY (id));
+PREPARE stmt FROM " INSERT INTO t1 () values ()";
+INSERT INTO t1 () values ();
+EXECUTE stmt;
+# Cleanup
+DROP TABLE t1;
+DROP SEQUENCE s;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 2b06cf27d9b..f5eb0857d54 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -4450,13 +4450,13 @@ bool table_already_fk_prelocked(TABLE_LIST *tl, LEX_CSTRING *db,
 }
 
 
-static bool internal_table_exists(TABLE_LIST *global_list,
-                                  const char *table_name)
+static TABLE_LIST *internal_table_exists(TABLE_LIST *global_list,
+                                         const char *table_name)
 {
   do
   {
     if (global_list->table_name.str == table_name)
-      return 1;
+      return global_list;
   } while ((global_list= global_list->next_global));
   return 0;
 }
@@ -4471,13 +4471,23 @@ add_internal_tables(THD *thd, Query_tables_list *prelocking_ctx,
 
   do
   {
+    TABLE_LIST *tmp __attribute__((unused));
     DBUG_PRINT("info", ("table name: %s", tables->table_name.str));
     /*
       Skip table if already in the list. Can happen with prepared statements
     */
-    if (tables->next_local &&
-        internal_table_exists(global_table_list, tables->table_name.str))
+    if ((tmp= internal_table_exists(global_table_list,
+                                    tables->table_name.str)))
+    {
+      /*
+        Use the original value for the next local, used by the
+        original prepared statement. We cannot trust the original
+        next_local value as it may have been changed by a previous
+        statement using the same table.
+      */
+      tables->next_local= tmp;
       continue;
+    }
 
     TABLE_LIST *tl= (TABLE_LIST *) thd->alloc(sizeof(TABLE_LIST));
     if (!tl)