This is because the Upsert::preExecute() method is protected.

If you use the upsert method and try to see the query with the devel function dpq() you get one error.

    $query = $this->connection->upsert('forcontu_database_counter')
              ->fields([
        'route' => $route,
        'uid' => $uid,
        'user_count' => 1,
        'lastcount' => time(),
      ]);
    $query->key('route');
    $query->execute();
    
    dpq($query);

Error: Call to protected method Drupal\Core\Database\Query\Upsert::preExecute() from context '' in dpq() (line 419 of /Users/adriancid/Sites/drupal82-test/modules/devel/devel.module) #0

But if you set to public the preExecute method you will see:

Error: Call to undefined method Drupal\Core\Database\Driver\mysql\Upsert::arguments() in dpq() (line 424 of /Users/adriancid/Sites/drupal82-test/modules/devel/devel.module) #0

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

adriancid created an issue. See original summary.

Znak’s picture

Assigned: Unassigned » Znak
Znak’s picture

Status: Active » Postponed (maintainer needs more info)

You are using this method in your custom module or theme?

adriancid’s picture

custom module, with the select and the update works fine

willzyx’s picture

Status: Postponed (maintainer needs more info) » Active
jackson.cooper’s picture

The method_exists() call can't simply be updated to is_callable(), because the Upsert class doesn't have an arguments() method. It does have a __toString() method that returns the query however. Here's a patch which casts the object to a string, if the __toString() method is callable.

lussoluca’s picture

Assigned: Znak » Unassigned

We should have a test for this

willzyx’s picture

Status: Active » Needs work
moshe weitzman’s picture

Status: Needs work » Closed (duplicate)