Skip to content

Commit 3852eef

Browse files
committed
Timestamp issue with prepared statements
1 parent 8416902 commit 3852eef

File tree

4 files changed

+61
-20
lines changed

4 files changed

+61
-20
lines changed

Examples/DataModification/src/Application.php

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace Example;
1919

20+
use DateTime;
2021
use MonetDB\Connection;
2122

2223

@@ -34,7 +35,8 @@ public function Run(array $args) {
3435
"weight_kg" decimal(8, 2),
3536
"category" text,
3637
"birth_date" date,
37-
"net_worth_usd" decimal(20, 4)
38+
"net_worth_usd" decimal(20, 4),
39+
"created" timestamp
3840
);
3941
');
4042

@@ -44,28 +46,30 @@ public function Run(array $args) {
4446

4547
/* *** */
4648

49+
$now = date("Y-m-d H:i:s.u");
50+
4751
$result = $connection->Query(<<<EOF
4852
start transaction;
4953
5054
insert into
5155
"cats"
52-
("name", "weight_kg", "category", "birth_date", "net_worth_usd")
56+
("name", "weight_kg", "category", "birth_date", "net_worth_usd", "created")
5357
values
54-
('Tiger', 8.2, 'fluffy', '2012-04-23', 2340000),
55-
('Oscar', 3.4, 'spotted', '2014-02-11', 556235.34),
56-
('Coco', 2.52, 'spotted', '2008-12-31', 1470500000),
57-
('Max', 4.23, 'spotted', '2010-01-15', 100),
58-
('Sooty', 7.2, 'shorthair', '2016-10-01', 580000),
59-
('Milo', 5.87, 'spotted', '2015-06-23', 1500.53),
60-
('Muffin', 12.6, 'fluffy', '2013-04-07', 230000),
61-
('Ginger', 9.4, 'shorthair', '2012-06-19', 177240.5),
62-
('Fluffor', 13.12, 'fluffy', '2000-10-07', 5730180200.12),
63-
('Lucy', 3.12, 'shorthair', '2018-06-29', 5780000),
64-
('Chloe', 2.12, 'spotted', '2013-05-01', 13666200),
65-
('Misty', 1.96, 'shorthair', '2014-11-24', 12000000),
66-
('Sam', 3.45, 'fluffy', '2018-12-19', 580.4),
67-
('Gizmo', 4.65, 'fluffy', '2016-05-11', 120300),
68-
('Kimba', 1.23, 'spotted', '2020-01-08', 890000);
58+
('Tiger', 8.2, 'fluffy', '2012-04-23', 2340000, timestamp '{$now}'),
59+
('Oscar', 3.4, 'spotted', '2014-02-11', 556235.34, timestamp '{$now}'),
60+
('Coco', 2.52, 'spotted', '2008-12-31', 1470500000, timestamp '{$now}'),
61+
('Max', 4.23, 'spotted', '2010-01-15', 100, timestamp '{$now}'),
62+
('Sooty', 7.2, 'shorthair', '2016-10-01', 580000, timestamp '{$now}'),
63+
('Milo', 5.87, 'spotted', '2015-06-23', 1500.53, timestamp '{$now}'),
64+
('Muffin', 12.6, 'fluffy', '2013-04-07', 230000, timestamp '{$now}'),
65+
('Ginger', 9.4, 'shorthair', '2012-06-19', 177240.5, timestamp '{$now}'),
66+
('Fluffor', 13.12, 'fluffy', '2000-10-07', 5730180200.12, timestamp '{$now}'),
67+
('Lucy', 3.12, 'shorthair', '2018-06-29', 5780000, timestamp '{$now}'),
68+
('Chloe', 2.12, 'spotted', '2013-05-01', 13666200, timestamp '{$now}'),
69+
('Misty', 1.96, 'shorthair', '2014-11-24', 12000000, timestamp '{$now}'),
70+
('Sam', 3.45, 'fluffy', '2018-12-19', 580.4, timestamp '{$now}'),
71+
('Gizmo', 4.65, 'fluffy', '2016-05-11', 120300, timestamp '{$now}'),
72+
('Kimba', 1.23, 'spotted', '2020-01-08', 890000, timestamp '{$now}');
6973
7074
update
7175
"cats"
@@ -93,9 +97,11 @@ public function Run(array $args) {
9397
round(avg("weight_kg"), 2) as "weight_mean"
9498
from
9599
"cats"
100+
where
101+
"created" <= ?
96102
group by
97103
"category"
98-
');
104+
', [new DateTime()]);
99105

100106
echo "Columns:\n\n";
101107

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,27 @@ $result = $connection->Query('
163163
', [ "D'artagnan", 5.3 ]);
164164
```
165165

166+
The parameter types for prepared statements have to match
167+
the column types. See the below example. Never pass `null`,
168+
`true`, `false` values as strings.
169+
170+
```php
171+
$result = $connection->Query('
172+
update
173+
"test"
174+
set
175+
"nullable_column" = ?
176+
where
177+
"bool_column" = ?
178+
and "numeric_column" > ?
179+
and "date_column" > ?
180+
and "timestamp_column" < ?
181+
', [ null, false, 5.3, "2020-12-08", new DateTime()]);
182+
```
183+
184+
While the `date` values have to be passed as normal strings, the
185+
`timestamp` type has be passed as a `DateTime` object.
186+
166187
## Example 4: Using escaping
167188

168189
```php

protocol_doc/README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -755,11 +755,20 @@ statement with the specified parameters. Example:
755755
sEXECUTE 15 ('First\'Value', 'Second\"Value');
756756

757757
Please note that all values passed to the execute statement are type sensitive.
758-
You cannot pass numbers or true/false values as strings, but they have to be
758+
You cannot pass `numbers`, `null` or `true`/`false` values as strings, but they have to be
759759
passed without quotes, example:
760760

761761
sEXECUTE 16 ('2020-08-12', true, false, null, 3.141592653589, 'another string');
762762

763+
While the `date` type is auto-converted from string, this doesn't happen for the `timestamp` type:
764+
765+
sEXECUTE 17 ('2020-08-12') // Date can be passed as string
766+
sEXECUTE 18 ('2020-08-12 12:00:00.000000') // Throws error for timestamp column
767+
768+
If the column has a `timestamp` type, then pass the value with explicit type conversion:
769+
770+
sEXECUTE 18 (timestamp '2020-08-12 12:00:00.000000')
771+
763772
All string values need to be escaped as discussed in chapter [Escaping](#61-escaping).
764773
Date values are also passed as strings.
765774

src/Connection.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace MonetDB;
1919

20+
use DateTime;
2021
use Exception;
2122

2223
/**
@@ -480,7 +481,11 @@ private function WritePreparedStatement(string $sql, array $params) {
480481
}
481482
elseif (is_numeric($param) && !is_string($param)) {
482483
$escaped[] = $param + 0;
483-
} else {
484+
}
485+
elseif ($param instanceof DateTime) {
486+
$escaped[] = "TIMESTAMP '".$param->format("Y-m-d H:i:s.u")."'";
487+
}
488+
else {
484489
$escaped[] = "'".$this->Escape((string)$param)."'";
485490
}
486491
}

0 commit comments

Comments
 (0)