From c5468eb92f01324c248585990bc8196c6f5eab40 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Fri, 5 Nov 2021 12:41:49 +0800
Subject: [PATCH 01/31] Use "marlon-sousa/sea-query"

---
 Cargo.toml             |  2 +-
 src/executor/insert.rs | 23 +++++++++++------------
 2 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index 4244c3058..db5abc698 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,7 +30,7 @@ futures-util = { version = "^0.3" }
 log = { version = "^0.4", optional = true }
 rust_decimal = { version = "^1", optional = true }
 sea-orm-macros = { version = "^0.3.1", path = "sea-orm-macros", optional = true }
-sea-query = { version = "^0.18.0", features = ["thread-safe"] }
+sea-query = { version = "^0.18.0", git = "https://github.com/marlon-sousa/sea-query.git", branch = "extended-returning-support", features = ["thread-safe"] }
 sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] }
 serde = { version = "^1.0", features = ["derive"] }
 serde_json = { version = "^1", optional = true }
diff --git a/src/executor/insert.rs b/src/executor/insert.rs
index 64b6c145b..8e97ccbc4 100644
--- a/src/executor/insert.rs
+++ b/src/executor/insert.rs
@@ -1,8 +1,8 @@
 use crate::{
-    error::*, ActiveModelTrait, ConnectionTrait, DbBackend, EntityTrait, Insert, PrimaryKeyTrait,
-    Statement, TryFromU64,
+    error::*, ActiveModelTrait, ConnectionTrait, DbBackend, EntityTrait, Insert, Iterable,
+    PrimaryKeyTrait, Statement, TryFromU64,
 };
-use sea_query::{FromValueTuple, InsertStatement, ValueTuple};
+use sea_query::{FromValueTuple, InsertStatement, IntoColumnRef, Returning, ValueTuple};
 use std::{future::Future, marker::PhantomData};
 
 /// Defines a structure to perform INSERT operations in an ActiveModel
@@ -39,15 +39,14 @@ where
     {
         // so that self is dropped before entering await
         let mut query = self.query;
-        if db.get_database_backend() == DbBackend::Postgres {
-            use crate::{sea_query::Query, Iterable};
-            if <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
-                query.returning(
-                    Query::select()
-                        .columns(<A::Entity as EntityTrait>::PrimaryKey::iter())
-                        .take(),
-                );
-            }
+        if db.get_database_backend() == DbBackend::Postgres
+            && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0
+        {
+            query.returning(Returning::Columns(
+                <A::Entity as EntityTrait>::PrimaryKey::iter()
+                    .map(|c| c.into_column_ref())
+                    .collect(),
+            ));
         }
         Inserter::<A>::new(self.primary_key, query).exec(db)
     }

From c39a3b8cb26ca7ec6bc230897dcb524d363a243f Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Fri, 5 Nov 2021 18:20:25 +0800
Subject: [PATCH 02/31] Insert with returning for Postgres

---
 src/entity/active_model.rs |  9 ++---
 src/executor/insert.rs     | 70 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 69 insertions(+), 10 deletions(-)

diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs
index d46c6dbfc..ea8d47a2b 100644
--- a/src/entity/active_model.rs
+++ b/src/entity/active_model.rs
@@ -147,14 +147,9 @@ pub trait ActiveModelTrait: Clone + Debug {
         C: ConnectionTrait<'a>,
     {
         let am = ActiveModelBehavior::before_save(self, true)?;
-        let res = <Self::Entity as EntityTrait>::insert(am).exec(db).await?;
-        let found = <Self::Entity as EntityTrait>::find_by_id(res.last_insert_id)
-            .one(db)
+        let am = <Self::Entity as EntityTrait>::insert(am)
+            .exec_with_returning(db)
             .await?;
-        let am = match found {
-            Some(model) => model.into_active_model(),
-            None => return Err(DbErr::Exec("Failed to find inserted item".to_owned())),
-        };
         ActiveModelBehavior::after_save(am, true)
     }
 
diff --git a/src/executor/insert.rs b/src/executor/insert.rs
index 8e97ccbc4..363dccd9c 100644
--- a/src/executor/insert.rs
+++ b/src/executor/insert.rs
@@ -1,6 +1,6 @@
 use crate::{
-    error::*, ActiveModelTrait, ConnectionTrait, DbBackend, EntityTrait, Insert, Iterable,
-    PrimaryKeyTrait, Statement, TryFromU64,
+    error::*, ActiveModelTrait, ConnectionTrait, DbBackend, EntityTrait, Insert, IntoActiveModel,
+    Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
 };
 use sea_query::{FromValueTuple, InsertStatement, IntoColumnRef, Returning, ValueTuple};
 use std::{future::Future, marker::PhantomData};
@@ -50,6 +50,19 @@ where
         }
         Inserter::<A>::new(self.primary_key, query).exec(db)
     }
+
+    /// Execute an insert operation and return inserted row
+    pub fn exec_with_returning<'a, C>(
+        self,
+        db: &'a C,
+    ) -> impl Future<Output = Result<A, DbErr>> + '_
+    where
+        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,
+        C: ConnectionTrait<'a>,
+        A: 'a,
+    {
+        Inserter::<A>::new(self.primary_key, self.query).exec_with_returning(db)
+    }
 }
 
 impl<A> Inserter<A>
@@ -74,6 +87,19 @@ where
         let builder = db.get_database_backend();
         exec_insert(self.primary_key, builder.build(&self.query), db)
     }
+
+    /// Execute an insert operation and return inserted row
+    pub fn exec_with_returning<'a, C>(
+        self,
+        db: &'a C,
+    ) -> impl Future<Output = Result<A, DbErr>> + '_
+    where
+        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,
+        C: ConnectionTrait<'a>,
+        A: 'a,
+    {
+        exec_insert_with_returning(self.primary_key, self.query, db)
+    }
 }
 
 async fn exec_insert<'a, A, C>(
@@ -89,7 +115,7 @@ where
     type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType;
     let last_insert_id_opt = match db.get_database_backend() {
         DbBackend::Postgres => {
-            use crate::{sea_query::Iden, Iterable};
+            use crate::sea_query::Iden;
             let cols = PrimaryKey::<A>::iter()
                 .map(|col| col.to_string())
                 .collect::<Vec<_>>();
@@ -110,3 +136,41 @@ where
     };
     Ok(InsertResult { last_insert_id })
 }
+
+async fn exec_insert_with_returning<'a, A, C>(
+    primary_key: Option<ValueTuple>,
+    mut insert_statement: InsertStatement,
+    db: &'a C,
+) -> Result<A, DbErr>
+where
+    <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,
+    C: ConnectionTrait<'a>,
+    A: ActiveModelTrait,
+{
+    let db_backend = db.get_database_backend();
+    let found = match db_backend {
+        DbBackend::Postgres => {
+            insert_statement.returning(Returning::Columns(
+                <A::Entity as EntityTrait>::Column::iter()
+                    .map(|c| c.into_column_ref())
+                    .collect(),
+            ));
+            SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
+                db_backend.build(&insert_statement),
+            )
+            .one(db)
+            .await?
+        }
+        _ => {
+            let insert_res =
+                exec_insert::<A, _>(primary_key, db_backend.build(&insert_statement), db).await?;
+            <A::Entity as EntityTrait>::find_by_id(insert_res.last_insert_id)
+                .one(db)
+                .await?
+        }
+    };
+    match found {
+        Some(model) => Ok(model.into_active_model()),
+        None => Err(DbErr::Exec("Failed to find inserted item".to_owned())),
+    }
+}

From 52ff9430e19db004f724c7d800976e20cfd8ae00 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Fri, 5 Nov 2021 18:25:20 +0800
Subject: [PATCH 03/31] Docs

---
 src/executor/insert.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/executor/insert.rs b/src/executor/insert.rs
index 363dccd9c..f198826d0 100644
--- a/src/executor/insert.rs
+++ b/src/executor/insert.rs
@@ -51,7 +51,7 @@ where
         Inserter::<A>::new(self.primary_key, query).exec(db)
     }
 
-    /// Execute an insert operation and return inserted row
+    /// Execute an insert operation and return the inserted model
     pub fn exec_with_returning<'a, C>(
         self,
         db: &'a C,
@@ -88,7 +88,7 @@ where
         exec_insert(self.primary_key, builder.build(&self.query), db)
     }
 
-    /// Execute an insert operation and return inserted row
+    /// Execute an insert operation and return the inserted model
     pub fn exec_with_returning<'a, C>(
         self,
         db: &'a C,

From a977572762634b36fa9fddfa132dd421d3bed980 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Fri, 5 Nov 2021 22:13:52 +0800
Subject: [PATCH 04/31] Update with returning for Postgres

---
 src/entity/active_model.rs |  1 +
 src/executor/update.rs     | 44 ++++++++++++++++++++++++++++++++------
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs
index ea8d47a2b..945b956a1 100644
--- a/src/entity/active_model.rs
+++ b/src/entity/active_model.rs
@@ -156,6 +156,7 @@ pub trait ActiveModelTrait: Clone + Debug {
     /// Perform the `UPDATE` operation on an ActiveModel
     async fn update<'a, C>(self, db: &'a C) -> Result<Self, DbErr>
     where
+        <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
         Self: ActiveModelBehavior + 'a,
         C: ConnectionTrait<'a>,
     {
diff --git a/src/executor/update.rs b/src/executor/update.rs
index 402f29acd..439bb8f9b 100644
--- a/src/executor/update.rs
+++ b/src/executor/update.rs
@@ -1,7 +1,8 @@
 use crate::{
-    error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, Statement, UpdateMany, UpdateOne,
+    error::*, ActiveModelTrait, ConnectionTrait, DbBackend, EntityTrait, IntoActiveModel, Iterable,
+    SelectModel, SelectorRaw, Statement, UpdateMany, UpdateOne,
 };
-use sea_query::UpdateStatement;
+use sea_query::{FromValueTuple, IntoColumnRef, Returning, UpdateStatement};
 use std::future::Future;
 
 /// Defines an update operation
@@ -25,10 +26,11 @@ where
     /// Execute an update operation on an ActiveModel
     pub async fn exec<'b, C>(self, db: &'b C) -> Result<A, DbErr>
     where
+        <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,
         C: ConnectionTrait<'b>,
     {
         // so that self is dropped before entering await
-        exec_update_and_return_original(self.query, self.model, db).await
+        exec_update_and_return_updated(self.query, self.model, db).await
     }
 }
 
@@ -78,17 +80,45 @@ where
     Updater::new(query).exec(db).await
 }
 
-async fn exec_update_and_return_original<'a, A, C>(
-    query: UpdateStatement,
+async fn exec_update_and_return_updated<'a, A, C>(
+    mut query: UpdateStatement,
     model: A,
     db: &'a C,
 ) -> Result<A, DbErr>
 where
+    <A::Entity as EntityTrait>::Model: IntoActiveModel<A>,
     A: ActiveModelTrait,
     C: ConnectionTrait<'a>,
 {
-    Updater::new(query).check_record_exists().exec(db).await?;
-    Ok(model)
+    let db_backend = db.get_database_backend();
+    let found = match db_backend {
+        DbBackend::Postgres => {
+            query.returning(Returning::Columns(
+                <A::Entity as EntityTrait>::Column::iter()
+                    .map(|c| c.into_column_ref())
+                    .collect(),
+            ));
+            SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
+                db_backend.build(&query),
+            )
+            .one(db)
+            .await?
+        }
+        _ => {
+            Updater::new(query).check_record_exists().exec(db).await?;
+            let primary_key_value = match model.get_primary_key_value() {
+                Some(val) => FromValueTuple::from_value_tuple(val),
+                None => return Err(DbErr::Exec("Fail to get primary key from model".to_owned())),
+            };
+            <A::Entity as EntityTrait>::find_by_id(primary_key_value)
+                .one(db)
+                .await?
+        }
+    };
+    match found {
+        Some(model) => Ok(model.into_active_model()),
+        None => Err(DbErr::Exec("Failed to find inserted item".to_owned())),
+    }
 }
 
 async fn exec_update<'a, C>(

From 50605c731b840e8abda7061158953a4fdb79625a Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Fri, 5 Nov 2021 22:39:25 +0800
Subject: [PATCH 05/31] FIXME: breaking behaviors

---
 src/entity/base_entity.rs |   2 +-
 src/executor/update.rs    | 108 +++++++++++++++++++++-----------------
 2 files changed, 60 insertions(+), 50 deletions(-)

diff --git a/src/entity/base_entity.rs b/src/entity/base_entity.rs
index c03199d78..93d8ac8ae 100644
--- a/src/entity/base_entity.rs
+++ b/src/entity/base_entity.rs
@@ -413,7 +413,7 @@ pub trait EntityTrait: EntityName {
     /// assert_eq!(
     ///     db.into_transaction_log(),
     ///     vec![Transaction::from_sql_and_values(
-    ///         DbBackend::Postgres, r#"UPDATE "fruit" SET "name" = $1 WHERE "fruit"."id" = $2 AND "fruit"."name" LIKE $3"#,
+    ///         DbBackend::Postgres, r#"UPDATE "fruit" SET "name" = $1 WHERE "fruit"."id" = $2 AND "fruit"."name" LIKE $3 RETURNING "id", "name", "cake_id""#,
     ///         vec!["Orange".into(), 1i32.into(), "%orange%".into()]
     ///     )]);
     /// ```
diff --git a/src/executor/update.rs b/src/executor/update.rs
index 439bb8f9b..b202ca374 100644
--- a/src/executor/update.rs
+++ b/src/executor/update.rs
@@ -149,6 +149,10 @@ mod tests {
     #[smol_potat::test]
     async fn update_record_not_found_1() -> Result<(), DbErr> {
         let db = MockDatabase::new(DbBackend::Postgres)
+            .append_query_results(vec![vec![cake::Model {
+                id: 1,
+                name: "Cheese Cake".to_owned(),
+            }]])
             .append_exec_results(vec![
                 MockExecResult {
                     last_insert_id: 0,
@@ -197,41 +201,43 @@ mod tests {
             name: "New York Cheese".to_owned(),
         };
 
-        assert_eq!(
-            cake::ActiveModel {
-                name: Set("Cheese Cake".to_owned()),
-                ..model.clone().into_active_model()
-            }
-            .update(&db)
-            .await,
-            Err(DbErr::RecordNotFound(
-                "None of the database rows are affected".to_owned()
-            ))
-        );
+        // FIXME: Breaking!
 
-        assert_eq!(
-            cake::Entity::update(cake::ActiveModel {
-                name: Set("Cheese Cake".to_owned()),
-                ..model.clone().into_active_model()
-            })
-            .exec(&db)
-            .await,
-            Err(DbErr::RecordNotFound(
-                "None of the database rows are affected".to_owned()
-            ))
-        );
+        // assert_eq!(
+        //     cake::ActiveModel {
+        //         name: Set("Cheese Cake".to_owned()),
+        //         ..model.clone().into_active_model()
+        //     }
+        //     .update(&db)
+        //     .await,
+        //     Err(DbErr::RecordNotFound(
+        //         "None of the database rows are affected".to_owned()
+        //     ))
+        // );
 
-        assert_eq!(
-            Update::one(cake::ActiveModel {
-                name: Set("Cheese Cake".to_owned()),
-                ..model.into_active_model()
-            })
-            .exec(&db)
-            .await,
-            Err(DbErr::RecordNotFound(
-                "None of the database rows are affected".to_owned()
-            ))
-        );
+        // assert_eq!(
+        //     cake::Entity::update(cake::ActiveModel {
+        //         name: Set("Cheese Cake".to_owned()),
+        //         ..model.clone().into_active_model()
+        //     })
+        //     .exec(&db)
+        //     .await,
+        //     Err(DbErr::RecordNotFound(
+        //         "None of the database rows are affected".to_owned()
+        //     ))
+        // );
+
+        // assert_eq!(
+        //     Update::one(cake::ActiveModel {
+        //         name: Set("Cheese Cake".to_owned()),
+        //         ..model.into_active_model()
+        //     })
+        //     .exec(&db)
+        //     .await,
+        //     Err(DbErr::RecordNotFound(
+        //         "None of the database rows are affected".to_owned()
+        //     ))
+        // );
 
         assert_eq!(
             Update::many(cake::Entity)
@@ -247,24 +253,28 @@ mod tests {
             vec![
                 Transaction::from_sql_and_values(
                     DbBackend::Postgres,
-                    r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,
+                    r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2 RETURNING "id", "name""#,
                     vec!["Cheese Cake".into(), 1i32.into()]
                 ),
-                Transaction::from_sql_and_values(
-                    DbBackend::Postgres,
-                    r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,
-                    vec!["Cheese Cake".into(), 2i32.into()]
-                ),
-                Transaction::from_sql_and_values(
-                    DbBackend::Postgres,
-                    r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,
-                    vec!["Cheese Cake".into(), 2i32.into()]
-                ),
-                Transaction::from_sql_and_values(
-                    DbBackend::Postgres,
-                    r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,
-                    vec!["Cheese Cake".into(), 2i32.into()]
-                ),
+                // FIXME: Breaking!
+
+                // Transaction::from_sql_and_values(
+                //     DbBackend::Postgres,
+                //     r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,
+                //     vec!["Cheese Cake".into(), 2i32.into()]
+                // ),
+
+                // Transaction::from_sql_and_values(
+                //     DbBackend::Postgres,
+                //     r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,
+                //     vec!["Cheese Cake".into(), 2i32.into()]
+                // ),
+
+                // Transaction::from_sql_and_values(
+                //     DbBackend::Postgres,
+                //     r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,
+                //     vec!["Cheese Cake".into(), 2i32.into()]
+                // ),
                 Transaction::from_sql_and_values(
                     DbBackend::Postgres,
                     r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,

From 623873678b4e3599431e55700d172140fb4ccabe Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Mon, 8 Nov 2021 15:12:47 +0800
Subject: [PATCH 06/31] Handle "None of the database rows are affected" for
 Postgres

---
 src/executor/update.rs | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/src/executor/update.rs b/src/executor/update.rs
index b202ca374..b7277ccd2 100644
--- a/src/executor/update.rs
+++ b/src/executor/update.rs
@@ -91,33 +91,43 @@ where
     C: ConnectionTrait<'a>,
 {
     let db_backend = db.get_database_backend();
-    let found = match db_backend {
+    match db_backend {
         DbBackend::Postgres => {
             query.returning(Returning::Columns(
                 <A::Entity as EntityTrait>::Column::iter()
                     .map(|c| c.into_column_ref())
                     .collect(),
             ));
-            SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
-                db_backend.build(&query),
-            )
-            .one(db)
-            .await?
+            let found: Option<<A::Entity as EntityTrait>::Model> =
+                SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
+                    db_backend.build(&query),
+                )
+                .one(db)
+                .await?;
+            // If we got `None` then we are updating a row that does not exist.
+            match found {
+                Some(model) => Ok(model.into_active_model()),
+                None => Err(DbErr::RecordNotFound(
+                    "None of the database rows are affected".to_owned(),
+                )),
+            }
         }
         _ => {
+            // If we updating a row that does not exist, error will be thrown here.
             Updater::new(query).check_record_exists().exec(db).await?;
             let primary_key_value = match model.get_primary_key_value() {
                 Some(val) => FromValueTuple::from_value_tuple(val),
                 None => return Err(DbErr::Exec("Fail to get primary key from model".to_owned())),
             };
-            <A::Entity as EntityTrait>::find_by_id(primary_key_value)
+            let found = <A::Entity as EntityTrait>::find_by_id(primary_key_value)
                 .one(db)
-                .await?
+                .await?;
+            // If we cannot select the updated row from db by the cached primary key
+            match found {
+                Some(model) => Ok(model.into_active_model()),
+                None => Err(DbErr::Exec("Failed to find inserted item".to_owned())),
+            }
         }
-    };
-    match found {
-        Some(model) => Ok(model.into_active_model()),
-        None => Err(DbErr::Exec("Failed to find inserted item".to_owned())),
     }
 }
 

From 2f7cffa74ddf833efdff5071cad0c2db8d14c478 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Mon, 8 Nov 2021 15:12:56 +0800
Subject: [PATCH 07/31] Fix test cases

---
 src/executor/update.rs | 115 ++++++++++++++++++++---------------------
 1 file changed, 57 insertions(+), 58 deletions(-)

diff --git a/src/executor/update.rs b/src/executor/update.rs
index b7277ccd2..0cd42903c 100644
--- a/src/executor/update.rs
+++ b/src/executor/update.rs
@@ -159,10 +159,15 @@ mod tests {
     #[smol_potat::test]
     async fn update_record_not_found_1() -> Result<(), DbErr> {
         let db = MockDatabase::new(DbBackend::Postgres)
-            .append_query_results(vec![vec![cake::Model {
-                id: 1,
-                name: "Cheese Cake".to_owned(),
-            }]])
+            .append_query_results(vec![
+                vec![cake::Model {
+                    id: 1,
+                    name: "Cheese Cake".to_owned(),
+                }],
+                vec![],
+                vec![],
+                vec![],
+            ])
             .append_exec_results(vec![
                 MockExecResult {
                     last_insert_id: 0,
@@ -211,43 +216,41 @@ mod tests {
             name: "New York Cheese".to_owned(),
         };
 
-        // FIXME: Breaking!
-
-        // assert_eq!(
-        //     cake::ActiveModel {
-        //         name: Set("Cheese Cake".to_owned()),
-        //         ..model.clone().into_active_model()
-        //     }
-        //     .update(&db)
-        //     .await,
-        //     Err(DbErr::RecordNotFound(
-        //         "None of the database rows are affected".to_owned()
-        //     ))
-        // );
+        assert_eq!(
+            cake::ActiveModel {
+                name: Set("Cheese Cake".to_owned()),
+                ..model.clone().into_active_model()
+            }
+            .update(&db)
+            .await,
+            Err(DbErr::RecordNotFound(
+                "None of the database rows are affected".to_owned()
+            ))
+        );
 
-        // assert_eq!(
-        //     cake::Entity::update(cake::ActiveModel {
-        //         name: Set("Cheese Cake".to_owned()),
-        //         ..model.clone().into_active_model()
-        //     })
-        //     .exec(&db)
-        //     .await,
-        //     Err(DbErr::RecordNotFound(
-        //         "None of the database rows are affected".to_owned()
-        //     ))
-        // );
+        assert_eq!(
+            cake::Entity::update(cake::ActiveModel {
+                name: Set("Cheese Cake".to_owned()),
+                ..model.clone().into_active_model()
+            })
+            .exec(&db)
+            .await,
+            Err(DbErr::RecordNotFound(
+                "None of the database rows are affected".to_owned()
+            ))
+        );
 
-        // assert_eq!(
-        //     Update::one(cake::ActiveModel {
-        //         name: Set("Cheese Cake".to_owned()),
-        //         ..model.into_active_model()
-        //     })
-        //     .exec(&db)
-        //     .await,
-        //     Err(DbErr::RecordNotFound(
-        //         "None of the database rows are affected".to_owned()
-        //     ))
-        // );
+        assert_eq!(
+            Update::one(cake::ActiveModel {
+                name: Set("Cheese Cake".to_owned()),
+                ..model.into_active_model()
+            })
+            .exec(&db)
+            .await,
+            Err(DbErr::RecordNotFound(
+                "None of the database rows are affected".to_owned()
+            ))
+        );
 
         assert_eq!(
             Update::many(cake::Entity)
@@ -266,25 +269,21 @@ mod tests {
                     r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2 RETURNING "id", "name""#,
                     vec!["Cheese Cake".into(), 1i32.into()]
                 ),
-                // FIXME: Breaking!
-
-                // Transaction::from_sql_and_values(
-                //     DbBackend::Postgres,
-                //     r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,
-                //     vec!["Cheese Cake".into(), 2i32.into()]
-                // ),
-
-                // Transaction::from_sql_and_values(
-                //     DbBackend::Postgres,
-                //     r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,
-                //     vec!["Cheese Cake".into(), 2i32.into()]
-                // ),
-
-                // Transaction::from_sql_and_values(
-                //     DbBackend::Postgres,
-                //     r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,
-                //     vec!["Cheese Cake".into(), 2i32.into()]
-                // ),
+                Transaction::from_sql_and_values(
+                    DbBackend::Postgres,
+                    r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2 RETURNING "id", "name""#,
+                    vec!["Cheese Cake".into(), 2i32.into()]
+                ),
+                Transaction::from_sql_and_values(
+                    DbBackend::Postgres,
+                    r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2 RETURNING "id", "name""#,
+                    vec!["Cheese Cake".into(), 2i32.into()]
+                ),
+                Transaction::from_sql_and_values(
+                    DbBackend::Postgres,
+                    r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2 RETURNING "id", "name""#,
+                    vec!["Cheese Cake".into(), 2i32.into()]
+                ),
                 Transaction::from_sql_and_values(
                     DbBackend::Postgres,
                     r#"UPDATE "cake" SET "name" = $1 WHERE "cake"."id" = $2"#,

From 732d08002062cb5f17cb039ac3288ef077654ea2 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Mon, 8 Nov 2021 15:24:51 +0800
Subject: [PATCH 08/31] Update docs

---
 src/executor/insert.rs | 7 +++----
 src/executor/update.rs | 2 +-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/executor/insert.rs b/src/executor/insert.rs
index f198826d0..6117e782b 100644
--- a/src/executor/insert.rs
+++ b/src/executor/insert.rs
@@ -2,7 +2,7 @@ use crate::{
     error::*, ActiveModelTrait, ConnectionTrait, DbBackend, EntityTrait, Insert, IntoActiveModel,
     Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
 };
-use sea_query::{FromValueTuple, InsertStatement, IntoColumnRef, Returning, ValueTuple};
+use sea_query::{FromValueTuple, Iden, InsertStatement, IntoColumnRef, Returning, ValueTuple};
 use std::{future::Future, marker::PhantomData};
 
 /// Defines a structure to perform INSERT operations in an ActiveModel
@@ -51,7 +51,7 @@ where
         Inserter::<A>::new(self.primary_key, query).exec(db)
     }
 
-    /// Execute an insert operation and return the inserted model
+    /// Execute an insert operation and return the inserted model (use `RETURNING` syntax if database supported)
     pub fn exec_with_returning<'a, C>(
         self,
         db: &'a C,
@@ -88,7 +88,7 @@ where
         exec_insert(self.primary_key, builder.build(&self.query), db)
     }
 
-    /// Execute an insert operation and return the inserted model
+    /// Execute an insert operation and return the inserted model (use `RETURNING` syntax if database supported)
     pub fn exec_with_returning<'a, C>(
         self,
         db: &'a C,
@@ -115,7 +115,6 @@ where
     type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType;
     let last_insert_id_opt = match db.get_database_backend() {
         DbBackend::Postgres => {
-            use crate::sea_query::Iden;
             let cols = PrimaryKey::<A>::iter()
                 .map(|col| col.to_string())
                 .collect::<Vec<_>>();
diff --git a/src/executor/update.rs b/src/executor/update.rs
index 0cd42903c..c16d4644c 100644
--- a/src/executor/update.rs
+++ b/src/executor/update.rs
@@ -113,7 +113,7 @@ where
             }
         }
         _ => {
-            // If we updating a row that does not exist, error will be thrown here.
+            // If we updating a row that does not exist then an error will be thrown here.
             Updater::new(query).check_record_exists().exec(db).await?;
             let primary_key_value = match model.get_primary_key_value() {
                 Some(val) => FromValueTuple::from_value_tuple(val),

From 0eafacc2a1bc34f0499c0b8a020fbe41504bb97d Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Mon, 8 Nov 2021 17:36:30 +0800
Subject: [PATCH 09/31] Try returning on MariaDB

---
 Cargo.toml                    |  1 +
 src/database/connection.rs    |  3 +++
 src/database/db_connection.rs | 45 ++++++++++++++++++++++++-------
 src/database/transaction.rs   |  8 ++++++
 src/driver/sqlx_mysql.rs      | 51 ++++++++++++++++++++++++++++++-----
 src/executor/insert.rs        | 20 +++++++-------
 src/executor/update.rs        | 10 +++----
 7 files changed, 107 insertions(+), 31 deletions(-)

diff --git a/Cargo.toml b/Cargo.toml
index db5abc698..32589dea3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -38,6 +38,7 @@ sqlx = { version = "^0.5", optional = true }
 uuid = { version = "0.8", features = ["serde", "v4"], optional = true }
 ouroboros = "0.11"
 url = "^2.2"
+regex = "^1"
 
 [dev-dependencies]
 smol = { version = "^1.2" }
diff --git a/src/database/connection.rs b/src/database/connection.rs
index be47f9da8..e06c6e576 100644
--- a/src/database/connection.rs
+++ b/src/database/connection.rs
@@ -45,6 +45,9 @@ pub trait ConnectionTrait<'a>: Sync {
         T: Send,
         E: std::error::Error + Send;
 
+    /// Check if the connection supports `RETURNING` syntax
+    fn support_returning(&self) -> bool;
+
     /// Check if the connection is a test connection for the Mock database
     fn is_mock_connection(&self) -> bool {
         false
diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index 681903ddd..9038dc20a 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -18,7 +18,12 @@ use std::sync::Arc;
 pub enum DatabaseConnection {
     /// Create a MYSQL database connection and pool
     #[cfg(feature = "sqlx-mysql")]
-    SqlxMySqlPoolConnection(crate::SqlxMySqlPoolConnection),
+    SqlxMySqlPoolConnection {
+        /// A SQLx MySQL pool
+        conn: crate::SqlxMySqlPoolConnection,
+        /// A flag indicating whether `RETURNING` syntax is supported
+        support_returning: bool,
+    },
     /// Create a  PostgreSQL database connection and pool
     #[cfg(feature = "sqlx-postgres")]
     SqlxPostgresPoolConnection(crate::SqlxPostgresPoolConnection),
@@ -73,7 +78,7 @@ impl std::fmt::Debug for DatabaseConnection {
             "{}",
             match self {
                 #[cfg(feature = "sqlx-mysql")]
-                Self::SqlxMySqlPoolConnection(_) => "SqlxMySqlPoolConnection",
+                Self::SqlxMySqlPoolConnection { .. } => "SqlxMySqlPoolConnection",
                 #[cfg(feature = "sqlx-postgres")]
                 Self::SqlxPostgresPoolConnection(_) => "SqlxPostgresPoolConnection",
                 #[cfg(feature = "sqlx-sqlite")]
@@ -93,7 +98,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     fn get_database_backend(&self) -> DbBackend {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection(_) => DbBackend::MySql,
+            DatabaseConnection::SqlxMySqlPoolConnection { .. } => DbBackend::MySql,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(_) => DbBackend::Postgres,
             #[cfg(feature = "sqlx-sqlite")]
@@ -107,7 +112,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     async fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.execute(stmt).await,
+            DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => conn.execute(stmt).await,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(conn) => conn.execute(stmt).await,
             #[cfg(feature = "sqlx-sqlite")]
@@ -121,7 +126,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     async fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_one(stmt).await,
+            DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => conn.query_one(stmt).await,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(conn) => conn.query_one(stmt).await,
             #[cfg(feature = "sqlx-sqlite")]
@@ -135,7 +140,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     async fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_all(stmt).await,
+            DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => conn.query_all(stmt).await,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(conn) => conn.query_all(stmt).await,
             #[cfg(feature = "sqlx-sqlite")]
@@ -153,7 +158,9 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
         Box::pin(async move {
             Ok(match self {
                 #[cfg(feature = "sqlx-mysql")]
-                DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.stream(stmt).await?,
+                DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => {
+                    conn.stream(stmt).await?
+                }
                 #[cfg(feature = "sqlx-postgres")]
                 DatabaseConnection::SqlxPostgresPoolConnection(conn) => conn.stream(stmt).await?,
                 #[cfg(feature = "sqlx-sqlite")]
@@ -170,7 +177,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.begin().await,
+            DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => conn.begin().await,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(conn) => conn.begin().await,
             #[cfg(feature = "sqlx-sqlite")]
@@ -196,7 +203,9 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.transaction(_callback).await,
+            DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => {
+                conn.transaction(_callback).await
+            }
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(conn) => {
                 conn.transaction(_callback).await
@@ -214,6 +223,24 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
         }
     }
 
+    fn support_returning(&self) -> bool {
+        match self {
+            #[cfg(feature = "sqlx-mysql")]
+            DatabaseConnection::SqlxMySqlPoolConnection { .. } => false,
+            #[cfg(feature = "sqlx-postgres")]
+            DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
+            #[cfg(feature = "sqlx-sqlite")]
+            DatabaseConnection::SqlxSqlitePoolConnection(_) => false,
+            #[cfg(feature = "mock")]
+            DatabaseConnection::MockDatabaseConnection(conn) => match conn.get_database_backend() {
+                DbBackend::MySql => false,
+                DbBackend::Postgres => true,
+                DbBackend::Sqlite => false,
+            },
+            DatabaseConnection::Disconnected => panic!("Disconnected"),
+        }
+    }
+
     #[cfg(feature = "mock")]
     fn is_mock_connection(&self) -> bool {
         matches!(self, DatabaseConnection::MockDatabaseConnection(_))
diff --git a/src/database/transaction.rs b/src/database/transaction.rs
index f4a1b6787..77394acd6 100644
--- a/src/database/transaction.rs
+++ b/src/database/transaction.rs
@@ -347,6 +347,14 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
         let transaction = self.begin().await.map_err(TransactionError::Connection)?;
         transaction.run(_callback).await
     }
+
+    fn support_returning(&self) -> bool {
+        match self.backend {
+            DbBackend::MySql => false,
+            DbBackend::Postgres => true,
+            DbBackend::Sqlite => false,
+        }
+    }
 }
 
 /// Defines errors for handling transaction failures
diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs
index b2b89c680..b8803edbe 100644
--- a/src/driver/sqlx_mysql.rs
+++ b/src/driver/sqlx_mysql.rs
@@ -1,3 +1,4 @@
+use regex::Regex;
 use std::{future::Future, pin::Pin};
 
 use sqlx::{
@@ -10,7 +11,7 @@ use sea_query_driver_mysql::bind_query;
 
 use crate::{
     debug_print, error::*, executor::*, ConnectOptions, DatabaseConnection, DatabaseTransaction,
-    QueryStream, Statement, TransactionError,
+    DbBackend, QueryStream, Statement, TransactionError,
 };
 
 use super::sqlx_common::*;
@@ -42,9 +43,7 @@ impl SqlxMySqlConnector {
             opt.disable_statement_logging();
         }
         if let Ok(pool) = options.pool_options().connect_with(opt).await {
-            Ok(DatabaseConnection::SqlxMySqlPoolConnection(
-                SqlxMySqlPoolConnection { pool },
-            ))
+            into_db_connection(pool).await
         } else {
             Err(DbErr::Conn("Failed to connect.".to_owned()))
         }
@@ -53,8 +52,8 @@ impl SqlxMySqlConnector {
 
 impl SqlxMySqlConnector {
     /// Instantiate a sqlx pool connection to a [DatabaseConnection]
-    pub fn from_sqlx_mysql_pool(pool: MySqlPool) -> DatabaseConnection {
-        DatabaseConnection::SqlxMySqlPoolConnection(SqlxMySqlPoolConnection { pool })
+    pub async fn from_sqlx_mysql_pool(pool: MySqlPool) -> Result<DatabaseConnection, DbErr> {
+        into_db_connection(pool).await
     }
 }
 
@@ -183,3 +182,43 @@ pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, MySq
     }
     query
 }
+
+async fn into_db_connection(pool: MySqlPool) -> Result<DatabaseConnection, DbErr> {
+    let conn = SqlxMySqlPoolConnection { pool };
+    let res = conn
+        .query_one(Statement::from_string(
+            DbBackend::MySql,
+            r#"SHOW VARIABLES LIKE "version""#.to_owned(),
+        ))
+        .await?;
+    let support_returning = if let Some(query_result) = res {
+        let version: String = query_result.try_get("", "Value")?;
+        if !version.contains("MariaDB") {
+            // This is MySQL
+            false
+        } else {
+            // This is MariaDB
+            let regex = Regex::new(r"^(\d+)?.(\d+)?.(\*|\d+)").unwrap();
+            let captures = regex.captures(&version).unwrap();
+            macro_rules! parse_captures {
+                ( $idx: expr ) => {
+                    captures.get($idx).map_or(0, |m| {
+                        m.as_str()
+                            .parse::<usize>()
+                            .map_err(|e| DbErr::Conn(e.to_string()))
+                            .unwrap()
+                    })
+                };
+            }
+            let ver_major = parse_captures!(1);
+            let ver_minor = parse_captures!(2);
+            ver_major >= 10 && ver_minor >= 5
+        }
+    } else {
+        return Err(DbErr::Conn("Fail to parse MySQL version".to_owned()));
+    };
+    Ok(DatabaseConnection::SqlxMySqlPoolConnection {
+        conn,
+        support_returning,
+    })
+}
diff --git a/src/executor/insert.rs b/src/executor/insert.rs
index 6117e782b..9f3713736 100644
--- a/src/executor/insert.rs
+++ b/src/executor/insert.rs
@@ -1,6 +1,6 @@
 use crate::{
-    error::*, ActiveModelTrait, ConnectionTrait, DbBackend, EntityTrait, Insert, IntoActiveModel,
-    Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
+    error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, Insert, IntoActiveModel, Iterable,
+    PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
 };
 use sea_query::{FromValueTuple, Iden, InsertStatement, IntoColumnRef, Returning, ValueTuple};
 use std::{future::Future, marker::PhantomData};
@@ -39,9 +39,7 @@ where
     {
         // so that self is dropped before entering await
         let mut query = self.query;
-        if db.get_database_backend() == DbBackend::Postgres
-            && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0
-        {
+        if db.support_returning() && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
             query.returning(Returning::Columns(
                 <A::Entity as EntityTrait>::PrimaryKey::iter()
                     .map(|c| c.into_column_ref())
@@ -113,15 +111,15 @@ where
 {
     type PrimaryKey<A> = <<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey;
     type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType;
-    let last_insert_id_opt = match db.get_database_backend() {
-        DbBackend::Postgres => {
+    let last_insert_id_opt = match db.support_returning() {
+        true => {
             let cols = PrimaryKey::<A>::iter()
                 .map(|col| col.to_string())
                 .collect::<Vec<_>>();
             let res = db.query_one(statement).await?.unwrap();
             res.try_get_many("", cols.as_ref()).ok()
         }
-        _ => {
+        false => {
             let last_insert_id = db.execute(statement).await?.last_insert_id();
             ValueTypeOf::<A>::try_from_u64(last_insert_id).ok()
         }
@@ -147,8 +145,8 @@ where
     A: ActiveModelTrait,
 {
     let db_backend = db.get_database_backend();
-    let found = match db_backend {
-        DbBackend::Postgres => {
+    let found = match db.support_returning() {
+        true => {
             insert_statement.returning(Returning::Columns(
                 <A::Entity as EntityTrait>::Column::iter()
                     .map(|c| c.into_column_ref())
@@ -160,7 +158,7 @@ where
             .one(db)
             .await?
         }
-        _ => {
+        false => {
             let insert_res =
                 exec_insert::<A, _>(primary_key, db_backend.build(&insert_statement), db).await?;
             <A::Entity as EntityTrait>::find_by_id(insert_res.last_insert_id)
diff --git a/src/executor/update.rs b/src/executor/update.rs
index c16d4644c..f83e8efb6 100644
--- a/src/executor/update.rs
+++ b/src/executor/update.rs
@@ -1,5 +1,5 @@
 use crate::{
-    error::*, ActiveModelTrait, ConnectionTrait, DbBackend, EntityTrait, IntoActiveModel, Iterable,
+    error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, IntoActiveModel, Iterable,
     SelectModel, SelectorRaw, Statement, UpdateMany, UpdateOne,
 };
 use sea_query::{FromValueTuple, IntoColumnRef, Returning, UpdateStatement};
@@ -90,14 +90,14 @@ where
     A: ActiveModelTrait,
     C: ConnectionTrait<'a>,
 {
-    let db_backend = db.get_database_backend();
-    match db_backend {
-        DbBackend::Postgres => {
+    match db.support_returning() {
+        true => {
             query.returning(Returning::Columns(
                 <A::Entity as EntityTrait>::Column::iter()
                     .map(|c| c.into_column_ref())
                     .collect(),
             ));
+            let db_backend = db.get_database_backend();
             let found: Option<<A::Entity as EntityTrait>::Model> =
                 SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
                     db_backend.build(&query),
@@ -112,7 +112,7 @@ where
                 )),
             }
         }
-        _ => {
+        false => {
             // If we updating a row that does not exist then an error will be thrown here.
             Updater::new(query).check_record_exists().exec(db).await?;
             let primary_key_value = match model.get_primary_key_value() {

From 30f43b64c6151dfc5423ed8842db9138071b521d Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Mon, 8 Nov 2021 19:03:06 +0800
Subject: [PATCH 10/31] Fixup

---
 .github/workflows/rust.yml    |  6 ++++-
 Cargo.toml                    |  2 +-
 src/database/db_connection.rs | 42 ++++++++++++++++++++++++++++++++---
 src/database/transaction.rs   |  6 +----
 src/driver/sqlx_mysql.rs      |  8 ++++---
 src/executor/insert.rs        | 33 ++++++++++++++++-----------
 src/executor/update.rs        | 22 +++++++++++-------
 tests/returning_tests.rs      | 37 ++++++++++++++++++++++++++++++
 8 files changed, 122 insertions(+), 34 deletions(-)
 create mode 100644 tests/returning_tests.rs

diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index ad18203e4..0734f3acf 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -350,6 +350,7 @@ jobs:
     env:
       DATABASE_URL: "sqlite::memory:"
     strategy:
+      fail-fast: false
       matrix:
         runtime: [async-std, actix, tokio]
         tls: [native-tls, rustls]
@@ -392,6 +393,7 @@ jobs:
     env:
       DATABASE_URL: "mysql://root:@localhost"
     strategy:
+      fail-fast: false
       matrix:
         version: [8.0, 5.7]
         runtime: [async-std, actix, tokio]
@@ -452,8 +454,9 @@ jobs:
     env:
       DATABASE_URL: "mysql://root:@localhost"
     strategy:
+      fail-fast: false
       matrix:
-        version: [10.6]
+        version: [10.7, 10.6, 10.5, 10.0, 5.5]
         runtime: [async-std, actix, tokio]
         tls: [native-tls]
     services:
@@ -512,6 +515,7 @@ jobs:
     env:
       DATABASE_URL: "postgres://root:root@localhost"
     strategy:
+      fail-fast: false
       matrix:
         version: [13.3, 12.7, 11.12, 10.17, 9.6.22]
         runtime: [tokio]
diff --git a/Cargo.toml b/Cargo.toml
index 32589dea3..46d8c617b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,7 +30,7 @@ futures-util = { version = "^0.3" }
 log = { version = "^0.4", optional = true }
 rust_decimal = { version = "^1", optional = true }
 sea-orm-macros = { version = "^0.3.1", path = "sea-orm-macros", optional = true }
-sea-query = { version = "^0.18.0", git = "https://github.com/marlon-sousa/sea-query.git", branch = "extended-returning-support", features = ["thread-safe"] }
+sea-query = { version = "^0.18.2", features = ["thread-safe"] }
 sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] }
 serde = { version = "^1.0", features = ["derive"] }
 serde_json = { version = "^1", optional = true }
diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index 9038dc20a..59aaf5f2d 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -19,9 +19,11 @@ pub enum DatabaseConnection {
     /// Create a MYSQL database connection and pool
     #[cfg(feature = "sqlx-mysql")]
     SqlxMySqlPoolConnection {
-        /// A SQLx MySQL pool
+        /// The SQLx MySQL pool
         conn: crate::SqlxMySqlPoolConnection,
-        /// A flag indicating whether `RETURNING` syntax is supported
+        /// The MySQL version
+        version: String,
+        /// The flag indicating whether `RETURNING` syntax is supported
         support_returning: bool,
     },
     /// Create a  PostgreSQL database connection and pool
@@ -226,7 +228,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     fn support_returning(&self) -> bool {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { .. } => false,
+            DatabaseConnection::SqlxMySqlPoolConnection { support_returning, .. } => *support_returning,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
             #[cfg(feature = "sqlx-sqlite")]
@@ -264,6 +266,40 @@ impl DatabaseConnection {
     }
 }
 
+impl DatabaseConnection {
+    /// Get database version
+    pub fn db_version(&self) -> String {
+        match self {
+            #[cfg(feature = "sqlx-mysql")]
+            DatabaseConnection::SqlxMySqlPoolConnection { version, .. } => version.to_string(),
+            // #[cfg(feature = "sqlx-postgres")]
+            // DatabaseConnection::SqlxPostgresPoolConnection(conn) => ,
+            // #[cfg(feature = "sqlx-sqlite")]
+            // DatabaseConnection::SqlxSqlitePoolConnection(conn) => ,
+            // #[cfg(feature = "mock")]
+            // DatabaseConnection::MockDatabaseConnection(conn) => ,
+            DatabaseConnection::Disconnected => panic!("Disconnected"),
+            _ => unimplemented!(),
+        }
+    }
+
+    /// Check if database supports `RETURNING`
+    pub fn db_support_returning(&self) -> bool {
+        match self {
+            #[cfg(feature = "sqlx-mysql")]
+            DatabaseConnection::SqlxMySqlPoolConnection { support_returning, .. } => *support_returning,
+            #[cfg(feature = "sqlx-postgres")]
+            DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
+            // #[cfg(feature = "sqlx-sqlite")]
+            // DatabaseConnection::SqlxSqlitePoolConnection(conn) => ,
+            // #[cfg(feature = "mock")]
+            // DatabaseConnection::MockDatabaseConnection(conn) => ,
+            DatabaseConnection::Disconnected => panic!("Disconnected"),
+            _ => unimplemented!(),
+        }
+    }
+}
+
 impl DbBackend {
     /// Check if the URI is the same as the specified database backend.
     /// Returns true if they match.
diff --git a/src/database/transaction.rs b/src/database/transaction.rs
index 77394acd6..474f5ede2 100644
--- a/src/database/transaction.rs
+++ b/src/database/transaction.rs
@@ -349,11 +349,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
     }
 
     fn support_returning(&self) -> bool {
-        match self.backend {
-            DbBackend::MySql => false,
-            DbBackend::Postgres => true,
-            DbBackend::Sqlite => false,
-        }
+        panic!("FIXME: How?")
     }
 }
 
diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs
index b8803edbe..b66e1078f 100644
--- a/src/driver/sqlx_mysql.rs
+++ b/src/driver/sqlx_mysql.rs
@@ -191,9 +191,9 @@ async fn into_db_connection(pool: MySqlPool) -> Result<DatabaseConnection, DbErr
             r#"SHOW VARIABLES LIKE "version""#.to_owned(),
         ))
         .await?;
-    let support_returning = if let Some(query_result) = res {
+    let (version, support_returning) = if let Some(query_result) = res {
         let version: String = query_result.try_get("", "Value")?;
-        if !version.contains("MariaDB") {
+        let support_returning = if !version.contains("MariaDB") {
             // This is MySQL
             false
         } else {
@@ -213,12 +213,14 @@ async fn into_db_connection(pool: MySqlPool) -> Result<DatabaseConnection, DbErr
             let ver_major = parse_captures!(1);
             let ver_minor = parse_captures!(2);
             ver_major >= 10 && ver_minor >= 5
-        }
+        };
+        (version, support_returning)
     } else {
         return Err(DbErr::Conn("Fail to parse MySQL version".to_owned()));
     };
     Ok(DatabaseConnection::SqlxMySqlPoolConnection {
         conn,
+        version,
         support_returning,
     })
 }
diff --git a/src/executor/insert.rs b/src/executor/insert.rs
index 9f3713736..b5c2cf982 100644
--- a/src/executor/insert.rs
+++ b/src/executor/insert.rs
@@ -1,8 +1,10 @@
 use crate::{
-    error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, Insert, IntoActiveModel, Iterable,
-    PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
+    error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, Insert, IntoActiveModel,
+    Iterable, PrimaryKeyTrait, SelectModel, SelectorRaw, Statement, TryFromU64,
+};
+use sea_query::{
+    Alias, Expr, FromValueTuple, Iden, InsertStatement, IntoColumnRef, Query, ValueTuple,
 };
-use sea_query::{FromValueTuple, Iden, InsertStatement, IntoColumnRef, Returning, ValueTuple};
 use std::{future::Future, marker::PhantomData};
 
 /// Defines a structure to perform INSERT operations in an ActiveModel
@@ -40,11 +42,10 @@ where
         // so that self is dropped before entering await
         let mut query = self.query;
         if db.support_returning() && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
-            query.returning(Returning::Columns(
-                <A::Entity as EntityTrait>::PrimaryKey::iter()
-                    .map(|c| c.into_column_ref())
-                    .collect(),
-            ));
+            let mut returning = Query::select();
+            returning
+                .columns(<A::Entity as EntityTrait>::PrimaryKey::iter().map(|c| c.into_column_ref()));
+            query.returning(returning);
         }
         Inserter::<A>::new(self.primary_key, query).exec(db)
     }
@@ -147,11 +148,17 @@ where
     let db_backend = db.get_database_backend();
     let found = match db.support_returning() {
         true => {
-            insert_statement.returning(Returning::Columns(
-                <A::Entity as EntityTrait>::Column::iter()
-                    .map(|c| c.into_column_ref())
-                    .collect(),
-            ));
+            let mut returning = Query::select();
+            returning.exprs(<A::Entity as EntityTrait>::Column::iter().map(|c| {
+                let col = Expr::col(c);
+                let col_def = ColumnTrait::def(&c);
+                let col_type = col_def.get_column_type();
+                match col_type.get_enum_name() {
+                    Some(_) => col.as_enum(Alias::new("text")),
+                    None => col.into(),
+                }
+            }));
+            insert_statement.returning(returning);
             SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
                 db_backend.build(&insert_statement),
             )
diff --git a/src/executor/update.rs b/src/executor/update.rs
index f83e8efb6..9870b10d9 100644
--- a/src/executor/update.rs
+++ b/src/executor/update.rs
@@ -1,8 +1,8 @@
 use crate::{
-    error::*, ActiveModelTrait, ConnectionTrait, EntityTrait, IntoActiveModel, Iterable,
-    SelectModel, SelectorRaw, Statement, UpdateMany, UpdateOne,
+    error::*, ActiveModelTrait, ColumnTrait, ConnectionTrait, EntityTrait, IntoActiveModel,
+    Iterable, SelectModel, SelectorRaw, Statement, UpdateMany, UpdateOne,
 };
-use sea_query::{FromValueTuple, IntoColumnRef, Returning, UpdateStatement};
+use sea_query::{Alias, Expr, FromValueTuple, Query, UpdateStatement};
 use std::future::Future;
 
 /// Defines an update operation
@@ -92,11 +92,17 @@ where
 {
     match db.support_returning() {
         true => {
-            query.returning(Returning::Columns(
-                <A::Entity as EntityTrait>::Column::iter()
-                    .map(|c| c.into_column_ref())
-                    .collect(),
-            ));
+            let mut returning = Query::select();
+            returning.exprs(<A::Entity as EntityTrait>::Column::iter().map(|c| {
+                let col = Expr::col(c);
+                let col_def = c.def();
+                let col_type = col_def.get_column_type();
+                match col_type.get_enum_name() {
+                    Some(_) => col.as_enum(Alias::new("text")),
+                    None => col.into(),
+                }
+            }));
+            query.returning(returning);
             let db_backend = db.get_database_backend();
             let found: Option<<A::Entity as EntityTrait>::Model> =
                 SelectorRaw::<SelectModel<<A::Entity as EntityTrait>::Model>>::from_statement(
diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs
new file mode 100644
index 000000000..0a1e02c9a
--- /dev/null
+++ b/tests/returning_tests.rs
@@ -0,0 +1,37 @@
+pub mod common;
+
+pub use common::{features::*, setup::*, TestContext};
+use sea_orm::{entity::prelude::*, entity::*, DatabaseConnection};
+
+#[sea_orm_macros::test]
+#[cfg(any(
+    feature = "sqlx-mysql",
+    feature = "sqlx-sqlite",
+    feature = "sqlx-postgres"
+))]
+async fn main() -> Result<(), DbErr> {
+    let ctx = TestContext::new("returning_tests").await;
+    let db = &ctx.db;
+
+    match db {
+        #[cfg(feature = "sqlx-mysql")]
+        DatabaseConnection::SqlxMySqlPoolConnection { .. } => {
+            let version = db.db_version();
+            match version.as_str() {
+                "5.7.26" => assert!(!db.db_support_returning()),
+                _ => unimplemented!("Version {} is not included", version),
+            };
+        },
+        #[cfg(feature = "sqlx-postgres")]
+        DatabaseConnection::SqlxPostgresPoolConnection(_) => {
+            assert!(db.db_support_returning());
+        },
+        #[cfg(feature = "sqlx-sqlite")]
+        DatabaseConnection::SqlxSqlitePoolConnection(_) => {},
+        _ => unreachable!(),
+    }
+
+    ctx.delete().await;
+
+    Ok(())
+}

From 2f0ac4ca1d8da7cf89a8f1fe30992eb7cef4fe3d Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Mon, 8 Nov 2021 20:11:44 +0800
Subject: [PATCH 11/31] Fixup

---
 .github/workflows/rust.yml  | 4 ++--
 src/database/transaction.rs | 3 ++-
 src/driver/sqlx_mysql.rs    | 2 +-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 0734f3acf..32e96980c 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -395,7 +395,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        version: [8.0, 5.7]
+        version: [8.0.27, 5.7.36]
         runtime: [async-std, actix, tokio]
         tls: [native-tls]
     services:
@@ -456,7 +456,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        version: [10.7, 10.6, 10.5, 10.0, 5.5]
+        version: [10.6, 10.5, 10.0, 5.5]
         runtime: [async-std, actix, tokio]
         tls: [native-tls]
     services:
diff --git a/src/database/transaction.rs b/src/database/transaction.rs
index 474f5ede2..5865311f5 100644
--- a/src/database/transaction.rs
+++ b/src/database/transaction.rs
@@ -349,7 +349,8 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
     }
 
     fn support_returning(&self) -> bool {
-        panic!("FIXME: How?")
+        // FIXME: How?
+        false
     }
 }
 
diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs
index b66e1078f..dae6b0d36 100644
--- a/src/driver/sqlx_mysql.rs
+++ b/src/driver/sqlx_mysql.rs
@@ -221,6 +221,6 @@ async fn into_db_connection(pool: MySqlPool) -> Result<DatabaseConnection, DbErr
     Ok(DatabaseConnection::SqlxMySqlPoolConnection {
         conn,
         version,
-        support_returning,
+        support_returning: false,
     })
 }

From afdb1afeb897a8a51387b4b6410c6c181f1b3cb4 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Mon, 8 Nov 2021 22:12:09 +0800
Subject: [PATCH 12/31] This will fail loll

---
 .github/workflows/rust.yml    |  4 +--
 Cargo.toml                    |  2 +-
 src/database/db_connection.rs | 26 +++++--------------
 src/executor/insert.rs        |  5 ++--
 tests/returning_tests.rs      | 48 ++++++++++++++++++++++-------------
 5 files changed, 43 insertions(+), 42 deletions(-)

diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 32e96980c..35ef5cc11 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -395,7 +395,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        version: [8.0.27, 5.7.36]
+        version: [8.0, 5.7]
         runtime: [async-std, actix, tokio]
         tls: [native-tls]
     services:
@@ -456,7 +456,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        version: [10.6, 10.5, 10.0, 5.5]
+        version: [10.6, 10.5, 10.4]
         runtime: [async-std, actix, tokio]
         tls: [native-tls]
     services:
diff --git a/Cargo.toml b/Cargo.toml
index 46d8c617b..3f0e0ea31 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,7 +30,7 @@ futures-util = { version = "^0.3" }
 log = { version = "^0.4", optional = true }
 rust_decimal = { version = "^1", optional = true }
 sea-orm-macros = { version = "^0.3.1", path = "sea-orm-macros", optional = true }
-sea-query = { version = "^0.18.2", features = ["thread-safe"] }
+sea-query = { version = "^0.18.2", git = "https://github.com/SeaQL/sea-query.git", branch = "sea-orm/returning", features = ["thread-safe"] }
 sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] }
 serde = { version = "^1.0", features = ["derive"] }
 serde_json = { version = "^1", optional = true }
diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index 59aaf5f2d..663858765 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -228,7 +228,9 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     fn support_returning(&self) -> bool {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { support_returning, .. } => *support_returning,
+            DatabaseConnection::SqlxMySqlPoolConnection {
+                support_returning, ..
+            } => *support_returning,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
             #[cfg(feature = "sqlx-sqlite")]
@@ -267,27 +269,13 @@ impl DatabaseConnection {
 }
 
 impl DatabaseConnection {
-    /// Get database version
-    pub fn db_version(&self) -> String {
-        match self {
-            #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { version, .. } => version.to_string(),
-            // #[cfg(feature = "sqlx-postgres")]
-            // DatabaseConnection::SqlxPostgresPoolConnection(conn) => ,
-            // #[cfg(feature = "sqlx-sqlite")]
-            // DatabaseConnection::SqlxSqlitePoolConnection(conn) => ,
-            // #[cfg(feature = "mock")]
-            // DatabaseConnection::MockDatabaseConnection(conn) => ,
-            DatabaseConnection::Disconnected => panic!("Disconnected"),
-            _ => unimplemented!(),
-        }
-    }
-
     /// Check if database supports `RETURNING`
-    pub fn db_support_returning(&self) -> bool {
+    pub fn support_returning(&self) -> bool {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { support_returning, .. } => *support_returning,
+            DatabaseConnection::SqlxMySqlPoolConnection {
+                support_returning, ..
+            } => *support_returning,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
             // #[cfg(feature = "sqlx-sqlite")]
diff --git a/src/executor/insert.rs b/src/executor/insert.rs
index b5c2cf982..a6dbcbd53 100644
--- a/src/executor/insert.rs
+++ b/src/executor/insert.rs
@@ -43,8 +43,9 @@ where
         let mut query = self.query;
         if db.support_returning() && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
             let mut returning = Query::select();
-            returning
-                .columns(<A::Entity as EntityTrait>::PrimaryKey::iter().map(|c| c.into_column_ref()));
+            returning.columns(
+                <A::Entity as EntityTrait>::PrimaryKey::iter().map(|c| c.into_column_ref()),
+            );
             query.returning(returning);
         }
         Inserter::<A>::new(self.primary_key, query).exec(db)
diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs
index 0a1e02c9a..df8fc1a99 100644
--- a/tests/returning_tests.rs
+++ b/tests/returning_tests.rs
@@ -1,7 +1,8 @@
 pub mod common;
 
-pub use common::{features::*, setup::*, TestContext};
-use sea_orm::{entity::prelude::*, entity::*, DatabaseConnection};
+pub use common::{bakery_chain::*, setup::*, TestContext};
+use sea_orm::{entity::prelude::*, *};
+use sea_query::Query;
 
 #[sea_orm_macros::test]
 #[cfg(any(
@@ -10,27 +11,38 @@ use sea_orm::{entity::prelude::*, entity::*, DatabaseConnection};
     feature = "sqlx-postgres"
 ))]
 async fn main() -> Result<(), DbErr> {
+    use bakery::*;
+
     let ctx = TestContext::new("returning_tests").await;
     let db = &ctx.db;
+    let builder = db.get_database_backend();
+
+    let mut insert = Query::insert();
+    insert
+        .into_table(Entity)
+        .columns(vec![Column::Name, Column::ProfitMargin])
+        .values_panic(vec!["Bakery Shop".into(), 0.5.into()]);
+
+    let mut update = Query::update();
+    update
+        .table(Entity)
+        .values(vec![
+            (Column::Name, "Bakery Shop".into()),
+            (Column::ProfitMargin, 0.5.into()),
+        ])
+        .and_where(Column::Id.eq(1));
 
-    match db {
-        #[cfg(feature = "sqlx-mysql")]
-        DatabaseConnection::SqlxMySqlPoolConnection { .. } => {
-            let version = db.db_version();
-            match version.as_str() {
-                "5.7.26" => assert!(!db.db_support_returning()),
-                _ => unimplemented!("Version {} is not included", version),
-            };
-        },
-        #[cfg(feature = "sqlx-postgres")]
-        DatabaseConnection::SqlxPostgresPoolConnection(_) => {
-            assert!(db.db_support_returning());
-        },
-        #[cfg(feature = "sqlx-sqlite")]
-        DatabaseConnection::SqlxSqlitePoolConnection(_) => {},
-        _ => unreachable!(),
+    if db.support_returning() {
+        let mut returning = Query::select();
+        returning.columns(vec![Column::Id, Column::Name, Column::ProfitMargin]);
+        insert.returning(returning.clone());
+        update.returning(returning);
     }
 
+    create_tables(db).await?;
+    db.query_one(builder.build(&insert)).await?;
+    db.query_one(builder.build(&update)).await?;
+    assert!(false);
     ctx.delete().await;
 
     Ok(())

From 17232063b3dd9507d26528075a3d28b58f99cd35 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Mon, 8 Nov 2021 22:29:18 +0800
Subject: [PATCH 13/31] This will fail loll

---
 .github/workflows/rust.yml    |  2 +-
 src/database/db_connection.rs | 16 ++++++++++++++++
 src/driver/sqlx_mysql.rs      |  2 +-
 tests/returning_tests.rs      |  1 +
 4 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 35ef5cc11..c4d112352 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -517,7 +517,7 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
-        version: [13.3, 12.7, 11.12, 10.17, 9.6.22]
+        version: [13, 12, 11, 10, 9]
         runtime: [tokio]
         tls: [native-tls]
     services:
diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index 663858765..d428e11e7 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -269,6 +269,22 @@ impl DatabaseConnection {
 }
 
 impl DatabaseConnection {
+    /// Get database version
+    pub fn version(&self) -> String {
+        match self {
+            #[cfg(feature = "sqlx-mysql")]
+            DatabaseConnection::SqlxMySqlPoolConnection { version, .. } => version.to_string(),
+            #[cfg(feature = "sqlx-postgres")]
+            DatabaseConnection::SqlxPostgresPoolConnection(_) => "".to_string(),
+            #[cfg(feature = "sqlx-sqlite")]
+            DatabaseConnection::SqlxSqlitePoolConnection(_) => "".to_string(),
+            #[cfg(feature = "mock")]
+            DatabaseConnection::MockDatabaseConnection(_) => "".to_string(),
+            DatabaseConnection::Disconnected => panic!("Disconnected"),
+            _ => unimplemented!(),
+        }
+    }
+
     /// Check if database supports `RETURNING`
     pub fn support_returning(&self) -> bool {
         match self {
diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs
index dae6b0d36..b66e1078f 100644
--- a/src/driver/sqlx_mysql.rs
+++ b/src/driver/sqlx_mysql.rs
@@ -221,6 +221,6 @@ async fn into_db_connection(pool: MySqlPool) -> Result<DatabaseConnection, DbErr
     Ok(DatabaseConnection::SqlxMySqlPoolConnection {
         conn,
         version,
-        support_returning: false,
+        support_returning,
     })
 }
diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs
index df8fc1a99..d441b68b5 100644
--- a/tests/returning_tests.rs
+++ b/tests/returning_tests.rs
@@ -40,6 +40,7 @@ async fn main() -> Result<(), DbErr> {
     }
 
     create_tables(db).await?;
+    println!("db_version: {:#?}", db.version());
     db.query_one(builder.build(&insert)).await?;
     db.query_one(builder.build(&update)).await?;
     assert!(false);

From 3e6423aa8afa856a06d786ea103eec497ee8ff0c Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Mon, 8 Nov 2021 22:55:00 +0800
Subject: [PATCH 14/31] This will fail loll

---
 src/database/db_connection.rs | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index d428e11e7..9c49927a1 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -294,10 +294,8 @@ impl DatabaseConnection {
             } => *support_returning,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
-            // #[cfg(feature = "sqlx-sqlite")]
-            // DatabaseConnection::SqlxSqlitePoolConnection(conn) => ,
-            // #[cfg(feature = "mock")]
-            // DatabaseConnection::MockDatabaseConnection(conn) => ,
+            #[cfg(feature = "sqlx-sqlite")]
+            DatabaseConnection::SqlxSqlitePoolConnection(_) => false,
             DatabaseConnection::Disconnected => panic!("Disconnected"),
             _ => unimplemented!(),
         }

From 30a50ca75d67871abee421dd21179e211f49cd18 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 9 Nov 2021 10:22:31 +0800
Subject: [PATCH 15/31] Try

---
 tests/returning_tests.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs
index d441b68b5..476905067 100644
--- a/tests/returning_tests.rs
+++ b/tests/returning_tests.rs
@@ -43,7 +43,6 @@ async fn main() -> Result<(), DbErr> {
     println!("db_version: {:#?}", db.version());
     db.query_one(builder.build(&insert)).await?;
     db.query_one(builder.build(&update)).await?;
-    assert!(false);
     ctx.delete().await;
 
     Ok(())

From 429b920dedcabc697a5b354ca6acc612c861b56c Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 9 Nov 2021 11:05:55 +0800
Subject: [PATCH 16/31] Fixup

---
 src/database/connection.rs    |  7 ++++--
 src/database/db_connection.rs | 40 +++++++++++++----------------------
 src/database/transaction.rs   |  7 +++++-
 src/executor/insert.rs        |  6 +++---
 src/executor/update.rs        |  2 +-
 tests/returning_tests.rs      | 12 ++++++-----
 6 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/src/database/connection.rs b/src/database/connection.rs
index e06c6e576..2a16156e9 100644
--- a/src/database/connection.rs
+++ b/src/database/connection.rs
@@ -45,8 +45,11 @@ pub trait ConnectionTrait<'a>: Sync {
         T: Send,
         E: std::error::Error + Send;
 
-    /// Check if the connection supports `RETURNING` syntax
-    fn support_returning(&self) -> bool;
+    /// Check if the connection supports `RETURNING` syntax on insert
+    fn returning_on_insert(&self) -> bool;
+
+    /// Check if the connection supports `RETURNING` syntax on update
+    fn returning_on_update(&self) -> bool;
 
     /// Check if the connection is a test connection for the Mock database
     fn is_mock_connection(&self) -> bool {
diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index 9c49927a1..90a472e4d 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -225,7 +225,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
         }
     }
 
-    fn support_returning(&self) -> bool {
+    fn returning_on_insert(&self) -> bool {
         match self {
             #[cfg(feature = "sqlx-mysql")]
             DatabaseConnection::SqlxMySqlPoolConnection {
@@ -235,13 +235,21 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
             DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
             #[cfg(feature = "sqlx-sqlite")]
             DatabaseConnection::SqlxSqlitePoolConnection(_) => false,
-            #[cfg(feature = "mock")]
-            DatabaseConnection::MockDatabaseConnection(conn) => match conn.get_database_backend() {
-                DbBackend::MySql => false,
-                DbBackend::Postgres => true,
-                DbBackend::Sqlite => false,
-            },
             DatabaseConnection::Disconnected => panic!("Disconnected"),
+            _ => unimplemented!(),
+        }
+    }
+
+    fn returning_on_update(&self) -> bool {
+        match self {
+            #[cfg(feature = "sqlx-mysql")]
+            DatabaseConnection::SqlxMySqlPoolConnection { .. } => false,
+            #[cfg(feature = "sqlx-postgres")]
+            DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
+            #[cfg(feature = "sqlx-sqlite")]
+            DatabaseConnection::SqlxSqlitePoolConnection(_) => false,
+            DatabaseConnection::Disconnected => panic!("Disconnected"),
+            _ => unimplemented!(),
         }
     }
 
@@ -278,24 +286,6 @@ impl DatabaseConnection {
             DatabaseConnection::SqlxPostgresPoolConnection(_) => "".to_string(),
             #[cfg(feature = "sqlx-sqlite")]
             DatabaseConnection::SqlxSqlitePoolConnection(_) => "".to_string(),
-            #[cfg(feature = "mock")]
-            DatabaseConnection::MockDatabaseConnection(_) => "".to_string(),
-            DatabaseConnection::Disconnected => panic!("Disconnected"),
-            _ => unimplemented!(),
-        }
-    }
-
-    /// Check if database supports `RETURNING`
-    pub fn support_returning(&self) -> bool {
-        match self {
-            #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection {
-                support_returning, ..
-            } => *support_returning,
-            #[cfg(feature = "sqlx-postgres")]
-            DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
-            #[cfg(feature = "sqlx-sqlite")]
-            DatabaseConnection::SqlxSqlitePoolConnection(_) => false,
             DatabaseConnection::Disconnected => panic!("Disconnected"),
             _ => unimplemented!(),
         }
diff --git a/src/database/transaction.rs b/src/database/transaction.rs
index 5865311f5..727f9bc66 100644
--- a/src/database/transaction.rs
+++ b/src/database/transaction.rs
@@ -348,7 +348,12 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
         transaction.run(_callback).await
     }
 
-    fn support_returning(&self) -> bool {
+    fn returning_on_insert(&self) -> bool {
+        // FIXME: How?
+        false
+    }
+
+    fn returning_on_update(&self) -> bool {
         // FIXME: How?
         false
     }
diff --git a/src/executor/insert.rs b/src/executor/insert.rs
index a6dbcbd53..fde1a3ab4 100644
--- a/src/executor/insert.rs
+++ b/src/executor/insert.rs
@@ -41,7 +41,7 @@ where
     {
         // so that self is dropped before entering await
         let mut query = self.query;
-        if db.support_returning() && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
+        if db.returning_on_insert() && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
             let mut returning = Query::select();
             returning.columns(
                 <A::Entity as EntityTrait>::PrimaryKey::iter().map(|c| c.into_column_ref()),
@@ -113,7 +113,7 @@ where
 {
     type PrimaryKey<A> = <<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey;
     type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType;
-    let last_insert_id_opt = match db.support_returning() {
+    let last_insert_id_opt = match db.returning_on_insert() {
         true => {
             let cols = PrimaryKey::<A>::iter()
                 .map(|col| col.to_string())
@@ -147,7 +147,7 @@ where
     A: ActiveModelTrait,
 {
     let db_backend = db.get_database_backend();
-    let found = match db.support_returning() {
+    let found = match db.returning_on_insert() {
         true => {
             let mut returning = Query::select();
             returning.exprs(<A::Entity as EntityTrait>::Column::iter().map(|c| {
diff --git a/src/executor/update.rs b/src/executor/update.rs
index 9870b10d9..d27aa41d4 100644
--- a/src/executor/update.rs
+++ b/src/executor/update.rs
@@ -90,7 +90,7 @@ where
     A: ActiveModelTrait,
     C: ConnectionTrait<'a>,
 {
-    match db.support_returning() {
+    match db.returning_on_update() {
         true => {
             let mut returning = Query::select();
             returning.exprs(<A::Entity as EntityTrait>::Column::iter().map(|c| {
diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs
index 476905067..561ba2c50 100644
--- a/tests/returning_tests.rs
+++ b/tests/returning_tests.rs
@@ -31,12 +31,14 @@ async fn main() -> Result<(), DbErr> {
             (Column::ProfitMargin, 0.5.into()),
         ])
         .and_where(Column::Id.eq(1));
-
-    if db.support_returning() {
-        let mut returning = Query::select();
-        returning.columns(vec![Column::Id, Column::Name, Column::ProfitMargin]);
+    
+    let mut returning = Query::select();
+    returning.columns(vec![Column::Id, Column::Name, Column::ProfitMargin]);
+    if db.returning_on_insert() {
         insert.returning(returning.clone());
-        update.returning(returning);
+    }
+    if db.returning_on_update() {
+        update.returning(returning.clone());
     }
 
     create_tables(db).await?;

From 24fab66d17b6feff2ed628bd93f2e418aded738d Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 9 Nov 2021 12:11:00 +0800
Subject: [PATCH 17/31] Try

---
 src/database/db_connection.rs | 45 ++++++++++++++++++++++++++++-------
 src/driver/sqlx_mysql.rs      |  2 ++
 tests/returning_tests.rs      | 16 ++++++++++---
 3 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index 90a472e4d..f04b67c7e 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -230,26 +230,55 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
             #[cfg(feature = "sqlx-mysql")]
             DatabaseConnection::SqlxMySqlPoolConnection {
                 support_returning, ..
-            } => *support_returning,
+            } => {
+                // Supported if it's MariaDB on or after version 10.5.0
+                // Not supported in all MySQL versions
+                *support_returning
+            }
             #[cfg(feature = "sqlx-postgres")]
-            DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
+            DatabaseConnection::SqlxPostgresPoolConnection(_) => {
+                // Supported by all Postgres versions
+                true
+            }
             #[cfg(feature = "sqlx-sqlite")]
-            DatabaseConnection::SqlxSqlitePoolConnection(_) => false,
+            DatabaseConnection::SqlxSqlitePoolConnection(_) => {
+                // Supported by SQLite on or after version 3.35.0 (2021-03-12)
+                false
+            }
+            #[cfg(feature = "mock")]
+            DatabaseConnection::MockDatabaseConnection(conn) => match conn.get_database_backend() {
+                DbBackend::MySql => false,
+                DbBackend::Postgres => true,
+                DbBackend::Sqlite => false,
+            },
             DatabaseConnection::Disconnected => panic!("Disconnected"),
-            _ => unimplemented!(),
         }
     }
 
     fn returning_on_update(&self) -> bool {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { .. } => false,
+            DatabaseConnection::SqlxMySqlPoolConnection { .. } => {
+                // Not supported in all MySQL & MariaDB versions
+                false
+            }
             #[cfg(feature = "sqlx-postgres")]
-            DatabaseConnection::SqlxPostgresPoolConnection(_) => true,
+            DatabaseConnection::SqlxPostgresPoolConnection(_) => {
+                // Supported by all Postgres versions
+                true
+            }
             #[cfg(feature = "sqlx-sqlite")]
-            DatabaseConnection::SqlxSqlitePoolConnection(_) => false,
+            DatabaseConnection::SqlxSqlitePoolConnection(_) => {
+                // Supported by SQLite on or after version 3.35.0 (2021-03-12)
+                false
+            }
+            #[cfg(feature = "mock")]
+            DatabaseConnection::MockDatabaseConnection(conn) => match conn.get_database_backend() {
+                DbBackend::MySql => false,
+                DbBackend::Postgres => true,
+                DbBackend::Sqlite => false,
+            },
             DatabaseConnection::Disconnected => panic!("Disconnected"),
-            _ => unimplemented!(),
         }
     }
 
diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs
index b66e1078f..55f46a945 100644
--- a/src/driver/sqlx_mysql.rs
+++ b/src/driver/sqlx_mysql.rs
@@ -195,6 +195,7 @@ async fn into_db_connection(pool: MySqlPool) -> Result<DatabaseConnection, DbErr
         let version: String = query_result.try_get("", "Value")?;
         let support_returning = if !version.contains("MariaDB") {
             // This is MySQL
+            // Not supported in all MySQL versions
             false
         } else {
             // This is MariaDB
@@ -212,6 +213,7 @@ async fn into_db_connection(pool: MySqlPool) -> Result<DatabaseConnection, DbErr
             }
             let ver_major = parse_captures!(1);
             let ver_minor = parse_captures!(2);
+            // Supported if it's MariaDB with version 10.5.0 or after
             ver_major >= 10 && ver_minor >= 5
         };
         (version, support_returning)
diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs
index 561ba2c50..d67612fe6 100644
--- a/tests/returning_tests.rs
+++ b/tests/returning_tests.rs
@@ -31,7 +31,7 @@ async fn main() -> Result<(), DbErr> {
             (Column::ProfitMargin, 0.5.into()),
         ])
         .and_where(Column::Id.eq(1));
-    
+
     let mut returning = Query::select();
     returning.columns(vec![Column::Id, Column::Name, Column::ProfitMargin]);
     if db.returning_on_insert() {
@@ -43,8 +43,18 @@ async fn main() -> Result<(), DbErr> {
 
     create_tables(db).await?;
     println!("db_version: {:#?}", db.version());
-    db.query_one(builder.build(&insert)).await?;
-    db.query_one(builder.build(&update)).await?;
+    let insert_res = db.query_one(builder.build(&insert)).await?.expect("Insert failed");
+    if db.returning_on_insert() {
+        let _id: i32 = insert_res.try_get("", "id")?;
+        let _name: String = insert_res.try_get("", "name")?;
+        let _profit_margin: f64 = insert_res.try_get("", "profit_margin")?;
+    }
+    let update_res = db.query_one(builder.build(&update)).await?.expect("Update filed");
+    if db.returning_on_update() {
+        let _id: i32 = insert_res.try_get("", "id")?;
+        let _name: String = insert_res.try_get("", "name")?;
+        let _profit_margin: f64 = insert_res.try_get("", "profit_margin")?;
+    }
     ctx.delete().await;
 
     Ok(())

From 8020ae1209db35ccc0d7fb7447eb8df5ca7b3c01 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 9 Nov 2021 12:23:49 +0800
Subject: [PATCH 18/31] Fixup

---
 tests/returning_tests.rs | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs
index d67612fe6..4f2a5a884 100644
--- a/tests/returning_tests.rs
+++ b/tests/returning_tests.rs
@@ -43,18 +43,32 @@ async fn main() -> Result<(), DbErr> {
 
     create_tables(db).await?;
     println!("db_version: {:#?}", db.version());
-    let insert_res = db.query_one(builder.build(&insert)).await?.expect("Insert failed");
+
     if db.returning_on_insert() {
+        let insert_res = db
+            .query_one(builder.build(&insert))
+            .await?
+            .expect("Insert failed with query_one");
         let _id: i32 = insert_res.try_get("", "id")?;
         let _name: String = insert_res.try_get("", "name")?;
         let _profit_margin: f64 = insert_res.try_get("", "profit_margin")?;
+    } else {
+        let insert_res = db.execute(builder.build(&insert)).await?;
+        assert!(insert_res.rows_affected() > 0);
     }
-    let update_res = db.query_one(builder.build(&update)).await?.expect("Update filed");
     if db.returning_on_update() {
-        let _id: i32 = insert_res.try_get("", "id")?;
-        let _name: String = insert_res.try_get("", "name")?;
-        let _profit_margin: f64 = insert_res.try_get("", "profit_margin")?;
+        let update_res = db
+            .query_one(builder.build(&update))
+            .await?
+            .expect("Update filed with query_one");
+        let _id: i32 = update_res.try_get("", "id")?;
+        let _name: String = update_res.try_get("", "name")?;
+        let _profit_margin: f64 = update_res.try_get("", "profit_margin")?;
+    } else {
+        let update_res = db.execute(builder.build(&update)).await?;
+        assert!(update_res.rows_affected() > 0);
     }
+
     ctx.delete().await;
 
     Ok(())

From 533c3cf175e33aa4ee0fe10eb23d26d689c1255c Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 9 Nov 2021 15:38:28 +0800
Subject: [PATCH 19/31] Try

---
 src/database/db_connection.rs | 39 +++++----------
 src/database/transaction.rs   | 54 ++++++++++++++++++---
 src/driver/sqlx_mysql.rs      | 90 +++++++++++++++++++----------------
 3 files changed, 109 insertions(+), 74 deletions(-)

diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index f04b67c7e..2f78bdd7a 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -18,14 +18,7 @@ use std::sync::Arc;
 pub enum DatabaseConnection {
     /// Create a MYSQL database connection and pool
     #[cfg(feature = "sqlx-mysql")]
-    SqlxMySqlPoolConnection {
-        /// The SQLx MySQL pool
-        conn: crate::SqlxMySqlPoolConnection,
-        /// The MySQL version
-        version: String,
-        /// The flag indicating whether `RETURNING` syntax is supported
-        support_returning: bool,
-    },
+    SqlxMySqlPoolConnection(crate::SqlxMySqlPoolConnection),
     /// Create a  PostgreSQL database connection and pool
     #[cfg(feature = "sqlx-postgres")]
     SqlxPostgresPoolConnection(crate::SqlxPostgresPoolConnection),
@@ -80,7 +73,7 @@ impl std::fmt::Debug for DatabaseConnection {
             "{}",
             match self {
                 #[cfg(feature = "sqlx-mysql")]
-                Self::SqlxMySqlPoolConnection { .. } => "SqlxMySqlPoolConnection",
+                Self::SqlxMySqlPoolConnection(_) => "SqlxMySqlPoolConnection",
                 #[cfg(feature = "sqlx-postgres")]
                 Self::SqlxPostgresPoolConnection(_) => "SqlxPostgresPoolConnection",
                 #[cfg(feature = "sqlx-sqlite")]
@@ -100,7 +93,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     fn get_database_backend(&self) -> DbBackend {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { .. } => DbBackend::MySql,
+            DatabaseConnection::SqlxMySqlPoolConnection(_) => DbBackend::MySql,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(_) => DbBackend::Postgres,
             #[cfg(feature = "sqlx-sqlite")]
@@ -114,7 +107,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     async fn execute(&self, stmt: Statement) -> Result<ExecResult, DbErr> {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => conn.execute(stmt).await,
+            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.execute(stmt).await,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(conn) => conn.execute(stmt).await,
             #[cfg(feature = "sqlx-sqlite")]
@@ -128,7 +121,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     async fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, DbErr> {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => conn.query_one(stmt).await,
+            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_one(stmt).await,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(conn) => conn.query_one(stmt).await,
             #[cfg(feature = "sqlx-sqlite")]
@@ -142,7 +135,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     async fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, DbErr> {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => conn.query_all(stmt).await,
+            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_all(stmt).await,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(conn) => conn.query_all(stmt).await,
             #[cfg(feature = "sqlx-sqlite")]
@@ -160,9 +153,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
         Box::pin(async move {
             Ok(match self {
                 #[cfg(feature = "sqlx-mysql")]
-                DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => {
-                    conn.stream(stmt).await?
-                }
+                DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.stream(stmt).await?,
                 #[cfg(feature = "sqlx-postgres")]
                 DatabaseConnection::SqlxPostgresPoolConnection(conn) => conn.stream(stmt).await?,
                 #[cfg(feature = "sqlx-sqlite")]
@@ -179,7 +170,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => conn.begin().await,
+            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.begin().await,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(conn) => conn.begin().await,
             #[cfg(feature = "sqlx-sqlite")]
@@ -205,9 +196,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { conn, .. } => {
-                conn.transaction(_callback).await
-            }
+            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.transaction(_callback).await,
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(conn) => {
                 conn.transaction(_callback).await
@@ -228,12 +217,10 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     fn returning_on_insert(&self) -> bool {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection {
-                support_returning, ..
-            } => {
+            DatabaseConnection::SqlxMySqlPoolConnection(conn) => {
                 // Supported if it's MariaDB on or after version 10.5.0
                 // Not supported in all MySQL versions
-                *support_returning
+                conn.support_returning
             }
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(_) => {
@@ -258,7 +245,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
     fn returning_on_update(&self) -> bool {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { .. } => {
+            DatabaseConnection::SqlxMySqlPoolConnection(_) => {
                 // Not supported in all MySQL & MariaDB versions
                 false
             }
@@ -310,7 +297,7 @@ impl DatabaseConnection {
     pub fn version(&self) -> String {
         match self {
             #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection { version, .. } => version.to_string(),
+            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.version.to_string(),
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(_) => "".to_string(),
             #[cfg(feature = "sqlx-sqlite")]
diff --git a/src/database/transaction.rs b/src/database/transaction.rs
index 727f9bc66..71573f0d7 100644
--- a/src/database/transaction.rs
+++ b/src/database/transaction.rs
@@ -16,6 +16,7 @@ pub struct DatabaseTransaction {
     conn: Arc<Mutex<InnerConnection>>,
     backend: DbBackend,
     open: bool,
+    support_returning: bool,
 }
 
 impl std::fmt::Debug for DatabaseTransaction {
@@ -28,10 +29,12 @@ impl DatabaseTransaction {
     #[cfg(feature = "sqlx-mysql")]
     pub(crate) async fn new_mysql(
         inner: PoolConnection<sqlx::MySql>,
+        support_returning: bool,
     ) -> Result<DatabaseTransaction, DbErr> {
         Self::begin(
             Arc::new(Mutex::new(InnerConnection::MySql(inner))),
             DbBackend::MySql,
+            support_returning,
         )
         .await
     }
@@ -43,6 +46,7 @@ impl DatabaseTransaction {
         Self::begin(
             Arc::new(Mutex::new(InnerConnection::Postgres(inner))),
             DbBackend::Postgres,
+            true,
         )
         .await
     }
@@ -54,6 +58,7 @@ impl DatabaseTransaction {
         Self::begin(
             Arc::new(Mutex::new(InnerConnection::Sqlite(inner))),
             DbBackend::Sqlite,
+            false,
         )
         .await
     }
@@ -63,17 +68,28 @@ impl DatabaseTransaction {
         inner: Arc<crate::MockDatabaseConnection>,
     ) -> Result<DatabaseTransaction, DbErr> {
         let backend = inner.get_database_backend();
-        Self::begin(Arc::new(Mutex::new(InnerConnection::Mock(inner))), backend).await
+        Self::begin(
+            Arc::new(Mutex::new(InnerConnection::Mock(inner))),
+            backend,
+            match backend {
+                DbBackend::MySql => false,
+                DbBackend::Postgres => true,
+                DbBackend::Sqlite => false,
+            },
+        )
+        .await
     }
 
     async fn begin(
         conn: Arc<Mutex<InnerConnection>>,
         backend: DbBackend,
+        support_returning: bool,
     ) -> Result<DatabaseTransaction, DbErr> {
         let res = DatabaseTransaction {
             conn,
             backend,
             open: true,
+            support_returning,
         };
         match *res.conn.lock().await {
             #[cfg(feature = "sqlx-mysql")]
@@ -330,7 +346,8 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
     }
 
     async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
-        DatabaseTransaction::begin(Arc::clone(&self.conn), self.backend).await
+        DatabaseTransaction::begin(Arc::clone(&self.conn), self.backend, self.support_returning)
+            .await
     }
 
     /// Execute the function inside a transaction.
@@ -349,13 +366,38 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
     }
 
     fn returning_on_insert(&self) -> bool {
-        // FIXME: How?
-        false
+        match self.backend {
+            DbBackend::MySql => {
+                // Supported if it's MariaDB on or after version 10.5.0
+                // Not supported in all MySQL versions
+                self.support_returning
+            }
+            DbBackend::Postgres => {
+                // Supported by all Postgres versions
+                true
+            }
+            DbBackend::Sqlite => {
+                // Supported by SQLite on or after version 3.35.0 (2021-03-12)
+                false
+            }
+        }
     }
 
     fn returning_on_update(&self) -> bool {
-        // FIXME: How?
-        false
+        match self.backend {
+            DbBackend::MySql => {
+                // Not supported in all MySQL & MariaDB versions
+                false
+            }
+            DbBackend::Postgres => {
+                // Supported by all Postgres versions
+                true
+            }
+            DbBackend::Sqlite => {
+                // Supported by SQLite on or after version 3.35.0 (2021-03-12)
+                false
+            }
+        }
     }
 }
 
diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs
index 55f46a945..e31307ee1 100644
--- a/src/driver/sqlx_mysql.rs
+++ b/src/driver/sqlx_mysql.rs
@@ -3,7 +3,7 @@ use std::{future::Future, pin::Pin};
 
 use sqlx::{
     mysql::{MySqlArguments, MySqlConnectOptions, MySqlQueryResult, MySqlRow},
-    MySql, MySqlPool,
+    MySql, MySqlPool, Row,
 };
 
 sea_query::sea_query_driver_mysql!();
@@ -24,6 +24,8 @@ pub struct SqlxMySqlConnector;
 #[derive(Debug, Clone)]
 pub struct SqlxMySqlPoolConnection {
     pool: MySqlPool,
+    pub(crate) version: String,
+    pub(crate) support_returning: bool,
 }
 
 impl SqlxMySqlConnector {
@@ -128,7 +130,7 @@ impl SqlxMySqlPoolConnection {
     /// Bundle a set of SQL statements that execute together.
     pub async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
         if let Ok(conn) = self.pool.acquire().await {
-            DatabaseTransaction::new_mysql(conn).await
+            DatabaseTransaction::new_mysql(conn, self.support_returning).await
         } else {
             Err(DbErr::Query(
                 "Failed to acquire connection from pool.".to_owned(),
@@ -147,7 +149,7 @@ impl SqlxMySqlPoolConnection {
         E: std::error::Error + Send,
     {
         if let Ok(conn) = self.pool.acquire().await {
-            let transaction = DatabaseTransaction::new_mysql(conn)
+            let transaction = DatabaseTransaction::new_mysql(conn, self.support_returning)
                 .await
                 .map_err(|e| TransactionError::Connection(e))?;
             transaction.run(callback).await
@@ -184,45 +186,49 @@ pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, MySq
 }
 
 async fn into_db_connection(pool: MySqlPool) -> Result<DatabaseConnection, DbErr> {
-    let conn = SqlxMySqlPoolConnection { pool };
-    let res = conn
-        .query_one(Statement::from_string(
-            DbBackend::MySql,
-            r#"SHOW VARIABLES LIKE "version""#.to_owned(),
-        ))
-        .await?;
-    let (version, support_returning) = if let Some(query_result) = res {
-        let version: String = query_result.try_get("", "Value")?;
-        let support_returning = if !version.contains("MariaDB") {
-            // This is MySQL
-            // Not supported in all MySQL versions
-            false
-        } else {
-            // This is MariaDB
-            let regex = Regex::new(r"^(\d+)?.(\d+)?.(\*|\d+)").unwrap();
-            let captures = regex.captures(&version).unwrap();
-            macro_rules! parse_captures {
-                ( $idx: expr ) => {
-                    captures.get($idx).map_or(0, |m| {
-                        m.as_str()
-                            .parse::<usize>()
-                            .map_err(|e| DbErr::Conn(e.to_string()))
-                            .unwrap()
-                    })
-                };
-            }
-            let ver_major = parse_captures!(1);
-            let ver_minor = parse_captures!(2);
-            // Supported if it's MariaDB with version 10.5.0 or after
-            ver_major >= 10 && ver_minor >= 5
-        };
-        (version, support_returning)
+    let (version, support_returning) = parse_support_returning(&pool).await?;
+    Ok(DatabaseConnection::SqlxMySqlPoolConnection(
+        SqlxMySqlPoolConnection {
+            pool,
+            version,
+            support_returning,
+        },
+    ))
+}
+
+async fn parse_support_returning(pool: &MySqlPool) -> Result<(String, bool), DbErr> {
+    let stmt = Statement::from_string(
+        DbBackend::MySql,
+        r#"SHOW VARIABLES LIKE "version""#.to_owned(),
+    );
+    let query = sqlx_query(&stmt);
+    let row = query
+        .fetch_one(pool)
+        .await
+        .map_err(sqlx_error_to_query_err)?;
+    let version: String = row.try_get("Value").map_err(sqlx_error_to_query_err)?;
+    let support_returning = if !version.contains("MariaDB") {
+        // This is MySQL
+        // Not supported in all MySQL versions
+        false
     } else {
-        return Err(DbErr::Conn("Fail to parse MySQL version".to_owned()));
+        // This is MariaDB
+        let regex = Regex::new(r"^(\d+)?.(\d+)?.(\*|\d+)").unwrap();
+        let captures = regex.captures(&version).unwrap();
+        macro_rules! parse_captures {
+            ( $idx: expr ) => {
+                captures.get($idx).map_or(0, |m| {
+                    m.as_str()
+                        .parse::<usize>()
+                        .map_err(|e| DbErr::Conn(e.to_string()))
+                        .unwrap()
+                })
+            };
+        }
+        let ver_major = parse_captures!(1);
+        let ver_minor = parse_captures!(2);
+        // Supported if it's MariaDB with version 10.5.0 or after
+        ver_major >= 10 && ver_minor >= 5
     };
-    Ok(DatabaseConnection::SqlxMySqlPoolConnection {
-        conn,
-        version,
-        support_returning,
-    })
+    Ok((version, support_returning))
 }

From ec637b26a04cad37d9907a1727571f55c22a7999 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 9 Nov 2021 16:10:52 +0800
Subject: [PATCH 20/31] Returning support for SQLite

---
 src/database/db_connection.rs | 10 +++---
 src/database/transaction.rs   |  7 ++--
 src/driver/sqlx_sqlite.rs     | 60 +++++++++++++++++++++++++++++------
 tests/returning_tests.rs      |  8 ++---
 4 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index 2f78bdd7a..476fe8e09 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -228,9 +228,9 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
                 true
             }
             #[cfg(feature = "sqlx-sqlite")]
-            DatabaseConnection::SqlxSqlitePoolConnection(_) => {
+            DatabaseConnection::SqlxSqlitePoolConnection(conn) => {
                 // Supported by SQLite on or after version 3.35.0 (2021-03-12)
-                false
+                conn.support_returning
             }
             #[cfg(feature = "mock")]
             DatabaseConnection::MockDatabaseConnection(conn) => match conn.get_database_backend() {
@@ -255,9 +255,9 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
                 true
             }
             #[cfg(feature = "sqlx-sqlite")]
-            DatabaseConnection::SqlxSqlitePoolConnection(_) => {
+            DatabaseConnection::SqlxSqlitePoolConnection(conn) => {
                 // Supported by SQLite on or after version 3.35.0 (2021-03-12)
-                false
+                conn.support_returning
             }
             #[cfg(feature = "mock")]
             DatabaseConnection::MockDatabaseConnection(conn) => match conn.get_database_backend() {
@@ -301,7 +301,7 @@ impl DatabaseConnection {
             #[cfg(feature = "sqlx-postgres")]
             DatabaseConnection::SqlxPostgresPoolConnection(_) => "".to_string(),
             #[cfg(feature = "sqlx-sqlite")]
-            DatabaseConnection::SqlxSqlitePoolConnection(_) => "".to_string(),
+            DatabaseConnection::SqlxSqlitePoolConnection(conn) => conn.version.to_string(),
             DatabaseConnection::Disconnected => panic!("Disconnected"),
             _ => unimplemented!(),
         }
diff --git a/src/database/transaction.rs b/src/database/transaction.rs
index 71573f0d7..168461c48 100644
--- a/src/database/transaction.rs
+++ b/src/database/transaction.rs
@@ -54,11 +54,12 @@ impl DatabaseTransaction {
     #[cfg(feature = "sqlx-sqlite")]
     pub(crate) async fn new_sqlite(
         inner: PoolConnection<sqlx::Sqlite>,
+        support_returning: bool,
     ) -> Result<DatabaseTransaction, DbErr> {
         Self::begin(
             Arc::new(Mutex::new(InnerConnection::Sqlite(inner))),
             DbBackend::Sqlite,
-            false,
+            support_returning,
         )
         .await
     }
@@ -378,7 +379,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
             }
             DbBackend::Sqlite => {
                 // Supported by SQLite on or after version 3.35.0 (2021-03-12)
-                false
+                self.support_returning
             }
         }
     }
@@ -395,7 +396,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
             }
             DbBackend::Sqlite => {
                 // Supported by SQLite on or after version 3.35.0 (2021-03-12)
-                false
+                self.support_returning
             }
         }
     }
diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs
index 69eee5752..c98a3dea4 100644
--- a/src/driver/sqlx_sqlite.rs
+++ b/src/driver/sqlx_sqlite.rs
@@ -1,8 +1,9 @@
+use regex::Regex;
 use std::{future::Future, pin::Pin};
 
 use sqlx::{
     sqlite::{SqliteArguments, SqliteConnectOptions, SqliteQueryResult, SqliteRow},
-    Sqlite, SqlitePool,
+    Row, Sqlite, SqlitePool,
 };
 
 sea_query::sea_query_driver_sqlite!();
@@ -10,7 +11,7 @@ use sea_query_driver_sqlite::bind_query;
 
 use crate::{
     debug_print, error::*, executor::*, ConnectOptions, DatabaseConnection, DatabaseTransaction,
-    QueryStream, Statement, TransactionError,
+    DbBackend, QueryStream, Statement, TransactionError,
 };
 
 use super::sqlx_common::*;
@@ -23,6 +24,8 @@ pub struct SqlxSqliteConnector;
 #[derive(Debug, Clone)]
 pub struct SqlxSqlitePoolConnection {
     pool: SqlitePool,
+    pub(crate) version: String,
+    pub(crate) support_returning: bool,
 }
 
 impl SqlxSqliteConnector {
@@ -46,9 +49,7 @@ impl SqlxSqliteConnector {
             options.max_connections(1);
         }
         if let Ok(pool) = options.pool_options().connect_with(opt).await {
-            Ok(DatabaseConnection::SqlxSqlitePoolConnection(
-                SqlxSqlitePoolConnection { pool },
-            ))
+            into_db_connection(pool).await
         } else {
             Err(DbErr::Conn("Failed to connect.".to_owned()))
         }
@@ -57,8 +58,8 @@ impl SqlxSqliteConnector {
 
 impl SqlxSqliteConnector {
     /// Instantiate a sqlx pool connection to a [DatabaseConnection]
-    pub fn from_sqlx_sqlite_pool(pool: SqlitePool) -> DatabaseConnection {
-        DatabaseConnection::SqlxSqlitePoolConnection(SqlxSqlitePoolConnection { pool })
+    pub async fn from_sqlx_sqlite_pool(pool: SqlitePool) -> Result<DatabaseConnection, DbErr> {
+        into_db_connection(pool).await
     }
 }
 
@@ -133,7 +134,7 @@ impl SqlxSqlitePoolConnection {
     /// Bundle a set of SQL statements that execute together.
     pub async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
         if let Ok(conn) = self.pool.acquire().await {
-            DatabaseTransaction::new_sqlite(conn).await
+            DatabaseTransaction::new_sqlite(conn, self.support_returning).await
         } else {
             Err(DbErr::Query(
                 "Failed to acquire connection from pool.".to_owned(),
@@ -152,7 +153,7 @@ impl SqlxSqlitePoolConnection {
         E: std::error::Error + Send,
     {
         if let Ok(conn) = self.pool.acquire().await {
-            let transaction = DatabaseTransaction::new_sqlite(conn)
+            let transaction = DatabaseTransaction::new_sqlite(conn, self.support_returning)
                 .await
                 .map_err(|e| TransactionError::Connection(e))?;
             transaction.run(callback).await
@@ -187,3 +188,44 @@ pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Sqlite, Sql
     }
     query
 }
+
+async fn into_db_connection(pool: SqlitePool) -> Result<DatabaseConnection, DbErr> {
+    let (version, support_returning) = parse_support_returning(&pool).await?;
+    Ok(DatabaseConnection::SqlxSqlitePoolConnection(
+        SqlxSqlitePoolConnection {
+            pool,
+            version,
+            support_returning,
+        },
+    ))
+}
+
+async fn parse_support_returning(pool: &SqlitePool) -> Result<(String, bool), DbErr> {
+    let stmt = Statement::from_string(
+        DbBackend::Sqlite,
+        r#"SELECT sqlite_version() AS version"#.to_owned(),
+    );
+    let query = sqlx_query(&stmt);
+    let row = query
+        .fetch_one(pool)
+        .await
+        .map_err(sqlx_error_to_query_err)?;
+    let version: String = row.try_get("version").map_err(sqlx_error_to_query_err)?;
+    let regex = Regex::new(r"^(\d+)?.(\d+)?.(\*|\d+)").unwrap();
+    let captures = regex.captures(&version).unwrap();
+    macro_rules! parse_captures {
+        ( $idx: expr ) => {
+            captures.get($idx).map_or(0, |m| {
+                m.as_str()
+                    .parse::<usize>()
+                    .map_err(|e| DbErr::Conn(e.to_string()))
+                    .unwrap()
+            })
+        };
+    }
+    let ver_major = parse_captures!(1);
+    let ver_minor = parse_captures!(2);
+    // Supported if it's version 3.35.0 (2021-03-12) or after
+    let support_returning = ver_major >= 3 && ver_minor >= 35;
+    Ok((version, support_returning))
+}
diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs
index 4f2a5a884..94e8a3990 100644
--- a/tests/returning_tests.rs
+++ b/tests/returning_tests.rs
@@ -34,17 +34,12 @@ async fn main() -> Result<(), DbErr> {
 
     let mut returning = Query::select();
     returning.columns(vec![Column::Id, Column::Name, Column::ProfitMargin]);
-    if db.returning_on_insert() {
-        insert.returning(returning.clone());
-    }
-    if db.returning_on_update() {
-        update.returning(returning.clone());
-    }
 
     create_tables(db).await?;
     println!("db_version: {:#?}", db.version());
 
     if db.returning_on_insert() {
+        insert.returning(returning.clone());
         let insert_res = db
             .query_one(builder.build(&insert))
             .await?
@@ -57,6 +52,7 @@ async fn main() -> Result<(), DbErr> {
         assert!(insert_res.rows_affected() > 0);
     }
     if db.returning_on_update() {
+        update.returning(returning.clone());
         let update_res = db
             .query_one(builder.build(&update))
             .await?

From c1fae1bc867c12f9d2fd567a7149e1545f8ea7da Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 9 Nov 2021 16:54:29 +0800
Subject: [PATCH 21/31] Debug print

---
 src/driver/sqlx_mysql.rs  | 2 ++
 src/driver/sqlx_sqlite.rs | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs
index e31307ee1..44efdc0ba 100644
--- a/src/driver/sqlx_mysql.rs
+++ b/src/driver/sqlx_mysql.rs
@@ -230,5 +230,7 @@ async fn parse_support_returning(pool: &MySqlPool) -> Result<(String, bool), DbE
         // Supported if it's MariaDB with version 10.5.0 or after
         ver_major >= 10 && ver_minor >= 5
     };
+    debug_print!("db_version: {}", version);
+    debug_print!("db_support_returning: {}", support_returning);
     Ok((version, support_returning))
 }
diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs
index c98a3dea4..4cbdc2318 100644
--- a/src/driver/sqlx_sqlite.rs
+++ b/src/driver/sqlx_sqlite.rs
@@ -227,5 +227,7 @@ async fn parse_support_returning(pool: &SqlitePool) -> Result<(String, bool), Db
     let ver_minor = parse_captures!(2);
     // Supported if it's version 3.35.0 (2021-03-12) or after
     let support_returning = ver_major >= 3 && ver_minor >= 35;
+    debug_print!("db_version: {}", version);
+    debug_print!("db_support_returning: {}", support_returning);
     Ok((version, support_returning))
 }

From cc035d7aa71f2c7f3396c4fb6b705b240a1c5df3 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 9 Nov 2021 18:14:13 +0800
Subject: [PATCH 22/31] Refactoring

---
 src/database/db_connection.rs | 16 ----------------
 src/database/transaction.rs   | 30 +++---------------------------
 src/driver/sqlx_mysql.rs      |  8 +++-----
 src/driver/sqlx_sqlite.rs     |  8 +++-----
 tests/returning_tests.rs      |  1 -
 5 files changed, 9 insertions(+), 54 deletions(-)

diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index 476fe8e09..ab9d734a1 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -292,22 +292,6 @@ impl DatabaseConnection {
     }
 }
 
-impl DatabaseConnection {
-    /// Get database version
-    pub fn version(&self) -> String {
-        match self {
-            #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.version.to_string(),
-            #[cfg(feature = "sqlx-postgres")]
-            DatabaseConnection::SqlxPostgresPoolConnection(_) => "".to_string(),
-            #[cfg(feature = "sqlx-sqlite")]
-            DatabaseConnection::SqlxSqlitePoolConnection(conn) => conn.version.to_string(),
-            DatabaseConnection::Disconnected => panic!("Disconnected"),
-            _ => unimplemented!(),
-        }
-    }
-}
-
 impl DbBackend {
     /// Check if the URI is the same as the specified database backend.
     /// Returns true if they match.
diff --git a/src/database/transaction.rs b/src/database/transaction.rs
index 168461c48..cfce9d58a 100644
--- a/src/database/transaction.rs
+++ b/src/database/transaction.rs
@@ -367,37 +367,13 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
     }
 
     fn returning_on_insert(&self) -> bool {
-        match self.backend {
-            DbBackend::MySql => {
-                // Supported if it's MariaDB on or after version 10.5.0
-                // Not supported in all MySQL versions
-                self.support_returning
-            }
-            DbBackend::Postgres => {
-                // Supported by all Postgres versions
-                true
-            }
-            DbBackend::Sqlite => {
-                // Supported by SQLite on or after version 3.35.0 (2021-03-12)
-                self.support_returning
-            }
-        }
+        self.support_returning
     }
 
     fn returning_on_update(&self) -> bool {
         match self.backend {
-            DbBackend::MySql => {
-                // Not supported in all MySQL & MariaDB versions
-                false
-            }
-            DbBackend::Postgres => {
-                // Supported by all Postgres versions
-                true
-            }
-            DbBackend::Sqlite => {
-                // Supported by SQLite on or after version 3.35.0 (2021-03-12)
-                self.support_returning
-            }
+            DbBackend::MySql => false,
+            _ => self.support_returning,
         }
     }
 }
diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs
index 44efdc0ba..e29ee9f80 100644
--- a/src/driver/sqlx_mysql.rs
+++ b/src/driver/sqlx_mysql.rs
@@ -24,7 +24,6 @@ pub struct SqlxMySqlConnector;
 #[derive(Debug, Clone)]
 pub struct SqlxMySqlPoolConnection {
     pool: MySqlPool,
-    pub(crate) version: String,
     pub(crate) support_returning: bool,
 }
 
@@ -186,17 +185,16 @@ pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, MySq
 }
 
 async fn into_db_connection(pool: MySqlPool) -> Result<DatabaseConnection, DbErr> {
-    let (version, support_returning) = parse_support_returning(&pool).await?;
+    let support_returning = parse_support_returning(&pool).await?;
     Ok(DatabaseConnection::SqlxMySqlPoolConnection(
         SqlxMySqlPoolConnection {
             pool,
-            version,
             support_returning,
         },
     ))
 }
 
-async fn parse_support_returning(pool: &MySqlPool) -> Result<(String, bool), DbErr> {
+async fn parse_support_returning(pool: &MySqlPool) -> Result<bool, DbErr> {
     let stmt = Statement::from_string(
         DbBackend::MySql,
         r#"SHOW VARIABLES LIKE "version""#.to_owned(),
@@ -232,5 +230,5 @@ async fn parse_support_returning(pool: &MySqlPool) -> Result<(String, bool), DbE
     };
     debug_print!("db_version: {}", version);
     debug_print!("db_support_returning: {}", support_returning);
-    Ok((version, support_returning))
+    Ok(support_returning)
 }
diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs
index 4cbdc2318..4ea160e85 100644
--- a/src/driver/sqlx_sqlite.rs
+++ b/src/driver/sqlx_sqlite.rs
@@ -24,7 +24,6 @@ pub struct SqlxSqliteConnector;
 #[derive(Debug, Clone)]
 pub struct SqlxSqlitePoolConnection {
     pool: SqlitePool,
-    pub(crate) version: String,
     pub(crate) support_returning: bool,
 }
 
@@ -190,17 +189,16 @@ pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Sqlite, Sql
 }
 
 async fn into_db_connection(pool: SqlitePool) -> Result<DatabaseConnection, DbErr> {
-    let (version, support_returning) = parse_support_returning(&pool).await?;
+    let support_returning = parse_support_returning(&pool).await?;
     Ok(DatabaseConnection::SqlxSqlitePoolConnection(
         SqlxSqlitePoolConnection {
             pool,
-            version,
             support_returning,
         },
     ))
 }
 
-async fn parse_support_returning(pool: &SqlitePool) -> Result<(String, bool), DbErr> {
+async fn parse_support_returning(pool: &SqlitePool) -> Result<bool, DbErr> {
     let stmt = Statement::from_string(
         DbBackend::Sqlite,
         r#"SELECT sqlite_version() AS version"#.to_owned(),
@@ -229,5 +227,5 @@ async fn parse_support_returning(pool: &SqlitePool) -> Result<(String, bool), Db
     let support_returning = ver_major >= 3 && ver_minor >= 35;
     debug_print!("db_version: {}", version);
     debug_print!("db_support_returning: {}", support_returning);
-    Ok((version, support_returning))
+    Ok(support_returning)
 }
diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs
index 94e8a3990..55506399f 100644
--- a/tests/returning_tests.rs
+++ b/tests/returning_tests.rs
@@ -36,7 +36,6 @@ async fn main() -> Result<(), DbErr> {
     returning.columns(vec![Column::Id, Column::Name, Column::ProfitMargin]);
 
     create_tables(db).await?;
-    println!("db_version: {:#?}", db.version());
 
     if db.returning_on_insert() {
         insert.returning(returning.clone());

From 66c23c85dbc998471b9a9ac6be5cea8c36a289f9 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Wed, 10 Nov 2021 14:40:44 +0800
Subject: [PATCH 23/31] Revert MySQL & SQLite returning support

---
 .github/workflows/rust.yml    |  2 ++
 Cargo.toml                    |  1 -
 src/database/connection.rs    | 10 +++---
 src/database/db_connection.rs | 60 +++----------------------------
 src/database/transaction.rs   | 33 ++---------------
 src/driver/sqlx_mysql.rs      | 67 +++++------------------------------
 src/driver/sqlx_sqlite.rs     | 60 +++++--------------------------
 src/executor/insert.rs        |  6 ++--
 src/executor/update.rs        |  2 +-
 tests/returning_tests.rs      | 15 ++++----
 10 files changed, 43 insertions(+), 213 deletions(-)

diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index c4d112352..2926e2ab8 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -288,6 +288,7 @@ jobs:
     name: Examples
     runs-on: ${{ matrix.os }}
     strategy:
+      fail-fast: false
       matrix:
         os: [ubuntu-latest]
         path: [basic, actix_example, actix4_example, axum_example, rocket_example]
@@ -312,6 +313,7 @@ jobs:
     if: ${{ (needs.init.outputs.run-partial == 'true' && needs.init.outputs.run-issues == 'true') }}
     runs-on: ${{ matrix.os }}
     strategy:
+      fail-fast: false
       matrix:
         os: [ubuntu-latest]
         path: [86, 249, 262]
diff --git a/Cargo.toml b/Cargo.toml
index 3f0e0ea31..d6d41c35e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -38,7 +38,6 @@ sqlx = { version = "^0.5", optional = true }
 uuid = { version = "0.8", features = ["serde", "v4"], optional = true }
 ouroboros = "0.11"
 url = "^2.2"
-regex = "^1"
 
 [dev-dependencies]
 smol = { version = "^1.2" }
diff --git a/src/database/connection.rs b/src/database/connection.rs
index 2a16156e9..c5730a4bd 100644
--- a/src/database/connection.rs
+++ b/src/database/connection.rs
@@ -45,11 +45,11 @@ pub trait ConnectionTrait<'a>: Sync {
         T: Send,
         E: std::error::Error + Send;
 
-    /// Check if the connection supports `RETURNING` syntax on insert
-    fn returning_on_insert(&self) -> bool;
-
-    /// Check if the connection supports `RETURNING` syntax on update
-    fn returning_on_update(&self) -> bool;
+    /// Check if the connection supports `RETURNING` syntax on insert and update
+    fn support_returning(&self) -> bool {
+        let db_backend = self.get_database_backend();
+        db_backend.support_returning()
+    }
 
     /// Check if the connection is a test connection for the Mock database
     fn is_mock_connection(&self) -> bool {
diff --git a/src/database/db_connection.rs b/src/database/db_connection.rs
index ab9d734a1..99de8633f 100644
--- a/src/database/db_connection.rs
+++ b/src/database/db_connection.rs
@@ -214,61 +214,6 @@ impl<'a> ConnectionTrait<'a> for DatabaseConnection {
         }
     }
 
-    fn returning_on_insert(&self) -> bool {
-        match self {
-            #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection(conn) => {
-                // Supported if it's MariaDB on or after version 10.5.0
-                // Not supported in all MySQL versions
-                conn.support_returning
-            }
-            #[cfg(feature = "sqlx-postgres")]
-            DatabaseConnection::SqlxPostgresPoolConnection(_) => {
-                // Supported by all Postgres versions
-                true
-            }
-            #[cfg(feature = "sqlx-sqlite")]
-            DatabaseConnection::SqlxSqlitePoolConnection(conn) => {
-                // Supported by SQLite on or after version 3.35.0 (2021-03-12)
-                conn.support_returning
-            }
-            #[cfg(feature = "mock")]
-            DatabaseConnection::MockDatabaseConnection(conn) => match conn.get_database_backend() {
-                DbBackend::MySql => false,
-                DbBackend::Postgres => true,
-                DbBackend::Sqlite => false,
-            },
-            DatabaseConnection::Disconnected => panic!("Disconnected"),
-        }
-    }
-
-    fn returning_on_update(&self) -> bool {
-        match self {
-            #[cfg(feature = "sqlx-mysql")]
-            DatabaseConnection::SqlxMySqlPoolConnection(_) => {
-                // Not supported in all MySQL & MariaDB versions
-                false
-            }
-            #[cfg(feature = "sqlx-postgres")]
-            DatabaseConnection::SqlxPostgresPoolConnection(_) => {
-                // Supported by all Postgres versions
-                true
-            }
-            #[cfg(feature = "sqlx-sqlite")]
-            DatabaseConnection::SqlxSqlitePoolConnection(conn) => {
-                // Supported by SQLite on or after version 3.35.0 (2021-03-12)
-                conn.support_returning
-            }
-            #[cfg(feature = "mock")]
-            DatabaseConnection::MockDatabaseConnection(conn) => match conn.get_database_backend() {
-                DbBackend::MySql => false,
-                DbBackend::Postgres => true,
-                DbBackend::Sqlite => false,
-            },
-            DatabaseConnection::Disconnected => panic!("Disconnected"),
-        }
-    }
-
     #[cfg(feature = "mock")]
     fn is_mock_connection(&self) -> bool {
         matches!(self, DatabaseConnection::MockDatabaseConnection(_))
@@ -322,6 +267,11 @@ impl DbBackend {
             Self::Sqlite => Box::new(SqliteQueryBuilder),
         }
     }
+
+    /// Check if the database supports `RETURNING` syntax on insert and update
+    pub fn support_returning(&self) -> bool {
+        matches!(self, Self::Postgres)
+    }
 }
 
 #[cfg(test)]
diff --git a/src/database/transaction.rs b/src/database/transaction.rs
index cfce9d58a..f4a1b6787 100644
--- a/src/database/transaction.rs
+++ b/src/database/transaction.rs
@@ -16,7 +16,6 @@ pub struct DatabaseTransaction {
     conn: Arc<Mutex<InnerConnection>>,
     backend: DbBackend,
     open: bool,
-    support_returning: bool,
 }
 
 impl std::fmt::Debug for DatabaseTransaction {
@@ -29,12 +28,10 @@ impl DatabaseTransaction {
     #[cfg(feature = "sqlx-mysql")]
     pub(crate) async fn new_mysql(
         inner: PoolConnection<sqlx::MySql>,
-        support_returning: bool,
     ) -> Result<DatabaseTransaction, DbErr> {
         Self::begin(
             Arc::new(Mutex::new(InnerConnection::MySql(inner))),
             DbBackend::MySql,
-            support_returning,
         )
         .await
     }
@@ -46,7 +43,6 @@ impl DatabaseTransaction {
         Self::begin(
             Arc::new(Mutex::new(InnerConnection::Postgres(inner))),
             DbBackend::Postgres,
-            true,
         )
         .await
     }
@@ -54,12 +50,10 @@ impl DatabaseTransaction {
     #[cfg(feature = "sqlx-sqlite")]
     pub(crate) async fn new_sqlite(
         inner: PoolConnection<sqlx::Sqlite>,
-        support_returning: bool,
     ) -> Result<DatabaseTransaction, DbErr> {
         Self::begin(
             Arc::new(Mutex::new(InnerConnection::Sqlite(inner))),
             DbBackend::Sqlite,
-            support_returning,
         )
         .await
     }
@@ -69,28 +63,17 @@ impl DatabaseTransaction {
         inner: Arc<crate::MockDatabaseConnection>,
     ) -> Result<DatabaseTransaction, DbErr> {
         let backend = inner.get_database_backend();
-        Self::begin(
-            Arc::new(Mutex::new(InnerConnection::Mock(inner))),
-            backend,
-            match backend {
-                DbBackend::MySql => false,
-                DbBackend::Postgres => true,
-                DbBackend::Sqlite => false,
-            },
-        )
-        .await
+        Self::begin(Arc::new(Mutex::new(InnerConnection::Mock(inner))), backend).await
     }
 
     async fn begin(
         conn: Arc<Mutex<InnerConnection>>,
         backend: DbBackend,
-        support_returning: bool,
     ) -> Result<DatabaseTransaction, DbErr> {
         let res = DatabaseTransaction {
             conn,
             backend,
             open: true,
-            support_returning,
         };
         match *res.conn.lock().await {
             #[cfg(feature = "sqlx-mysql")]
@@ -347,8 +330,7 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
     }
 
     async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
-        DatabaseTransaction::begin(Arc::clone(&self.conn), self.backend, self.support_returning)
-            .await
+        DatabaseTransaction::begin(Arc::clone(&self.conn), self.backend).await
     }
 
     /// Execute the function inside a transaction.
@@ -365,17 +347,6 @@ impl<'a> ConnectionTrait<'a> for DatabaseTransaction {
         let transaction = self.begin().await.map_err(TransactionError::Connection)?;
         transaction.run(_callback).await
     }
-
-    fn returning_on_insert(&self) -> bool {
-        self.support_returning
-    }
-
-    fn returning_on_update(&self) -> bool {
-        match self.backend {
-            DbBackend::MySql => false,
-            _ => self.support_returning,
-        }
-    }
 }
 
 /// Defines errors for handling transaction failures
diff --git a/src/driver/sqlx_mysql.rs b/src/driver/sqlx_mysql.rs
index e29ee9f80..b2b89c680 100644
--- a/src/driver/sqlx_mysql.rs
+++ b/src/driver/sqlx_mysql.rs
@@ -1,9 +1,8 @@
-use regex::Regex;
 use std::{future::Future, pin::Pin};
 
 use sqlx::{
     mysql::{MySqlArguments, MySqlConnectOptions, MySqlQueryResult, MySqlRow},
-    MySql, MySqlPool, Row,
+    MySql, MySqlPool,
 };
 
 sea_query::sea_query_driver_mysql!();
@@ -11,7 +10,7 @@ use sea_query_driver_mysql::bind_query;
 
 use crate::{
     debug_print, error::*, executor::*, ConnectOptions, DatabaseConnection, DatabaseTransaction,
-    DbBackend, QueryStream, Statement, TransactionError,
+    QueryStream, Statement, TransactionError,
 };
 
 use super::sqlx_common::*;
@@ -24,7 +23,6 @@ pub struct SqlxMySqlConnector;
 #[derive(Debug, Clone)]
 pub struct SqlxMySqlPoolConnection {
     pool: MySqlPool,
-    pub(crate) support_returning: bool,
 }
 
 impl SqlxMySqlConnector {
@@ -44,7 +42,9 @@ impl SqlxMySqlConnector {
             opt.disable_statement_logging();
         }
         if let Ok(pool) = options.pool_options().connect_with(opt).await {
-            into_db_connection(pool).await
+            Ok(DatabaseConnection::SqlxMySqlPoolConnection(
+                SqlxMySqlPoolConnection { pool },
+            ))
         } else {
             Err(DbErr::Conn("Failed to connect.".to_owned()))
         }
@@ -53,8 +53,8 @@ impl SqlxMySqlConnector {
 
 impl SqlxMySqlConnector {
     /// Instantiate a sqlx pool connection to a [DatabaseConnection]
-    pub async fn from_sqlx_mysql_pool(pool: MySqlPool) -> Result<DatabaseConnection, DbErr> {
-        into_db_connection(pool).await
+    pub fn from_sqlx_mysql_pool(pool: MySqlPool) -> DatabaseConnection {
+        DatabaseConnection::SqlxMySqlPoolConnection(SqlxMySqlPoolConnection { pool })
     }
 }
 
@@ -129,7 +129,7 @@ impl SqlxMySqlPoolConnection {
     /// Bundle a set of SQL statements that execute together.
     pub async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
         if let Ok(conn) = self.pool.acquire().await {
-            DatabaseTransaction::new_mysql(conn, self.support_returning).await
+            DatabaseTransaction::new_mysql(conn).await
         } else {
             Err(DbErr::Query(
                 "Failed to acquire connection from pool.".to_owned(),
@@ -148,7 +148,7 @@ impl SqlxMySqlPoolConnection {
         E: std::error::Error + Send,
     {
         if let Ok(conn) = self.pool.acquire().await {
-            let transaction = DatabaseTransaction::new_mysql(conn, self.support_returning)
+            let transaction = DatabaseTransaction::new_mysql(conn)
                 .await
                 .map_err(|e| TransactionError::Connection(e))?;
             transaction.run(callback).await
@@ -183,52 +183,3 @@ pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, MySq
     }
     query
 }
-
-async fn into_db_connection(pool: MySqlPool) -> Result<DatabaseConnection, DbErr> {
-    let support_returning = parse_support_returning(&pool).await?;
-    Ok(DatabaseConnection::SqlxMySqlPoolConnection(
-        SqlxMySqlPoolConnection {
-            pool,
-            support_returning,
-        },
-    ))
-}
-
-async fn parse_support_returning(pool: &MySqlPool) -> Result<bool, DbErr> {
-    let stmt = Statement::from_string(
-        DbBackend::MySql,
-        r#"SHOW VARIABLES LIKE "version""#.to_owned(),
-    );
-    let query = sqlx_query(&stmt);
-    let row = query
-        .fetch_one(pool)
-        .await
-        .map_err(sqlx_error_to_query_err)?;
-    let version: String = row.try_get("Value").map_err(sqlx_error_to_query_err)?;
-    let support_returning = if !version.contains("MariaDB") {
-        // This is MySQL
-        // Not supported in all MySQL versions
-        false
-    } else {
-        // This is MariaDB
-        let regex = Regex::new(r"^(\d+)?.(\d+)?.(\*|\d+)").unwrap();
-        let captures = regex.captures(&version).unwrap();
-        macro_rules! parse_captures {
-            ( $idx: expr ) => {
-                captures.get($idx).map_or(0, |m| {
-                    m.as_str()
-                        .parse::<usize>()
-                        .map_err(|e| DbErr::Conn(e.to_string()))
-                        .unwrap()
-                })
-            };
-        }
-        let ver_major = parse_captures!(1);
-        let ver_minor = parse_captures!(2);
-        // Supported if it's MariaDB with version 10.5.0 or after
-        ver_major >= 10 && ver_minor >= 5
-    };
-    debug_print!("db_version: {}", version);
-    debug_print!("db_support_returning: {}", support_returning);
-    Ok(support_returning)
-}
diff --git a/src/driver/sqlx_sqlite.rs b/src/driver/sqlx_sqlite.rs
index 4ea160e85..69eee5752 100644
--- a/src/driver/sqlx_sqlite.rs
+++ b/src/driver/sqlx_sqlite.rs
@@ -1,9 +1,8 @@
-use regex::Regex;
 use std::{future::Future, pin::Pin};
 
 use sqlx::{
     sqlite::{SqliteArguments, SqliteConnectOptions, SqliteQueryResult, SqliteRow},
-    Row, Sqlite, SqlitePool,
+    Sqlite, SqlitePool,
 };
 
 sea_query::sea_query_driver_sqlite!();
@@ -11,7 +10,7 @@ use sea_query_driver_sqlite::bind_query;
 
 use crate::{
     debug_print, error::*, executor::*, ConnectOptions, DatabaseConnection, DatabaseTransaction,
-    DbBackend, QueryStream, Statement, TransactionError,
+    QueryStream, Statement, TransactionError,
 };
 
 use super::sqlx_common::*;
@@ -24,7 +23,6 @@ pub struct SqlxSqliteConnector;
 #[derive(Debug, Clone)]
 pub struct SqlxSqlitePoolConnection {
     pool: SqlitePool,
-    pub(crate) support_returning: bool,
 }
 
 impl SqlxSqliteConnector {
@@ -48,7 +46,9 @@ impl SqlxSqliteConnector {
             options.max_connections(1);
         }
         if let Ok(pool) = options.pool_options().connect_with(opt).await {
-            into_db_connection(pool).await
+            Ok(DatabaseConnection::SqlxSqlitePoolConnection(
+                SqlxSqlitePoolConnection { pool },
+            ))
         } else {
             Err(DbErr::Conn("Failed to connect.".to_owned()))
         }
@@ -57,8 +57,8 @@ impl SqlxSqliteConnector {
 
 impl SqlxSqliteConnector {
     /// Instantiate a sqlx pool connection to a [DatabaseConnection]
-    pub async fn from_sqlx_sqlite_pool(pool: SqlitePool) -> Result<DatabaseConnection, DbErr> {
-        into_db_connection(pool).await
+    pub fn from_sqlx_sqlite_pool(pool: SqlitePool) -> DatabaseConnection {
+        DatabaseConnection::SqlxSqlitePoolConnection(SqlxSqlitePoolConnection { pool })
     }
 }
 
@@ -133,7 +133,7 @@ impl SqlxSqlitePoolConnection {
     /// Bundle a set of SQL statements that execute together.
     pub async fn begin(&self) -> Result<DatabaseTransaction, DbErr> {
         if let Ok(conn) = self.pool.acquire().await {
-            DatabaseTransaction::new_sqlite(conn, self.support_returning).await
+            DatabaseTransaction::new_sqlite(conn).await
         } else {
             Err(DbErr::Query(
                 "Failed to acquire connection from pool.".to_owned(),
@@ -152,7 +152,7 @@ impl SqlxSqlitePoolConnection {
         E: std::error::Error + Send,
     {
         if let Ok(conn) = self.pool.acquire().await {
-            let transaction = DatabaseTransaction::new_sqlite(conn, self.support_returning)
+            let transaction = DatabaseTransaction::new_sqlite(conn)
                 .await
                 .map_err(|e| TransactionError::Connection(e))?;
             transaction.run(callback).await
@@ -187,45 +187,3 @@ pub(crate) fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Sqlite, Sql
     }
     query
 }
-
-async fn into_db_connection(pool: SqlitePool) -> Result<DatabaseConnection, DbErr> {
-    let support_returning = parse_support_returning(&pool).await?;
-    Ok(DatabaseConnection::SqlxSqlitePoolConnection(
-        SqlxSqlitePoolConnection {
-            pool,
-            support_returning,
-        },
-    ))
-}
-
-async fn parse_support_returning(pool: &SqlitePool) -> Result<bool, DbErr> {
-    let stmt = Statement::from_string(
-        DbBackend::Sqlite,
-        r#"SELECT sqlite_version() AS version"#.to_owned(),
-    );
-    let query = sqlx_query(&stmt);
-    let row = query
-        .fetch_one(pool)
-        .await
-        .map_err(sqlx_error_to_query_err)?;
-    let version: String = row.try_get("version").map_err(sqlx_error_to_query_err)?;
-    let regex = Regex::new(r"^(\d+)?.(\d+)?.(\*|\d+)").unwrap();
-    let captures = regex.captures(&version).unwrap();
-    macro_rules! parse_captures {
-        ( $idx: expr ) => {
-            captures.get($idx).map_or(0, |m| {
-                m.as_str()
-                    .parse::<usize>()
-                    .map_err(|e| DbErr::Conn(e.to_string()))
-                    .unwrap()
-            })
-        };
-    }
-    let ver_major = parse_captures!(1);
-    let ver_minor = parse_captures!(2);
-    // Supported if it's version 3.35.0 (2021-03-12) or after
-    let support_returning = ver_major >= 3 && ver_minor >= 35;
-    debug_print!("db_version: {}", version);
-    debug_print!("db_support_returning: {}", support_returning);
-    Ok(support_returning)
-}
diff --git a/src/executor/insert.rs b/src/executor/insert.rs
index fde1a3ab4..a6dbcbd53 100644
--- a/src/executor/insert.rs
+++ b/src/executor/insert.rs
@@ -41,7 +41,7 @@ where
     {
         // so that self is dropped before entering await
         let mut query = self.query;
-        if db.returning_on_insert() && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
+        if db.support_returning() && <A::Entity as EntityTrait>::PrimaryKey::iter().count() > 0 {
             let mut returning = Query::select();
             returning.columns(
                 <A::Entity as EntityTrait>::PrimaryKey::iter().map(|c| c.into_column_ref()),
@@ -113,7 +113,7 @@ where
 {
     type PrimaryKey<A> = <<A as ActiveModelTrait>::Entity as EntityTrait>::PrimaryKey;
     type ValueTypeOf<A> = <PrimaryKey<A> as PrimaryKeyTrait>::ValueType;
-    let last_insert_id_opt = match db.returning_on_insert() {
+    let last_insert_id_opt = match db.support_returning() {
         true => {
             let cols = PrimaryKey::<A>::iter()
                 .map(|col| col.to_string())
@@ -147,7 +147,7 @@ where
     A: ActiveModelTrait,
 {
     let db_backend = db.get_database_backend();
-    let found = match db.returning_on_insert() {
+    let found = match db.support_returning() {
         true => {
             let mut returning = Query::select();
             returning.exprs(<A::Entity as EntityTrait>::Column::iter().map(|c| {
diff --git a/src/executor/update.rs b/src/executor/update.rs
index d27aa41d4..9870b10d9 100644
--- a/src/executor/update.rs
+++ b/src/executor/update.rs
@@ -90,7 +90,7 @@ where
     A: ActiveModelTrait,
     C: ConnectionTrait<'a>,
 {
-    match db.returning_on_update() {
+    match db.support_returning() {
         true => {
             let mut returning = Query::select();
             returning.exprs(<A::Entity as EntityTrait>::Column::iter().map(|c| {
diff --git a/tests/returning_tests.rs b/tests/returning_tests.rs
index 55506399f..7fa0447b4 100644
--- a/tests/returning_tests.rs
+++ b/tests/returning_tests.rs
@@ -1,8 +1,8 @@
 pub mod common;
 
 pub use common::{bakery_chain::*, setup::*, TestContext};
-use sea_orm::{entity::prelude::*, *};
-use sea_query::Query;
+pub use sea_orm::{entity::prelude::*, *};
+pub use sea_query::Query;
 
 #[sea_orm_macros::test]
 #[cfg(any(
@@ -37,7 +37,7 @@ async fn main() -> Result<(), DbErr> {
 
     create_tables(db).await?;
 
-    if db.returning_on_insert() {
+    if db.support_returning() {
         insert.returning(returning.clone());
         let insert_res = db
             .query_one(builder.build(&insert))
@@ -46,11 +46,7 @@ async fn main() -> Result<(), DbErr> {
         let _id: i32 = insert_res.try_get("", "id")?;
         let _name: String = insert_res.try_get("", "name")?;
         let _profit_margin: f64 = insert_res.try_get("", "profit_margin")?;
-    } else {
-        let insert_res = db.execute(builder.build(&insert)).await?;
-        assert!(insert_res.rows_affected() > 0);
-    }
-    if db.returning_on_update() {
+
         update.returning(returning.clone());
         let update_res = db
             .query_one(builder.build(&update))
@@ -60,6 +56,9 @@ async fn main() -> Result<(), DbErr> {
         let _name: String = update_res.try_get("", "name")?;
         let _profit_margin: f64 = update_res.try_get("", "profit_margin")?;
     } else {
+        let insert_res = db.execute(builder.build(&insert)).await?;
+        assert!(insert_res.rows_affected() > 0);
+
         let update_res = db.execute(builder.build(&update)).await?;
         assert!(update_res.rows_affected() > 0);
     }

From 257a893e1b1295de063dc94d1edf285fde00cde1 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Wed, 10 Nov 2021 15:28:43 +0800
Subject: [PATCH 24/31] Use `sea-query` master

---
 Cargo.toml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Cargo.toml b/Cargo.toml
index d6d41c35e..2345844cd 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,7 +30,7 @@ futures-util = { version = "^0.3" }
 log = { version = "^0.4", optional = true }
 rust_decimal = { version = "^1", optional = true }
 sea-orm-macros = { version = "^0.3.1", path = "sea-orm-macros", optional = true }
-sea-query = { version = "^0.18.2", git = "https://github.com/SeaQL/sea-query.git", branch = "sea-orm/returning", features = ["thread-safe"] }
+sea-query = { version = "^0.18.0", git = "https://github.com/SeaQL/sea-query.git", features = ["thread-safe"] }
 sea-strum = { version = "^0.21", features = ["derive", "sea-orm"] }
 serde = { version = "^1.0", features = ["derive"] }
 serde_json = { version = "^1", optional = true }

From 4d44827d2f32e2021478de01377723479e5c9d15 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Thu, 11 Nov 2021 13:30:36 +0800
Subject: [PATCH 25/31] Docs

---
 src/entity/base_entity.rs | 171 +++++++++++++++++++++++++++++++++++---
 1 file changed, 160 insertions(+), 11 deletions(-)

diff --git a/src/entity/base_entity.rs b/src/entity/base_entity.rs
index 93d8ac8ae..681cce680 100644
--- a/src/entity/base_entity.rs
+++ b/src/entity/base_entity.rs
@@ -272,7 +272,7 @@ pub trait EntityTrait: EntityName {
 
     /// Insert an model into database
     ///
-    /// # Example
+    /// # Example (Postgres)
     ///
     /// ```
     /// # #[cfg(feature = "mock")]
@@ -299,7 +299,6 @@ pub trait EntityTrait: EntityName {
     /// let insert_result = cake::Entity::insert(apple).exec(&db).await?;
     ///
     /// assert_eq!(insert_result.last_insert_id, 15);
-    /// // assert_eq!(insert_result.rows_affected, 1);
     /// #
     /// # Ok(())
     /// # });
@@ -307,7 +306,49 @@ pub trait EntityTrait: EntityName {
     /// assert_eq!(
     ///     db.into_transaction_log(),
     ///     vec![Transaction::from_sql_and_values(
-    ///         DbBackend::Postgres, r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id""#, vec!["Apple Pie".into()]
+    ///         DbBackend::Postgres,
+    ///         r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id""#,
+    ///         vec!["Apple Pie".into()]
+    ///     )]);
+    /// ```
+    ///
+    /// # Example (MySQL)
+    ///
+    /// ```
+    /// # #[cfg(feature = "mock")]
+    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// #
+    /// # let db = MockDatabase::new(DbBackend::MySql)
+    /// #     .append_exec_results(vec![
+    /// #         MockExecResult {
+    /// #             last_insert_id: 15,
+    /// #             rows_affected: 1,
+    /// #         },
+    /// #     ])
+    /// #     .into_connection();
+    /// #
+    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
+    ///
+    /// let apple = cake::ActiveModel {
+    ///     name: Set("Apple Pie".to_owned()),
+    ///     ..Default::default()
+    /// };
+    ///
+    /// # let _: Result<(), DbErr> = smol::block_on(async {
+    /// #
+    /// let insert_result = cake::Entity::insert(apple).exec(&db).await?;
+    ///
+    /// assert_eq!(insert_result.last_insert_id, 15);
+    /// #
+    /// # Ok(())
+    /// # });
+    ///
+    /// assert_eq!(
+    ///     db.into_transaction_log(),
+    ///     vec![Transaction::from_sql_and_values(
+    ///         DbBackend::MySql,
+    ///         r#"INSERT INTO `cake` (`name`) VALUES (?)"#,
+    ///         vec!["Apple Pie".into()]
     ///     )]);
     /// ```
     fn insert<A>(model: A) -> Insert<A>
@@ -319,7 +360,7 @@ pub trait EntityTrait: EntityName {
 
     /// Insert many models into database
     ///
-    /// # Example
+    /// # Example (Postgres)
     ///
     /// ```
     /// # #[cfg(feature = "mock")]
@@ -350,7 +391,6 @@ pub trait EntityTrait: EntityName {
     /// let insert_result = cake::Entity::insert_many(vec![apple, orange]).exec(&db).await?;
     ///
     /// assert_eq!(insert_result.last_insert_id, 28);
-    /// // assert_eq!(insert_result.rows_affected, 2);
     /// #
     /// # Ok(())
     /// # });
@@ -358,7 +398,52 @@ pub trait EntityTrait: EntityName {
     /// assert_eq!(
     ///     db.into_transaction_log(),
     ///     vec![Transaction::from_sql_and_values(
-    ///         DbBackend::Postgres, r#"INSERT INTO "cake" ("name") VALUES ($1), ($2) RETURNING "id""#,
+    ///         DbBackend::Postgres,
+    ///         r#"INSERT INTO "cake" ("name") VALUES ($1), ($2) RETURNING "id""#,
+    ///         vec!["Apple Pie".into(), "Orange Scone".into()]
+    ///     )]);
+    /// ```
+    ///
+    /// # Example (MySQL)
+    ///
+    /// ```
+    /// # #[cfg(feature = "mock")]
+    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// #
+    /// # let db = MockDatabase::new(DbBackend::MySql)
+    /// #     .append_exec_results(vec![
+    /// #         MockExecResult {
+    /// #             last_insert_id: 28,
+    /// #             rows_affected: 2,
+    /// #         },
+    /// #     ])
+    /// #     .into_connection();
+    /// #
+    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
+    ///
+    /// let apple = cake::ActiveModel {
+    ///     name: Set("Apple Pie".to_owned()),
+    ///     ..Default::default()
+    /// };
+    /// let orange = cake::ActiveModel {
+    ///     name: Set("Orange Scone".to_owned()),
+    ///     ..Default::default()
+    /// };
+    ///
+    /// # let _: Result<(), DbErr> = smol::block_on(async {
+    /// #
+    /// let insert_result = cake::Entity::insert_many(vec![apple, orange]).exec(&db).await?;
+    ///
+    /// assert_eq!(insert_result.last_insert_id, 28);
+    /// #
+    /// # Ok(())
+    /// # });
+    ///
+    /// assert_eq!(
+    ///     db.into_transaction_log(),
+    ///     vec![Transaction::from_sql_and_values(
+    ///         DbBackend::MySql,
+    ///         r#"INSERT INTO `cake` (`name`) VALUES (?), (?)"#,
     ///         vec!["Apple Pie".into(), "Orange Scone".into()]
     ///     )]);
     /// ```
@@ -374,7 +459,7 @@ pub trait EntityTrait: EntityName {
     ///
     /// - To apply where conditions / filters, see [`QueryFilter`](crate::query::QueryFilter)
     ///
-    /// # Example
+    /// # Example (Postgres)
     ///
     /// ```
     /// # #[cfg(feature = "mock")]
@@ -413,10 +498,69 @@ pub trait EntityTrait: EntityName {
     /// assert_eq!(
     ///     db.into_transaction_log(),
     ///     vec![Transaction::from_sql_and_values(
-    ///         DbBackend::Postgres, r#"UPDATE "fruit" SET "name" = $1 WHERE "fruit"."id" = $2 AND "fruit"."name" LIKE $3 RETURNING "id", "name", "cake_id""#,
+    ///         DbBackend::Postgres,
+    ///         r#"UPDATE "fruit" SET "name" = $1 WHERE "fruit"."id" = $2 AND "fruit"."name" LIKE $3 RETURNING "id", "name", "cake_id""#,
     ///         vec!["Orange".into(), 1i32.into(), "%orange%".into()]
     ///     )]);
     /// ```
+    ///
+    /// # Example (MySQL)
+    ///
+    /// ```
+    /// # #[cfg(feature = "mock")]
+    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// #
+    /// # let db = MockDatabase::new(DbBackend::MySql)
+    /// #     .append_query_results(vec![
+    /// #         vec![fruit::Model {
+    /// #             id: 1,
+    /// #             name: "Orange".to_owned(),
+    /// #             cake_id: None,
+    /// #         }],
+    /// #     ])
+    /// #     .append_exec_results(vec![
+    /// #         MockExecResult {
+    /// #             last_insert_id: 0,
+    /// #             rows_affected: 1,
+    /// #         },
+    /// #     ])
+    /// #     .into_connection();
+    /// #
+    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
+    ///
+    /// let orange = fruit::ActiveModel {
+    ///     id: Set(1),
+    ///     name: Set("Orange".to_owned()),
+    ///     ..Default::default()
+    /// };
+    ///
+    /// # let _: Result<(), DbErr> = smol::block_on(async {
+    /// #
+    /// assert_eq!(
+    ///     fruit::Entity::update(orange.clone())
+    ///         .filter(fruit::Column::Name.contains("orange"))
+    ///         .exec(&db)
+    ///         .await?,
+    ///     orange
+    /// );
+    /// #
+    /// # Ok(())
+    /// # });
+    ///
+    /// assert_eq!(
+    ///     db.into_transaction_log(),
+    ///     vec![
+    ///         Transaction::from_sql_and_values(
+    ///             DbBackend::MySql,
+    ///             r#"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ? AND `fruit`.`name` LIKE ?"#,
+    ///             vec!["Orange".into(), 1i32.into(), "%orange%".into()]
+    ///         ),
+    ///         Transaction::from_sql_and_values(
+    ///             DbBackend::MySql,
+    ///             r#"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?"#,
+    ///             vec![1i32.into(), 1u64.into()]
+    ///         )]);
+    /// ```
     fn update<A>(model: A) -> UpdateOne<A>
     where
         A: ActiveModelTrait<Entity = Self>,
@@ -461,7 +605,9 @@ pub trait EntityTrait: EntityName {
     /// assert_eq!(
     ///     db.into_transaction_log(),
     ///     vec![Transaction::from_sql_and_values(
-    ///         DbBackend::Postgres, r#"UPDATE "fruit" SET "cake_id" = $1 WHERE "fruit"."name" LIKE $2"#, vec![Value::Int(None), "%Apple%".into()]
+    ///         DbBackend::Postgres,
+    ///         r#"UPDATE "fruit" SET "cake_id" = $1 WHERE "fruit"."name" LIKE $2"#,
+    ///         vec![Value::Int(None), "%Apple%".into()]
     ///     )]);
     /// ```
     fn update_many() -> UpdateMany<Self> {
@@ -506,7 +652,8 @@ pub trait EntityTrait: EntityName {
     /// assert_eq!(
     ///     db.into_transaction_log(),
     ///     vec![Transaction::from_sql_and_values(
-    ///         DbBackend::Postgres, r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#, vec![3i32.into()]
+    ///         DbBackend::Postgres, r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
+    ///         vec![3i32.into()]
     ///     )]);
     /// ```
     fn delete<A>(model: A) -> DeleteOne<A>
@@ -552,7 +699,9 @@ pub trait EntityTrait: EntityName {
     /// assert_eq!(
     ///     db.into_transaction_log(),
     ///     vec![Transaction::from_sql_and_values(
-    ///         DbBackend::Postgres, r#"DELETE FROM "fruit" WHERE "fruit"."name" LIKE $1"#, vec!["%Apple%".into()]
+    ///         DbBackend::Postgres,
+    ///         r#"DELETE FROM "fruit" WHERE "fruit"."name" LIKE $1"#,
+    ///         vec!["%Apple%".into()]
     ///     )]);
     /// ```
     fn delete_many() -> DeleteMany<Self> {

From d5de8b1c4842b4d1097f6871f3af6e655a0dd48d Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 16 Nov 2021 15:38:22 +0800
Subject: [PATCH 26/31] Should fail

---
 src/entity/base_entity.rs | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/entity/base_entity.rs b/src/entity/base_entity.rs
index 8ce8060a0..1cefda1a7 100644
--- a/src/entity/base_entity.rs
+++ b/src/entity/base_entity.rs
@@ -298,7 +298,8 @@ pub trait EntityTrait: EntityName {
     /// #
     /// let insert_result = cake::Entity::insert(apple).exec(&db).await?;
     ///
-    /// assert_eq!(insert_result.last_insert_id, 15);
+    /// assert_eq!(dbg!(insert_result.last_insert_id), 150);
+    /// assert!(false);
     /// #
     /// # Ok(())
     /// # });

From 9655805316c8f32ee3015838263c5d40792c4f90 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 16 Nov 2021 15:54:17 +0800
Subject: [PATCH 27/31] Will fail, as expected

---
 src/entity/base_entity.rs | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/entity/base_entity.rs b/src/entity/base_entity.rs
index 1cefda1a7..603696233 100644
--- a/src/entity/base_entity.rs
+++ b/src/entity/base_entity.rs
@@ -275,8 +275,11 @@ pub trait EntityTrait: EntityName {
     /// # Example (Postgres)
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_exec_results(vec![
@@ -294,15 +297,10 @@ pub trait EntityTrait: EntityName {
     ///     ..Default::default()
     /// };
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let insert_result = cake::Entity::insert(apple).exec(&db).await?;
     ///
     /// assert_eq!(dbg!(insert_result.last_insert_id), 150);
     /// assert!(false);
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -311,6 +309,9 @@ pub trait EntityTrait: EntityName {
     ///         r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id""#,
     ///         vec!["Apple Pie".into()]
     ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     ///
     /// # Example (MySQL)

From 4c147a2d24dcbede4a2dac598dedfda43ea45266 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 16 Nov 2021 16:27:54 +0800
Subject: [PATCH 28/31] Rewrite doctests

---
 src/docs.rs                |  11 +-
 src/entity/active_model.rs | 253 +++++++++++++++++++++++++++++++++++++
 src/entity/base_entity.rs  | 143 +++++++++++----------
 src/entity/model.rs        |  12 +-
 src/executor/paginator.rs  |  18 ++-
 src/executor/query.rs      |  13 +-
 src/executor/select.rs     |  78 ++++++------
 7 files changed, 406 insertions(+), 122 deletions(-)

diff --git a/src/docs.rs b/src/docs.rs
index 4d1226c3a..3870e716f 100644
--- a/src/docs.rs
+++ b/src/docs.rs
@@ -3,7 +3,12 @@
 //!     Relying on [SQLx](https://github.com/launchbadge/sqlx), SeaORM is a new library with async support from day 1.
 //!
 //! ```
-//! # use sea_orm::{DbConn, error::*, entity::*, query::*, tests_cfg::*, DatabaseConnection, DbBackend, MockDatabase, Transaction, IntoMockRow};
+//! # use sea_orm::{error::*, tests_cfg::*, *};
+//! #
+//! # #[smol_potat::main]
+//! # #[cfg(feature = "mock")]
+//! # pub async fn main() -> Result<(), DbErr> {
+//! #
 //! # let db = MockDatabase::new(DbBackend::Postgres)
 //! #     .append_query_results(vec![
 //! #         vec![cake::Model {
@@ -19,7 +24,7 @@
 //! #         .into_mock_row()],
 //! #     ])
 //! #     .into_connection();
-//! # let _: Result<(), DbErr> = smol::block_on(async {
+//! #
 //! // execute multiple queries in parallel
 //! let cakes_and_fruits: (Vec<cake::Model>, Vec<fruit::Model>) =
 //!     futures::try_join!(Cake::find().all(&db), Fruit::find().all(&db))?;
@@ -53,7 +58,7 @@
 //! #     ]
 //! # );
 //! # Ok(())
-//! # });
+//! # }
 //! ```
 //!
 //! 2. Dynamic
diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs
index efb234ea1..c7d26574a 100644
--- a/src/entity/active_model.rs
+++ b/src/entity/active_model.rs
@@ -140,6 +140,106 @@ pub trait ActiveModelTrait: Clone + Debug {
     }
 
     /// Perform an `INSERT` operation on the ActiveModel
+    ///
+    /// # Example (Postgres)
+    ///
+    /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
+    /// # #[cfg(feature = "mock")]
+    /// # pub async fn main() -> Result<(), DbErr> {
+    /// #
+    /// # let db = MockDatabase::new(DbBackend::Postgres)
+    /// #     .append_exec_results(vec![
+    /// #         MockExecResult {
+    /// #             last_insert_id: 15,
+    /// #             rows_affected: 1,
+    /// #         },
+    /// #     ])
+    /// #     .into_connection();
+    /// #
+    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
+    ///
+    /// let apple = cake::ActiveModel {
+    ///     name: Set("Apple Pie".to_owned()),
+    ///     ..Default::default()
+    /// };
+    ///
+    /// assert_eq!(
+    ///     apple
+    ///         .insert(&db)
+    ///         .await?,
+    ///     cake::ActiveModel {
+    ///         id: Set(150),
+    ///         name: Set("Apple Pie".to_owned()),
+    ///     }
+    /// );
+    /// assert!(false);
+    ///
+    /// assert_eq!(
+    ///     db.into_transaction_log(),
+    ///     vec![Transaction::from_sql_and_values(
+    ///         DbBackend::Postgres,
+    ///         r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id", "name""#,
+    ///         vec!["Apple Pie".into()]
+    ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// # Example (MySQL)
+    ///
+    /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
+    /// # #[cfg(feature = "mock")]
+    /// # pub async fn main() -> Result<(), DbErr> {
+    /// #
+    /// # let db = MockDatabase::new(DbBackend::MySql)
+    /// #     .append_exec_results(vec![
+    /// #         MockExecResult {
+    /// #             last_insert_id: 15,
+    /// #             rows_affected: 1,
+    /// #         },
+    /// #     ])
+    /// #     .into_connection();
+    /// #
+    /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
+    ///
+    /// let apple = cake::ActiveModel {
+    ///     name: Set("Apple Pie".to_owned()),
+    ///     ..Default::default()
+    /// };
+    ///
+    /// assert_eq!(
+    ///     apple
+    ///         .insert(&db)
+    ///         .await?,
+    ///     cake::ActiveModel {
+    ///         id: Set(150),
+    ///         name: Set("Apple Pie".to_owned()),
+    ///     }
+    /// );
+    ///
+    /// assert_eq!(
+    ///     db.into_transaction_log(),
+    ///     vec![
+    ///         Transaction::from_sql_and_values(
+    ///             DbBackend::MySql,
+    ///             r#"INSERT INTO `cake` (`name`) VALUES (?)"#,
+    ///             vec!["Apple Pie".into()]
+    ///         ),
+    ///         Transaction::from_sql_and_values(
+    ///             DbBackend::MySql,
+    ///             r#"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = ? LIMIT ?"#,
+    ///             vec![15.into(), 1u64.into()])]);
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     async fn insert<'a, C>(self, db: &'a C) -> Result<Self, DbErr>
     where
         <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
@@ -154,6 +254,117 @@ pub trait ActiveModelTrait: Clone + Debug {
     }
 
     /// Perform the `UPDATE` operation on an ActiveModel
+    ///
+    /// # Example (Postgres)
+    ///
+    /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
+    /// # #[cfg(feature = "mock")]
+    /// # pub async fn main() -> Result<(), DbErr> {
+    /// #
+    /// # let db = MockDatabase::new(DbBackend::Postgres)
+    /// #     .append_exec_results(vec![
+    /// #         MockExecResult {
+    /// #             last_insert_id: 0,
+    /// #             rows_affected: 1,
+    /// #         },
+    /// #     ])
+    /// #     .into_connection();
+    /// #
+    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
+    ///
+    /// let orange = fruit::ActiveModel {
+    ///     id: Set(1),
+    ///     name: Set("Orange".to_owned()),
+    ///     ..Default::default()
+    /// };
+    ///
+    /// assert_eq!(
+    ///     orange
+    ///         .update(&db)
+    ///         .await?,
+    ///     fruit::ActiveModel {
+    ///         id: Set(1),
+    ///         name: Set("Orange".to_owned()),
+    ///         cake_id: Set(None),
+    ///     }
+    /// );
+    ///
+    /// assert_eq!(
+    ///     db.into_transaction_log(),
+    ///     vec![Transaction::from_sql_and_values(
+    ///         DbBackend::Postgres,
+    ///         r#"UPDATE "fruit" SET "name" = $1 WHERE "fruit"."id" = $2 RETURNING "id", "name", "cake_id""#,
+    ///         vec!["Orange".into(), 1i32.into()]
+    ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// # Example (MySQL)
+    ///
+    /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
+    /// # #[cfg(feature = "mock")]
+    /// # pub async fn main() -> Result<(), DbErr> {
+    /// #
+    /// # let db = MockDatabase::new(DbBackend::MySql)
+    /// #     .append_query_results(vec![
+    /// #         vec![fruit::Model {
+    /// #             id: 1,
+    /// #             name: "Orange".to_owned(),
+    /// #             cake_id: None,
+    /// #         }],
+    /// #     ])
+    /// #     .append_exec_results(vec![
+    /// #         MockExecResult {
+    /// #             last_insert_id: 0,
+    /// #             rows_affected: 1,
+    /// #         },
+    /// #     ])
+    /// #     .into_connection();
+    /// #
+    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
+    ///
+    /// let orange = fruit::ActiveModel {
+    ///     id: Set(1),
+    ///     name: Set("Orange".to_owned()),
+    ///     ..Default::default()
+    /// };
+    ///
+    /// assert_eq!(
+    ///     orange
+    ///         .update(&db)
+    ///         .await?,
+    ///     fruit::ActiveModel {
+    ///         id: Set(1),
+    ///         name: Set("Orange".to_owned()),
+    ///         cake_id: Set(None),
+    ///     }
+    /// );
+    ///
+    /// assert_eq!(
+    ///     db.into_transaction_log(),
+    ///     vec![
+    ///         Transaction::from_sql_and_values(
+    ///             DbBackend::MySql,
+    ///             r#"UPDATE `fruit` SET `name` = ? WHERE `fruit`.`id` = ?"#,
+    ///             vec!["Orange".into(), 1i32.into()]
+    ///         ),
+    ///         Transaction::from_sql_and_values(
+    ///             DbBackend::MySql,
+    ///             r#"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?"#,
+    ///             vec![1i32.into(), 1u64.into()]
+    ///         )]);
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     async fn update<'a, C>(self, db: &'a C) -> Result<Self, DbErr>
     where
         <Self::Entity as EntityTrait>::Model: IntoActiveModel<Self>,
@@ -191,6 +402,48 @@ pub trait ActiveModelTrait: Clone + Debug {
     }
 
     /// Delete an active model by its primary key
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
+    /// # #[cfg(feature = "mock")]
+    /// # pub async fn main() -> Result<(), DbErr> {
+    /// #
+    /// # let db = MockDatabase::new(DbBackend::Postgres)
+    /// #     .append_exec_results(vec![
+    /// #         MockExecResult {
+    /// #             last_insert_id: 0,
+    /// #             rows_affected: 1,
+    /// #         },
+    /// #     ])
+    /// #     .into_connection();
+    /// #
+    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
+    ///
+    /// let orange = fruit::ActiveModel {
+    ///     id: Set(3),
+    ///     ..Default::default()
+    /// };
+    ///
+    /// let delete_result = orange.delete(&db).await?;
+    ///
+    /// assert_eq!(delete_result.rows_affected, 1);
+    ///
+    /// assert_eq!(
+    ///     db.into_transaction_log(),
+    ///     vec![Transaction::from_sql_and_values(
+    ///         DbBackend::Postgres,
+    ///         r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
+    ///         vec![3i32.into()]
+    ///     )]
+    /// );
+    /// #
+    /// # Ok(())
+    /// # }
+    /// ```
     async fn delete<'a, C>(self, db: &'a C) -> Result<DeleteResult, DbErr>
     where
         Self: ActiveModelBehavior + 'a,
diff --git a/src/entity/base_entity.rs b/src/entity/base_entity.rs
index 603696233..8bbb6195d 100644
--- a/src/entity/base_entity.rs
+++ b/src/entity/base_entity.rs
@@ -95,8 +95,11 @@ pub trait EntityTrait: EntityName {
     /// # Example
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_query_results(vec![
@@ -121,8 +124,6 @@ pub trait EntityTrait: EntityName {
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// assert_eq!(
     ///     cake::Entity::find().one(&db).await?,
     ///     Some(cake::Model {
@@ -144,9 +145,6 @@ pub trait EntityTrait: EntityName {
     ///         },
     ///     ]
     /// );
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -163,6 +161,9 @@ pub trait EntityTrait: EntityName {
     ///         ),
     ///     ]
     /// );
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     fn find() -> Select<Self> {
         Select::new()
@@ -173,8 +174,11 @@ pub trait EntityTrait: EntityName {
     /// # Example
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_query_results(vec![
@@ -189,8 +193,6 @@ pub trait EntityTrait: EntityName {
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// assert_eq!(
     ///     cake::Entity::find_by_id(11).all(&db).await?,
     ///     vec![cake::Model {
@@ -198,9 +200,6 @@ pub trait EntityTrait: EntityName {
     ///         name: "Sponge Cake".to_owned(),
     ///     }]
     /// );
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -210,11 +209,17 @@ pub trait EntityTrait: EntityName {
     ///         vec![11i32.into()]
     ///     )]
     /// );
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     /// Find by composite key
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_query_results(vec![
@@ -229,8 +234,6 @@ pub trait EntityTrait: EntityName {
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake_filling};
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// assert_eq!(
     ///     cake_filling::Entity::find_by_id((2, 3)).all(&db).await?,
     ///     vec![cake_filling::Model {
@@ -238,9 +241,6 @@ pub trait EntityTrait: EntityName {
     ///         filling_id: 3,
     ///     }]
     /// );
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -252,6 +252,9 @@ pub trait EntityTrait: EntityName {
     ///         ].join(" ").as_str(),
     ///         vec![2i32.into(), 3i32.into()]
     ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     fn find_by_id(values: <Self::PrimaryKey as PrimaryKeyTrait>::ValueType) -> Select<Self> {
         let mut select = Self::find();
@@ -317,8 +320,11 @@ pub trait EntityTrait: EntityName {
     /// # Example (MySQL)
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::MySql)
     /// #     .append_exec_results(vec![
@@ -336,14 +342,9 @@ pub trait EntityTrait: EntityName {
     ///     ..Default::default()
     /// };
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let insert_result = cake::Entity::insert(apple).exec(&db).await?;
     ///
     /// assert_eq!(insert_result.last_insert_id, 15);
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -352,6 +353,9 @@ pub trait EntityTrait: EntityName {
     ///         r#"INSERT INTO `cake` (`name`) VALUES (?)"#,
     ///         vec!["Apple Pie".into()]
     ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     fn insert<A>(model: A) -> Insert<A>
     where
@@ -365,8 +369,11 @@ pub trait EntityTrait: EntityName {
     /// # Example (Postgres)
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_exec_results(vec![
@@ -388,14 +395,9 @@ pub trait EntityTrait: EntityName {
     ///     ..Default::default()
     /// };
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let insert_result = cake::Entity::insert_many(vec![apple, orange]).exec(&db).await?;
     ///
     /// assert_eq!(insert_result.last_insert_id, 28);
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -404,13 +406,19 @@ pub trait EntityTrait: EntityName {
     ///         r#"INSERT INTO "cake" ("name") VALUES ($1), ($2) RETURNING "id""#,
     ///         vec!["Apple Pie".into(), "Orange Scone".into()]
     ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     ///
     /// # Example (MySQL)
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::MySql)
     /// #     .append_exec_results(vec![
@@ -432,14 +440,9 @@ pub trait EntityTrait: EntityName {
     ///     ..Default::default()
     /// };
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let insert_result = cake::Entity::insert_many(vec![apple, orange]).exec(&db).await?;
     ///
     /// assert_eq!(insert_result.last_insert_id, 28);
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -448,6 +451,9 @@ pub trait EntityTrait: EntityName {
     ///         r#"INSERT INTO `cake` (`name`) VALUES (?), (?)"#,
     ///         vec!["Apple Pie".into(), "Orange Scone".into()]
     ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     fn insert_many<A, I>(models: I) -> Insert<A>
     where
@@ -464,8 +470,11 @@ pub trait EntityTrait: EntityName {
     /// # Example (Postgres)
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_exec_results(vec![
@@ -484,8 +493,6 @@ pub trait EntityTrait: EntityName {
     ///     ..Default::default()
     /// };
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// assert_eq!(
     ///     fruit::Entity::update(orange.clone())
     ///         .filter(fruit::Column::Name.contains("orange"))
@@ -493,9 +500,6 @@ pub trait EntityTrait: EntityName {
     ///         .await?,
     ///     orange
     /// );
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -504,13 +508,19 @@ pub trait EntityTrait: EntityName {
     ///         r#"UPDATE "fruit" SET "name" = $1 WHERE "fruit"."id" = $2 AND "fruit"."name" LIKE $3 RETURNING "id", "name", "cake_id""#,
     ///         vec!["Orange".into(), 1i32.into(), "%orange%".into()]
     ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     ///
     /// # Example (MySQL)
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::MySql)
     /// #     .append_query_results(vec![
@@ -536,8 +546,6 @@ pub trait EntityTrait: EntityName {
     ///     ..Default::default()
     /// };
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// assert_eq!(
     ///     fruit::Entity::update(orange.clone())
     ///         .filter(fruit::Column::Name.contains("orange"))
@@ -545,9 +553,6 @@ pub trait EntityTrait: EntityName {
     ///         .await?,
     ///     orange
     /// );
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -562,6 +567,9 @@ pub trait EntityTrait: EntityName {
     ///             r#"SELECT `fruit`.`id`, `fruit`.`name`, `fruit`.`cake_id` FROM `fruit` WHERE `fruit`.`id` = ? LIMIT ?"#,
     ///             vec![1i32.into(), 1u64.into()]
     ///         )]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     fn update<A>(model: A) -> UpdateOne<A>
     where
@@ -577,8 +585,11 @@ pub trait EntityTrait: EntityName {
     /// # Example
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_exec_results(vec![
@@ -591,8 +602,6 @@ pub trait EntityTrait: EntityName {
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::fruit, sea_query::{Expr, Value}};
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let update_result = fruit::Entity::update_many()
     ///     .col_expr(fruit::Column::CakeId, Expr::value(Value::Int(None)))
     ///     .filter(fruit::Column::Name.contains("Apple"))
@@ -600,9 +609,6 @@ pub trait EntityTrait: EntityName {
     ///     .await?;
     ///
     /// assert_eq!(update_result.rows_affected, 5);
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -611,6 +617,9 @@ pub trait EntityTrait: EntityName {
     ///         r#"UPDATE "fruit" SET "cake_id" = $1 WHERE "fruit"."name" LIKE $2"#,
     ///         vec![Value::Int(None), "%Apple%".into()]
     ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     fn update_many() -> UpdateMany<Self> {
         Update::many(Self::default())
@@ -623,8 +632,11 @@ pub trait EntityTrait: EntityName {
     /// # Example
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_exec_results(vec![
@@ -642,14 +654,9 @@ pub trait EntityTrait: EntityName {
     ///     ..Default::default()
     /// };
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let delete_result = fruit::Entity::delete(orange).exec(&db).await?;
     ///
     /// assert_eq!(delete_result.rows_affected, 1);
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -657,6 +664,9 @@ pub trait EntityTrait: EntityName {
     ///         DbBackend::Postgres, r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
     ///         vec![3i32.into()]
     ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     fn delete<A>(model: A) -> DeleteOne<A>
     where
@@ -672,8 +682,11 @@ pub trait EntityTrait: EntityName {
     /// # Example
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{entity::*, error::*, query::*, tests_cfg::*, MockDatabase, MockExecResult, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_exec_results(vec![
@@ -686,17 +699,12 @@ pub trait EntityTrait: EntityName {
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let delete_result = fruit::Entity::delete_many()
     ///     .filter(fruit::Column::Name.contains("Apple"))
     ///     .exec(&db)
     ///     .await?;
     ///
     /// assert_eq!(delete_result.rows_affected, 5);
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -705,6 +713,9 @@ pub trait EntityTrait: EntityName {
     ///         r#"DELETE FROM "fruit" WHERE "fruit"."name" LIKE $1"#,
     ///         vec!["%Apple%".into()]
     ///     )]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     fn delete_many() -> DeleteMany<Self> {
         Delete::many(Self::default())
diff --git a/src/entity/model.rs b/src/entity/model.rs
index b11a700ba..acea83d63 100644
--- a/src/entity/model.rs
+++ b/src/entity/model.rs
@@ -47,8 +47,11 @@ pub trait FromQueryResult: Sized {
     }
 
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_query_results(vec![vec![
@@ -67,8 +70,6 @@ pub trait FromQueryResult: Sized {
     ///     num_of_cakes: i32,
     /// }
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let res: Vec<SelectResult> = SelectResult::find_by_statement(Statement::from_sql_and_values(
     ///     DbBackend::Postgres,
     ///     r#"SELECT "name", COUNT(*) AS "num_of_cakes" FROM "cake" GROUP BY("name")"#,
@@ -85,8 +86,6 @@ pub trait FromQueryResult: Sized {
     ///     },]
     /// );
     /// #
-    /// # Ok(())
-    /// # });
     /// # assert_eq!(
     /// #     db.into_transaction_log(),
     /// #     vec![Transaction::from_sql_and_values(
@@ -95,6 +94,9 @@ pub trait FromQueryResult: Sized {
     /// #         vec![]
     /// #     ),]
     /// # );
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     fn find_by_statement(stmt: Statement) -> SelectorRaw<SelectModel<Self>> {
         SelectorRaw::<SelectModel<Self>>::from_statement(stmt)
diff --git a/src/executor/paginator.rs b/src/executor/paginator.rs
index f52b3bd86..47548a0af 100644
--- a/src/executor/paginator.rs
+++ b/src/executor/paginator.rs
@@ -97,11 +97,14 @@ where
     /// Fetch one page and increment the page counter
     ///
     /// ```rust
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, MockDatabase, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
+    /// #
     /// # let owned_db = MockDatabase::new(DbBackend::Postgres).into_connection();
     /// # let db = &owned_db;
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
     /// let mut cake_pages = cake::Entity::find()
@@ -113,7 +116,7 @@ where
     /// }
     /// #
     /// # Ok(())
-    /// # });
+    /// # }
     /// ```
     pub async fn fetch_and_next(&mut self) -> Result<Option<Vec<S::Item>>, DbErr> {
         let vec = self.fetch().await?;
@@ -125,11 +128,14 @@ where
     /// Convert self into an async stream
     ///
     /// ```rust
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, MockDatabase, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
+    /// #
     /// # let owned_db = MockDatabase::new(DbBackend::Postgres).into_connection();
     /// # let db = &owned_db;
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
     /// #
     /// use futures::TryStreamExt;
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
@@ -143,7 +149,7 @@ where
     /// }
     /// #
     /// # Ok(())
-    /// # });
+    /// # }
     /// ```
     pub fn into_stream(mut self) -> PinBoxStream<'db, Result<Vec<S::Item>, DbErr>> {
         Box::pin(stream! {
diff --git a/src/executor/query.rs b/src/executor/query.rs
index 3c1a9184d..12d0c7cfa 100644
--- a/src/executor/query.rs
+++ b/src/executor/query.rs
@@ -320,8 +320,11 @@ pub trait TryGetableMany: Sized {
     fn try_get_many(res: &QueryResult, pre: &str, cols: &[String]) -> Result<Self, TryGetError>;
 
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(all(feature = "mock", feature = "macros"))]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_query_results(vec![vec![
@@ -344,8 +347,6 @@ pub trait TryGetableMany: Sized {
     ///     NumOfCakes,
     /// }
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let res: Vec<(String, i32)> =
     ///     <(String, i32)>::find_by_statement::<ResultCol>(Statement::from_sql_and_values(
     ///         DbBackend::Postgres,
@@ -362,9 +363,6 @@ pub trait TryGetableMany: Sized {
     ///         ("New York Cheese".to_owned(), 1),
     ///     ]
     /// );
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -374,6 +372,9 @@ pub trait TryGetableMany: Sized {
     ///         vec![]
     ///     ),]
     /// );
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     fn find_by_statement<C>(stmt: Statement) -> SelectorRaw<SelectGetableValue<Self, C>>
     where
diff --git a/src/executor/select.rs b/src/executor/select.rs
index 9fb906cf6..3a08392e0 100644
--- a/src/executor/select.rs
+++ b/src/executor/select.rs
@@ -143,8 +143,11 @@ where
     }
 
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(all(feature = "mock", feature = "macros"))]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_query_results(vec![vec![
@@ -164,8 +167,6 @@ where
     ///     CakeName,
     /// }
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let res: Vec<String> = cake::Entity::find()
     ///     .select_only()
     ///     .column_as(cake::Column::Name, QueryAs::CakeName)
@@ -177,9 +178,6 @@ where
     ///     res,
     ///     vec!["Chocolate Forest".to_owned(), "New York Cheese".to_owned()]
     /// );
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -189,11 +187,17 @@ where
     ///         vec![]
     ///     )]
     /// );
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     ///
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(all(feature = "mock", feature = "macros"))]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_query_results(vec![vec![
@@ -212,8 +216,6 @@ where
     ///     NumOfCakes,
     /// }
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let res: Vec<(String, i64)> = cake::Entity::find()
     ///     .select_only()
     ///     .column_as(cake::Column::Name, QueryAs::CakeName)
@@ -224,9 +226,6 @@ where
     ///     .await?;
     ///
     /// assert_eq!(res, vec![("Chocolate Forest".to_owned(), 2i64)]);
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -241,6 +240,9 @@ where
     ///         vec![]
     ///     )]
     /// );
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     pub fn into_values<T, C>(self) -> Selector<SelectGetableValue<T, C>>
     where
@@ -490,8 +492,11 @@ where
     }
 
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_query_results(vec![vec![
@@ -514,8 +519,6 @@ where
     ///     num_of_cakes: i32,
     /// }
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let res: Vec<SelectResult> = cake::Entity::find()
     ///     .from_raw_sql(Statement::from_sql_and_values(
     ///         DbBackend::Postgres,
@@ -539,9 +542,6 @@ where
     ///         },
     ///     ]
     /// );
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -551,6 +551,9 @@ where
     ///         vec![]
     ///     ),]
     /// );
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     pub fn into_model<M>(self) -> SelectorRaw<SelectModel<M>>
     where
@@ -563,8 +566,11 @@ where
     }
 
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
     /// #     .append_query_results(vec![vec![
@@ -581,8 +587,6 @@ where
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let res: Vec<serde_json::Value> = cake::Entity::find().from_raw_sql(
     ///     Statement::from_sql_and_values(
     ///         DbBackend::Postgres, r#"SELECT "cake"."id", "cake"."name" FROM "cake""#, vec![]
@@ -605,9 +609,6 @@ where
     ///         }),
     ///     ]
     /// );
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -616,6 +617,9 @@ where
     ///             DbBackend::Postgres, r#"SELECT "cake"."id", "cake"."name" FROM "cake""#, vec![]
     ///     ),
     /// ]);
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     #[cfg(feature = "with-json")]
     pub fn into_json(self) -> SelectorRaw<SelectModel<JsonValue>> {
@@ -627,15 +631,16 @@ where
 
     /// Get an item from the Select query
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres).into_connection();
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let _: Option<cake::Model> = cake::Entity::find()
     ///     .from_raw_sql(Statement::from_sql_and_values(
     ///         DbBackend::Postgres,
@@ -644,9 +649,6 @@ where
     ///     ))
     ///     .one(&db)
     ///     .await?;
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -656,6 +658,9 @@ where
     ///         vec![1.into()]
     ///     ),]
     /// );
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     pub async fn one<'a, C>(self, db: &C) -> Result<Option<S::Item>, DbErr>
     where
@@ -670,15 +675,16 @@ where
 
     /// Get all items from the Select query
     /// ```
+    /// # use sea_orm::{error::*, tests_cfg::*, *};
+    /// #
+    /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
-    /// # use sea_orm::{error::*, tests_cfg::*, MockDatabase, Transaction, DbBackend};
+    /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres).into_connection();
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
     ///
-    /// # let _: Result<(), DbErr> = smol::block_on(async {
-    /// #
     /// let _: Vec<cake::Model> = cake::Entity::find()
     ///     .from_raw_sql(Statement::from_sql_and_values(
     ///         DbBackend::Postgres,
@@ -687,9 +693,6 @@ where
     ///     ))
     ///     .all(&db)
     ///     .await?;
-    /// #
-    /// # Ok(())
-    /// # });
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -699,6 +702,9 @@ where
     ///         vec![]
     ///     ),]
     /// );
+    /// #
+    /// # Ok(())
+    /// # }
     /// ```
     pub async fn all<'a, C>(self, db: &C) -> Result<Vec<S::Item>, DbErr>
     where

From f9d04fc73feae198e0e821b318be571f96e29bd2 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 16 Nov 2021 17:21:44 +0800
Subject: [PATCH 29/31] Hotfix - separate counter for mock exec & query

---
 src/driver/mock.rs | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/src/driver/mock.rs b/src/driver/mock.rs
index c0ffa0a23..cdded50c8 100644
--- a/src/driver/mock.rs
+++ b/src/driver/mock.rs
@@ -19,7 +19,8 @@ pub struct MockDatabaseConnector;
 /// Defines a connection for the [MockDatabase]
 #[derive(Debug)]
 pub struct MockDatabaseConnection {
-    counter: AtomicUsize,
+    execute_counter: AtomicUsize,
+    query_counter: AtomicUsize,
     mocker: Mutex<Box<dyn MockDatabaseTrait>>,
 }
 
@@ -100,7 +101,8 @@ impl MockDatabaseConnection {
         M: MockDatabaseTrait,
     {
         Self {
-            counter: AtomicUsize::new(0),
+            execute_counter: AtomicUsize::new(0),
+            query_counter: AtomicUsize::new(0),
             mocker: Mutex::new(Box::new(m)),
         }
     }
@@ -117,14 +119,14 @@ impl MockDatabaseConnection {
     /// Execute the SQL statement in the [MockDatabase]
     pub fn execute(&self, statement: Statement) -> Result<ExecResult, DbErr> {
         debug_print!("{}", statement);
-        let counter = self.counter.fetch_add(1, Ordering::SeqCst);
+        let counter = self.execute_counter.fetch_add(1, Ordering::SeqCst);
         self.mocker.lock().unwrap().execute(counter, statement)
     }
 
     /// Return one [QueryResult] if the query was successful
     pub fn query_one(&self, statement: Statement) -> Result<Option<QueryResult>, DbErr> {
         debug_print!("{}", statement);
-        let counter = self.counter.fetch_add(1, Ordering::SeqCst);
+        let counter = self.query_counter.fetch_add(1, Ordering::SeqCst);
         let result = self.mocker.lock().unwrap().query(counter, statement)?;
         Ok(result.into_iter().next())
     }
@@ -132,7 +134,7 @@ impl MockDatabaseConnection {
     /// Return all [QueryResult]s if the query was successful
     pub fn query_all(&self, statement: Statement) -> Result<Vec<QueryResult>, DbErr> {
         debug_print!("{}", statement);
-        let counter = self.counter.fetch_add(1, Ordering::SeqCst);
+        let counter = self.query_counter.fetch_add(1, Ordering::SeqCst);
         self.mocker.lock().unwrap().query(counter, statement)
     }
 

From 7298fdeda9ef71a661804eab44ac21793f549a37 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 16 Nov 2021 17:35:49 +0800
Subject: [PATCH 30/31] Rewrite doctests

---
 src/entity/active_model.rs |  84 ++++++++++++++++--------------
 src/entity/base_entity.rs  | 103 +++++++++++++++++++++++--------------
 src/executor/paginator.rs  |  24 +++++++--
 src/executor/select.rs     |  18 ++++++-
 4 files changed, 146 insertions(+), 83 deletions(-)

diff --git a/src/entity/active_model.rs b/src/entity/active_model.rs
index c7d26574a..06e01fcbe 100644
--- a/src/entity/active_model.rs
+++ b/src/entity/active_model.rs
@@ -151,11 +151,11 @@ pub trait ActiveModelTrait: Clone + Debug {
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
-    /// #     .append_exec_results(vec![
-    /// #         MockExecResult {
-    /// #             last_insert_id: 15,
-    /// #             rows_affected: 1,
-    /// #         },
+    /// #     .append_query_results(vec![
+    /// #         vec![cake::Model {
+    /// #             id: 15,
+    /// #             name: "Apple Pie".to_owned(),
+    /// #         }],
     /// #     ])
     /// #     .into_connection();
     /// #
@@ -167,15 +167,13 @@ pub trait ActiveModelTrait: Clone + Debug {
     /// };
     ///
     /// assert_eq!(
-    ///     apple
-    ///         .insert(&db)
-    ///         .await?,
-    ///     cake::ActiveModel {
-    ///         id: Set(150),
-    ///         name: Set("Apple Pie".to_owned()),
+    ///     apple.insert(&db).await?,
+    ///     cake::Model {
+    ///         id: 15,
+    ///         name: "Apple Pie".to_owned(),
     ///     }
+    ///     .into_active_model()
     /// );
-    /// assert!(false);
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -183,7 +181,8 @@ pub trait ActiveModelTrait: Clone + Debug {
     ///         DbBackend::Postgres,
     ///         r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id", "name""#,
     ///         vec!["Apple Pie".into()]
-    ///     )]);
+    ///     )]
+    /// );
     /// #
     /// # Ok(())
     /// # }
@@ -199,6 +198,12 @@ pub trait ActiveModelTrait: Clone + Debug {
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::MySql)
+    /// #     .append_query_results(vec![
+    /// #         vec![cake::Model {
+    /// #             id: 15,
+    /// #             name: "Apple Pie".to_owned(),
+    /// #         }],
+    /// #     ])
     /// #     .append_exec_results(vec![
     /// #         MockExecResult {
     /// #             last_insert_id: 15,
@@ -215,13 +220,12 @@ pub trait ActiveModelTrait: Clone + Debug {
     /// };
     ///
     /// assert_eq!(
-    ///     apple
-    ///         .insert(&db)
-    ///         .await?,
-    ///     cake::ActiveModel {
-    ///         id: Set(150),
-    ///         name: Set("Apple Pie".to_owned()),
+    ///     apple.insert(&db).await?,
+    ///     cake::Model {
+    ///         id: 15,
+    ///         name: "Apple Pie".to_owned(),
     ///     }
+    ///     .into_active_model()
     /// );
     ///
     /// assert_eq!(
@@ -235,7 +239,10 @@ pub trait ActiveModelTrait: Clone + Debug {
     ///         Transaction::from_sql_and_values(
     ///             DbBackend::MySql,
     ///             r#"SELECT `cake`.`id`, `cake`.`name` FROM `cake` WHERE `cake`.`id` = ? LIMIT ?"#,
-    ///             vec![15.into(), 1u64.into()])]);
+    ///             vec![15.into(), 1u64.into()]
+    ///         )
+    ///     ]
+    /// );
     /// #
     /// # Ok(())
     /// # }
@@ -265,11 +272,12 @@ pub trait ActiveModelTrait: Clone + Debug {
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
-    /// #     .append_exec_results(vec![
-    /// #         MockExecResult {
-    /// #             last_insert_id: 0,
-    /// #             rows_affected: 1,
-    /// #         },
+    /// #     .append_query_results(vec![
+    /// #         vec![fruit::Model {
+    /// #             id: 1,
+    /// #             name: "Orange".to_owned(),
+    /// #             cake_id: None,
+    /// #         }],
     /// #     ])
     /// #     .into_connection();
     /// #
@@ -282,14 +290,13 @@ pub trait ActiveModelTrait: Clone + Debug {
     /// };
     ///
     /// assert_eq!(
-    ///     orange
-    ///         .update(&db)
-    ///         .await?,
-    ///     fruit::ActiveModel {
-    ///         id: Set(1),
-    ///         name: Set("Orange".to_owned()),
-    ///         cake_id: Set(None),
+    ///     orange.update(&db).await?,
+    ///     fruit::Model {
+    ///         id: 1,
+    ///         name: "Orange".to_owned(),
+    ///         cake_id: None,
     ///     }
+    ///     .into_active_model()
     /// );
     ///
     /// assert_eq!(
@@ -338,14 +345,13 @@ pub trait ActiveModelTrait: Clone + Debug {
     /// };
     ///
     /// assert_eq!(
-    ///     orange
-    ///         .update(&db)
-    ///         .await?,
-    ///     fruit::ActiveModel {
-    ///         id: Set(1),
-    ///         name: Set("Orange".to_owned()),
-    ///         cake_id: Set(None),
+    ///     orange.update(&db).await?,
+    ///     fruit::Model {
+    ///         id: 1,
+    ///         name: "Orange".to_owned(),
+    ///         cake_id: None,
     ///     }
+    ///     .into_active_model()
     /// );
     ///
     /// assert_eq!(
diff --git a/src/entity/base_entity.rs b/src/entity/base_entity.rs
index 8bbb6195d..e6247d352 100644
--- a/src/entity/base_entity.rs
+++ b/src/entity/base_entity.rs
@@ -285,12 +285,9 @@ pub trait EntityTrait: EntityName {
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
-    /// #     .append_exec_results(vec![
-    /// #         MockExecResult {
-    /// #             last_insert_id: 15,
-    /// #             rows_affected: 1,
-    /// #         },
-    /// #     ])
+    /// #     .append_query_results(vec![vec![maplit::btreemap! {
+    /// #         "id" => Into::<Value>::into(15),
+    /// #     }]])
     /// #     .into_connection();
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
@@ -302,8 +299,7 @@ pub trait EntityTrait: EntityName {
     ///
     /// let insert_result = cake::Entity::insert(apple).exec(&db).await?;
     ///
-    /// assert_eq!(dbg!(insert_result.last_insert_id), 150);
-    /// assert!(false);
+    /// assert_eq!(dbg!(insert_result.last_insert_id), 15);
     ///
     /// assert_eq!(
     ///     db.into_transaction_log(),
@@ -311,7 +307,8 @@ pub trait EntityTrait: EntityName {
     ///         DbBackend::Postgres,
     ///         r#"INSERT INTO "cake" ("name") VALUES ($1) RETURNING "id""#,
     ///         vec!["Apple Pie".into()]
-    ///     )]);
+    ///     )]
+    /// );
     /// #
     /// # Ok(())
     /// # }
@@ -352,7 +349,8 @@ pub trait EntityTrait: EntityName {
     ///         DbBackend::MySql,
     ///         r#"INSERT INTO `cake` (`name`) VALUES (?)"#,
     ///         vec!["Apple Pie".into()]
-    ///     )]);
+    ///     )]
+    /// );
     /// #
     /// # Ok(())
     /// # }
@@ -376,12 +374,9 @@ pub trait EntityTrait: EntityName {
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
-    /// #     .append_exec_results(vec![
-    /// #         MockExecResult {
-    /// #             last_insert_id: 28,
-    /// #             rows_affected: 2,
-    /// #         },
-    /// #     ])
+    /// #     .append_query_results(vec![vec![maplit::btreemap! {
+    /// #         "id" => Into::<Value>::into(28),
+    /// #     }]])
     /// #     .into_connection();
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
@@ -395,7 +390,9 @@ pub trait EntityTrait: EntityName {
     ///     ..Default::default()
     /// };
     ///
-    /// let insert_result = cake::Entity::insert_many(vec![apple, orange]).exec(&db).await?;
+    /// let insert_result = cake::Entity::insert_many(vec![apple, orange])
+    ///     .exec(&db)
+    ///     .await?;
     ///
     /// assert_eq!(insert_result.last_insert_id, 28);
     ///
@@ -405,7 +402,8 @@ pub trait EntityTrait: EntityName {
     ///         DbBackend::Postgres,
     ///         r#"INSERT INTO "cake" ("name") VALUES ($1), ($2) RETURNING "id""#,
     ///         vec!["Apple Pie".into(), "Orange Scone".into()]
-    ///     )]);
+    ///     )]
+    /// );
     /// #
     /// # Ok(())
     /// # }
@@ -440,7 +438,9 @@ pub trait EntityTrait: EntityName {
     ///     ..Default::default()
     /// };
     ///
-    /// let insert_result = cake::Entity::insert_many(vec![apple, orange]).exec(&db).await?;
+    /// let insert_result = cake::Entity::insert_many(vec![apple, orange])
+    ///     .exec(&db)
+    ///     .await?;
     ///
     /// assert_eq!(insert_result.last_insert_id, 28);
     ///
@@ -450,7 +450,8 @@ pub trait EntityTrait: EntityName {
     ///         DbBackend::MySql,
     ///         r#"INSERT INTO `cake` (`name`) VALUES (?), (?)"#,
     ///         vec!["Apple Pie".into(), "Orange Scone".into()]
-    ///     )]);
+    ///     )]
+    /// );
     /// #
     /// # Ok(())
     /// # }
@@ -477,11 +478,12 @@ pub trait EntityTrait: EntityName {
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::Postgres)
-    /// #     .append_exec_results(vec![
-    /// #         MockExecResult {
-    /// #             last_insert_id: 0,
-    /// #             rows_affected: 1,
-    /// #         },
+    /// #     .append_query_results(vec![
+    /// #         vec![fruit::Model {
+    /// #             id: 1,
+    /// #             name: "Orange".to_owned(),
+    /// #             cake_id: None,
+    /// #         }],
     /// #     ])
     /// #     .into_connection();
     /// #
@@ -498,7 +500,12 @@ pub trait EntityTrait: EntityName {
     ///         .filter(fruit::Column::Name.contains("orange"))
     ///         .exec(&db)
     ///         .await?,
-    ///     orange
+    ///     fruit::Model {
+    ///         id: 1,
+    ///         name: "Orange".to_owned(),
+    ///         cake_id: None,
+    ///     }
+    ///     .into_active_model(),
     /// );
     ///
     /// assert_eq!(
@@ -523,6 +530,12 @@ pub trait EntityTrait: EntityName {
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
     /// # let db = MockDatabase::new(DbBackend::MySql)
+    /// #     .append_exec_results(vec![
+    /// #         MockExecResult {
+    /// #             last_insert_id: 0,
+    /// #             rows_affected: 1,
+    /// #         },
+    /// #     ])
     /// #     .append_query_results(vec![
     /// #         vec![fruit::Model {
     /// #             id: 1,
@@ -530,12 +543,6 @@ pub trait EntityTrait: EntityName {
     /// #             cake_id: None,
     /// #         }],
     /// #     ])
-    /// #     .append_exec_results(vec![
-    /// #         MockExecResult {
-    /// #             last_insert_id: 0,
-    /// #             rows_affected: 1,
-    /// #         },
-    /// #     ])
     /// #     .into_connection();
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
@@ -551,7 +558,12 @@ pub trait EntityTrait: EntityName {
     ///         .filter(fruit::Column::Name.contains("orange"))
     ///         .exec(&db)
     ///         .await?,
-    ///     orange
+    ///     fruit::Model {
+    ///         id: 1,
+    ///         name: "Orange".to_owned(),
+    ///         cake_id: None,
+    ///     }
+    ///     .into_active_model(),
     /// );
     ///
     /// assert_eq!(
@@ -600,7 +612,12 @@ pub trait EntityTrait: EntityName {
     /// #     ])
     /// #     .into_connection();
     /// #
-    /// use sea_orm::{entity::*, query::*, tests_cfg::fruit, sea_query::{Expr, Value}};
+    /// use sea_orm::{
+    ///     entity::*,
+    ///     query::*,
+    ///     sea_query::{Expr, Value},
+    ///     tests_cfg::fruit,
+    /// };
     ///
     /// let update_result = fruit::Entity::update_many()
     ///     .col_expr(fruit::Column::CakeId, Expr::value(Value::Int(None)))
@@ -616,7 +633,8 @@ pub trait EntityTrait: EntityName {
     ///         DbBackend::Postgres,
     ///         r#"UPDATE "fruit" SET "cake_id" = $1 WHERE "fruit"."name" LIKE $2"#,
     ///         vec![Value::Int(None), "%Apple%".into()]
-    ///     )]);
+    ///     )]
+    /// );
     /// #
     /// # Ok(())
     /// # }
@@ -661,9 +679,11 @@ pub trait EntityTrait: EntityName {
     /// assert_eq!(
     ///     db.into_transaction_log(),
     ///     vec![Transaction::from_sql_and_values(
-    ///         DbBackend::Postgres, r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
+    ///         DbBackend::Postgres,
+    ///         r#"DELETE FROM "fruit" WHERE "fruit"."id" = $1"#,
     ///         vec![3i32.into()]
-    ///     )]);
+    ///     )]
+    /// );
     /// #
     /// # Ok(())
     /// # }
@@ -695,6 +715,12 @@ pub trait EntityTrait: EntityName {
     /// #             rows_affected: 5,
     /// #         },
     /// #     ])
+    /// #     .append_query_results(vec![
+    /// #         vec![cake::Model {
+    /// #             id: 15,
+    /// #             name: "Apple Pie".to_owned(),
+    /// #         }],
+    /// #     ])
     /// #     .into_connection();
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::fruit};
@@ -712,7 +738,8 @@ pub trait EntityTrait: EntityName {
     ///         DbBackend::Postgres,
     ///         r#"DELETE FROM "fruit" WHERE "fruit"."name" LIKE $1"#,
     ///         vec!["%Apple%".into()]
-    ///     )]);
+    ///     )]
+    /// );
     /// #
     /// # Ok(())
     /// # }
diff --git a/src/executor/paginator.rs b/src/executor/paginator.rs
index 47548a0af..e8f37bea7 100644
--- a/src/executor/paginator.rs
+++ b/src/executor/paginator.rs
@@ -96,14 +96,22 @@ where
 
     /// Fetch one page and increment the page counter
     ///
-    /// ```rust
+    /// ```
     /// # use sea_orm::{error::*, tests_cfg::*, *};
     /// #
     /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
-    /// # let owned_db = MockDatabase::new(DbBackend::Postgres).into_connection();
+    /// # let owned_db = MockDatabase::new(DbBackend::Postgres)
+    /// #     .append_query_results(vec![
+    /// #         vec![cake::Model {
+    /// #             id: 1,
+    /// #             name: "Cake".to_owned(),
+    /// #         }],
+    /// #         vec![],
+    /// #     ])
+    /// #     .into_connection();
     /// # let db = &owned_db;
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
@@ -127,14 +135,22 @@ where
 
     /// Convert self into an async stream
     ///
-    /// ```rust
+    /// ```
     /// # use sea_orm::{error::*, tests_cfg::*, *};
     /// #
     /// # #[smol_potat::main]
     /// # #[cfg(feature = "mock")]
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
-    /// # let owned_db = MockDatabase::new(DbBackend::Postgres).into_connection();
+    /// # let owned_db = MockDatabase::new(DbBackend::Postgres)
+    /// #     .append_query_results(vec![
+    /// #         vec![cake::Model {
+    /// #             id: 1,
+    /// #             name: "Cake".to_owned(),
+    /// #         }],
+    /// #         vec![],
+    /// #     ])
+    /// #     .into_connection();
     /// # let db = &owned_db;
     /// #
     /// use futures::TryStreamExt;
diff --git a/src/executor/select.rs b/src/executor/select.rs
index 3a08392e0..4c0d8ecfc 100644
--- a/src/executor/select.rs
+++ b/src/executor/select.rs
@@ -637,7 +637,14 @@ where
     /// # #[cfg(feature = "mock")]
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
-    /// # let db = MockDatabase::new(DbBackend::Postgres).into_connection();
+    /// # let db = MockDatabase::new(DbBackend::Postgres)
+    /// #     .append_query_results(vec![
+    /// #         vec![cake::Model {
+    /// #             id: 1,
+    /// #             name: "Cake".to_owned(),
+    /// #         }],
+    /// #     ])
+    /// #     .into_connection();
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
     ///
@@ -681,7 +688,14 @@ where
     /// # #[cfg(feature = "mock")]
     /// # pub async fn main() -> Result<(), DbErr> {
     /// #
-    /// # let db = MockDatabase::new(DbBackend::Postgres).into_connection();
+    /// # let db = MockDatabase::new(DbBackend::Postgres)
+    /// #     .append_query_results(vec![
+    /// #         vec![cake::Model {
+    /// #             id: 1,
+    /// #             name: "Cake".to_owned(),
+    /// #         }],
+    /// #     ])
+    /// #     .into_connection();
     /// #
     /// use sea_orm::{entity::*, query::*, tests_cfg::cake};
     ///

From 42404eb5253dee050443b3251d710ba9001d96f3 Mon Sep 17 00:00:00 2001
From: Billy Chan <ccw.billy.123@gmail.com>
Date: Tue, 16 Nov 2021 17:56:22 +0800
Subject: [PATCH 31/31] Fixup

---
 src/executor/update.rs | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/src/executor/update.rs b/src/executor/update.rs
index 9870b10d9..83747e2d6 100644
--- a/src/executor/update.rs
+++ b/src/executor/update.rs
@@ -175,22 +175,6 @@ mod tests {
                 vec![],
             ])
             .append_exec_results(vec![
-                MockExecResult {
-                    last_insert_id: 0,
-                    rows_affected: 1,
-                },
-                MockExecResult {
-                    last_insert_id: 0,
-                    rows_affected: 0,
-                },
-                MockExecResult {
-                    last_insert_id: 0,
-                    rows_affected: 0,
-                },
-                MockExecResult {
-                    last_insert_id: 0,
-                    rows_affected: 0,
-                },
                 MockExecResult {
                     last_insert_id: 0,
                     rows_affected: 0,