using db_insert with big ints
When I use db_insert in D7 (RC3), drupal_write_record (the engine behind db_insert) allows ints, serials, and floats for numbers. If it sees int in the schema definition, it casts the number in PHP as an int before writing the record. Thus my facebook id of 100000412533411 becomes much much smaller. I have D6 code that I'm bringing to D7, btw. In common.inc: // Type cast to proper datatype, except when the value is NULL and the // column allows this. // // MySQL PDO silently casts e.g. FALSE and '' to 0 when inserting the value // into an integer column, but PostgreSQL PDO does not. Also type cast NULL // when the column does not allow this. if (isset($object->$field) || !empty($info['not null'])) { if ($info['type'] == 'int' || $info['type'] == 'serial') { $fields[$field] = (int) $fields[$field]; // ****HERE*** } elseif ($info['type'] == 'float') { $fields[$field] = (float) $fields[$field]; } else { $fields[$field] = (string) $fields[$field]; } } There doesn't appear to be a way to insert bigints using db_insert ...or am I completely missing something? -Andre'
My advice is to use it that value like a varchar(N), in order to avoid any kind of problems, obviously if you don't need to have some kind of calculation behind it, but i don't think as this bigint field is a facebook_id. On Tue, Dec 28, 2010 at 8:28 PM, Andre Angelantoni <aangel@mac.com> wrote:
When I use db_insert in D7 (RC3), drupal_write_record (the engine behind db_insert) allows ints, serials, and floats for numbers.
If it sees int in the schema definition, it casts the number in PHP as an int before writing the record. Thus my facebook id of 100000412533411 becomes much much smaller. I have D6 code that I'm bringing to D7, btw.
In common.inc:
// Type cast to proper datatype, except when the value is NULL and the // column allows this. // // MySQL PDO silently casts e.g. FALSE and '' to 0 when inserting the value // into an integer column, but PostgreSQL PDO does not. Also type cast NULL // when the column does not allow this. if (isset($object->$field) || !empty($info['not null'])) { if ($info['type'] == 'int' || $info['type'] == 'serial') { $fields[$field] = (int) $fields[$field]; // ****HERE*** } elseif ($info['type'] == 'float') { $fields[$field] = (float) $fields[$field]; } else { $fields[$field] = (string) $fields[$field]; } }
There doesn't appear to be a way to insert bigints using db_insert
...or am I completely missing something?
-Andre'
-- Paolo Mainardi CTO Twinbit Blog: http://www.paolomainardi.com -- Please consider the environment before printing this email --
Is Drupal's db layer so weak that users must change their database schema in order to use it? Is that acceptable? Sounds like a bug to me. -Dave On Tue, 28 Dec 2010 21:28 +0100, "Paolo Mainardi" <paolomainardi@gmail.com> wrote:
My advice is to use it that value like a varchar(N), in order to avoid any kind of problems, obviously if you don't need to have some kind of calculation behind it, but i don't think as this bigint field is a facebook_id.
On Tue, Dec 28, 2010 at 8:28 PM, Andre Angelantoni <aangel@mac.com> wrote:
When I use db_insert in D7 (RC3), drupal_write_record (the engine behind db_insert) allows ints, serials, and floats for numbers.
If it sees int in the schema definition, it casts the number in PHP as an int before writing the record. Thus my facebook id of 100000412533411 becomes much much smaller. I have D6 code that I'm bringing to D7, btw.
In common.inc:
// Type cast to proper datatype, except when the value is NULL and the // column allows this. // // MySQL PDO silently casts e.g. FALSE and '' to 0 when inserting the value // into an integer column, but PostgreSQL PDO does not. Also type cast NULL // when the column does not allow this. if (isset($object->$field) || !empty($info['not null'])) { if ($info['type'] == 'int' || $info['type'] == 'serial') { $fields[$field] = (int) $fields[$field]; // ****HERE*** } elseif ($info['type'] == 'float') { $fields[$field] = (float) $fields[$field]; } else { $fields[$field] = (string) $fields[$field]; } }
There doesn't appear to be a way to insert bigints using db_insert
...or am I completely missing something?
-Andre'
-- Paolo Mainardi
CTO Twinbit Blog: http://www.paolomainardi.com
-- Please consider the environment before printing this email --
I'm surprised it worked in D6. That number is simply longer than should have fit in an 'int' field. He needs to use 'bigint.' Nancy Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr. ________________________________ From: David Cohen Is Drupal's db layer so weak that users must change their database schema in order to use it? Is that acceptable? Sounds like a bug to me.
In the problem Andre describes, the database schema is correct. He is using bigint. It's the php code that causes a problem, it casts to an (int) before submitting to the database, because (I presume) it wants to avoid malicious queries embedded within what should be an int. Casting to an (int) has different effects depending on whether the hardware is 32 bit or 64 bit, as described on http://us3.php.net/manual/en/function.is-int.php#97006 My opinion is that instead of casting, the db code should test something like: if (is_int($x) || ctype_digit($x)) ... -Dave On Tue, 28 Dec 2010 13:34 -0800, "nan wich" <nan_wich@bellsouth.net> wrote:
I'm surprised it worked in D6. That number is simply longer than should have fit in an 'int' field. He needs to use 'bigint.' Nancy Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr.
________________________________
From: David Cohen Is Drupal's db layer so weak that users must change their database schema in order to use it?
Is that acceptable?
Sounds like a bug to me.
This entire thread belongs in an issue where it can be addressed properly. Also to correct a statement in the original posting, db_insert() does not rely on drupal_write_record(). drupal_write_record() is not a part of DB API; it's a Drupal serialization function that leverages the DB API, and I am quite open about my desire to see drupal_write_record() die a swift death in Drupal 8. --Larry Garfield On Tuesday, December 28, 2010 4:53:40 pm David Cohen wrote:
In the problem Andre describes, the database schema is correct. He is using bigint.
It's the php code that causes a problem, it casts to an (int) before submitting to the database, because (I presume) it wants to avoid malicious queries embedded within what should be an int. Casting to an (int) has different effects depending on whether the hardware is 32 bit or 64 bit, as described on http://us3.php.net/manual/en/function.is-int.php#97006
My opinion is that instead of casting, the db code should test something like: if (is_int($x) || ctype_digit($x)) ...
-Dave
On Tue, 28 Dec 2010 13:34 -0800, "nan wich" <nan_wich@bellsouth.net>
wrote:
I'm surprised it worked in D6. That number is simply longer than should have fit in an 'int' field. He needs to use 'bigint.'
Nancy
Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr.
________________________________
From: David Cohen Is Drupal's db layer so weak that users must change their database schema in order to use it?
Is that acceptable?
Sounds like a bug to me.
'size' => 'big', Nancy Injustice anywhere is a threat to justice everywhere. -- Dr. Martin L. King, Jr. ________________________________ From: Andre Angelantoni <aangel@mac.com> To: development@drupal.org Sent: Tue, December 28, 2010 2:28:32 PM Subject: [development] using db_insert with big ints When I use db_insert in D7 (RC3), drupal_write_record (the engine behind db_insert) allows ints, serials, and floats for numbers. If it sees int in the schema definition, it casts the number in PHP as an int before writing the record. Thus my facebook id of 100000412533411 becomes much much smaller. I have D6 code that I'm bringing to D7, btw. In common.inc: // Type cast to proper datatype, except when the value is NULL and the // column allows this. // // MySQL PDO silently casts e.g. FALSE and '' to 0 when inserting the value // into an integer column, but PostgreSQL PDO does not. Also type cast NULL // when the column does not allow this. if (isset($object->$field) || !empty($info['not null'])) { if ($info['type'] == 'int' || $info['type'] == 'serial') { $fields[$field] = (int) $fields[$field]; // ****HERE*** } elseif ($info['type'] == 'float') { $fields[$field] = (float) $fields[$field]; } else { $fields[$field] = (string) $fields[$field]; } } There doesn't appear to be a way to insert bigints using db_insert ...or am I completely missing something? -Andre'
participants (5)
-
Andre Angelantoni -
David Cohen -
Larry Garfield -
nan wich -
Paolo Mainardi