mirror of
https://github.com/moodle/moodle.git
synced 2025-04-21 00:12:56 +02:00
MDL-39038 nasty workaround for Oracle NULL concats
This commit is contained in:
parent
422f68fb86
commit
031a6de97a
@ -1540,43 +1540,57 @@ class oci_native_moodle_database extends moodle_database {
|
||||
}
|
||||
|
||||
public function sql_concat() {
|
||||
// NOTE: Oracle concat implementation isn't ANSI compliant when using NULLs (the result of
|
||||
// any concatenation with NULL must return NULL) because of his inability to differentiate
|
||||
// NULLs and empty strings. So this function will cause some tests to fail. Hopefully
|
||||
// it's only a side case and it won't affect normal concatenation operations in Moodle.
|
||||
$arr = func_get_args();
|
||||
if ($this->oci_package_installed()) {
|
||||
foreach ($arr as $k => $v) {
|
||||
if (strpos($v, "'") === 0) {
|
||||
continue;
|
||||
}
|
||||
$arr[$k] = "MOODLELIB.UNDO_DIRTY_HACK($v)";
|
||||
}
|
||||
}
|
||||
$s = implode(' || ', $arr);
|
||||
if ($s === '') {
|
||||
if (empty($arr)) {
|
||||
return " ' ' ";
|
||||
}
|
||||
return " MOODLELIB.DIRTY_HACK($s) ";
|
||||
foreach ($arr as $k => $v) {
|
||||
if ($v === "' '") {
|
||||
$arr[$k] = "'*OCISP*'"; // New mega hack.
|
||||
}
|
||||
}
|
||||
$s = $this->recursive_concat($arr);
|
||||
return " MOODLELIB.UNDO_MEGA_HACK($s) ";
|
||||
}
|
||||
|
||||
public function sql_concat_join($separator="' '", $elements=array()) {
|
||||
if ($this->oci_package_installed()) {
|
||||
foreach ($elements as $k => $v) {
|
||||
if (strpos($v, "'") === 0) {
|
||||
continue;
|
||||
}
|
||||
$elements[$k] = "MOODLELIB.UNDO_DIRTY_HACK($v)";
|
||||
public function sql_concat_join($separator="' '", $elements = array()) {
|
||||
if ($separator === "' '") {
|
||||
$separator = "'*OCISP*'"; // New mega hack.
|
||||
}
|
||||
foreach ($elements as $k => $v) {
|
||||
if ($v === "' '") {
|
||||
$elements[$k] = "'*OCISP*'"; // New mega hack.
|
||||
}
|
||||
}
|
||||
for ($n = count($elements)-1; $n > 0 ; $n--) {
|
||||
array_splice($elements, $n, 0, $separator);
|
||||
}
|
||||
$s = implode(' || ', $elements);
|
||||
if ($s === '') {
|
||||
if (empty($elements)) {
|
||||
return " ' ' ";
|
||||
}
|
||||
return " MOODLELIB.DIRTY_HACK($s) ";
|
||||
$s = $this->recursive_concat($elements);
|
||||
return " MOODLELIB.UNDO_MEGA_HACK($s) ";
|
||||
}
|
||||
|
||||
/**
|
||||
* Mega hacky magic to work around crazy Oracle NULL concats.
|
||||
* @param array $args
|
||||
* @return string
|
||||
*/
|
||||
protected function recursive_concat(array $args) {
|
||||
$count = count($args);
|
||||
if ($count == 1) {
|
||||
$arg = reset($args);
|
||||
return $arg;
|
||||
}
|
||||
if ($count == 2) {
|
||||
$args[] = "' '";
|
||||
// No return here intentionally.
|
||||
}
|
||||
$first = array_shift($args);
|
||||
$second = array_shift($args);
|
||||
$third = $this->recursive_concat($args);
|
||||
return "MOODLELIB.TRICONCAT($first, $second, $third)";
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,8 +41,9 @@ FUNCTION GET_HANDLE (lock_name IN VARCHAR2) RETURN VARCHAR2;
|
||||
FUNCTION GET_LOCK (lock_name IN VARCHAR2, lock_timeout IN INTEGER) RETURN INTEGER;
|
||||
FUNCTION RELEASE_LOCK(lock_name IN VARCHAR2) RETURN INTEGER;
|
||||
|
||||
FUNCTION DIRTY_HACK(somestring IN VARCHAR2) RETURN VARCHAR2;
|
||||
FUNCTION UNDO_DIRTY_HACK(hackedstring IN VARCHAR2) RETURN VARCHAR2;
|
||||
FUNCTION UNDO_MEGA_HACK(hackedstring IN VARCHAR2) RETURN VARCHAR2;
|
||||
FUNCTION TRICONCAT(string1 IN VARCHAR2, string2 IN VARCHAR2, string3 IN VARCHAR2) RETURN VARCHAR2;
|
||||
|
||||
END MOODLELIB;
|
||||
/
|
||||
@ -101,15 +102,6 @@ BEGIN
|
||||
RETURN 1;
|
||||
END RELEASE_LOCK;
|
||||
|
||||
FUNCTION DIRTY_HACK(somestring IN VARCHAR2) RETURN VARCHAR2 IS
|
||||
|
||||
BEGIN
|
||||
IF somestring = '' THEN
|
||||
RETURN ' ';
|
||||
END IF;
|
||||
RETURN somestring;
|
||||
END DIRTY_HACK;
|
||||
|
||||
FUNCTION UNDO_DIRTY_HACK(hackedstring IN VARCHAR2) RETURN VARCHAR2 IS
|
||||
|
||||
BEGIN
|
||||
@ -119,5 +111,36 @@ BEGIN
|
||||
RETURN hackedstring;
|
||||
END UNDO_DIRTY_HACK;
|
||||
|
||||
FUNCTION UNDO_MEGA_HACK(hackedstring IN VARCHAR2) RETURN VARCHAR2 IS
|
||||
|
||||
BEGIN
|
||||
IF hackedstring IS NULL THEN
|
||||
RETURN hackedstring;
|
||||
END IF;
|
||||
RETURN REPLACE(hackedstring, '*OCISP*', ' ');
|
||||
END UNDO_MEGA_HACK;
|
||||
|
||||
FUNCTION TRICONCAT(string1 IN VARCHAR2, string2 IN VARCHAR2, string3 IN VARCHAR2) RETURN VARCHAR2 IS
|
||||
stringresult VARCHAR2(1333);
|
||||
BEGIN
|
||||
IF string1 IS NULL THEN
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
IF string2 IS NULL THEN
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
IF string3 IS NULL THEN
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
|
||||
stringresult := CONCAT(CONCAT(MOODLELIB.UNDO_DIRTY_HACK(string1), MOODLELIB.UNDO_DIRTY_HACK(string2)), MOODLELIB.UNDO_DIRTY_HACK(string3));
|
||||
|
||||
IF stringresult IS NULL THEN
|
||||
RETURN ' ';
|
||||
END IF;
|
||||
|
||||
RETURN stringresult;
|
||||
END;
|
||||
|
||||
END MOODLELIB;
|
||||
/
|
||||
|
@ -3796,7 +3796,7 @@ class dml_testcase extends database_driver_testcase {
|
||||
$this->assertEquals('123456', $DB->get_field_sql($sql, $params));
|
||||
// float, null and strings
|
||||
$params = array(123.45, null, 'test');
|
||||
$this->assertNull($DB->get_field_sql($sql, $params), 'ANSI behaviour: Concatenating NULL must return NULL - But in Oracle :-(. [%s]'); // Concatenate NULL with anything result = NULL
|
||||
$this->assertNull($DB->get_field_sql($sql, $params)); // Concatenate NULL with anything result = NULL
|
||||
|
||||
// Testing fieldnames + values and also integer fieldnames
|
||||
$table = $this->get_test_table();
|
||||
|
Loading…
x
Reference in New Issue
Block a user