Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: insertBatch not return false #9362

Closed
okatse opened this issue Jan 1, 2025 · 6 comments · Fixed by #9363
Closed

Bug: insertBatch not return false #9362

okatse opened this issue Jan 1, 2025 · 6 comments · Fixed by #9363
Labels
bug Verified issues on the current code behavior or pull requests that will fix them database Issues or pull requests that affect the database layer

Comments

@okatse
Copy link

okatse commented Jan 1, 2025

PHP Version

8.1

CodeIgniter4 Version

4.5.1

CodeIgniter4 Installation Method

Composer (using codeigniter4/appstarter)

Which operating systems have you tested for this bug?

Windows

Which server did you use?

apache

Database

PostgreSQL 15

What happened?

insertBatch never not return false

Steps to Reproduce

DataBase

CREATE TABLE public.test (
	id serial4 NOT NULL,
	"name" varchar(22) NOT NULL
);

Controller

public function test2()
{
    $db = \Config\Database::connect();
    $toInsert[] = [
        'name' => 'aaaa'
    ];
    $toInsert[] = [
        'name' => null
    ];
    try {
        $db->transBegin();
        $query = $this->db->table('public.test');
        if ($query->insertBatch($toInsert) === false) {
            d($db->error());
            d('Error from IF');
            $db->transRollback();
        }
        else
        {
            $db->transCommit();
        }
    } catch (DatabaseException $th) {
        d($th->getMessage());
        d('Error from TRY');
        $db->transRollback();
    }
}

Expected Output

$query->insertBatch($toInsert) === false

Anything else?

Without the transaction, the code works correctly. With the transaction, there is an error. pg_affected_rows(): Argument #1 ($result) must be of type PgSql\Result, bool given

@okatse okatse added the bug Verified issues on the current code behavior or pull requests that will fix them label Jan 1, 2025
@kenjis kenjis added the database Issues or pull requests that affect the database layer label Jan 2, 2025
@michalsn
Copy link
Member

michalsn commented Jan 2, 2025

A couple of things:

  1. Transaction without explicitly use of $db->transException(true) will not throw on error.
  2. The description of returning false in $db->insertBatch() is misleading, because it will only return it if there is no data to perform the insert operation.
  3. You should use $db->transStatus() === false comparison to determine if everything went ok.

Anyway, I was able to recreate the problem.

@okatse
Copy link
Author

okatse commented Jan 2, 2025

public function test2()
{
    $db = \Config\Database::connect();
    $toInsert[] = [
        'name' => 'aaaa'
    ];
    $toInsert[] = [
        'name' => null
    ];
    try {
        $db->transException(true)->transStart();

        $query = $this->db->table('public.test');
        if ($query->insertBatch($toInsert) === false) {
            d($db->error());
            d('Error from IF');
            $db->transRollback();
        }
        $this->db->transComplete();

    } catch (DatabaseException $th) {

        d('Error from TRY');

    }
}

In this way, it is fine. Output 'Error from TRY'

With this $db->transStatus() === false ? hym not working ?

public function test2()
{
    $db = \Config\Database::connect();
    $toInsert[] = [
        'name' => 'aaaa'
    ];
    $toInsert[] = [
        'name' => null
    ];
    try {
        $db->transException(true)->transStart();

        $query = $this->db->table('public.test');
        if ($query->insertBatch($toInsert) === false) {
            d($db->error());
            d('Error from IF');
            $db->transRollback();
        }
        d('A',$db->transStatus());
        $this->db->transComplete();

    } catch (DatabaseException $th) {
            d('B',$db->transStatus());
        d('Error from TRY');

    }
}

@michalsn
Copy link
Member

michalsn commented Jan 2, 2025

Sorry, but I'm not sure what you're asking me. Here are the cases when you use transactions.

When transException() is enabled, this is how your code should look like:

try {
    $db->transException(true)->transStart();
    $query = $db->table('public.test');
    $query->insertBatch($toInsert);
    $db->transComplete();
} catch (DatabaseException $th) {
    d('Error from TRY');
}

If something goes wrong with your insert, the query will be rolled back automatically and an exception will be thrown.


The second case is when transException() is disabled (default).

$db->transStart();
$query = $db->table('public.test');
$query->insertBatch($toInsert);
$db->transComplete();
if ($db->transStatus() === false) {
    d('Error from insert');
}

In this case, we need to check whether the transaction was unsuccessful to display the error.

@michalsn
Copy link
Member

michalsn commented Jan 2, 2025

Please check if #9363 fixes your problem.

@okatse
Copy link
Author

okatse commented Jan 2, 2025

        if ($this->resultID === false) {
            return 0;
        }

Yes, this change works correctly - thank you.

@michalsn
Copy link
Member

michalsn commented Jan 3, 2025

Thank you @okatse

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Verified issues on the current code behavior or pull requests that will fix them database Issues or pull requests that affect the database layer
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants