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

TypeError: StatementWrapper::bindValue(): Argument #3 ($dataType) must be of type int #1966

Open
TheUnableDeveloper opened this issue May 11, 2023 · 12 comments

Comments

@TheUnableDeveloper
Copy link

Hello,
we are lately facing this error in different K8S environments serving a PHP API that use Propel ORM:

"Unable to execute statement
[SELECT settings.id, settings.setting_value FROM settings WHERE settings.id=:p1 LIMIT 1]
TypeError: Propel\\Runtime\\Connection\\StatementWrapper::bindValue(): Argument #3 ($dataType) must be of type int, null given"

The problem is not related to this table only, but to "random" tables, in "random" queries.
With random I mean: every time it occur in different tables and queries.. I still didn't find a way to reproduce it.

I noticed though, that after restarting the API pod, the problem disappear for a while and generally appears again after the next deploy of the API.

So maybe there is a thing with K8S, but I can't get what.

Versions:

  • PHP 8.1
  • Propel 2.0.0-beta2
  • Laminas-mvc 3.6

Thanks in advance!

Full stack trace:

"Unable to execute statement
[SELECT settings.id, settings.setting_value FROM settings WHERE settings.id=:p1 LIMIT 1]
TypeError: Propel\\Runtime\\Connection\\StatementWrapper::bindValue(): Argument #3 ($dataType) must be of type int, null given,
called in {project_root}/vendor/propel/propel/src/Propel/Runtime/Adapter/Pdo/MysqlAdapter.php on line 184 and defined in
{project_root}/vendor/propel/propel/src/Propel/Runtime/Connection/StatementWrapper.php:144\nStack trace:\n#0
{project_root}/vendor/propel/propel/src/Propel/Runtime/Adapter/Pdo/MysqlAdapter.php(184):
Propel\\Runtime\\Connection\\StatementWrapper->bindValue(':p1', 'attachment_vali...', NULL)\n#1
{project_root}/vendor/propel/propel/src/Propel/Runtime/Adapter/Pdo/PdoAdapter.php(586):
Propel\\Runtime\\Adapter\\Pdo\\MysqlAdapter->bindValue(Object(Propel\\Runtime\\Connection\\StatementWrapper), ':p1', 'attachment_vali...',
Object(Propel\\Runtime\\Map\\ColumnMap), 1)\n#2 {project_root}/vendor/propel/propel/src/Propel/Runtime/ActiveQuery/QueryExecutor/AbstractQueryExecutor.php(101):
Propel\\Runtime\\Adapter\\Pdo\\PdoAdapter->bindValues(Object(Propel\\Runtime\\Connection\\StatementWrapper), Array, Object(Propel\\Runtime\\Map\\DatabaseMap))\n#3
{project_root}/vendor/propel/propel/src/Propel/Runtime/ActiveQuery/QueryExecutor/SelectQueryExecutor.php(49):
Propel\\Runtime\\ActiveQuery\\QueryExecutor\\AbstractQueryExecutor->executeStatement(Object(Propel\\Runtime\\ActiveQuery\\SqlBuilder\\PreparedStatementDto))\n#4
{project_root}/vendor/propel/propel/src/Propel/Runtime/ActiveQuery/QueryExecutor/SelectQueryExecutor.php(37):
Propel\\Runtime\\ActiveQuery\\QueryExecutor\\SelectQueryExecutor->runSelect()\n#5 {project_root}/vendor/propel/propel/src/Propel/Runtime/ActiveQuery/Criteria.php(2444):
Propel\\Runtime\\ActiveQuery\\QueryExecutor\\SelectQueryExecutor::execute(Object(SettingsQuery), Object(Propel\\Runtime\\Connection\\ConnectionWrapper))\n#6
{project_root}/vendor/propel/propel/src/Propel/Runtime/ActiveQuery/ModelCriteria.php(2277):
Propel\\Runtime\\ActiveQuery\\Criteria->doSelect(Object(Propel\\Runtime\\Connection\\ConnectionWrapper))\n#7
{project_root}/vendor/propel/propel/src/Propel/Runtime/ActiveQuery/ModelCriteria.php(1328):
Propel\\Runtime\\ActiveQuery\\ModelCriteria->doSelect(Object(Propel\\Runtime\\Connection\\ConnectionWrapper))\n#8
{project_root}/vendor/propel/propel/src/Propel/Runtime/ActiveQuery/ModelCriteria.php(1641):
Propel\\Runtime\\ActiveQuery\\ModelCriteria->findOne(Object(Propel\\Runtime\\Connection\\ConnectionWrapper))\n#9
{project_root}/vendor/propel/propel/src/Propel/Runtime/ActiveQuery/ModelCriteria.php(2497):
Propel\\Runtime\\ActiveQuery\\ModelCriteria->findOneBy('Id', 'attachment_vali...')\n#10
{project_root}/vendor/package/prj/src/package/prj/Common/Utils.php(145):
Propel\\Runtime\\ActiveQuery\\ModelCriteria->__call('findOneById', Array)\n#11
{project_root}/module/ApiAttachment/src/ApiAttachment/V1/Rest/Attachments/AttachmentsResource.php(129):
package\\prj\\Common\\Utils::getSettings(Object(SettingsQuery), 'attachment_vali...', 'SettingValue')\n#12
{project_root}/module/ApiAttachment/src/ApiAttachment/V1/Rest/Attachments/AttachmentsResource.php(41):
ApiAttachment\\V1\\Rest\\Attachments\\AttachmentsResource->validate(Array)\n#13
{project_root}/vendor/laminas-api-tools/api-tools-rest/src/AbstractResourceListener.php(173):
ApiAttachment\\V1\\Rest\\Attachments\\AttachmentsResource->create(Array)\n#14
{project_root}/vendor/laminas/laminas-eventmanager/src/EventManager.php(318):
Laminas\\ApiTools\\Rest\\AbstractResourceListener->dispatch(Object(Laminas\\ApiTools\\Rest\\ResourceEvent))\n#15
{project_root}/vendor/laminas/laminas-eventmanager/src/EventManager.php(178):
Laminas\\EventManager\\EventManager->triggerListeners(Object(Laminas\\ApiTools\\Rest\\ResourceEvent),
Object(Closure))\n#16 {project_root}/vendor/laminas-api-tools/api-tools-rest/src/Resource.php(549):
Laminas\\EventManager\\EventManager->triggerEventUntil(Object(Closure), Object(Laminas\\ApiTools\\Rest\\ResourceEvent))\n#17
{project_root}/vendor/laminas-api-tools/api-tools-rest/src/Resource.php(242): Laminas\\ApiTools\\Rest\\Resource->triggerEvent('create', Array)\n#18
{project_root}/vendor/laminas-api-tools/api-tools-rest/src/RestController.php(373): Laminas\\ApiTools\\Rest\\Resource->create(Object(stdClass))\n#19
{project_root}/vendor/laminas-api-tools/api-tools-rest/src/RestController.php(895): Laminas\\ApiTools\\Rest\\RestController->create(Array)\n#20
{project_root}/vendor/laminas/laminas-mvc/src/Controller/AbstractRestfulController.php(422):
Laminas\\ApiTools\\Rest\\RestController->processPostData(Object(Laminas\\Http\\PhpEnvironment\\Request))\n#21
{project_root}/vendor/laminas-api-tools/api-tools-rest/src/RestController.php(335):
Laminas\\Mvc\\Controller\\AbstractRestfulController->onDispatch(Object(Laminas\\Mvc\\MvcEvent))\n#22
{project_root}/vendor/laminas/laminas-eventmanager/src/EventManager.php(318):
Laminas\\ApiTools\\Rest\\RestController->onDispatch(Object(Laminas\\Mvc\\MvcEvent))\n#23
{project_root}/vendor/laminas/laminas-eventmanager/src/EventManager.php(178):
Laminas\\EventManager\\EventManager->triggerListeners(Object(Laminas\\Mvc\\MvcEvent),
Object(Closure))\n#24 {project_root}/vendor/laminas/laminas-mvc/src/Controller/AbstractController.php(105):
Laminas\\EventManager\\EventManager->triggerEventUntil(Object(Closure), Object(Laminas\\Mvc\\MvcEvent))\n#25
{project_root}/vendor/laminas/laminas-mvc/src/Controller/AbstractRestfulController.php(306):
Laminas\\Mvc\\Controller\\AbstractController->dispatch(Object(Laminas\\Http\\PhpEnvironment\\Request),
Object(Laminas\\Http\\PhpEnvironment\\Response))\n#26 {project_root}/vendor/laminas/laminas-mvc/src/DispatchListener.php(117):
Laminas\\Mvc\\Controller\\AbstractRestfulController->dispatch(Object(Laminas\\Http\\PhpEnvironment\\Request),
Object(Laminas\\Http\\PhpEnvironment\\Response))\n#27 {project_root}/vendor/laminas/laminas-eventmanager/src/EventManager.php(318):
Laminas\\Mvc\\DispatchListener->onDispatch(Object(Laminas\\Mvc\\MvcEvent))\n#28 {project_root}/vendor/laminas/laminas-eventmanager/src/EventManager.php(178):
Laminas\\EventManager\\EventManager->triggerListeners(Object(Laminas\\Mvc\\MvcEvent), Object(Closure))\n#29
{project_root}/vendor/laminas/laminas-mvc/src/Application.php(319): Laminas\\EventManager\\EventManager->triggerEventUntil(Object(Closure),
Object(Laminas\\Mvc\\MvcEvent))\n#30 {project_root}/public/index.php(52): Laminas\\Mvc\\Application->run()\n#31 {main}",
@mringler
Copy link
Contributor

mringler commented May 12, 2023

Seems like the type of the id column is not recognized. Can you add the definition of the settings table in schema.xml?

@TheUnableDeveloper
Copy link
Author

Hi! thanks for the fast reply.
Here it is the schema.xml table definition:

<table name="settings" idMethod="native" phpName="Settings">
    <column name="id" phpName="Id" type="VARCHAR" size="50" primaryKey="true" required="true"/>
    <column name="setting_value" phpName="SettingValue" type="LONGVARCHAR" required="true"/>
    <vendor type="mysql">
      <parameter name="Engine" value="InnoDB"/>
    </vendor>
  </table>

and the relative SQL part:

DROP TABLE IF EXISTS "settings";

CREATE TABLE "settings"
(
    "id" VARCHAR(50) NOT NULL,
    "setting_value" TEXT NOT NULL,
    PRIMARY KEY ("id")
) ENGINE=InnoDB;

Thank you

@mringler
Copy link
Contributor

Hmm, hard to say where this could go wrong. It's a varchar column...

In your output, you can see that bindValue() is called with NULL as third parameter:

StatementWrapper->bindValue(':p1', 'attachment_vali...', NULL)

This should be an int indicating the parameter type to PDO (2 for a string parameter).

The value is retrieved from the table map file describing your Settings table (aptly called SettingsTableMap.php), which should contain a line like

$this->addPrimaryKey('id', 'Id', 'VARCHAR', true, 50, null);

and the VARCHAR value there should make Propel figure out the type of the parameter. You can check if the line is there, but one way or another, I would start by rebuilding the model files (which also rebuilds table maps) with the propel model:build command. If that doesn't work, try to update Propel. Otherwise, I have no idea what could go wrong.

Let me know how it goes

@TheUnableDeveloper
Copy link
Author

I'll try asap and let you know, thank you!

@TheUnableDeveloper
Copy link
Author

Hi,
I'm back.
I tried to run the build command, though the problem was hard to replicate before (and now too) so it'll take a while to check the solution.
In the meantime I'll plan a full upgrade of the orm.
Thank you for your time!

@TheUnableDeveloper
Copy link
Author

Hello,
We upgraded to the last version of Propel and we didn't face the issue anymore, lately.
So I believe we can close the issue.
Thank for your support.

Note: After a deeper analysis of the logs, I saw the 90% of the occurrences were related to the update of an INT column with an Integer value. But not all the times we declared that value as INT, sometimes it was implicitly casted to INT by PHP. I don't think this could be related, but still "90%" would be a big coincidence.

@TheUnableDeveloper
Copy link
Author

Hello,
after some weeks without any problems , we lately faced this problem again.
Always on different tables and with different kind of queries (SELECT, UPDATE etc).

The only infos I can add:
1) propel version: 2.0.0-beta3
2) server type: Apache on kubernetes pods (image: php:8.1.14RC1-apache-buster)
3) we are still not able to reproduce the error in our test or dev envs
4) most of the times that we face this problem, it disappear if we restart the pod.

Maybe propel has a local cache within the pod? It gets corrupted and restarting the pod, problem is solved?
But this would be an effect of a prior bug.

This issue is getting critical for us, considering that happens in production envs.
What can I do to help debugging?

Thanks in advance

@mringler
Copy link
Contributor

Hmm, curios.

The type id that shouldn't be null is retrieved from the column map in /Propel/Runtime/Adapter/Pdo/MysqlAdapter::bindValue(). The type identifier stored in the ColumnMap is turned into the PDO id through a lookup in \Propel\Generator\Model\PropelTypes. The values are hard-coded into files, either from model:build or Propel directly. If the type identifier from the column map does not exist in the lookup array in PropelTypes, you should get an "Undefined array key" warning, but this is likely disabled on prod. So from a distance, this is the most likely candidate for an error, maybe something weird in opcache?

Since the error occurs indeterminately, I would start by finding out what the ColumnMap looks like when the error happens. So I would change the Propel file manually (yes, changing a library file per hand, desperate measures...):

    public function bindValue(StatementInterface $stmt, string $parameter, $value, ColumnMap $cMap, ?int $position = null): bool
    {
        $pdoType = $cMap->getPdoType(); // <---- should not return null
        if ($pdoType === null){
            $reflector = new \ReflectionClass(get_class($cMap->getTable()));
            $vals = [
                'map file'  => $reflector->getFileName(),
                'column' => $cMap->getFullyQualifiedName(),
                'type' => $cMap->getType(),
            ];
            // then log or throw $vals
    }

Also, getting to the lookup table in PropelTypes would be interesting.

Let me know if you find anything.

@TheUnableDeveloper
Copy link
Author

Hello,
I confirm that we use opCache, we will try to disable it.
In the meantime I'll check the files you mentioned and I'll be back to you.

Thank you for your help!

@mringler
Copy link
Contributor

Oh, disabling opcache will ruin performance. Even if the problem comes from there, just disabling it will not work as solution. As a workaround, you are probably better off reloading the whole page.

@TheUnableDeveloper
Copy link
Author

Hi,
we disabled opcache in order to make a test and the problem immediately disappeared.
We'll keep it monitored, and the app doesn't seem that much slower so, at the moment, we'll proceed in this way.

Let us know if you find any confirmed relation with opcache, and eventually if there is a fix.

Thank you!

@mringler
Copy link
Contributor

Very interesting. Huzzah, I guess, problem found.

That would mean that the classes read from opcache behave differently than what was put in. I don't think that this is related to Propel, particularly when the issue is non-deterministic. Very likely, the problem comes from the PHP setup in the pods. But let me know what you find.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants