1--TEST-- 2MySQL PDO->prepare() and 1295 (ER_UNSUPPORTED_PS) 3--SKIPIF-- 4<?php 5require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc'); 6require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); 7MySQLPDOTest::skip(); 8 9// Run test only locally - not against remote hosts 10$db = MySQLPDOTest::factory(); 11$stmt = $db->query('SELECT USER() as _user'); 12$row = $stmt->fetch(PDO::FETCH_ASSOC); 13$tmp = explode('@', $row['_user']); 14if (count($tmp) < 2) 15 die("skip Cannot detect if test is run against local or remote database server"); 16if (($tmp[1] !== 'localhost') && ($tmp[1] !== '127.0.0.1')) 17 die("skip Test cannot be run against remote database server"); 18 19$stmt = $db->query("SHOW VARIABLES LIKE 'secure_file_priv'"); 20if (($row = $stmt->fetch(PDO::FETCH_ASSOC)) && ($row['value'] != '')) { 21 if (!is_writable($row['value'])) 22 die("skip secure_file_priv directory not writable: {$row['value']}"); 23 24 $filename = $row['value'] . DIRECTORY_SEPARATOR . "pdo_mysql_exec_load_data.csv"; 25 26 if (file_exists($filename) && !is_writable($filename)) 27 die("skip {$filename} not writable"); 28} 29 30?> 31--FILE-- 32<?php 33 function exec_and_count($offset, &$db, $sql, $exp) { 34 35 try { 36 37 $ret = $db->exec($sql); 38 if ($ret !== $exp) { 39 printf("[%03d] Expecting '%s'/%s got '%s'/%s when running '%s', [%s] %s\n", 40 $offset, $exp, gettype($exp), $ret, gettype($ret), $sql, 41 $db->errorCode(), implode(' ', $db->errorInfo())); 42 return false; 43 } 44 45 } catch (PDOException $e) { 46 47 if (42000 == $db->errorCode()) { 48 // Error: 1148 SQLSTATE: 42000 (ER_NOT_ALLOWED_COMMAND) 49 // Load data infile not allowed 50 return false; 51 } 52 53 printf("[%03d] '%s' has failed, [%s] %s\n", 54 $offset, $sql, $db->errorCode(), implode(' ', $db->errorInfo())); 55 return false; 56 } 57 58 return true; 59 } 60 61 require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); 62 $db = MySQLPDOTest::factory(); 63 // Run with native PS. 64 // The test is about checking the fallback to emulation 65 $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0); 66 MySQLPDOTest::createTestTable($db, MySQLPDOTest::detect_transactional_mysql_engine($db)); 67 68 /* affected rows related */ 69 try { 70 71 exec_and_count(2, $db, 'DROP TABLE IF EXISTS test', 0); 72 exec_and_count(3, $db, sprintf('CREATE TABLE test(id INT NOT NULL PRIMARY KEY, col1 CHAR(10)) ENGINE=%s', PDO_MYSQL_TEST_ENGINE), 0); 73 74 $stmt = $db->query("SHOW VARIABLES LIKE 'secure_file_priv'"); 75 if (($row = $stmt->fetch(PDO::FETCH_ASSOC)) && ($row['value'] != '')) { 76 $filename = $row['value'] . DIRECTORY_SEPARATOR . "pdo_mysql_exec_load_data.csv"; 77 } else { 78 $filename = MySQLPDOTest::getTempDir() . DIRECTORY_SEPARATOR . "pdo_mysql_exec_load_data.csv"; 79 } 80 81 $fp = fopen($filename, "w"); 82 fwrite($fp, b"1;foo\n"); 83 fwrite($fp, b"2;bar"); 84 fclose($fp); 85 86 // This should fail, the PS protocol should not support it. 87 // mysqlnd will give 2014 as a follow-up of the fallback logic 88 // libmysql will give a little more precise 2030 error code 89 // However, you get an error and the big question is what happens to the line 90 $stmt = $db->prepare(sprintf("LOAD DATA INFILE %s INTO TABLE test FIELDS TERMINATED BY ';' LINES TERMINATED BY '\n'", $db->quote($filename))); 91 if (!$stmt->execute()) { 92 printf("[004] [%d] %s\n", $stmt->errorCode(), var_export($stmt->errorInfo(), true)); 93 } 94 95 // Check the line 96 $stmt = $db->query("SELECT 1 as 'one'"); 97 if ($stmt->errorCode() != '0000') { 98 printf("[005] [%d] %s\n", $stmt->errorCode(), var_export($stmt->errorInfo(), true)); 99 } else { 100 $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); 101 if (!isset($rows[0]['one']) || $rows[0]['one'] != 1) 102 printf("[006] [%d] %s\n", $stmt->errorCode(), var_export($stmt->errorInfo(), true)); 103 } 104 105 unlink($filename); 106 107 } catch (PDOException $e) { 108 printf("[001] %s, [%s] %s (%s)\n", 109 $e->getMessage(), 110 $db->errorCode(), 111 implode(' ', $db->errorInfo()), 112 (isset($stmt)) ? implode(' ', $stmt->errorInfo()) : 'N/A'); 113 } 114 115 print "done!"; 116?> 117--CLEAN-- 118<?php 119require dirname(__FILE__) . '/mysql_pdo_test.inc'; 120MySQLPDOTest::dropTestTable(); 121?> 122--EXPECTF-- 123Warning: PDOStatement::execute(): SQLSTATE[HY000]: General error: %s in %s on line %d 124[004] [0] array ( 125 0 => 'HY000', 126 1 => %d, 127 2 => %s, 128) 129done! 130