1--TEST--
2PDO_OCI: PDOStatement->getColumnMeta
3--EXTENSIONS--
4pdo
5pdo_oci
6--SKIPIF--
7<?php
8require(__DIR__ . '/../../pdo/tests/pdo_test.inc');
9PDOTest::skip();
10?>
11--FILE--
12<?php
13
14echo "Preparations before the test\n";
15
16require(__DIR__ . '/../../pdo/tests/pdo_test.inc');
17try {
18    $db = PDOTest::factory();
19    $db->exec(<<<SQL
20BEGIN
21   EXECUTE IMMEDIATE 'DROP TABLE test';
22EXCEPTION
23   WHEN OTHERS THEN
24      IF SQLCODE != -942 THEN
25     RAISE;
26      END IF;
27END;
28SQL
29);
30    $db->exec("CREATE TABLE test(id INT)");
31
32    $db->beginTransaction();
33
34    $stmt = $db->prepare('SELECT id FROM test ORDER BY id ASC');
35
36    echo "Test 1. calling function with invalid parameters\n";
37
38    // execute() has not been called yet
39    // NOTE: no warning
40    $tmp = $stmt->getColumnMeta(0);
41    printf(" 1.1 Expecting false got %s\n", var_export($tmp, true));
42
43    echo(" 1.2 ");
44    $stmt->execute();
45    // PDOStatement::getColumnMeta() expects exactly 1 argument, 0 given in
46    try {
47        $tmp = $stmt->getColumnMeta();
48    } catch (ArgumentCountError $e) {
49        if (false !== $tmp) {
50            printf("[1.2] Expecting false got %s\n", var_export($tmp, true));
51        }
52        echo $e->getMessage(), "\n";
53    }
54
55    // invalid offset
56    echo " 1.3 ";
57    try {
58        $tmp = $stmt->getColumnMeta(-1);
59    } catch (ValueError $e) {
60        if (false !== $tmp) {
61            printf("[1.3] Expecting false got %s\n", var_export($tmp, true));
62        }
63        echo $e->getMessage(), "\n";
64    }
65
66    // PDOStatement::getColumnMeta(): Argument #1 must be of type int, array given in
67    echo " 1.4 ";
68    try {
69        $tmp = $stmt->getColumnMeta(array());
70    } catch (TypeError $e) {
71        if (false !== $tmp)
72            printf("[1.4] Expecting false got %s\n", var_export($tmp, true));
73        echo $e->getMessage(), "\n";
74    }
75
76    // PDOStatement::getColumnMeta() expects exactly 1 argument, 2 given in
77    echo " 1.5 ";
78    try {
79        $tmp = $stmt->getColumnMeta(1, 1);
80    } catch (ArgumentCountError $e) {
81        if (false !== $tmp)
82            printf("[1.5] Expecting false got %s\n", var_export($tmp, true));
83        echo $e->getMessage(), "\n";
84    }
85
86    // invalid offset
87    $tmp = $stmt->getColumnMeta(1);
88    printf(" 1.6 Expecting false because of invalid offset got %s\n", var_export($tmp, true));
89
90    echo "Test 2. testing return values\n";
91    echo "Test 2.1 testing array returned\n";
92
93    $stmt = $db->prepare('SELECT id FROM test ORDER BY id ASC');
94    $stmt->execute();
95    $native = $stmt->getColumnMeta(0);
96    if (count($native) == 0) {
97        printf("[008] Meta data seems wrong, %s / %s\n",
98            var_export($native, true), var_export($emulated, true));
99    }
100
101
102    function test_return($meta, $offset, $native_type, $pdo_type){
103        if (empty($meta)) {
104            printf("[%03d + 2] getColumnMeta() failed, %d - %s\n", $offset,
105                $stmt->errorCode(), var_export($stmt->errorInfo(), true));
106            return false;
107        }
108        $elements = array('flags', 'scale', 'name', 'len', 'precision', 'pdo_type');
109        foreach ($elements as $k => $element)
110            if (!isset($meta[$element])) {
111                printf("[%03d + 3] Element %s missing, %s\n", $offset,
112                    $element, var_export($meta, true));
113                return false;
114            }
115
116        if (!is_null($native_type)) {
117            if (!isset($meta['native_type'])) {
118                printf("[%03d + 4] Element native_type missing, %s\n", $offset,
119                    var_export($meta, true));
120                return false;
121            }
122
123            if (!is_array($native_type))
124                $native_type = array($native_type);
125
126            $found = false;
127            foreach ($native_type as $k => $type) {
128                if ($meta['native_type'] == $type) {
129                    $found = true;
130                    break;
131                }
132            }
133
134            if (!$found) {
135                printf("[%03d + 5] Expecting native type %s, %s\n", $offset,
136                    var_export($native_type, true), var_export($meta, true));
137                return false;
138            }
139        }
140
141        if (!is_null($pdo_type) && ($meta['pdo_type'] != $pdo_type)) {
142            printf("[%03d + 6] Expecting PDO type %s got %s (%s)\n", $offset,
143                $pdo_type, var_export($meta, true), var_export($meta['native_type']));
144            return false;
145        }
146
147        return true;
148    }
149
150
151    function test_meta(&$db, $offset, $sql_type, $value, $native_type, $pdo_type) {
152
153        $db->exec(<<<SQL
154BEGIN
155   EXECUTE IMMEDIATE 'DROP TABLE test';
156EXCEPTION
157   WHEN OTHERS THEN
158      IF SQLCODE != -942 THEN
159         RAISE;
160      END IF;
161END;
162SQL
163);
164
165        $sql = sprintf('CREATE TABLE test(id INT, label %s)', $sql_type);
166        $stmt = $db->prepare($sql);
167        $stmt->execute();
168
169        if (!$db->exec(sprintf("INSERT INTO test(id, label) VALUES (1, '%s')", $value))) {
170            printf("[%03d] + 1] Insert failed, %d - %s\n", $offset,
171                $db->errorCode(), var_export($db->errorInfo(), true));
172            return false;
173        }
174
175        $stmt = $db->prepare('SELECT id, label FROM test');
176        $stmt->execute();
177        $meta = $stmt->getColumnMeta(1);
178        return test_return($meta, $offset, $native_type, $pdo_type);
179    }
180
181    echo "Test 2.2 testing numeric columns\n";
182
183    test_meta($db, 20, 'NUMBER'         , 0                    , 'NUMBER', PDO::PARAM_STR);
184    test_meta($db, 30, 'NUMBER'         , 256                  , 'NUMBER', PDO::PARAM_STR);
185    test_meta($db, 40, 'INT'            , 256                  , 'NUMBER', PDO::PARAM_STR);
186    test_meta($db, 50, 'INTEGER'        , 256                  , 'NUMBER', PDO::PARAM_STR);
187    test_meta($db, 60, 'NUMBER'         , 256.01               , 'NUMBER', PDO::PARAM_STR);
188    test_meta($db, 70, 'NUMBER'         , -8388608             , 'NUMBER', PDO::PARAM_STR);
189
190    test_meta($db, 80, 'NUMBER'         , 2147483648           , 'NUMBER', PDO::PARAM_STR);
191    test_meta($db, 90, 'NUMBER'         , 4294967295           , 'NUMBER', PDO::PARAM_STR);
192
193    test_meta($db, 100, 'DEC'             , 1.01               , 'NUMBER'       , PDO::PARAM_STR);
194    test_meta($db, 110, 'DECIMAL'         , 1.01               , 'NUMBER'       , PDO::PARAM_STR);
195    test_meta($db, 120, 'FLOAT'           , 1.01               , 'FLOAT'        , PDO::PARAM_STR);
196    test_meta($db, 130, 'DOUBLE PRECISION', 1.01               , 'FLOAT'        , PDO::PARAM_STR);
197    test_meta($db, 140, 'BINARY_FLOAT'    , 1.01               , 'BINARY_FLOAT' , PDO::PARAM_STR);
198    test_meta($db, 150, 'BINARY_DOUBLE'   , 1.01               , 'BINARY_DOUBLE', PDO::PARAM_STR);
199
200    echo "Test 2.3 testing temporal columns\n";
201
202    $db->exec("alter session set nls_date_format='YYYY-MM-DD'");
203    test_meta($db, 160, 'DATE'           , '2008-04-23'        , 'DATE', PDO::PARAM_STR);
204
205    echo "Test 2.4 testing string columns\n";
206
207    test_meta($db, 170, 'CHAR(1)'       , 'a'                  , 'CHAR'     , PDO::PARAM_STR);
208    test_meta($db, 180, 'CHAR(10)'      , '0123456789'         , 'CHAR'     , PDO::PARAM_STR);
209    test_meta($db, 190, 'CHAR(255)'     , str_repeat('z', 255) , 'CHAR'     , PDO::PARAM_STR);
210    test_meta($db, 200, 'VARCHAR(1)'    , 'a'                  , 'VARCHAR2' , PDO::PARAM_STR);
211    test_meta($db, 210, 'VARCHAR(10)'   , '0123456789'         , 'VARCHAR2' , PDO::PARAM_STR);
212    test_meta($db, 220, 'VARCHAR(255)'  , str_repeat('z', 255) , 'VARCHAR2' , PDO::PARAM_STR);
213    test_meta($db, 230, 'VARCHAR2(1)'   , 'a'                  , 'VARCHAR2' , PDO::PARAM_STR);
214    test_meta($db, 240, 'VARCHAR2(10)'  , '0123456789'         , 'VARCHAR2' , PDO::PARAM_STR);
215    test_meta($db, 250, 'VARCHAR2(255)' , str_repeat('z', 255) , 'VARCHAR2' , PDO::PARAM_STR);
216
217    test_meta($db, 260, 'NCHAR(1)'      , 'a'                  , 'NCHAR'    , PDO::PARAM_STR);
218    test_meta($db, 270, 'NCHAR(10)'     , '0123456789'         , 'NCHAR'    , PDO::PARAM_STR);
219    test_meta($db, 280, 'NCHAR(255)'    , str_repeat('z', 255) , 'NCHAR'    , PDO::PARAM_STR);
220    test_meta($db, 290, 'NVARCHAR2(1)'  , 'a'                  , 'NVARCHAR2', PDO::PARAM_STR);
221    test_meta($db, 300, 'NVARCHAR2(10)' , '0123456789'         , 'NVARCHAR2', PDO::PARAM_STR);
222    test_meta($db, 310, 'NVARCHAR2(255)', str_repeat('z', 255) , 'NVARCHAR2', PDO::PARAM_STR);
223
224    echo "Test 2.5 testing lobs columns\n";
225
226    test_meta($db, 320, 'CLOB'          , str_repeat('b', 255) , 'CLOB'    , PDO::PARAM_LOB);
227    test_meta($db, 330, 'BLOB'          , str_repeat('b', 256) , 'BLOB'    , PDO::PARAM_LOB);
228    test_meta($db, 340, 'NCLOB'         , str_repeat('b', 255) , 'NCLOB'   , PDO::PARAM_LOB);
229
230    test_meta($db, 350, 'LONG'          , str_repeat('b', 256) , 'LONG'    , PDO::PARAM_STR);
231    test_meta($db, 360, 'LONG RAW'      , str_repeat('b', 256) , 'LONG RAW', PDO::PARAM_STR);
232    test_meta($db, 370, 'RAW(256)'      , str_repeat('b', 256) , 'RAW'     , PDO::PARAM_STR);
233
234
235    $db->exec(<<<SQL
236BEGIN
237   EXECUTE IMMEDIATE 'DROP TABLE test';
238EXCEPTION
239   WHEN OTHERS THEN
240      IF SQLCODE != -942 THEN
241         RAISE;
242      END IF;
243END;
244SQL
245);
246    echo "Test 2.6 testing function return\n";
247
248    $stmt = $db->query('SELECT count(*) FROM dual');
249    $meta = $stmt->getColumnMeta(0);
250    test_return($meta, 380, 'NUMBER', PDO::PARAM_STR);
251    $stmt = $db->query("SELECT TO_DATE('2008-04-23') FROM dual");
252    $meta = $stmt->getColumnMeta(0);
253    test_return($meta, 390, 'DATE', PDO::PARAM_STR);
254    $stmt = $db->query("SELECT TO_CHAR(542) FROM dual");
255    $meta = $stmt->getColumnMeta(0);
256    test_return($meta, 400, 'VARCHAR2', PDO::PARAM_STR);
257
258
259    echo "Test 2.7 testing flags returned\n";
260
261    $sql = sprintf('CREATE TABLE test(id INT NOT NULL, label INT NULL)');
262    $stmt = $db->prepare($sql);
263    $stmt->execute();
264    $db->exec('INSERT INTO test(id, label) VALUES (1, 1)');
265    $stmt = $db->query('SELECT id, label FROM test');
266    $meta = $stmt->getColumnMeta(0);
267    // verify the flags array contains a not_null flag and not nullable flags
268    if (!isset($meta['flags'])) {
269        printf("[1001] No flags contained in metadata %s\n", var_export($meta, true));
270    } else {
271        $flags = $meta['flags'];
272        $found = false;
273        foreach ($flags as $k => $flag) {
274            if ($flag == 'not_null')
275                $found = true;
276            if ($flag == 'nullable')
277                printf("[1003] Flags seem wrong %s\n", var_export($meta, true));
278        }
279        if (!$found)
280            printf("[1002] Flags seem wrong %s\n", var_export($meta, true));
281    }
282    $meta = $stmt->getColumnMeta(1);
283    // verify the flags array contains a nullable flag and not not_null flags
284    if (!isset($meta['flags'])) {
285        printf("[1003] No flags contained in metadata %s\n", var_export($meta, true));
286    } else {
287        $flags = $meta['flags'];
288        $found = false;
289        foreach ($flags as $k => $flag) {
290            if ($flag == 'not_null')
291                printf("[1004] Flags seem wrong %s\n", var_export($meta, true));
292            if ($flag == 'nullable')
293                $found = true;
294        }
295        if (!$found)
296            printf("[1005] Flags seem wrong %s\n", var_export($meta, true));
297    }
298
299} catch (PDOException $e) {
300    // we should never get here, we use warnings, but never trust a system...
301    printf("[001] %s, [%s} %s\n",
302        $e->getMessage(), $db->errorInfo(), implode(' ', $db->errorInfo()));
303}
304
305$db->exec(<<<SQL
306BEGIN
307   EXECUTE IMMEDIATE 'DROP TABLE test';
308EXCEPTION
309   WHEN OTHERS THEN
310      IF SQLCODE != -942 THEN
311         RAISE;
312      END IF;
313END;
314SQL
315);
316print "done!";
317?>
318--EXPECT--
319Preparations before the test
320Test 1. calling function with invalid parameters
321 1.1 Expecting false got false
322 1.2 PDOStatement::getColumnMeta() expects exactly 1 argument, 0 given
323 1.3 PDOStatement::getColumnMeta(): Argument #1 ($column) must be greater than or equal to 0
324 1.4 PDOStatement::getColumnMeta(): Argument #1 ($column) must be of type int, array given
325 1.5 PDOStatement::getColumnMeta() expects exactly 1 argument, 2 given
326 1.6 Expecting false because of invalid offset got false
327Test 2. testing return values
328Test 2.1 testing array returned
329Test 2.2 testing numeric columns
330Test 2.3 testing temporal columns
331Test 2.4 testing string columns
332Test 2.5 testing lobs columns
333Test 2.6 testing function return
334Test 2.7 testing flags returned
335done!
336