diff --git a/src/sql/drivers/db2/qsql_db2.cpp b/src/sql/drivers/db2/qsql_db2.cpp
index d5d02ff20b47be08040ddc50fe92af94116c233a..8ee65fd53651b76d4ffeeb32c6ea997e25228b8b 100644
--- a/src/sql/drivers/db2/qsql_db2.cpp
+++ b/src/sql/drivers/db2/qsql_db2.cpp
@@ -1120,19 +1120,17 @@ bool QDB2Result::nextResult()
 void QDB2Result::virtual_hook(int id, void *data)
 {
     switch (id) {
-    case QSqlResult::NextResult:
-        Q_ASSERT(data);
-        *static_cast<bool*>(data) = nextResult();
-        break;
-    case QSqlResult::DetachFromResultSet:
-        if (d->hStmt)
-            SQLCloseCursor(d->hStmt);
-        break;
     default:
         QSqlResult::virtual_hook(id, data);
     }
 }
 
+void QDB2Result::detachFromResultSet()
+{
+    if (d->hStmt)
+        SQLCloseCursor(d->hStmt);
+}
+
 /************************************/
 
 QDB2Driver::QDB2Driver(QObject* parent)
diff --git a/src/sql/drivers/db2/qsql_db2.h b/src/sql/drivers/db2/qsql_db2.h
index a2462a343535dcd056d08f9e7d6a2b082b18d732..cf25dee09617c080480cc10b062d131d25c4f379 100644
--- a/src/sql/drivers/db2/qsql_db2.h
+++ b/src/sql/drivers/db2/qsql_db2.h
@@ -80,6 +80,7 @@ protected:
     int numRowsAffected();
     QSqlRecord record() const;
     void virtual_hook(int id, void *data);
+    void detachFromResultSet();
     bool nextResult();
 
 private:
diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp
index 9bd1de1851be110a8724aad77dd7d52ddfcc2576..84648ae8150a7b23ff2bdbeb329701c0683329d4 100644
--- a/src/sql/drivers/mysql/qsql_mysql.cpp
+++ b/src/sql/drivers/mysql/qsql_mysql.cpp
@@ -839,10 +839,6 @@ bool QMYSQLResult::nextResult()
 void QMYSQLResult::virtual_hook(int id, void *data)
 {
     switch (id) {
-    case QSqlResult::NextResult:
-        Q_ASSERT(data);
-        *static_cast<bool*>(data) = nextResult();
-        break;
     default:
         QSqlResult::virtual_hook(id, data);
     }
diff --git a/src/sql/drivers/oci/qsql_oci.cpp b/src/sql/drivers/oci/qsql_oci.cpp
index 1e001f77b210b605ca52224536f52d1a00ec6d43..02eda36c9a0d728145b375648d8bcf6f34a83729 100644
--- a/src/sql/drivers/oci/qsql_oci.cpp
+++ b/src/sql/drivers/oci/qsql_oci.cpp
@@ -2042,14 +2042,18 @@ QVariant QOCIResult::lastInsertId() const
     return QVariant();
 }
 
+bool QOCIResult::execBatch(bool arrayBind)
+{
+    QOCICols::execBatch(d, boundValues(), arrayBind);
+    d->resetBindCount();
+    return d->error.type() == QSqlError::NoError;
+}
+
 void QOCIResult::virtual_hook(int id, void *data)
 {
     Q_ASSERT(data);
 
     switch (id) {
-    case QSqlResult::BatchOperation:
-        QOCICols::execBatch(d, boundValues(), *reinterpret_cast<bool *>(data));
-        break;
     default:
         QSqlCachedResult::virtual_hook(id, data);
     }
diff --git a/src/sql/drivers/oci/qsql_oci.h b/src/sql/drivers/oci/qsql_oci.h
index 9e97c84a7f58002220c8f1a4e2e153b6747d0133..42a7c860addc82ca091d77114cfea34a4419c505 100644
--- a/src/sql/drivers/oci/qsql_oci.h
+++ b/src/sql/drivers/oci/qsql_oci.h
@@ -83,6 +83,7 @@ protected:
     int numRowsAffected();
     QSqlRecord record() const;
     QVariant lastInsertId() const;
+    bool execBatch(bool arrayBind = false);
     void virtual_hook(int id, void *data);
 
 private:
diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp
index 04bc0cc894205826f69db1212ba21543130dc58c..05f740cb41e57e070530efc9d1354470606f6f34 100644
--- a/src/sql/drivers/odbc/qsql_odbc.cpp
+++ b/src/sql/drivers/odbc/qsql_odbc.cpp
@@ -1710,19 +1710,17 @@ bool QODBCResult::nextResult()
 void QODBCResult::virtual_hook(int id, void *data)
 {
     switch (id) {
-    case QSqlResult::DetachFromResultSet:
-        if (d->hStmt)
-            SQLCloseCursor(d->hStmt);
-        break;
-    case QSqlResult::NextResult:
-        Q_ASSERT(data);
-        *static_cast<bool*>(data) = nextResult();
-        break;
     default:
         QSqlResult::virtual_hook(id, data);
     }
 }
 
+void QODBCResult::detachFromResultSet()
+{
+    if (d->hStmt)
+        SQLCloseCursor(d->hStmt);
+}
+
 void QODBCResult::setForwardOnly(bool forward)
 {
     d->userForwardOnly = forward;
diff --git a/src/sql/drivers/odbc/qsql_odbc.h b/src/sql/drivers/odbc/qsql_odbc.h
index a89ce0f9b344b06b301e3f6ab5098fadcd700588..6ae65a080551be3c9ea8b4091ab7332d30ee9a33 100644
--- a/src/sql/drivers/odbc/qsql_odbc.h
+++ b/src/sql/drivers/odbc/qsql_odbc.h
@@ -104,6 +104,7 @@ protected:
     int numRowsAffected();
     QSqlRecord record() const;
     void virtual_hook(int id, void *data);
+    void detachFromResultSet();
     bool nextResult();
 
 private:
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp
index 168500e5a879e19fb1f53ad251a4335a7082a44a..bfd08c9750377b3ef5363ca5c0814c67d9a14f50 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.cpp
+++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp
@@ -334,10 +334,6 @@ QSQLiteResult::~QSQLiteResult()
 void QSQLiteResult::virtual_hook(int id, void *data)
 {
     switch (id) {
-    case QSqlResult::DetachFromResultSet:
-        if (d->stmt)
-            sqlite3_reset(d->stmt);
-        break;
     default:
         QSqlCachedResult::virtual_hook(id, data);
     }
@@ -495,6 +491,12 @@ QSqlRecord QSQLiteResult::record() const
     return d->rInf;
 }
 
+void QSQLiteResult::detachFromResultSet()
+{
+    if (d->stmt)
+        sqlite3_reset(d->stmt);
+}
+
 QVariant QSQLiteResult::handle() const
 {
     return QVariant::fromValue(d->stmt);
diff --git a/src/sql/drivers/sqlite/qsql_sqlite.h b/src/sql/drivers/sqlite/qsql_sqlite.h
index 8232be0ebcc69787abbb5cb7785ab863d831158e..0af6f6392f6483f1a9ba6b77fcbf81d1fb5b4e15 100644
--- a/src/sql/drivers/sqlite/qsql_sqlite.h
+++ b/src/sql/drivers/sqlite/qsql_sqlite.h
@@ -79,6 +79,7 @@ protected:
     int numRowsAffected();
     QVariant lastInsertId() const;
     QSqlRecord record() const;
+    void detachFromResultSet();
     void virtual_hook(int id, void *data);
 
 private:
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
index 53876404c023fd9c66d5bdc41d2b03dcfbe4b435..70dd1784975a443036f6017fa8b11cc8ec5ec4b9 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.cpp
@@ -267,9 +267,6 @@ QSQLite2Result::~QSQLite2Result()
 void QSQLite2Result::virtual_hook(int id, void *data)
 {
     switch (id) {
-    case QSqlResult::DetachFromResultSet:
-        d->finalize();
-        break;
     default:
         QSqlCachedResult::virtual_hook(id, data);
     }
@@ -343,6 +340,11 @@ QSqlRecord QSQLite2Result::record() const
     return d->rInf;
 }
 
+void QSQLite2Result::detachFromResultSet()
+{
+    d->finalize();
+}
+
 QVariant QSQLite2Result::handle() const
 {
     return QVariant::fromValue(d->currentMachine);
diff --git a/src/sql/drivers/sqlite2/qsql_sqlite2.h b/src/sql/drivers/sqlite2/qsql_sqlite2.h
index 4df870f3ae5155c08d36f55f6479cf8b37face7f..83961ec371f0ae71ae9094db61d701c145a00865 100644
--- a/src/sql/drivers/sqlite2/qsql_sqlite2.h
+++ b/src/sql/drivers/sqlite2/qsql_sqlite2.h
@@ -77,6 +77,7 @@ protected:
     int size();
     int numRowsAffected();
     QSqlRecord record() const;
+    void detachFromResultSet();
     void virtual_hook(int id, void *data);
 
 private:
diff --git a/src/sql/kernel/qsqlcachedresult.cpp b/src/sql/kernel/qsqlcachedresult.cpp
index 1971a2935de355c27c79a37ea91540745f5779e2..38d9525c925734d8a45b3094eca3c931e29ab1e1 100644
--- a/src/sql/kernel/qsqlcachedresult.cpp
+++ b/src/sql/kernel/qsqlcachedresult.cpp
@@ -305,14 +305,21 @@ QSqlCachedResult::ValueCache &QSqlCachedResult::cache()
 void QSqlCachedResult::virtual_hook(int id, void *data)
 {
     switch (id) {
-    case QSqlResult::DetachFromResultSet:
-    case QSqlResult::SetNumericalPrecision:
-        cleanup();
-        break;
     default:
         QSqlResult::virtual_hook(id, data);
     }
 }
 
+void QSqlCachedResult::detachFromResultSet()
+{
+    cleanup();
+}
+
+void QSqlCachedResult::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy)
+{
+    QSqlResult::setNumericalPrecisionPolicy(policy);
+    cleanup();
+}
+
 
 QT_END_NAMESPACE
diff --git a/src/sql/kernel/qsqlcachedresult_p.h b/src/sql/kernel/qsqlcachedresult_p.h
index 9feaa54999402e01cd1dccd454c60f0855da1fde..1fcd62b44fd30a0e55f31f15d1c27af7bef9f954 100644
--- a/src/sql/kernel/qsqlcachedresult_p.h
+++ b/src/sql/kernel/qsqlcachedresult_p.h
@@ -90,6 +90,8 @@ protected:
     ValueCache &cache();
 
     void virtual_hook(int id, void *data);
+    void detachFromResultSet();
+    void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy);
 private:
     bool cacheNext();
     QSqlCachedResultPrivate *d;
diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp
index 03e227bffc019990fe0d2cd5e3fafa0c76243434..2abcf857861cbf7279839bc38a08853b8fd11f9b 100644
--- a/src/sql/kernel/qsqlresult.cpp
+++ b/src/sql/kernel/qsqlresult.cpp
@@ -961,32 +961,24 @@ void QSqlResult::virtual_hook(int, void *)
 */
 bool QSqlResult::execBatch(bool arrayBind)
 {
-    if (driver()->hasFeature(QSqlDriver::BatchOperations)) {
-        virtual_hook(BatchOperation, &arrayBind);
-        d->resetBindCount();
-        return d->error.type() == QSqlError::NoError;
-    } else {
-        QVector<QVariant> values = d->values;
-        if (values.count() == 0)
+    Q_UNUSED(arrayBind);
+
+    QVector<QVariant> values = d->values;
+    if (values.count() == 0)
+        return false;
+    for (int i = 0; i < values.at(0).toList().count(); ++i) {
+        for (int j = 0; j < values.count(); ++j)
+            bindValue(j, values.at(j).toList().at(i), QSql::In);
+        if (!exec())
             return false;
-        for (int i = 0; i < values.at(0).toList().count(); ++i) {
-            for (int j = 0; j < values.count(); ++j)
-                bindValue(j, values.at(j).toList().at(i), QSql::In);
-            if (!exec())
-                return false;
-        }
-        return true;
     }
-    return false;
+    return true;
 }
 
 /*! \internal
  */
 void QSqlResult::detachFromResultSet()
 {
-    if (driver()->hasFeature(QSqlDriver::FinishQuery) 
-            || driver()->hasFeature(QSqlDriver::SimpleLocking))
-        virtual_hook(DetachFromResultSet, 0);
 }
 
 /*! \internal
@@ -994,7 +986,6 @@ void QSqlResult::detachFromResultSet()
 void QSqlResult::setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy)
 {
     d->precisionPolicy = policy;
-    virtual_hook(SetNumericalPrecision, &policy);
 }
 
 /*! \internal
@@ -1008,11 +999,6 @@ QSql::NumericalPrecisionPolicy QSqlResult::numericalPrecisionPolicy() const
 */
 bool QSqlResult::nextResult()
 {
-    if (driver()->hasFeature(QSqlDriver::MultipleResultSets)) {
-        bool result = false;
-        virtual_hook(NextResult, &result);
-        return result;
-    }
     return false;
 }
 
diff --git a/src/sql/kernel/qsqlresult.h b/src/sql/kernel/qsqlresult.h
index 162451c6ddc82b8aa906e5e14c66c2fb94d90119..9c4213f3635edba6cd040718ed269dd6caea6f5e 100644
--- a/src/sql/kernel/qsqlresult.h
+++ b/src/sql/kernel/qsqlresult.h
@@ -125,13 +125,13 @@ protected:
     virtual QSqlRecord record() const;
     virtual QVariant lastInsertId() const;
 
-    enum VirtualHookOperation { BatchOperation, DetachFromResultSet, SetNumericalPrecision, NextResult };
+    enum VirtualHookOperation { };
     virtual void virtual_hook(int id, void *data);
-    bool execBatch(bool arrayBind = false);
-    void detachFromResultSet();
-    void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy);
+    virtual bool execBatch(bool arrayBind = false);
+    virtual void detachFromResultSet();
+    virtual void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy policy);
     QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
-    bool nextResult();
+    virtual bool nextResult();
 
 private:
     QSqlResultPrivate* d;