-
Notifications
You must be signed in to change notification settings - Fork 7.8k
Implement PDO driver specific sub-classes #12804
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
Conversation
@Danack I'll try to take care of your RFC :) For now, I only managed to rebase your PR on master, so I didn't change it much yet. |
Since it will be unbundled, it seems possible to exclude OCI. |
40769bc
to
b55473a
Compare
e740462
to
08e50ef
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LCTM for the pgsql part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made some comments.
Most are minor nits.
ext/pdo/pdo_dbh.c
Outdated
@@ -1334,6 +1410,8 @@ static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count) | |||
} | |||
|
|||
static zend_object_handlers pdo_dbh_object_handlers; | |||
static zend_object_handlers pdosqlite_dbh_object_handlers; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this just for SQLite?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah no, I'm not sure how it ended up being here... But it's unused, nothing uses this struct.
ext/pdo/pdo_dbh.c
Outdated
memcpy(&pdosqlite_dbh_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); | ||
pdosqlite_dbh_object_handlers.offset = XtOffsetOf(pdo_dbh_object_t, std); | ||
pdosqlite_dbh_object_handlers.free_obj = pdo_dbh_free_storage; | ||
pdosqlite_dbh_object_handlers.get_method = dbh_method_get; | ||
pdosqlite_dbh_object_handlers.compare = zend_objects_not_comparable; | ||
pdosqlite_dbh_object_handlers.get_gc = dbh_get_gc; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
$db->query("CREATE TABLE #pdo_dblib_001(name varchar(32)); "); | ||
$db->query("INSERT INTO #pdo_dblib_001 values('PHP'), ('PHP6');"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nits
$db->query("CREATE TABLE #pdo_dblib_001(name varchar(32)); "); | |
$db->query("INSERT INTO #pdo_dblib_001 values('PHP'), ('PHP6');"); | |
$db->query("CREATE TABLE #pdo_dblib_001(name VARCHAR(32)); "); | |
$db->query("INSERT INTO #pdo_dblib_001 VALUES('PHP'), ('PHP6');"); |
$db->query("CREATE TABLE #pdo_dblib_002(name varchar(32))"); | ||
$db->query("INSERT INTO #pdo_dblib_002 values('PHP'), ('PHP6')"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
|
||
$db = getDbConnection(); | ||
|
||
$db->query('CREATE TABLE pdofirebird_001 (idx int NOT NULL PRIMARY KEY, name VARCHAR(20))'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nits
$db->query('CREATE TABLE pdofirebird_001 (idx int NOT NULL PRIMARY KEY, name VARCHAR(20))'); | |
$db->query('CREATE TABLE pdofirebird_001 (idx INT NOT NULL PRIMARY KEY, name VARCHAR(20))'); |
echo "Wrong class type. Should be PdoMysql but is " . get_class($db) . "\n"; | ||
} | ||
|
||
$db->exec('CREATE TABLE pdomysql_002(id int NOT NULL PRIMARY KEY, name VARCHAR(10))'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nits
$db->exec('CREATE TABLE pdomysql_002(id int NOT NULL PRIMARY KEY, name VARCHAR(10))'); | |
$db->exec('CREATE TABLE pdomysql_002(id INT NOT NULL PRIMARY KEY, name VARCHAR(10))'); |
ext/pdo_odbc/tests/pdoodbc_002.phpt
Outdated
echo "Wrong class type. Should be PdoOdbc but is " . get_class($db) . "\n"; | ||
} | ||
|
||
$db->exec('CREATE TABLE pdoodbc_002(id int NOT NULL PRIMARY KEY, name VARCHAR(10))'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nits
$db->exec('CREATE TABLE pdoodbc_002(id int NOT NULL PRIMARY KEY, name VARCHAR(10))'); | |
$db->exec('CREATE TABLE pdoodbc_002(id INT NOT NULL PRIMARY KEY, name VARCHAR(10))'); |
echo "Wrong class type. Should be PdoPgsql but is " . get_class($db) . "\n"; | ||
} | ||
|
||
$db->exec('CREATE TABLE pdopgsql_002(id int NOT NULL PRIMARY KEY, name VARCHAR(10))'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nits
$db->exec('CREATE TABLE pdopgsql_002(id int NOT NULL PRIMARY KEY, name VARCHAR(10))'); | |
$db->exec('CREATE TABLE pdopgsql_002(id INT NOT NULL PRIMARY KEY, name VARCHAR(10))'); |
$db = new PdoSqlite('sqlite::memory:'); | ||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); | ||
|
||
$db->query('CREATE TABLE IF NOT EXISTS test_pdo_sqlite_createcollation (id INT AUTO INCREMENT, name TEXT)'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it need IF NOT EXISTS
? Maybe forgot to fix this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I forgot it previously.
|
||
$db = new PdoSqlite('sqlite::memory:'); | ||
|
||
$db->query('CREATE TABLE test_pdo_sqlite_createcollation_trampoline (s varchar(4))'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nits
$db->query('CREATE TABLE test_pdo_sqlite_createcollation_trampoline (s varchar(4))'); | |
$db->query('CREATE TABLE test_pdo_sqlite_createcollation_trampoline (s VARCHAR(4))'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor comments of things I noticed in quick glance.
I dislike the 1:1 code copies from driver files, e.g. sqlite_driver.c
contains from a quick glance the exact same implementation for createFunction
as PHP_METHOD(PdoSqlite, createFunction)
, this is risky as they can get out of sync and are bad for maintenance.
/* proto string PDO::mysqlGetWarningCount() | ||
* Returns the number of SQL warnings during the execution of the last statement | ||
*/ | ||
PHP_METHOD(PdoMysql, getWarningCount) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't you need a ZPP check here to parse no parameters?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uh, ZPP is definitely needed here... Unfortunately I couldn't spot this bug from the original implementation
ext/pdo_odbc/pdo_odbc.c
Outdated
@@ -27,6 +27,8 @@ | |||
#include "php_pdo_odbc_int.h" | |||
#include "pdo_odbc_arginfo.h" | |||
|
|||
zend_class_entry *pdo_odbc_ce; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this a global?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coincidentally, I had just noticed that these class entries had been accidentally declared global, so I have already added the static modifier locally. :) Anyway, thanks for the reminder!
@@ -41,6 +41,9 @@ zend_class_entry *pdo_exception_ce; | |||
/* the registry of PDO drivers */ | |||
HashTable pdo_driver_hash; | |||
|
|||
/* the registry of PDO driver specific class entries */ | |||
HashTable pdo_driver_specific_ce_hash; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make static perhaps?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one is exposed as it's needed by pdo_dbh.c.
ext/pdo_pgsql/pdo_pgsql.c
Outdated
#include "pdo/php_pdo_driver.h" | ||
#include "php_pdo_pgsql.h" | ||
#include "php_pdo_pgsql_int.h" | ||
#include "pdo_pgsql_arginfo.h" | ||
|
||
zend_class_entry *PdoPgsql_ce; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same "why is this a global" question here. Actually each driver seems to have their own global CE, so the question could be repeated for each of them :P
According to the RFC section "When to deprecate old function on PDO", these functions in the PDO Core should be removed at some point. There is no mention of how it will be maintained in the interim, so that is up for debate. |
That doesn't stop us from using an implementation alias or moving the code to a common place. We should still follow best practices during the time the code is not yet deprecated. |
I agree that we shouldn't have duplicate implementations. Besides SQLite, pgsql is the only driver with a unique method in the existing implementation, and pgsql seems to have a good idea about this problem. Personally, I think it's enough to make SQLite work like pgsql. Maybe I misunderstood your point. I think this PR's way of implementing pgsql's unique methods makes sense in terms of duplication, how do you think of this? |
Yes, I agree with you. I forgot to unify the implementations indeed. Now, I double checked the duplications, and fixed them for pdo_sqlite. Additionally, I tried to address Saki's review comments. |
Thank you, LGTM! |
I found a few more things which can be deduplicated, so I pushed yet another commit. Sorry for the noise! |
Yep, I was specifically talking about sqlite, which Máté has cleaned up nicely now :-) I do still see from a quick glance there are still global zend_class_entry vars which could either be static or locals (e.g. PdoDblib_ce) |
Ah yes, indeed! Fixed now :) |
Cool, thanks! I didn't take a deep look, only a glance, nothing else caught my eye :-) |
@Girgias Are you also fine with the merge? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes :)
pdo_firebird | ||
--SKIPIF-- | ||
<?php require(__DIR__ . '/skipif.inc'); ?> | ||
--FILE-- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kocsismate See #12699, these should be marked with XLEAK
. For reference: https://github.com/php/php-src/actions/runs/7509344302/job/20446349499
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iluuu1994
ah! I knew about the firebird leak, but I overlooked it in the review.
@kocsismate
This and 002 also require XLEAK.
This also broke https://github.com/php/php-src/actions/runs/7509344302/job/20446344121. @kocsismate Can you have a look? |
I took a look and found that this constant is only defined when using mysqlnd, so it should use |
@SakiTakamachi Thanks for looking into it! @iluuu1994 Thanks for letting me know about the failure! My recent commit should fix the problem: 9c7b391 |
Cool, @kocsismate thanks for taking care of it and thanks @SakiTakamachi for investigating. |
Would it be possible to add also some |
@janedbal And perhaps your suggestion would be better discussed on the mailing list. |
Rebased version of #8707
RFC: https://wiki.php.net/rfc/pdo_driver_specific_subclasses