Permalink
Browse files

MDL-28080 oracle - avoid tweak_param_names() tweaking too much :-P

Sometimes the (oracle only) tweak_param_names() method was causing
placeholders having > 28 chars length to exceed the 30 chars limit
imposed by Oracle. With this commit the tweak is performed by
replacement for such long placeholders and, at the same time, the
tweak has been commented out from insert/update because it is not
necessary there (placeholders are safe column name always)
  • Loading branch information...
1 parent a167057 commit a4c5837ad7e9bb7cb80f5d00e67aa83a80c94c23 @stronk7 stronk7 committed Sep 1, 2011
Showing with 31 additions and 6 deletions.
  1. +31 −6 lib/dml/oci_native_moodle_database.php
@@ -364,11 +364,23 @@ protected function tweak_param_names($sql, array $params) {
if (empty($params)) {
return array($sql, $params);
}
+
$newparams = array();
- foreach ($params as $name=>$value) {
- $newparams['o_'.$name] = $value;
+ $searcharr = array(); // search => replace pairs
+ foreach ($params as $name => $value) {
+ // Keep the name within the 30 chars limit always (prefixing/replacing)
+ if (strlen($name) <= 28) {
+ $newname = 'o_' . $name;
+ } else {
+ $newname = 'o_' . substr($name, 2);
+ }
+ $newparams[$newname] = $value;
+ $searcharr[':' . $name] = ':' . $newname;
}
- $sql = preg_replace('/:([a-z0-9_-]+[$a-z0-9_-])/', ':o_$1', $sql);
+ // sort by length desc to avoid potential str_replace() overlap
+ uksort($searcharr, array('oci_native_moodle_database', 'compare_by_length_desc'));
+
+ $sql = str_replace(array_keys($searcharr), $searcharr, $sql);
return array($sql, $newparams);
}
@@ -822,6 +834,17 @@ private function oracle_dirty_hack ($table, $field, $value) {
}
/**
+ * Helper function to order by string length desc
+ *
+ * @param $a string first element to compare
+ * @param $b string second element to compare
+ * @return int < 0 $a goes first (is less), 0 $b goes first, 0 doesn't matter
+ */
+ private function compare_by_length_desc($a, $b) {
+ return strlen($b) - strlen($a);
+ }
+
+ /**
* Is db in unicode mode?
* @return bool
*/
@@ -1164,12 +1187,13 @@ public function insert_record_raw($table, $params, $returnid=true, $bulk=false,
$id = null;
- list($sql, $params) = $this->tweak_param_names($sql, $params);
+ // note we don't need tweak_param_names() here. Placeholders are safe column names. MDL-28080
+ // list($sql, $params) = $this->tweak_param_names($sql, $params);
$this->query_start($sql, $params, SQL_QUERY_INSERT);
$stmt = $this->parse_query($sql);
$descriptors = $this->bind_params($stmt, $params, $table);
if ($returning) {
- oci_bind_by_name($stmt, ":o_oracle_id", $id, 10, SQLT_INT); // :o_ prefix added in tweak_param_names()
+ oci_bind_by_name($stmt, ":oracle_id", $id, 10, SQLT_INT);
}
$result = oci_execute($stmt, $this->commit_status);
$this->free_descriptors($descriptors);
@@ -1276,7 +1300,8 @@ public function update_record_raw($table, $params, $bulk=false) {
$sql = "UPDATE {" . $table . "} SET $sets WHERE id=:id";
list($sql, $params, $type) = $this->fix_sql_params($sql, $params);
- list($sql, $params) = $this->tweak_param_names($sql, $params);
+ // note we don't need tweak_param_names() here. Placeholders are safe column names. MDL-28080
+ // list($sql, $params) = $this->tweak_param_names($sql, $params);
$this->query_start($sql, $params, SQL_QUERY_UPDATE);
$stmt = $this->parse_query($sql);
$descriptors = $this->bind_params($stmt, $params, $table);

0 comments on commit a4c5837

Please sign in to comment.