diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\includes\database.oracle.inc drupal-6.x-dev\includes\database.oracle.inc
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\includes\database.oracle.inc	Wed Dec 31 16:00:00 1969
+++ drupal-6.x-dev\includes\database.oracle.inc	Mon May 21 00:11:18 2007
@@ -0,0 +1,1308 @@
+<?php
+/**
+ * @file
+ * Database interface code for Oracle database servers.
+ */
+
+/**
+ * @ingroup database
+ * @{
+ */
+
+/**
+ * Report database status.
+ */
+function db_status_report($phase) {
+  $t = get_t();
+
+  $version = db_version();
+
+  $form['oracle'] = array(
+    'title' => $t('Oracle database'),
+    'value' => ($phase == 'runtime') ? l($version, 'admin/logs/status/sql') : $version,
+  );
+
+  // -- checkpoint 01: no checking for Oracle server
+  //            TODO
+  //            $version : from system.install
+  //  if (version_compare($version, DRUPAL_MINIMUM_MYSQL) < 0) {
+  //    $form['oracle']['severity'] = REQUIREMENT_ERROR;
+  //    $form['oracle']['description'] = $t('Your MySQL Server is too old. Drupal requires at least MySQL %version.', array('%version' => DRUPAL_MINIMUM_MYSQL));
+  //  }
+  // -- end 01
+
+  return $form;
+}
+
+/**
+ * Returns the version of the database server currently in use.
+ *
+ * @return Database server version
+ */
+function db_version() {
+  return db_result(db_query('SELECT banner FROM sys.V_$VERSION'));
+}
+
+/**
+ * Initialize a database connection.
+ */
+function db_connect($url) {
+  	
+  // Check if Oracle support is present in PHP 4 or 5
+  if (!(function_exists('oci_connect'))) {
+    drupal_maintenance_theme();
+    drupal_set_title('PHP Oracle support not enabled');
+    print theme('maintenance_page', '<p>We were unable to use the Oracle database because the Oracle extension for PHP is not installed. Check your <code>PHP.ini</code> to see how you can enable it.</p>');
+    //create a book page about Oracle support.
+    exit;
+  }
+
+  $url = parse_url($url);
+  
+  //print_r($url);	
+  //die(); 
+  // Decode url-encoded information in the db connection string
+  $url['user'] = urldecode($url['user']);
+  $url['pass'] = urldecode($url['pass']);
+  $url['host'] = urldecode($url['host']);
+  $url['path'] = urldecode($url['path']);
+
+  // Allow for non-standard Oracle port.
+  if (isset($url['port'])) {
+     $url['host'] = $url['host'] .':'. $url['port'];
+  }
+
+  // -- checkpoint 02 : extract charset from path
+  // $db_url = 'oracle://user:pass@host/SID/charset';
+  $tmp_path = explode('/', substr($url['path'], 1));
+  $url['charset'] = $tmp_path[1];
+  $url['path'] = "/" . $tmp_path[0];
+  // -- end 02
+  $string_db = '//'.$url['host'].'/'.substr($url['path'], 1);
+  
+  //TODO: investigate for the use of charset parameter.
+  //TODO: Currently, this requires that the $url['path'] value be 
+  //      set in the TNSNAMES.ora file on the local system. Investigate
+  //      how to specify server, port and DB Instance. 
+  
+  /*
+  Re: TODO above, using a connection string like this might work
+  $db="(DESCRIPTION =
+     (ADDRESS_LIST =
+         (ADDRESS =
+           (COMMUNITY = xxx)
+           (PROTOCOL = TCP)
+           (Host = xxx)
+           (Port = xxx)
+         )
+     )
+     (CONNECT_DATA = (SID = xxx)
+     )
+   )"; 
+   */
+
+// -- checkpoint 03
+//    Add connection charset parameter
+//    use string_db instead of substr
+//    as 'Can't find listenser before
+//  $connection = @oci_connect($url['user'], $url['pass'], substr($url['path'], 1));
+  if ($url['charset']) {
+    $connection = @oci_connect($url['user'], $url['pass'], $string_db, $url['charset']);
+  } else {
+    $connection = @oci_connect($url['user'], $url['pass'], $string_db);
+  }
+// -- end 03
+  
+  if (!$connection) {
+  	
+    drupal_maintenance_theme();
+    drupal_set_title('Unable to connect to database server');
+    $error = ocierror();
+    print theme('maintenance_page', '<p>This either means that the username and password information in your <code>settings.php</code> file is incorrect or we can\'t contact the Oracle database server. This could mean your hosting provider\'s database server is down.</p>
+<p>The Oracle error was: '. theme('placeholder', $error['message']) .'.</p>
+<p>Currently, the username is '. theme('placeholder', $url['user']) .' and the database server is '. theme('placeholder', $url['host']) .'.</p>
+<ul>
+  <li>Are you sure you have the correct username and password?</li>
+  <li>Are you sure that you have typed the correct hostname?</li>
+  <li>Are you sure that the database server is running?</li>
+</ul>
+<p>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.</p>');
+    exit;
+  }  
+  
+  return $connection;
+}
+ /**
+ * Sanitize query adding "" around Oracle SQL reserved column names.
+ */
+
+function _db_reserved_words($part) {
+  $part = " " . $part . " "; //hack to get around the fact that the column name might be at the front or at the end of the string
+  $db_reserved_words = array ('access', 'comment', 'mode', 'session', 'uid');
+  foreach ($db_reserved_words as $word) {
+    $part = eregi_replace('([[:space:],\.\(<>\+-=!*])'.$word.'([[:space:],\.\)<>\+-=!*])','\\1"'.$word.'"\\2', $part);
+  }
+  return substr($part,1,-1);
+}
+
+  /**
+   *  _db_query_rewrite_select() : rewrite SELECT query quote reserved word and handle CLOB comparison
+   *  @param string query : SELECT query string
+   *  @param integer debug : debug mode ON/OFF to print message(OFF)
+   *  @return string : query string with reserved words quoted
+   */
+// Isolated function to rewrite select query
+// planned for INSERT INTO ... SELECT
+function _db_query_rewrite_select($query, $debug = 0) {
+  
+  global $active_db, $last_result, $_query_rc_result, $queries;
+
+  // Parsing SELECT query, because we need to manage CLOB and BLOBs in WHERE clause
+  // This is only for simple queries
+  // TODO: think of better $re to handle complex queries (JOINS)
+  	
+  if (strpos($query, 'JOIN') || strpos($query, 'ORDER') || strpos($query, 'GROUP') || strpos($query, 'LIKE') || !strpos($query, 'WHERE')) {
+
+    $newSQL = _db_reserved_words($query);
+    return $newSQL;
+
+  } else { 
+
+    //$re = "/select\\s*(.*)\\s*from\\s*(.*)\\s*where\\s*(.*)/si";  		
+    $re = "/\sfrom\s*(\w+)/si";
+    preg_match($re, $query, $tmpArr);		
+    $tablename = trim($tmpArr[1]);		
+    // -- checkpoint 04
+    //    for query select only constant
+    //    give it virtual table 'dual'
+    if (!$tablename) {
+      $query .= " FROM DUAL";
+    }
+    // -- end 04
+    
+    /*
+     * Determine whether or not each column is a LOB (CLOB or BLOB) and 
+     * substitute a bind variable. If the column list is not provided, 
+     * we'll need to obtain it from the DB.
+     */
+    //TODO: Augment this query with some sort of caching system, so it knows
+    //       which columns are LOBs without having to ask the DB every time.
+    $col_query = "SELECT column_name, data_type, column_id
+                FROM USER_TAB_COLUMNS
+                WHERE table_name = '" . strtoupper($tablename) . "'
+                ORDER BY column_id";
+	    
+    $col_result = oci_parse($active_db, $col_query);
+    oci_execute($col_result , OCI_DEFAULT);
+    oci_fetch_all($col_result, $ora_cols, 0, -1, OCI_ASSOC);
+	    	    	    
+    for ($i=0; $i<sizeof($ora_cols["DATA_TYPE"]); $i++) {
+      if ($ora_cols["DATA_TYPE"][$i] == 'CLOB') {
+    	$CLOB_vars[] = $ora_cols["COLUMN_NAME"][$i];
+      }
+    }
+	    
+    $newSQL = _db_reserved_words($query);
+    if (sizeof($CLOB_vars)) {
+      $CLOB_str = implode("|", $CLOB_vars);   
+      $sql = str_replace("\'", chr(0), $query);
+      $sql = str_replace("''", chr(1), $sql);
+      $pattern = "/(" . $CLOB_str . ")\s*(=|!=)\s*('.*?')/si";
+      //$pattern = "/(" . $CLOB_str . ")\s*(=|!=)\s*('(?:\\'|[^'])*')/si";
+      $containerArr = array();
+      preg_match_all($pattern, $sql, $containerArr);
+      
+      for ($j=0; $j<sizeof($containerArr[0]); $j++) {
+        $sql = str_replace($containerArr[0][$j], " dbms_lob.instr(" . $containerArr[1][$j] . ", " . $containerArr[3][$j] . ") > 0 ", $sql);
+      }
+
+      $newSQL = str_replace(chr(1), "''", $sql);
+      $newSQL = str_replace(chr(0), "\'", $newSQL);
+      $newSQL = _db_reserved_words($newSQL);
+    }
+    return $newSQL;
+
+  }
+}
+
+// -- checkpoint 24: Parsing implementation
+// -- Try to handle queries without bucket '()'
+//    JOIN:   is in FROM part,
+//            seems can be handled in it.
+//    GROUP:  not tested
+// SELECT A FROM B WHERE C ORDER BY D
+function _regexp_select_easy($query) {
+  $hasWhere = 0;
+  $hasOrder = 0;
+  $hasIn = 0;
+  $argOrder = array();
+  $regexp_select = "/^select (.*) from (.*)";
+  $i = 3;
+  if (strpos($query, " WHERE ")) {
+    $hasWhere = 1;
+    $argOrder['where'] = $i;
+    $i++;
+    $regexp_select .= " where (.*)";
+    if (strpos($query, " IN ")) {
+      $hasIn = 1;
+      $argOrder['in'] = $i;
+      $i++;
+      $regexp_select .= " in (\(.*\))";
+    }
+  }
+  if (strpos($query, " ORDER ")) {
+    $hasOrder = 1;
+    $argOrder['order'] = $i;
+    $i++;
+    $regexp_select .= " order by (.*)";
+  }
+  $regexp_select .= "/Dsi";
+  preg_match($regexp_select, $query, $matches2);
+//  drupal_set_message($regexp_select);
+
+  if (isset($matches2[1]) && $matches2[1]) {
+    $returnSQL  = "SELECT "._db_reserved_words($matches2[1]);
+    $returnSQL .= " FROM "._db_reserved_words($matches2[2]);
+    if ($hasWhere) {
+      $returnSQL .= " WHERE "._db_reserved_words($matches2[($argOrder['where'])]);
+    }
+    if ($hasIn) {
+      $returnSQL .= " IN ".$matches2[($argOrder['in'])];
+    }
+    if ($hasOrder) {
+      $returnSQL .= " ORDER BY "._db_reserved_words($matches2[($argOrder['order'])]);
+    }
+  } else {
+    // not a query, just field names
+    $returnSQL = $query;
+  }
+  return $returnSQL;
+}
+// -- end 24
+
+// -- checkpoint 23: parsing query with recursive function
+//                    break bucket until no bucket.
+//                    at the same time do complete parsing to remaining SQL segment
+function _regexp_select_recur($query) {
+  $regexp_bucket = "/\((.*)\)/Dsi";
+  preg_match($regexp_bucket, $query, $matches);
+  if (isset($matches[1]) && $matches[1]) {
+//    drupal_set_message("Matches: ".$matches[1]);
+    $return_str = _regexp_select_recur($matches[1]);
+    // replace query in bucket with some string
+    // prevent re-parsing
+    $new_query = str_replace($matches[1],"a1", $query);
+
+    $new_query = _regexp_select_easy($new_query);
+
+    // restore the query
+    $return_query = str_replace("a1", $return_str, $new_query);
+    return $return_query;
+  } else {
+    // end of recursive: no bucket found
+    $return_query = _regexp_select_easy($query);
+
+    return $return_query;
+  }
+}
+// -- end 23
+
+/**
+ * Helper function for db_query().
+ */
+function _db_query($query, $debug = 0) {
+	global $counterS;
+        $counterS++;
+        $dbug = 0;
+        global $active_db, $last_result, $_query_rc_result, $queries;
+        $CLOB_vars = array();
+
+//  drupal_set_message("_db_query(): ".$query);
+  if (variable_get('dev_query', 0)) {
+    list($usec, $sec) = explode(' ', microtime());
+    $timer = (float)$usec + (float)$sec;
+  }
+  
+  if (!isset($_query_rc_result)) {
+    $_query_rc_result = array();
+  }
+  
+  //Rewrite all INSERT/UPDATE statements to check and handle LOBs since Oracle
+  //  cannot handle them as just strings of text delimited by single quote 
+  //  marks (') once they go over 4000 charecters (common in Drupal).
+  if (eregi('^(INSERT INTO )', $query)) {
+    //Rewrite INSERT INTO statement
+    //$query = "INSERT INTO boxes (title, body, info, format) VALUES ('', '', 'a', 1)";
+    
+  	//echo "<br />------------------------------------<br />Step $counterS <br />";
+  	//echo $query . "<br />";
+    /* 
+     * Split statement into three groups - the table name, the field list 
+     * (if provided) and "VALUES" and the value list. Then, further split
+     * the column list and value/ list into arrays. 
+     */
+
+    // -- checkpoint 05 : Handle "INSERT INTO .. SELECT .. " query
+    //$query = "INSERT INTO node_data_field_cck0101
+    //          (vid, nid, field_cck0101_value)
+    //          SELECT vid, nid, field_cck0101_value 
+    //          FROM node_content_cck01";
+    // CCK: content_admin.inc
+    // TODO: do data type validation between INSERT fields and SELECT fields
+    
+    $re = "/[\s)]values\s*(\(.*\))/si";
+    preg_match($re, $query, $tmpArr);	
+    if (!isset($tmpArr[0]) || !trim($tmpArr[0])) {
+      //drupal_set_message("The INSERT query does not contain VALUES, function not yet DONE, checking is skipped");
+      $re = "/^insert into ([a-z0-9_\"]+)(?:\s*\((.*)\))? (select .*)$/Dsi";
+      preg_match($re, $query, $parts);
+
+      $tablename = _db_reserved_words($parts[1]);
+      $col_list = _db_reserved_words($parts[2]);
+      $val_list = _db_query_rewrite_select($parts[3]);
+
+      $query = "INSERT INTO " . $tablename . " (" . $col_list . ") " . $val_list;
+      $result = OCIParse($active_db, $query);
+      OCIExecute($result, OCI_DEFAULT) or die($query);
+      OCICommit($active_db);
+      return true;
+    }
+    // -- end 05
+
+    //$re = "/^insert into ([a-z0-9_\"]+)(?:\s*\((.*)\))? values \((.*)\)$/Dsi";
+    //$re = "/^insert into ([a-z0-9_\"]+)(?:\s*\((.*)\))? values\s+\((.*)\)$/Dsi";
+    // checkpoint 20 : break INSERT statement into parts
+    $re = "/^insert into ([a-zA-Z0-9_\"]+)\s+\((.*)\)\s+values\s*\((.*)\)/Dsi";
+    // -- end 20
+    
+    preg_match($re, $query, $parts);
+    if (isset($parts[3]) && count($parts[3])) {
+      // INSERT INTO tablename (column_list) VALUES (value_list)
+//    print_r($parts); echo "<br />";
+//  die();
+      $tablename = _db_reserved_words($parts[1]);
+      $col_list = _db_reserved_words($parts[2]);
+      $val_list = $parts[3];
+      $col_arr = explode(",",$col_list); //the column list is strictly delimited by ","
+      $hasColName = 1;
+    } else {
+      $re = "/^insert into ([a-zA-Z0-9_\"]+)\s+values\s*\((.*)\)/Dsi";
+      // dbug01
+//      print "OLD: ".$query."<br />";
+      preg_match($re, $query, $parts);
+      $tablename = _db_reserved_words($parts[1]);
+      $val_list = $parts[2];
+      $hasColName  = 0;
+    }
+    
+    //However, the value list is not strictly delimited by ",", use a regex to break it up
+    $re="/,(?=(?:[^']*'[^']*')*(?![^']*'))/";
+    $results=preg_split($re, trim($val_list));
+    $val_arr = preg_replace("/^\"(.*)\"$/","$1", $results);
+    
+    /*
+     * Determine whether or not each column is a LOB (CLOB or BLOB) and 
+     * substitute a bind variable. If the column list is not provided, 
+     * we'll need to obtain it from the DB.
+     */
+    //TODO: Augment this query with some sort of caching system, so it knows
+    //       which columns are LOBs without having to ask the DB every time.
+    $col_query = "select column_name, data_type, column_id
+                from USER_TAB_COLUMNS
+                where table_name = '" . strtoupper($tablename) . "'
+                order by column_id";
+    $col_result = ociparse($active_db, $col_query);
+    OCIExecute($col_result , OCI_DEFAULT);
+    ocifetchstatement($col_result, $ora_cols, 0, -1, OCI_ASSOC);
+    
+    // Check + Build $col_arr
+    if (! is_array($col_arr)) {
+      //populate $col_list
+      $col_arr = $ora_cols['COLUMN_NAME'];
+      for($i=0; $i < count($col_arr);$i++) {
+        // If column name is in lower case, it needs to have "" around it since its a reserved word
+        if ($col_arr[$i] == strtolower($col_arr[$i])){
+          $col_arr[$i] = "\"" . $col_arr[$i] . "\"";
+        }
+      }
+      array_change_key_case($col_arr, CASE_LOWER);
+    }
+    
+    //Clean $col_arr and $val_arr
+    foreach ($col_arr as $key => $value) {
+      $col_arr[$key] = trim($value);
+    }
+    foreach ($val_arr as $key => $value) {
+      $val_arr[$key] = trim($value);
+    }
+    
+    // $lob_cols[n] => [0] Column Name, [1] Value to be stored
+    $lob_cols = array();
+    
+    // Check for CLOB/BLOB
+    for($i=0; $i < count($col_arr);$i++) {
+      $query_col = trim(str_replace("\"", "", strtolower($col_arr[$i])));
+      for($j=0; $j < count($ora_cols['COLUMN_NAME']);$j++) {
+        $ora_col = trim(strtolower($ora_cols['COLUMN_NAME'][$j]));  
+        if ($query_col == $ora_col) {
+          if ($ora_cols['DATA_TYPE'][$j] == "CLOB" || $ora_cols['DATA_TYPE'][$j] == "BLOB") {
+            // Replace that value with a bind variable if the data is not ''
+            if ($val_arr[$i] != "''") {
+              $lob_cols[] = array($col_arr[$i], $val_arr[$i]);
+            } 
+            $val_arr[$i] = "EMPTY_" . $ora_cols['DATA_TYPE'][$j] . "()";
+          }
+          break;
+        }
+      }
+    }
+    //Rebuild Query
+    $newquery  = "INSERT INTO " . $tablename;
+    if ($hasColName) {
+      $newquery .= " (" . implode(",", $col_arr) . ")";
+    }
+    $newquery .= " VALUES (" .  implode(",", $val_arr) . ")";
+//    print "NEW: ".$newquery."<br />";
+
+    //Build RETURNING string
+    if (count($lob_cols) > 0) {
+      $lobcollist = null;
+      $bindvarlist = null;
+      for($i=0;$i < count($lob_cols);$i++) {
+        $lobcollist .=  "," . $lob_cols[$i][0];
+        $bindvarlist .= "," . ":" . $lob_cols[$i][0];
+      }
+      $lobcollist = substr($lobcollist,1);
+      $bindvarlist = substr($bindvarlist,1);
+      $newquery .= " RETURNING " . $lobcollist . " INTO " . $bindvarlist;
+    }
+    
+    $result = OCIParse($active_db, $newquery);
+    $clobs = array();
+    
+    //Create bind variables
+    if (count($lob_cols) > 0) {
+      for($i=0;$i < count($lob_cols);$i++) {
+        $clob = ocinewdescriptor($active_db, OCI_D_LOB);
+        ocibindbyname($result, ':' . $lob_cols[$i][0], $clob, -1, OCI_B_CLOB);
+        $clobs[] = $clob;
+      }
+    }
+    
+    OCIExecute($result, OCI_DEFAULT) or die($newquery);
+    
+    //Bind CLOB data
+    if (count($lob_cols) > 0) {
+      for($i=0;$i < count($lob_cols);$i++) {
+        $clob = $clobs[$i];
+        $data = $lob_cols[$i][1];
+        //Strip ' from the beginning and end of the string (since they'll be 
+        //  interpreted literally and not as string encapsulators)
+        if (substr($data,0,1) == "'" && substr($data,-1,1) == "'") {
+          $data = substr($data,1,-1);
+          // -- checkpoint 06 : remove duplicated quote for further steps
+          $tmp_str = str_replace("''", "'", $data);
+          $data = $tmp_str;
+          // -- end 06
+        }
+        // In order to update the table, a row must have been found in the where clause!
+        if (ocirowcount($result) > 0) {
+          $clob->save($data);
+        }
+      }
+    }
+    
+    OCICommit($active_db);
+    
+    //Free CLOBs
+    if (count($lob_cols) > 0) {
+      for($i=0;$i < count($lob_cols);$i++) {
+        $clob = $clobs[$i];
+        $clob->free();
+      }
+    }
+  
+  } // end (eregi('^(INSERT INTO )', $query))
+  else if (eregi('^(UPDATE )', $query)) {
+    //Rewrite UPDATE statement
+    
+    /* 
+     * Split statement into three groups - the table name, the field and 
+     * value list, and the WHERE clause (if provided). Then, further split
+     * the column list and value list into arrays. 
+     */
+    $re = "/update\\s*([a-z0-9_\"]+)\\s*set\\s*(.*)\\s*where\\s*(.*)/si";
+    preg_match($re, $query, $parts);
+    $tablename = _db_reserved_words($parts[1]);
+    $item_list = $parts[2];
+    $whereclause = _db_reserved_words($parts[3]);
+    
+    $re="/,(?=(?:[^']*'[^']*')*(?![^']*'))/";
+    $results=preg_split($re, trim($item_list));
+    $item_arr = preg_replace("/^\"(.*)\"$/","$1", $results);
+
+    //Split item array into column and value arrays
+    $col_arr = array();
+    $val_arr = array();
+    
+    for($i=0; $i < count($item_arr);$i++) {
+      $pos = strpos($item_arr[$i], "=");
+      $col_arr[] = trim(substr($item_arr[$i],0,$pos-1));
+      $val_arr[] = trim(substr($item_arr[$i],$pos+1));
+    }
+    
+    $col_arr = explode(",",_db_reserved_words(implode(",", $col_arr)));
+    
+    /*
+     * Determine whether or not each column is a LOB (CLOB or BLOB) and 
+     * substitute a bind variable. If the column list is not provided, 
+     * we'll need to obtain it from the DB.
+     */
+    //TODO: Augment this query with some sort of caching system, so it knows
+    //       which columns are LOBs without having to ask the DB every time.
+    $col_query = "select column_name, data_type, column_id
+                from USER_TAB_COLUMNS
+                where table_name = '" . strtoupper($tablename) . "'
+                order by column_id";
+    $col_result = OCIParse($active_db, $col_query);
+    OCIExecute($col_result , OCI_DEFAULT);
+    ocifetchstatement($col_result, $ora_cols, 0, -1, OCI_ASSOC);
+    
+    // Check + Build $col_arr
+    if (! is_array($col_arr)) {
+      //populate $col_list
+      $col_arr = $ora_cols['COLUMN_NAME'];
+      for($i=0; $i < count($col_arr);$i++) {
+        // If column name is in lower case, it needs to have "" around it since its a reserved word
+        if ($col_arr[$i] == strtolower($col_arr[$i])){
+          $col_arr[$i] = "\"" . $col_arr[$i] . "\"";
+        }
+      }
+      array_change_key_case($col_arr, CASE_LOWER);
+    }
+    
+    //Clean $col_arr and $val_arr
+    foreach ($col_arr as $key => $value) {
+      $col_arr[$key] = trim($value);
+    }
+    foreach ($val_arr as $key => $value) {
+      $val_arr[$key] = trim($value);
+    }
+    
+    //array of arrays, the items below are defined as... 
+    // $lob_cols[n] => [0] Column Name, [1] Value to be stored
+    $lob_cols = array();
+    
+    // Check for CLOB/BLOB
+    for($i=0; $i < count($col_arr);$i++) {
+      $query_col = trim(str_replace("\"", "", strtolower($col_arr[$i])));
+      for($j=0; $j < count($ora_cols['COLUMN_NAME']);$j++) {
+        $ora_col = trim(strtolower($ora_cols['COLUMN_NAME'][$j]));  
+        if ($query_col == $ora_col) {
+          if ($ora_cols['DATA_TYPE'][$j] == "CLOB" || $ora_cols['DATA_TYPE'][$j] == "BLOB") {
+            // Replace that value with a bind variable if the data is not ''
+            if ($val_arr[$i] != "''") {
+              $lob_cols[] = array($col_arr[$i], $val_arr[$i]);
+            }
+            $val_arr[$i] = "EMPTY_" . $ora_cols['DATA_TYPE'][$j] . "()";
+          }
+          break;
+        }
+      }
+    }
+    
+    //Rebuild Query
+    $newquery = "UPDATE " . $tablename . " SET ";
+    for($i=0; $i < count($col_arr); $i++) {
+      $newquery .= $col_arr[$i] . " = " . $val_arr[$i];
+      if ($i < (count($col_arr)-1)) $newquery .= ", ";
+    }
+    if ($whereclause != "") {
+      $newquery .= " where " . $whereclause;
+    }
+    
+    //Build RETURNING string
+    if (count($lob_cols) > 0) {
+      $lobcollist = null;
+      $bindvarlist = null;
+      for($i=0;$i < count($lob_cols);$i++) {
+        $lobcollist .=  "," . $lob_cols[$i][0];
+        $bindvarlist .= "," . ":" . $lob_cols[$i][0];
+      }
+      $lobcollist = substr($lobcollist,1);
+      $bindvarlist = substr($bindvarlist,1);
+      $newquery .= " RETURNING " . $lobcollist . " INTO " . $bindvarlist;
+    }
+        
+    $result = OCIParse($active_db, $newquery);
+    $clobs = array();
+    
+    //Create bind variables
+    if (count($lob_cols) > 0) {
+      for($i=0;$i < count($lob_cols);$i++) {
+        $clob = ocinewdescriptor($active_db, OCI_D_LOB);
+        ocibindbyname($result, ':' . $lob_cols[$i][0], $clob, -1, OCI_B_CLOB);
+        $clobs[] = $clob;
+      }
+    }
+    OCIExecute($result, OCI_DEFAULT) or die($newquery);
+    
+    //Bind CLOB data
+    if (count($lob_cols) > 0) {
+      for($i=0;$i < count($lob_cols);$i++) {
+        $clob = $clobs[$i];
+        $data = $lob_cols[$i][1];
+        //Strip ' from the beginning and end of the string (since they'll be 
+        //  interpreted literally and not as string encapsulators)
+        if (substr($data,0,1) == "'" && substr($data,-1,1) == "'") {
+          $data = substr($data,1,-1);
+          // -- checkpoint 07 : remove duplicated quote for further steps
+          $tmp_str = str_replace("''", "'", $data);
+          $data = $tmp_str;
+          // -- end 07
+        }
+
+        // In order to update the table, a row must have been found in the where clause!
+        if (ocirowcount($result) > 0) {
+          $clob->save($data);
+        }
+      }
+    }
+    
+    OCICommit($active_db);
+    
+    //Free CLOBs
+    if (count($lob_cols) > 0) {
+      for($i=0;$i < count($lob_cols);$i++) {
+        $clob = $clobs[$i];
+        $clob->free();
+      }
+    }
+  } // end (eregi('^(UPDATE )', $query))
+  else if (ereg('^(SELECT DISTINCT)', $query)) {
+//    drupal_set_message("DISTINCT: ".$query);
+    // Oracle cannot SELECT DISTINCT(clob_field) ... 
+    $query = str_replace("DISTINCT", "", $query);
+    $query = _db_reserved_words($query);
+    $result = OCIParse($active_db, $query);
+    OCIExecute($result, OCI_DEFAULT) or die($query);
+    //Re-execute query for when the app requests a rowcount (so it wont disturb the cursor of the real result set)
+    $result_rc = OCIParse($active_db, $query);
+    OCIExecute($result_rc, OCI_DEFAULT) or die($query);
+    // -- checkpoint 08: $_query_rc_result stores numrow number instead
+//    $_query_rc_result[$result] = $result_rc;
+    db_set_num_rows($result, $result_rc);
+  }
+  else if (ereg('^(LOCK TABLE)', $query)) {
+//    drupal_set_message("QUERY(LOCK): ". $query);
+    //Lock Table has a keyword thats in the reserved word list, we don't want it in ""s
+    //echo $query . "<br/>";
+
+    $re = "/^(lock table\s+)([a-z0-9_]+)(\\s+.*)$/si";
+    preg_match($re, $query, $parts);
+    $parts[2] = _db_reserved_words($parts[2]);
+    array_shift($parts); //shift off the entire string
+    $query = implode("",$parts);
+    $result = OCIParse($active_db, $query);
+    OCIExecute($result, OCI_DEFAULT);
+  }
+  else if (ereg('^(SELECT)', $query)) {
+    //Limit double query for row count to SELECT statements
+    //echo $query . "<br/>";
+    //$query = _db_reserved_words($query);
+    
+    	// Parsing SELECT query, because we need to manage CLOB and BLOBs in WHERE clause
+  	// This is only for simple queries
+  	// TODO: think of better $re to handle complex queries (JOINS)
+  	
+//            drupal_set_message("Unvised: ".$query);
+  	if (strpos($query, 'JOIN') || strpos($query, 'ORDER') || strpos($query, 'GROUP') || strpos($query, 'LIKE') || !strpos($query, 'WHERE')) {
+          //$query = _db_reserved_words($query);
+          $query = _regexp_select_recur($query);
+//            drupal_set_message("Revised: ".$query);
+            $result = OCIParse($active_db, $query);
+	    OCIExecute($result, OCI_DEFAULT);
+	    //Re-execute query for when the app requests a rowcount (so it wont disturb the cursor of the real result set)
+	    $result_rc = OCIParse($active_db, $query);
+	    OCIExecute($result_rc, OCI_DEFAULT);
+            // -- checkpoint 09: $_query_rc_result stores numrow number instead
+//            $_query_rc_result[$result] = $result_rc;
+            db_set_num_rows($result, $result_rc);
+            // -- end 09
+  	}
+  	else { 
+          //$re = "/select\\s*(.*)\\s*from\\s*(.*)\\s*where\\s*(.*)/si";  		
+//          print "Query1: ".$query."<br />";
+            $re = "/\sfrom\s*(\w+)/si";
+            preg_match($re, $query, $tmpArr);		
+            $tablename = trim($tmpArr[1]);		
+            // -- checkpoint 10
+            if (!$tablename) {
+              $query .= " FROM DUAL";
+            }
+//          print "Query2: ".$query."<br />";
+            // -- end 10
+
+            /*
+	     * Determine whether or not each column is a LOB (CLOB or BLOB) and 
+	     * substitute a bind variable. If the column list is not provided, 
+	     * we'll need to obtain it from the DB.
+	     */
+	    //TODO: Augment this query with some sort of caching system, so it knows
+	    //       which columns are LOBs without having to ask the DB every time.
+	    $col_query = "select column_name, data_type, column_id
+	                from USER_TAB_COLUMNS
+	                where table_name = '" . strtoupper($tablename) . "'
+	                order by column_id";
+            
+	    $col_result = oci_parse($active_db, $col_query);
+	    oci_execute($col_result , OCI_DEFAULT);
+	    oci_fetch_all($col_result, $ora_cols, 0, -1, OCI_ASSOC);
+	    	    	    
+	    for ($i=0; $i<sizeof($ora_cols["DATA_TYPE"]); $i++) {
+	    	if ($ora_cols["DATA_TYPE"][$i] == 'CLOB') {
+	    		$CLOB_vars[] = $ora_cols["COLUMN_NAME"][$i];
+	    	}
+	    }
+
+            // -- checkpoint 22: write deeper parsing for nested SELECT query
+            //$newSQL = _db_reserved_words($query);
+            $newSQL = _regexp_select_recur($query);
+            // end 22
+	    if (sizeof($CLOB_vars)) {
+		    $CLOB_str = implode("|", $CLOB_vars);   
+                    $sql = str_replace("\'", chr(0), $query);
+                    // -- checkpoint 26: replace the escaped single quote
+                    //    so no need to do in regexp
+                    $sql = str_replace("''", chr(1), $sql);
+                    // 05-15 stop here
+		    $pattern = "/(" . $CLOB_str . ")\s*(=|!=)\s*('.*?')/si";
+		    //$pattern = "/(" . $CLOB_str . ")\s*(=|!=)\s*('(?:\\'|[^'])*')/si";
+		    $containerArr = array();
+		    preg_match_all($pattern, $sql, $containerArr);
+			
+		    for ($j=0; $j<sizeof($containerArr[0]); $j++) {
+		      $sql = str_replace($containerArr[0][$j], " dbms_lob.instr(" . $containerArr[1][$j] . ", " . $containerArr[3][$j] . ") > 0 ", $sql);
+		    }
+		    $newSQL = str_replace(chr(1), "''", $sql);
+		    $newSQL = str_replace(chr(0), "\'", $newSQL);
+		    $newSQL = _db_reserved_words($newSQL);
+            }
+//            drupal_set_message("NEW: ".$newSQL);
+            $result = OCIParse($active_db, $newSQL);
+            OCIExecute($result, OCI_DEFAULT);	    	
+	    //Re-execute query for when the app requests a rowcount (so it wont disturb the cursor of the real result set)
+	    $result_rc = OCIParse($active_db, $newSQL);
+	    OCIExecute($result_rc, OCI_DEFAULT);
+            // -- checkpoint 11: $_query_rc_result stores numrow number instead
+//            $_query_rc_result[$result] = $result_rc;
+            db_set_num_rows($result, $result_rc);
+            // -- end 11
+  	}
+  }
+  else {
+    $query = _db_reserved_words($query);
+    $result = OCIParse($active_db, $query);
+    OCIExecute($result, OCI_DEFAULT) or die($query);
+  }
+  
+  $last_result = $result;
+  
+  $error = ocierror($result);
+
+  if (variable_get('dev_query', 0)) {
+    $bt = debug_backtrace();
+    $query = $bt[2]['function'] . "\n" . $query;
+    list($usec, $sec) = explode(' ', microtime());
+    $stop = (float)$usec + (float)$sec;
+    $diff = $stop - $timer;
+    $queries[] = array($query, $diff);
+  }
+
+  if ($debug) {
+    print '<p>query: '. $query .'<br />error:'. $error['message'] .'</p>';
+  }
+
+  if ($last_result !== FALSE) {
+    return $result;
+  }
+  else {
+    trigger_error(check_plain($error['message']."\nquery: ". $error['sqltext']), E_USER_WARNING);
+    return FALSE;
+  }
+}
+
+
+/*
+// For debugging purposes only
+function userErrorHandler($errno, $errmsg, $filename, $linenum, $vars)
+{
+  echo "<div style=\"border:1px solid black\">";
+  echo "ERR: ";
+  echo $errmsg . " | ";
+  echo $filename . " | ";
+  echo $errmsg . " | ";
+  echo $linenum . " | ";
+  print_r($vars);
+  echo "</div>";
+}
+*/
+
+
+/**
+ * Fetch one result row from the previous query as an object.
+ *
+ * @param $result
+ *   A database query result resource, as returned from db_query().
+ * @return
+ *   An object representing the next row of the result. The attributes of this
+ *   object are the table fields selected by the query.
+ *   
+ * NOTE: - Oracle returns table fields in uppercase, so we convert them into lowercase.
+ *       - Oracle will return the " marks around reserved column names - remove then or 
+ *         it will break other items down the line. 
+ *       - Oracle Clob are Objects, so we read their value.
+ *       - To maintain compatibility with PHP4 as well as PHP5, OCI_FETCH_OBJECT is 
+ *         not used (it does not exist in PHP4), instead OCIFETCHINTO is used.
+ */
+function db_fetch_object($result, $debug = 0) {
+  
+  if ($result) {
+    $new_obj = null;
+    //ocifetchinto($result, $arr, OCI_ASSOC+OCI_RETURN_NULLS+OCI_RETURN_LOBS); // To return LOBs as strings of text automatically
+    @ocifetchinto($result, $arr, OCI_ASSOC+OCI_RETURN_NULLS);
+    if ($myerr = ocierror($result)) {
+      // -- checkpoint 21: Use soft alert...
+      //print_r($myerr);
+      if ($debug)
+        drupal_set_message($myerr['message']."<br />".$myerr['sqltext']);
+    }
+    /*if ($debug) {
+      print_r($arr);
+    }*/
+    if (is_array($arr)) {
+      foreach ($arr as $key => $value) {
+        //if ($debug) print 'key:'.$key.'-value:'.$value.'<br>';
+        $lower_key = str_replace("\"","",strtolower($key));
+        
+        //Return LOB value.
+        if (is_object($value)) {
+          //TODO: use OCI-Lob->load instead ?
+          $new_obj->$lower_key = $value->load();
+          /*if ($debug) {
+            print 'name:'.$lower_key.'-value:'.$value->read($value->size()).'<br/>';
+          }*/
+        }
+        else {
+          $new_obj->$lower_key = $value;
+          ///if ($debug) print 'key:'.$lower_key.'-value:'.$value.'<br>';
+        }
+      }
+    }
+    /*if ($debug) {
+      print_r($new_obj);
+    }*/
+    return $new_obj;
+  }
+}
+
+/**
+ * Fetch one result row from the previous query as an array.
+ *
+ * @param $result
+ *   A database query result resource, as returned from db_query().
+ * @return
+ *   An associative array representing the next row of the result. The keys of
+ *   this object are the names of the table fields selected by the query, and
+ *   the values are the field values for this result row.
+ * 
+ * NOTE: - Oracle returns table fields in uppercase, so we convert them into lowercase.
+ */
+function db_fetch_array($result) {
+  if ($result) { 
+    ocifetchinto($result, $array_result, OCI_ASSOC + OCI_RETURN_NULLS + OCI_RETURN_LOBS);
+    if (is_array($array_result)) {
+      return array_change_key_case($array_result, CASE_LOWER);
+    }
+    else {
+      return FALSE;
+    }
+  }
+}
+
+/**
+ * Determine how many result rows were found by the preceding query.
+ *
+ * @param $result
+ *   A database query result resource, as returned from db_query().
+ * @return
+ *   The number of result rows.
+ * 
+ * NOTE: ocirowcount doesn't return the number of lines selected in a SELECT query. It
+ *       cannot be used here. Further, there is no way to implement this function cleanly 
+ *       with an Oracle DB. Oracle stores its query results on the server side, therefore
+ *       the client does not have to download the entire result set when the query is
+ *       executed. However, since the client can not see the entire result set, it cant 
+ *       (from within the client only) determine how many rows were selected. 
+ *
+ *       Unfortunately, the cleanest possible way I could figure out was to have two
+ *       result resources for SELECT statements, one for retrieving data and the other 
+ *       for counting rows. The alternate resource is set above in _db_query. 
+ */
+/*
+function db_num_rows($result) {
+  global $_query_rc_result;
+  $result_rc = $_query_rc_result[$result];
+  if ($result_rc) {
+    // Reset result cursor and count
+    ociexecute($result_rc, OCI_COMMIT_ON_SUCCESS);
+    ocifetchstatement($result_rc,$rows, 0, 1, OCI_FETCHSTATEMENT_BY_ROW);
+    $num_rows = count($rows);
+    return $num_rows;
+  }
+  else {
+    //Just test $result with OCIROWCOUNT (this is appropriate for INSERT/UPDATE/DELETE statements)
+    return ocirowcount($result);
+  }
+}
+ */
+
+/*  db_set_num_rows($result, $result_rc, $mode = 0)
+ *    store number of result row in global array, let db_num_rows() to query
+ *  @param $result
+ *    A database query result resource, as returned from OCIParse().
+ *    Just for array indexing
+ *  @param $result_rc
+ *    A database query result resource, returned from OCIParse()
+ *    The result resource to be counted
+ *  @param $mode
+ *    mode 0 : For SELECT statement
+ *    mode x : For INSERT/UPDATE/DELETE (not used, just placed)
+ *
+ *  NOTE: As the previous version store the entire resource into array,
+ *        in some heavy query page(?q=admin/build/menu)
+ *        it exceeds the limit of maximum cursor in Oracle.
+ *        Instead of adjusting the limit,
+ *        here just store the num_rows of each query,
+ *        instead of the resource itself
+ */
+  
+// -- checkpoint 12 : "helper" function for db_num_rows()
+function db_set_num_rows($result, $result_rc, $mode = 0) {
+  global $_query_rc_result;
+  if (!$mode) {
+    // Reset result cursor and count
+    ociexecute($result_rc, OCI_COMMIT_ON_SUCCESS);
+    // Simply use OCIFetchStatement() to get num_rows
+    $num_rows = OCIFetchStatement($result_rc, $rows);
+//    ocifetchstatement($result_rc, $rows, 0, 1, OCI_FETCHSTATEMENT_BY_ROW);
+//    $num_rows = count($rows);
+    $_query_rc_result[$result] = $num_rows;
+    return $num_rows;
+  } else {
+    //Just test $result with OCIROWCOUNT (this is appropriate for INSERT/UPDATE/DELETE statements)
+    $num_rows = ocirowcount($result_rc);
+    $_query_rc_result[$result] = $num_rows;
+    return $num_rows;
+  }
+}
+// -- end 12
+
+// -- checkpoint 13 : Re-implement num_rows counting
+function db_num_rows($result) {
+  global $_query_rc_result;
+  $num_rows = $_query_rc_result[$result];
+  if ($num_rows) {
+    //-- checkpoint :  numrow for SELECT query is already stored in global array 
+    //                instead of storing resultset
+    return $num_rows;
+  }
+  else {
+    //Just test $result with OCIROWCOUNT (this is appropriate for INSERT/UPDATE/DELETE statements)
+    return ocirowcount($result);
+  }
+}
+// -- end 13
+
+
+/**
+ * Return an individual result field from the previous query.
+ *
+ * Only use this function if exactly one field is being selected; otherwise,
+ * use db_fetch_object() or db_fetch_array().
+ *
+ * @param $result
+ *   A database query result resource, as returned from db_query().
+ * @param $row
+ *   The index of the row whose result is needed.
+ * @return
+ *   The resulting field.
+ */
+function db_result($result, $row = 0) {
+    //First we have to fetch the first row then we return the first column.
+    //TODO: validate the number of rows ? This would generate problems for
+    //      db_next_id query as we need to run query one time to get the number
+    //      of rows, and then run it a second time to get the result, so we will
+    //      "jumped" some id.
+//  while ($row = db_fetch_object($result)) {
+//    print_r($row);
+  //  }
+  // checkpoint 17: ocifetch only fetch the resource link of CLOB
+  //                Use OCIFetchInto to get content instead 
+  //ocifetch($result);
+  //  return ociresult($result, 1);
+  if (@OCIFetchInto($result, $result_row, OCI_NUM+OCI_RETURN_LOBS)) {
+    //var_dump($row);
+    return $result_row[0];
+  }
+    return False;
+}
+
+/**
+ * Determine whether the previous query caused an error.
+ */
+function db_error() {
+  $error = ocierror();
+  return $error['message'];
+}
+
+/**
+ * Return a new unique ID in the given sequence.
+ *
+ * For compatibility reasons, Drupal does not use auto-numbered fields in its
+ * database tables. Instead, this function is used to return a new unique ID
+ * of the type requested. With the Oracle DB implementation, all sequences 
+ * must be created at the time of Oracle scema creation. 
+ */
+function db_next_id($name) {
+  global $active_db;
+  // checkpoint 18: cant use db_query(),
+  //                seq num additionally +2 for each call..
+  //                not know the reason
+//  $id = db_result(db_query("SELECT %s_seq.nextval FROM DUAL", db_prefix_tables($name)));
+  $name = db_prefix_tables($name);
+  $result = OCIParse($active_db, "SELECT ".$name."_seq.nextval FROM DUAL");
+  OCIExecute($result, OCI_DEFAULT);
+  $id = db_result($result);
+  return $id;
+}
+
+/**
+ * Determine the number of rows changed by the preceding query.
+ */
+function db_affected_rows() {
+  global $last_result;
+  return ocirowcount($last_result);
+}
+
+/**
+ * Runs a limited-range query in the active database.
+ *
+ * Use this as a substitute for db_query() when a subset of the query is to be
+ * returned.
+ * User-supplied arguments to the query should be passed in as separate parameters
+ * so that they can be properly escaped to avoid SQL injection attacks.
+ *
+ * Note that if you need to know how many results were returned, you should do
+ * a SELECT COUNT(*) on the temporary table afterwards. db_num_rows() and
+ * db_affected_rows() do not give consistent result across different database
+ * types in this case.
+ *
+ * @param $query
+ *   A string containing an SQL query.
+ * @param ...
+ *   A variable number of arguments which are substituted into the query
+ *   using printf() syntax. The query arguments can be enclosed in one
+ *   array instead.
+ *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
+ *   in '') and %%.
+ *
+ *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ *   and TRUE values to decimal 1.
+ *
+ * @param $from
+ *   The first result row to return.
+ * @param $count
+ *   The maximum number of result rows to return.
+ * @return
+ *   A database query result resource, or FALSE if the query was not executed
+ *   correctly.
+ */
+function db_query_range($query) {
+  $args = func_get_args();
+  $count = (int) array_pop($args);
+  $from = (int) array_pop($args);
+  array_shift($args);
+
+  $query = db_prefix_tables($query);
+  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+    $args = $args[0];
+  }
+  _db_query_callback($args, TRUE);
+  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
+  $query = 'SELECT * FROM (SELECT sub.*, rownum AS line FROM ('. $query .') sub) WHERE line BETWEEN '. ($from + 1) .' AND '. ($from + $count);
+  return _db_query($query);
+}
+
+/**
+ * Runs a SELECT query and stores its results in a temporary table.
+ *
+ * Use this as a substitute for db_query() when the results need to stored
+ * in a temporary table. Temporary tables exist for the duration of the page
+ * request.
+ * User-supplied arguments to the query should be passed in as separate parameters
+ * so that they can be properly escaped to avoid SQL injection attacks.
+ *
+ * Note that if you need to know how many results were returned, you should do
+ * a SELECT COUNT(*) on the temporary table afterwards. db_num_rows() and
+ * db_affected_rows() do not give consistent result across different database
+ * types in this case.
+ *
+ * @param $query
+ *   A string containing a normal SELECT SQL query.
+ * @param ...
+ *   A variable number of arguments which are substituted into the query
+ *   using printf() syntax. The query arguments can be enclosed in one
+ *   array instead.
+ *   Valid %-modifiers are: %s, %d, %f, %b (binary data, do not enclose
+ *   in '') and %%.
+ *
+ *   NOTE: using this syntax will cast NULL and FALSE values to decimal 0,
+ *   and TRUE values to decimal 1.
+ *
+ * @param $table
+ *   The name of the temporary table to select into. This name will not be
+ *   prefixed as there is no risk of collision.
+ * @return
+ *   A database query result resource, or FALSE if the query was not executed
+ *   correctly.
+ */
+function db_query_temporary($query) {
+  $args = func_get_args();
+  $tablename = array_pop($args);
+  array_shift($args);
+  _check_table_existance($tablename);
+  $query = preg_replace('/^SELECT/i', 'CREATE GLOBAL TEMPORARY TABLE '. $tablename .' ON COMMIT PRESERVE ROWS AS SELECT ', db_prefix_tables($query));
+  
+  if (isset($args[0]) and is_array($args[0])) { // 'All arguments in one array' syntax
+    $args = $args[0];
+  }
+  _db_query_callback($args, TRUE);
+  $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
+  return _db_query($query);
+}
+
+/**
+ * Returns a properly formatted Binary Large OBject value.
+ *
+ * @param $data
+ *   Data to encode.
+ * @return
+ *  Encoded data.
+ */
+function db_encode_blob($data) {
+  //No processing is needed here, since LOBs in Oracle are input via LOB->Save() and 
+  // dont need any escaping of charecters like \ or '
+  // -- checkpoint 14: Move the modification from
+  //            database.inc to here
+  //            keep database.inc original
+//  return "'" . $data . "'";
+  return "'" . db_escape_string($data) . "'";
+  // -- end 11
+}
+
+/**
+ * Returns text from a Binary Large Object value.
+ *
+ * @param $data
+ *   Data to decode.
+ * @return
+ *  Decoded data.
+ */
+function db_decode_blob($data) {
+  //No processing is needed here, since LOBs in Oracle are read via LOB->Load()
+  return $data;
+}
+
+/**
+ * Prepare user input for use in a database query, preventing SQL injection attacks.
+ */
+function db_escape_string($text) {
+  // Replace any single ' with two ' 
+  return str_replace("'", "''",$text);
+}
+
+/**
+ * Lock a table.
+ */
+function db_lock_table($table) {
+  //TODO: should we put a NOWAIT clause ?
+  db_query('LOCK TABLE {%s} IN EXCLUSIVE MODE', $table);
+}
+
+/**
+ * Unlock all locked tables.
+ */
+function db_unlock_tables() {
+  db_query('COMMIT');
+}
+
+/**
+ * Checks if table exists and if so, drops it
+ */
+function _check_table_existance($tableName) {
+	$tableName = strtoupper($tableName);
+	$sql = 'SELECT table_name FROM user_tables WHERE table_name = \'' . $tableName . '\' ';
+	$result = db_query($sql);
+	$check = db_fetch_object($result);
+	if (is_array($check) && ($check->table_name == $tableName)) {
+		$sql = 'DROP TABLE ' . $tableName;
+		_db_query($sql);
+	}
+}
+
+// -- checkpoint 15 : Oracle version
+/**
+ * Check if a table exists.
+ */
+function db_table_exists($table) {
+  return db_num_rows(db_query("SELECT table_name FROM user_tables WHERE table_name LIKE UPPER('{" . db_escape_table($table) . "}')"));
+}
+// -- end 15
+
+// -- checkpoint 19 : drupal 6 func
+/**
+ * Check if a column exists in the given table.
+ */
+function db_column_exists($table, $column) {
+  return db_num_rows(db_query("SELECT column_name FROM user_tab_cols WHERE table_name LIKE UPPER('{". db_escape_table($table) ."}') AND column_name LIKE UPPER(TRIM('$column'))"));
+}
+// -- end 19
+
+// -- checkpoint 16 : Just copy the func from MySQL
+/**
+ * Wraps the given table.field entry with a DISTINCT(). The wrapper is added to
+ * the SELECT list entry of the given query and the resulting query is returned.
+ * This function only applies the wrapper if a DISTINCT doesn't already exist in
+ * the query.
+ *
+ * @param $table Table containing the field to set as DISTINCT
+ * @param $field Field to set as DISTINCT
+ * @param $query Query to apply the wrapper to
+ * @return SQL query with the DISTINCT wrapper surrounding the given table.field.
+ */
+function db_distinct_field($table, $field, $query) {
+  $field_to_select = 'DISTINCT('. $table .'.'. $field .')';
+  // (?<!text) is a negative look-behind (no need to rewrite queries that already use DISTINCT).
+  return preg_replace('/(SELECT.*)(?:'. $table .'\.|\s)(?<!DISTINCT\()(?<!DISTINCT\('. $table .'\.)'. $field .'(.*FROM )/AUsi', '\1 '. $field_to_select .'\2', $query);
+}
+// -- end 16
+
+/**
+ * @} End of "ingroup database".
+ */
+
+
+
+
+
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\includes\install.inc drupal-6.x-dev\includes\install.inc
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\includes\install.inc	Tue May 15 08:29:48 2007
+++ drupal-6.x-dev\includes\install.inc	Thu May 17 20:47:24 2007
@@ -144,7 +144,7 @@
 function drupal_detect_database_types() {
   $databases = array();
 
-  foreach (array('mysql', 'mysqli', 'pgsql') as $type) {
+  foreach (array('mysql', 'mysqli', 'pgsql', 'oracle') as $type) {
     if (file_exists('./includes/install.'. $type .'.inc')) {
       include_once './includes/install.'. $type .'.inc';
       $function = $type .'_is_available';
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\includes\install.oracle.inc drupal-6.x-dev\includes\install.oracle.inc
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\includes\install.oracle.inc	Wed Dec 31 16:00:00 1969
+++ drupal-6.x-dev\includes\install.oracle.inc	Thu May 17 21:34:38 2007
@@ -0,0 +1,160 @@
+<?php
+// $Id: install.oracle.inc,v 1.3 2007/04/13 08:56:57 dries Exp $
+
+// ORACLE specific install functions
+
+/**
+ * Check if oracle is available.
+ *
+ * @return
+ *  TRUE/FALSE
+ */
+function oracle_is_available() {
+  return function_exists('oci_connect');
+}
+
+/**
+ * Check if we can connect to Oracle.
+ *
+ * @return
+ *  TRUE/FALSE
+ */
+function drupal_test_oracle($url, &$success) {
+  return true;
+
+  if (!oracle_is_available()) {
+    drupal_set_message(st('PHP OCI8 support not enabled.'), 'error');
+    return FALSE;
+  }
+
+  $url = parse_url($url);
+
+  // Decode url-encoded information in the db connection string.
+  $url['user'] = urldecode($url['user']);
+  $url['pass'] = urldecode($url['pass']);
+  $url['host'] = urldecode($url['host']);
+  $url['path'] = urldecode($url['path']);
+
+  // Allow for non-standard Oracle port.
+  if (isset($url['port'])) {
+     $url['host'] = $url['host'] .':'. $url['port'];
+  }
+
+  $tmp_path = explode('/', substr($url['path'], 1));
+  $url['charset'] = $tmp_path[1];
+  $url['path'] = "/" . $tmp_path[0];
+
+  $conn_string = '//'.$url['host'].'/'.substr($url['path'], 1);
+//  $conn_string = ' user='. $url['user'] .' dbname='. substr($url['path'], 1) .' password='. $url['pass'] .' host='. $url['host'];
+//  $conn_string .= isset($url['port']) ? ' port='. $url['port'] : '';
+
+  // Test connecting to the database.
+  if (isset($url['charset']) && $url['charset']) {
+    $connection = @oci_connect($url['user'], $url['pass'], $conn_string, $url['charset']);
+  } else {
+    $connection = @oci_connect($url['user'], $url['pass'], $conn_string);
+  }
+  if (!$connection && ($error = oci_error())) {
+    drupal_set_message(st('Failure to connect to your Oracle database server. Oracle reports the following message: %error.<ul><li>Are you sure you have the correct username and password?</li><li>Are you sure that you have typed the correct database hostname?</li><li>Are you sure that the database server is running?</li><li>Are you sure you typed the correct database name?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.<br />Error: '.$error, array('%error' => 'Connection failed. See log file for failure reason')), 'error');
+    return FALSE;
+  }
+
+  $success = array('CONNECT');
+
+  // Test CREATE.
+  $query = 'CREATE TABLE drupal_install_test (id integer NOT NULL)';
+  $stmt = @OCIParse($connection, $query);
+  if (!$stmt && $error = oci_error($connection)) {
+    drupal_set_message(st('We were unable to create a test table on your Oracle database server with the command %query. Oracle reports the following message: %error.<ul><li>Are you sure the configured username has the necessary Oracle permissions to create tables in the database?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', array('%query' => $query, '%error' => $error)), 'error');
+    return FALSE;
+  }
+  $result = @OCIExecute($stmt);
+  if (!$result && ($error = oci_error($stmt))) {
+    drupal_set_message(st('We were unable to create a test table on your Oracle database server with the command %query. Oracle reports the following message: %error.<ul><li>Are you sure the configured username has the necessary Oracle permissions to create tables in the database?</li></ul>For more help, see the <a href="http://drupal.org/node/258">Installation and upgrading handbook</a>. If you are unsure what these terms mean you should probably contact your hosting provider.', array('%query' => $query, '%error' => $error)), 'error');
+    return FALSE;
+  }
+  $err = FALSE;
+  $success[] = 'SELECT';
+  $success[] = 'CREATE';
+
+  // Test INSERT.
+  $query = 'INSERT INTO drupal_install_test (id) VALUES (1)';
+  $stmt = @OCIParse($connection, $query);
+  $result = @OCIExecute($stmt);
+  if ($error = oci_error($stmt)) {
+    drupal_set_message(st('We were unable to insert a value into a test table on your Oracle database server. We tried inserting a value with the command %query and Oracle reported the following error: %error.', array('%query' => $query, '%error' => $error)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'INSERT';
+  }
+
+  // Test UPDATE.
+  $query = 'UPDATE drupal_install_test SET id = 2';
+  $stmt = @OCIParse($connection, $query);
+  $result = @OCIExecute($stmt);
+  if ($error = oci_error($stmt)) {
+    drupal_set_message(st('We were unable to update a value in a test table on your Oracle database server. We tried updating a value with the command %query and Oracle reported the following error: %error.', array('%query' => $query, '%error' => $error)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'UPDATE';
+  }
+
+  // Test LOCK.
+  $query = 'LOCK TABLE drupal_install_test IN EXCLUSIVE MODE';
+  $stmt = @OCIParse($connection, $query);
+  $result = @OCIExecute($stmt);
+  if ($error = oci_error($stmt)) {
+    drupal_set_message(st('We were unable to lock a test table on your Oracle database server. We tried locking a table with the command %query and Oracle reported the following error: %error.', array('%query' => $query, '%error' => $error)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'LOCK';
+  }
+
+  // Test UNLOCK, which is done automatically upon transaction end in Oracle
+  $query = 'COMMIT';
+  $stmt = @OCIParse($connection, $query);
+  $result = @OCIExecute($stmt);
+  if ($error = oci_error($stmt)) {
+    drupal_set_message(st('We were unable to unlock a test table on your Oracle database server. We tried unlocking a table with the command %query and Oracle reported the following error: %error.', array('%query' => $query, '%error' => $error)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'UNLOCK';
+  }
+
+  // Test DELETE.
+  $query = 'DELETE FROM drupal_install_test';
+  $result = pg_query($connection, $query);
+  $stmt = @OCIParse($connection, $query);
+  $result = @OCIExecute($stmt);
+  if ($error = oci_error($stmt)) {
+    drupal_set_message(st('We were unable to delete a value from a test table on your Oracle database server. We tried deleting a value with the command %query and Oracle reported the following error: %error.', array('%query' => $query, '%error' => $error)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'DELETE';
+  }
+
+  // Test DROP.
+  $query = 'DROP TABLE drupal_install_test';
+  $stmt = @OCIParse($connection, $query);
+  $result = @OCIExecute($stmt);
+  if ($error = oci_error($stmt)) {
+    drupal_set_message(st('We were unable to drop a test table from your Oracle database server. We tried dropping a table with the command %query and Oracle reported the following error %error.', array('%query' => $query, '%error' => $error)), 'error');
+    $err = TRUE;
+  }
+  else {
+    $success[] = 'DROP';
+  }
+
+  if ($err) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+?>
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\includes\menu.inc drupal-6.x-dev\includes\menu.inc
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\includes\menu.inc	Wed May 16 06:45:16 2007
+++ drupal-6.x-dev\includes\menu.inc	Mon May 21 02:04:40 2007
@@ -626,10 +626,11 @@
       }
       // LEFT JOIN since there is no match in {menu_router} for an external link.
       // No need to order by p6 - there is a sort by weight later.
-      list(, $tree[$menu_name]) = _menu_tree_data(db_query("
-        SELECT *, ml.weight + 50000 AS weight FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path
-        WHERE ml.menu_name = '%s' AND ml.plid IN (". $placeholders .")
-        ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC", $args), $parents);
+      // checkpoint 01 : write all field name instead of '*'
+//      $strSQL = "SELECT *, ml.weight + 50000 AS weight FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path WHERE ml.menu_name = '%s' AND ml.plid IN (". $placeholders .") ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC";
+      $strSQL = "SELECT m.*, ml.menu_name, ml.mlid, ml.plid, ml.href, ml.router_path, ml.hidden, ml.external, ml.has_children, ml.expanded, ml.weight + 50000 AS weight, ml.depth, ml.p1, ml.p2, ml.p3, ml.p4, ml.p5, ml.p6, ml.module, ml.link_title, ml.options FROM {menu_links} ml LEFT JOIN {menu_router} m ON m.path = ml.router_path WHERE ml.menu_name = '%s' AND ml.plid IN (". $placeholders .") ORDER BY p1 ASC, p2 ASC, p3 ASC, p4 ASC, p5 ASC";
+      // end 01
+      list(, $tree[$menu_name]) = _menu_tree_data(db_query($strSQL, $args), $parents);
 
       // TODO: cache_set() for the untranslated links
       // TODO: special case node links and access check via db_rewite_sql()
@@ -820,7 +821,9 @@
       return array();
     }
     // Get all tabs
-    $result = db_query("SELECT * FROM {menu_router} WHERE tab_root = '%s' AND tab_parent != '' ORDER BY weight, title", $router_item->tab_root);
+    // checkpoint 02: use NOT NULL instead of '!='
+    $result = db_query("SELECT * FROM {menu_router} WHERE tab_root = '%s' AND tab_parent IS NOT NULL ORDER BY weight, title", $router_item->tab_root);
+    // end 02
     $map = arg();
     $children = array();
     $tab_parent = array();
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\aggregator\aggregator.install drupal-6.x-dev\modules\aggregator\aggregator.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\aggregator\aggregator.install	Tue Sep 26 07:19:00 2006
+++ drupal-6.x-dev\modules\aggregator\aggregator.install	Thu May 17 23:30:18 2007
@@ -113,6 +113,106 @@
       db_query("CREATE INDEX {aggregator_item}_fid_idx ON {aggregator_item} (fid)");
 
       break;
+
+    case 'oracle':
+      
+      // -- Table structure for aggregator_category
+      db_query("CREATE TABLE {aggregator_category} (
+        cid         NUMBER                    NOT NULL,
+        title       VARCHAR2(255),
+        description VARCHAR2(4000),
+        block       NUMBER(5)       default 0 NOT NULL,
+        PRIMARY KEY (cid),
+        UNIQUE (title)
+      )");
+      db_query("CREATE SEQUENCE {aggregator_category}_cid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {aggregator_category}_be_in
+        BEFORE INSERT ON {aggregator_category}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.cid IS NULL THEN
+            SELECT {aggregator_category}_cid_seq.NEXTVAL
+            INTO :NEW.cid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for aggregator_category_feed
+      db_query("CREATE TABLE {aggregator_category_feed} (
+        fid NUMBER default 0 NOT NULL,
+        cid NUMBER default 0 NOT NULL,
+        PRIMARY KEY (fid,cid)
+      )");
+
+      // -- Table structure for aggregator_category_item
+      db_query("CREATE TABLE {aggregator_category_item} (
+        iid NUMBER default 0 NOT NULL,
+        cid NUMBER default 0 NOT NULL,
+        PRIMARY KEY (iid,cid)
+      )");
+
+      // -- Table structure for aggregator_feed
+      db_query("CREATE TABLE {aggregator_feed} (
+        fid         NUMBER                   NOT NULL,
+        title       VARCHAR2(255),
+        url         VARCHAR2(255),
+        refresh     NUMBER         default 0 NOT NULL,
+        checked     NUMBER         default 0 NOT NULL,
+        link        VARCHAR2(255),
+        description VARCHAR2(4000),
+        image       VARCHAR2(4000),
+        etag        VARCHAR2(255),
+        modified    NUMBER         default 0 NOT NULL,
+        block       NUMBER(5)      default 0 NOT NULL,
+        PRIMARY KEY (fid),
+        UNIQUE (url),
+        UNIQUE (title)
+      )");
+      db_query("CREATE SEQUENCE {aggregator_feed}_fid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {aggregator_feed}_be_in
+        BEFORE INSERT ON {aggregator_feed}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.fid IS NULL THEN
+            SELECT {aggregator_feed}_fid_seq.NEXTVAL
+            INTO :NEW.fid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+
+      // -- Table structure for aggregator_item
+      db_query("CREATE TABLE {aggregator_item} (
+        iid         NUMBER                    NOT NULL,
+        fid         NUMBER          default 0 NOT NULL,
+        title       VARCHAR2(255),
+        link        VARCHAR2(255),
+        author      VARCHAR2(255),
+        description VARCHAR2(4000),
+        timestamp   NUMBER,
+        guid        VARCHAR2(255),
+        PRIMARY KEY (iid)
+      )");
+      db_query("CREATE SEQUENCE {aggregator_item}_iid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {aggregator_item}_be_in
+        BEFORE INSERT ON {aggregator_item}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.iid IS NULL THEN
+            SELECT {aggregator_item}_iid_seq.NEXTVAL
+            INTO :NEW.iid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      break;
+
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\aggregator\aggregator.module drupal-6.x-dev\modules\aggregator\aggregator.module
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\aggregator\aggregator.module	Mon May 14 06:43:34 2007
+++ drupal-6.x-dev\modules\aggregator\aggregator.module	Mon May 21 00:23:34 2007
@@ -1080,7 +1080,9 @@
 
   drupal_add_feed(url('aggregator/rss/'. arg(2)), variable_get('site_name', 'Drupal') .' '. t('aggregator - @title', array('@title' => $category->title)));
 
-  return _aggregator_page_list('SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_category_item} c LEFT JOIN {aggregator_item} i ON c.iid = i.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE cid = '. $category->cid .' ORDER BY timestamp DESC, iid DESC', arg(3));
+  // checkpoint 01: column ambiguously defined(iid)
+  return _aggregator_page_list('SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_category_item} c LEFT JOIN {aggregator_item} i ON c.iid = i.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE cid = '. $category->cid .' ORDER BY timestamp DESC, i.iid DESC', arg(3));
+  // end 01
 }
 
 function aggregator_page_list($sql, $header, $categorize) {
@@ -1223,7 +1225,9 @@
     $category = db_fetch_object(db_query('SELECT cid, title FROM {aggregator_category} WHERE cid = %d', arg(2)));
     $url = '/categories/'. $category->cid;
     $title = ' '. t('in category') .' '. $category->title;
-    $sql = 'SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_category_item} c LEFT JOIN {aggregator_item} i ON c.iid = i.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE cid = %d ORDER BY timestamp DESC, iid DESC';
+    // checkpoint 02: column ambiguously defined(iid)
+    $sql = 'SELECT i.*, f.title AS ftitle, f.link AS flink FROM {aggregator_category_item} c LEFT JOIN {aggregator_item} i ON c.iid = i.iid LEFT JOIN {aggregator_feed} f ON i.fid = f.fid WHERE cid = %d ORDER BY timestamp DESC, i.iid DESC';
+    // end 02
     $result = db_query_range($sql, $category->cid, 0, variable_get('feed_default_items', 10));
   }
   // or, get the default aggregator items
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\block\block.module drupal-6.x-dev\modules\block\block.module
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\block\block.module	Mon May 14 06:53:02 2007
+++ drupal-6.x-dev\modules\block\block.module	Mon May 21 17:42:28 2007
@@ -295,7 +295,13 @@
 function block_admin_display_submit($form_values, $form, &$form_state) {
   foreach ($form_values as $block) {
     $block['status'] = $block['region'] != BLOCK_REGION_NONE;
-    $block['region'] = $block['status'] ? $block['region'] : '';
+    // checkpoint 01: give a 'left' for Oracle works
+    if ($GLOBALS['db_type'] == 'oracle') {
+      $block['region'] = $block['status'] ? $block['region'] : 'left';
+    } else {
+      $block['region'] = $block['status'] ? $block['region'] : '';
+    }
+    // end 01
     db_query("UPDATE {blocks} SET status = %d, weight = %d, region = '%s', throttle = %d WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $block['status'], $block['weight'], $block['region'], isset($block['throttle']) ? $block['throttle'] : 0, $block['module'], $block['delta'], $block['theme']);
   }
   drupal_set_message(t('The block settings have been updated.'));
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\book\book.install drupal-6.x-dev\modules\book\book.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\book\book.install	Fri Sep 01 00:40:08 2006
+++ drupal-6.x-dev\modules\book\book.install	Thu May 17 20:31:26 2007
@@ -29,6 +29,19 @@
       db_query("CREATE INDEX {book}_nid_idx ON {book} (nid)");
       db_query("CREATE INDEX {book}_parent_idx ON {book} (parent)");
       break;
+
+    case 'oracle':
+      // Table structure for book
+      db_query("CREATE TABLE {book} (
+        vid    NUMBER    default 0 NOT NULL,
+        nid    NUMBER    default 0 NOT NULL,
+        parent NUMBER    default 0 NOT NULL,
+        weight NUMBER(5) default 0 NOT NULL,
+        PRIMARY KEY (vid)
+      )");
+      db_query("CREATE INDEX {book}_idx_1 ON {book} (nid)");
+      db_query("CREATE INDEX {book}_idx_2 ON {book} (parent)");
+      break;
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\contact\contact.install drupal-6.x-dev\modules\contact\contact.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\contact\contact.install	Mon Jan 01 22:30:30 2007
+++ drupal-6.x-dev\modules\contact\contact.install	Thu May 17 23:31:06 2007
@@ -31,6 +31,32 @@
         UNIQUE (category)
       )");
       break;
+    case 'oracle':
+    // Table structre for table contact
+      db_query("CREATE TABLE {contact} (
+        cid         NUMBER                              NOT NULL,
+        category    VARCHAR2(255),
+        recipients  CLOB,
+        reply       CLOB,
+        weight      NUMBER(5)     default 0             NOT NULL,
+        selected    NUMBER(5)     default 0             NOT NULL,
+        PRIMARY KEY (cid),
+        UNIQUE (category)
+      )");
+      db_query("CREATE SEQUENCE {contact}_cid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {contact}_be_in
+        BEFORE INSERT ON {contact}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.cid IS NULL THEN
+            SELECT {contact}_cid_seq.NEXTVAL
+            INTO :NEW.cid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+      break;
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\dblog\dblog.install drupal-6.x-dev\modules\dblog\dblog.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\dblog\dblog.install	Tue Apr 24 06:53:12 2007
+++ drupal-6.x-dev\modules\dblog\dblog.install	Mon May 21 00:58:30 2007
@@ -44,6 +44,38 @@
 
 
       break;
+
+    case 'oracle':
+      // Table structure for watchdog
+      db_query('CREATE TABLE {watchdog} (
+        wid       NUMBER              NOT NULL,
+        "uid"     NUMBER    default 0 NOT NULL,
+        type      VARCHAR2(16),
+        message   VARCHAR2(4000),
+        variables VARCHAR2(4000),
+        severity  NUMBER(5) default 0 NOT NULL,
+        link      VARCHAR2(255),
+        location  CLOB,
+        referer   VARCHAR2(128),
+        hostname  VARCHAR2(128),
+        timestamp NUMBER    default 0 NOT NULL,
+        PRIMARY KEY (wid)
+      )');
+      db_query("CREATE INDEX {watchdog}_idx_1 ON {watchdog} (type)");
+      db_query("CREATE SEQUENCE {watchdog}_wid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {watchdog}_be_in
+        BEFORE INSERT ON {watchdog}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.wid IS NULL THEN
+            SELECT {watchdog}_wid_seq.NEXTVAL
+            INTO :NEW.wid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+      break;
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\dblog\dblog.module drupal-6.x-dev\modules\dblog\dblog.module
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\dblog\dblog.module	Mon May 14 06:43:36 2007
+++ drupal-6.x-dev\modules\dblog\dblog.module	Mon May 21 00:28:10 2007
@@ -196,7 +196,9 @@
     array('data' => t('Message'), 'field' => 'message')
   );
 
-  $result = pager_query("SELECT COUNT(wid) AS count, message, variables FROM {watchdog} WHERE type = '%s' GROUP BY message ". tablesort_sql($header), 30, 0, "SELECT COUNT(DISTINCT(message)) FROM {watchdog} WHERE type = '%s'", $type);
+  // checkpoint 01: variables not be GROUP BY
+  $result = pager_query("SELECT COUNT(wid) AS count, message, variables FROM {watchdog} WHERE type = '%s' GROUP BY (message,variables) ". tablesort_sql($header), 30, 0, "SELECT COUNT(DISTINCT(message)) FROM {watchdog} WHERE type = '%s'", $type);
+  // end 01
 
   $rows = array();
   while ($dblog = db_fetch_object($result)) {
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\drupal\drupal.install drupal-6.x-dev\modules\drupal\drupal.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\drupal\drupal.install	Fri Sep 01 00:40:08 2006
+++ drupal-6.x-dev\modules\drupal\drupal.install	Thu May 17 23:31:32 2007
@@ -53,6 +53,46 @@
         PRIMARY KEY (cid,name)
       )");
       break;
+
+    case 'oracle':
+      // Table structure for 'client'
+      db_query("CREATE TABLE {client} (
+        cid     NUMBER                              NOT NULL,
+        link    VARCHAR2(255),
+        name    VARCHAR2(128),
+        mail    VARCHAR2(128),
+        slogan  CLOB          DEFAULT EMPTY_CLOB()  NOT NULL,
+        mission CLOB          DEFAULT EMPTY_CLOB()  NOT NULL,
+        users   NUMBER        default 0             NOT NULL,
+        nodes   NUMBER        default 0             NOT NULL,
+        version VARCHAR2(35),
+        created NUMBER        default 0             NOT NULL,
+        changed NUMBER        default 0             NOT NULL,
+        PRIMARY KEY (cid)
+      )");
+      db_query("CREATE SEQUENCE {client}_cid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {client}_be_in
+        BEFORE INSERT ON {client}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.cid IS NULL THEN
+            SELECT {client}_cid_seq.NEXTVAL
+            INTO :NEW.cid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+  
+      // Table structure for 'client_system'
+      db_query("CREATE TABLE {client_system} (
+        cid   INTEGER        DEFAULT 0 NOT NULL,
+        name  VARCHAR2(255),
+        type  VARCHAR2(255),
+        PRIMARY KEY (cid,name)
+      )");
+      break;
+
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\forum\forum.install drupal-6.x-dev\modules\forum\forum.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\forum\forum.install	Fri Sep 01 00:40:08 2006
+++ drupal-6.x-dev\modules\forum\forum.install	Thu May 17 20:31:32 2007
@@ -27,6 +27,18 @@
       db_query("CREATE INDEX {forum}_nid_idx ON {forum} (nid)");
       db_query("CREATE INDEX {forum}_tid_idx ON {forum} (tid)");
       break;
+
+    case 'oracle':
+      // Table structure for 'forum'
+      db_query("CREATE TABLE {forum} (
+        nid NUMBER default 0 NOT NULL,
+        vid NUMBER default 0 NOT NULL,
+        tid NUMBER default 0 NOT NULL,
+        PRIMARY KEY (vid)
+      )");
+      db_query("CREATE INDEX {forum}_idx_1 ON {forum} (nid)");
+      db_query("CREATE INDEX {forum}_idx_2 ON {forum} (tid)");
+      break;
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\locale\locale.install drupal-6.x-dev\modules\locale\locale.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\locale\locale.install	Thu May 03 02:51:08 2007
+++ drupal-6.x-dev\modules\locale\locale.install	Fri May 18 01:45:54 2007
@@ -83,6 +83,61 @@
       db_query("CREATE INDEX {locales_target}_plural_idx ON {locales_target} (plural)");
       db_query("CREATE INDEX {locales_source}_source_idx ON {locales_source} (source)");
       break;
+
+    case 'oracle':
+      // Table structure for 'languages'
+      db_query("CREATE TABLE {languages} (
+        language  VARCHAR2(12),
+        name      VARCHAR2(64),
+        native    VARCHAR2(64),
+        direction INTEGER       DEFAULT 0 NOT NULL,
+        enabled   INTEGER       DEFAULT 0 NOT NULL,
+        plurals   INTEGER       DEFAULT 0 NOT NULL,
+        formula   VARCHAR2(128),
+        domain    VARCHAR2(128),
+        prefix    VARCHAR2(128),
+        weight    INTEGER       DEFAULT 0 NOT NULL,
+        PRIMARY KEY (language)
+      )");
+
+      // Table structure for 'locales_source'
+      db_query("CREATE TABLE {locales_source} (
+        lid       NUMBER        NOT NULL,
+        location  VARCHAR2(255),
+        textgroup VARCHAR2(255),
+        source    CLOB          NOT NULL,
+        PRIMARY KEY (lid)
+      )");
+      // cannot create index on expression with datatype LOB
+//      db_query("CREATE INDEX {locales_source}_idx_1 ON {locales_source} (source)");
+      db_query("CREATE SEQUENCE {locales_source}_lid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {locales_source}_be_in
+        BEFORE INSERT ON {locales_source}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.lid IS NULL THEN
+            SELECT {locales_source}_lid_seq.NEXTVAL
+            INTO :NEW.lid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // Table structure for 'locales_target'
+      db_query("CREATE TABLE {locales_target} (
+        lid         NUMBER(10)    default 0 NOT NULL,
+        translation CLOB,
+        language    VARCHAR2(12),
+        plid        NUMBER(10)    default 0 NOT NULL,
+        plural      NUMBER(10)    default 0 NOT NULL
+      )");
+      db_query("CREATE INDEX {locales_target}_idx_1 ON {locales_target} (lid)");
+      db_query("CREATE INDEX {locales_target}_idx_2 ON {locales_target} (language)");
+      db_query("CREATE INDEX {locales_target}_idx_3 ON {locales_target} (plid)");
+      db_query("CREATE INDEX {locales_target}_idx_4 ON {locales_target} (plural)");
+      break;
+
   }
   db_query("INSERT INTO {languages} (language, name, native, direction, enabled, weight) VALUES ('en', 'English', 'English', '0', '1', '0')");
 }
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\menu\menu.install drupal-6.x-dev\modules\menu\menu.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\menu\menu.install	Sun Apr 15 07:38:16 2007
+++ drupal-6.x-dev\modules\menu\menu.install	Thu May 17 20:31:34 2007
@@ -33,6 +33,21 @@
         PRIMARY KEY (path)
       )");
       break;
+
+    case 'oracle':
+      // Table structure for 'menu_custom'
+      db_query("CREATE TABLE {menu_custom} (
+        path        VARCHAR2(255),
+        disabled    INTEGER         DEFAULT 0 NOT NULL,
+        title       VARCHAR2(255),
+        description VARCHAR2(255),
+        weight      INTEGER         DEFAULT 0 NOT NULL,
+        type        INTEGER         DEFAULT 0 NOT NULL,
+        admin       INTEGER         DEFAULT 0 NOT NULL,
+        parent      VARCHAR2(255),
+        PRIMARY KEY (path)
+      )");
+      break;
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\node\node.module drupal-6.x-dev\modules\node\node.module
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\node\node.module	Wed May 16 06:45:16 2007
+++ drupal-6.x-dev\modules\node\node.module	Mon May 21 00:25:18 2007
@@ -1590,7 +1590,9 @@
 function node_admin_nodes() {
   $filter = node_build_filter_query();
 
-  $result = pager_query('SELECT n.*, u.name, u.uid FROM {node} n '. $filter['join'] .' INNER JOIN {users} u ON n.uid = u.uid '. $filter['where'] .' ORDER BY n.changed DESC', 50, 0, NULL, $filter['args']);
+  // checkpoint 01: 2 uid are selected
+  $result = pager_query('SELECT n.*, u.name FROM {node} n '. $filter['join'] .' INNER JOIN {users} u ON n.uid = u.uid '. $filter['where'] .' ORDER BY n.changed DESC', 50, 0, NULL, $filter['args']);
+  // end 01
 
   // Enable language column if locale is enabled or if we have any node with language
   $count = db_result(db_query("SELECT COUNT(*) FROM {node} n WHERE language != ''"));
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\poll\poll.install drupal-6.x-dev\modules\poll\poll.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\poll\poll.install	Fri Sep 01 00:40:08 2006
+++ drupal-6.x-dev\modules\poll\poll.install	Thu May 17 23:16:10 2007
@@ -64,6 +64,50 @@
       )");
       db_query("CREATE INDEX {poll_choices}_nid_idx ON {poll_choices} (nid)");
       break;
+
+    case 'oracle':
+      // Table structure for 'poll'
+      db_query("CREATE TABLE {poll} (
+        nid     NUMBER default 0 NOT NULL,
+        runtime NUMBER default 0 NOT NULL,
+        active  NUMBER default 0 NOT NULL,
+        PRIMARY KEY (nid)
+      )");
+
+      // Table structure for 'poll_votes'
+      db_query('CREATE TABLE {poll_votes} (
+        nid       INTEGER             NOT NULL,
+        "uid"     INTEGER default 0   NOT NULL,
+        chorder   INTEGER DEFAULT -1  NOT NULL,
+        hostname  VARCHAR2(128)
+      )');
+      db_query("CREATE INDEX {poll_votes}_idx_1 ON {poll_votes} (nid)");
+      db_query("CREATE INDEX {poll_votes}_idx_2 ON {poll_votes} (uid)");
+      db_query("CREATE INDEX {poll_votes}_idx_3 ON {poll_votes} (hostname)");
+
+      // Table structure for 'poll_choices'
+      db_query("CREATE TABLE {poll_choices} (
+        chid    NUMBER            NOT NULL,
+        nid     NUMBER  default 0 NOT NULL,
+        chtext  VARCHAR2(128),
+        chvotes NUMBER  default 0 NOT NULL,
+        chorder NUMBER  default 0 NOT NULL,
+        PRIMARY KEY (chid)
+      )");
+      db_query("CREATE INDEX {poll_choices}_idx_1 ON {poll_choices} (nid)");
+      db_query("CREATE SEQUENCE {poll_choices}_chid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {poll_choices}_be_in
+        BEFORE INSERT ON {poll_choices}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.chid IS NULL THEN
+            SELECT {poll_choices}_chid_seq.NEXTVAL
+            INTO :NEW.chid
+            FROM dual;
+          END IF;
+        END"
+      );
+      break;
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\profile\profile.install drupal-6.x-dev\modules\profile\profile.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\profile\profile.install	Tue Nov 28 07:37:44 2006
+++ drupal-6.x-dev\modules\profile\profile.install	Thu May 17 23:32:30 2007
@@ -64,6 +64,50 @@
       db_query("CREATE INDEX {profile_values}_uid_idx ON {profile_values} (uid)");
       db_query("CREATE INDEX {profile_values}_fid_idx ON {profile_values} (fid)");
       break;
+
+    case 'oracle':
+      // Table structure for 'profile_fields'
+      db_query("CREATE TABLE {profile_fields} (
+        fid           NUMBER                    NOT NULL,
+        title         VARCHAR2(255) default NULL,
+        name          VARCHAR2(128) default NULL,
+        explanation   CLOB          default EMPTY_CLOB(),
+        category      VARCHAR2(255) default NULL,
+        page          VARCHAR2(255) default NULL,
+        type          VARCHAR2(128) default NULL,
+        weight        NUMBER(5)     DEFAULT 0   NOT NULL,
+        required      NUMBER(5)     DEFAULT 0   NOT NULL,
+        register      NUMBER(5)     DEFAULT 0   NOT NULL,
+        visibility    NUMBER(5)     DEFAULT 0   NOT NULL,
+        autocomplete  NUMBER(5)     DEFAULT 0   NOT NULL,
+        options     CLOB,
+        UNIQUE (name),
+        PRIMARY KEY (fid)
+      )");
+      db_query("CREATE INDEX {profile_fields}_idx_1 ON {profile_fields} (category)");
+      db_query("CREATE SEQUENCE {profile_fields}_fid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {profile_fields}_be_in
+        BEFORE INSERT ON {profile_fields}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.fid IS NULL THEN
+            SELECT {profile_fields}_fid_seq.NEXTVAL
+            INTO :NEW.fid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // Table structure for 'profile_values'
+      db_query('CREATE TABLE {profile_values} (
+        fid   NUMBER default '0',
+        "uid" NUMBER default '0',
+        value CLOB
+      )');
+      db_query("CREATE INDEX {profile_values}_idx_1 ON {profile_values} (uid)");
+      db_query("CREATE INDEX {profile_values}_idx_2 ON {profile_values} (fid)");
+      break;
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\search\search.install drupal-6.x-dev\modules\search\search.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\search\search.install	Fri Sep 01 00:40:08 2006
+++ drupal-6.x-dev\modules\search\search.install	Thu May 17 20:31:40 2007
@@ -59,6 +59,36 @@
         PRIMARY KEY (word)
       )");
       break;
+
+    case 'oracle':
+      // Table structure for 'search_dataset'
+      db_query("CREATE TABLE {search_dataset} (
+        sid   NUMBER        default 0 NOT NULL,
+        type  VARCHAR2(16)  default NULL,
+        data CLOB
+      )");
+      db_query("CREATE INDEX {search_dataset}_idx_1 ON {search_dataset} (sid, type)");
+
+      // Table structure for 'search_index'
+      db_query("CREATE TABLE {search_index} (
+        word      VARCHAR2(50),
+        sid       NUMBER        default 0 NOT NULL,
+        type      VARCHAR2(16),
+        fromsid   NUMBER        default 0 NOT NULL,
+        fromtype  VARCHAR2(16),
+        score     float         default NULL
+      )");
+      db_query("CREATE INDEX {search_index}_idx_1 ON {search_index} (sid, type)");
+      db_query("CREATE INDEX {search_index}_idx_2 ON {search_index} (fromsid, fromtype)");
+      db_query("CREATE INDEX {search_index}_idx_3 ON {search_index} (word)");
+
+      // Table structure for 'search_total'
+      db_query("CREATE TABLE {search_total} (
+        word  VARCHAR2(50),
+        count float default NULL,
+        PRIMARY KEY(word)
+      )");
+      break;
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\statistics\statistics.install drupal-6.x-dev\modules\statistics\statistics.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\statistics\statistics.install	Tue Nov 07 15:27:08 2006
+++ drupal-6.x-dev\modules\statistics\statistics.install	Thu May 17 23:32:54 2007
@@ -37,6 +37,36 @@
       )");
       db_query("CREATE INDEX {accesslog}_accesslog_timestamp_idx ON {accesslog} (timestamp)");
       break;
+
+    case 'oracle':
+      // Table structure for 'accesslog'
+      db_query('CREATE TABLE {accesslog} (
+        aid       NUMBER                   NOT NULL,
+        sid       VARCHAR2(64),
+        title     VARCHAR2(255),
+        path      VARCHAR2(255),
+        url       VARCHAR2(255),
+        hostname  VARCHAR2(128),
+        "uid"     NUMBER         default 0 NOT NULL,
+        timer     NUMBER         default 0 NOT NULL,
+        timestamp NUMBER         default 0 NOT NULL,
+        PRIMARY KEY (aid)
+      )');
+      db_query("CREATE INDEX {accesslog}_idx_1 ON {accesslog} (timestamp)");
+      db_query("CREATE SEQUENCE {accesslog}_aid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {accesslog}_be_in
+        BEFORE INSERT ON {accesslog}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.aid IS NULL THEN
+            SELECT {accesslog}_aid_seq.NEXTVAL
+            INTO :NEW.aid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+      break;
   }
 }
 
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\system\system.install drupal-6.x-dev\modules\system\system.install
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\system\system.install	Wed May 16 07:41:38 2007
+++ drupal-6.x-dev\modules\system\system.install	Sun May 20 21:46:08 2007
@@ -896,7 +896,7 @@
       db_query("CREATE INDEX {menu_router}_fit_idx ON {menu_router} (fit)");
       db_query("CREATE INDEX {menu_router}_tab_parent_idx ON {menu_router} (tab_parent)");
 
-      db_query("CREATE TABLE {menu_link} (
+      db_query("CREATE TABLE {menu_links} (
         menu_name varchar(64) NOT NULL default '',
         mlid int NOT NULL default '0',
         plid int NOT NULL default '0',
@@ -919,9 +919,9 @@
         options text,
         PRIMARY KEY (mlid)
       )");
-      db_query("CREATE INDEX {menu_link}_parents_idx ON {menu_link} (plid, p1, p2, p3, p4, p5)");
-      db_query("CREATE INDEX {menu_link}_menu_name_idx ON {menu_link} (menu_name, href)");
-      db_query("CREATE INDEX {menu_link}_expanded_children_idx ON {menu_link} (expanded, has_children)");
+      db_query("CREATE INDEX {menu_links}_parents_idx ON {menu_links} (plid, p1, p2, p3, p4, p5)");
+      db_query("CREATE INDEX {menu_links}_menu_name_idx ON {menu_links} (menu_name, href)");
+      db_query("CREATE INDEX {menu_links}_expanded_children_idx ON {menu_links} (expanded, has_children)");
 
       db_query("CREATE TABLE {node} (
         nid serial CHECK (nid >= 0),
@@ -1174,6 +1174,849 @@
         type varchar(32) NOT NULL DEFAULT '',
         PRIMARY KEY (vid, type)
       )");
+
+      break;
+
+    case 'oracle':
+      
+      /************************************/ 
+      /*      Function for Oracle         */
+      /************************************/
+
+      db_query("CREATE OR REPLACE FUNCTION from_unixtime(sttTime number)
+        RETURN date IS
+        BEGIN
+          RETURN to_date(19700101, 'yyyymmdd') + sttTime/24/60/60;
+        END
+        ;
+      ");
+
+      db_query("CREATE OR REPLACE FUNCTION to_unixtime(oracleDate date)
+        RETURN number IS
+        BEGIN
+          RETURN (oracleDate - to_date(19700101, 'yyyymmdd'))*24*60*60;
+        END
+        ;
+      ");
+
+      db_query("CREATE OR REPLACE FUNCTION POW(base_num IN number, pow_num IN number)
+        RETURN number IS
+        BEGIN
+          RETURN POWER(base_num, pow_num);
+        END
+        ;
+      ");
+
+    
+      /************************************/ 
+      /*       Tables for Oracle          */
+      /************************************/
+
+      // -- Table structure for access
+      db_query("CREATE TABLE {access} (
+        aid    NUMBER                  NOT NULL,
+        mask   VARCHAR2(255),
+        type   VARCHAR2(255),
+        status NUMBER(5)     default 0 NOT NULL,
+        PRIMARY KEY (aid)
+      )");
+      db_query("CREATE SEQUENCE {access}_aid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {access}_be_in
+        BEFORE INSERT ON {access}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.aid IS NULL THEN
+            SELECT {access}_aid_seq.NEXTVAL
+            INTO :NEW.aid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+        // -- Table structure for authmap
+
+      db_query('CREATE TABLE {authmap} (
+        aid      NUMBER                  NOT NULL,
+        "uid"    NUMBER        default 0 NOT NULL,
+        authname VARCHAR2(128),
+        module   VARCHAR2(128),
+        PRIMARY KEY (aid),
+        UNIQUE (authname)
+      )');
+      db_query("CREATE SEQUENCE {authmap}_aid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {authmap}_be_in
+        BEFORE INSERT ON {authmap}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.aid IS NULL THEN
+            SELECT {authmap}_aid_seq.NEXTVAL
+            INTO :NEW.aid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for batch - 6.x new table
+      db_query('CREATE TABLE {batch} (
+        bid       NUMBER                   NOT NULL,
+        token     VARCHAR2(64),
+        timestamp INTEGER        default 0 NOT NULL,
+        batch     CLOB,
+        PRIMARY KEY (bid)
+      )');
+      db_query("CREATE INDEX {batch}_idx ON {batch}(token)");
+      db_query("CREATE SEQUENCE {batch}_bid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {batch}_be_in
+        BEFORE INSERT ON {batch}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.bid IS NULL THEN
+            SELECT {batch}_bid_seq.NEXTVAL
+            INTO :NEW.bid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for blocks
+      db_query("CREATE TABLE {blocks} (
+        bid        NUMBER                             NOT NULL,
+        module     VARCHAR2(64)                       NOT NULL,
+        delta      VARCHAR2(32)  default 0            NOT NULL,
+        theme      VARCHAR2(255),
+        status     NUMBER(5)     default 0            NOT NULL,
+        weight     NUMBER(5)     default 0            NOT NULL,
+        region     VARCHAR2(64)  DEFAULT 'left'       NOT NULL,
+        custom     NUMBER(5)     default 0            NOT NULL,
+        throttle   NUMBER(5)     default 0            NOT NULL,
+        visibility NUMBER(5)     default 0            NOT NULL,
+        pages      CLOB          default EMPTY_CLOB() NOT NULL,
+        title      VARCHAR2(64),
+        PRIMARY KEY (bid)
+      )");
+      db_query("CREATE SEQUENCE {blocks}_bid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {blocks}_be_in
+        BEFORE INSERT ON {blocks}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.bid IS NULL THEN
+            SELECT {blocks}_bid_seq.NEXTVAL
+            INTO :NEW.bid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for boxes
+      db_query("CREATE TABLE {boxes} (
+        bid    NUMBER                  NOT NULL,
+        body   CLOB,
+        info   VARCHAR2(128),
+        format NUMBER(5)     default 0 NOT NULL,
+        PRIMARY KEY (bid),
+        UNIQUE (info)
+      )");
+      db_query("CREATE SEQUENCE {boxes}_bid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {boxes}_be_in
+        BEFORE INSERT ON {boxes}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.bid IS NULL THEN
+            SELECT {boxes}_bid_seq.NEXTVAL
+            INTO :NEW.bid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for cache
+      db_query("CREATE TABLE {cache} (
+        cid         VARCHAR2(255)                       NOT NULL,
+        data        CLOB          default EMPTY_CLOB(),
+        expire      NUMBER        default 0             NOT NULL,
+        created     NUMBER        default 0             NOT NULL,
+        headers     CLOB          default EMPTY_CLOB(),
+        serialized  NUMBER(5)     DEFAULT 0             NOT NULL,
+        PRIMARY KEY (cid)
+      )");
+      db_query("CREATE INDEX {cache}_idx ON {cache}(expire)");
+
+      // -- Table structure for cache_filter
+      db_query("CREATE TABLE {cache_filter} (
+        cid         VARCHAR2(255)                       NOT NULL,
+        data        CLOB          default EMPTY_CLOB(),
+        expire      NUMBER        default 0             NOT NULL,
+        created     NUMBER        default 0             NOT NULL,
+        headers     CLOB          default EMPTY_CLOB(),
+        serialized  NUMBER(5)     DEFAULT 0             NOT NULL,
+        PRIMARY KEY (cid)
+      )");
+      db_query("CREATE INDEX {cache_filter}_idx ON {cache_filter}(expire)");
+      
+      // -- Table structure for cache_page
+      db_query("CREATE TABLE {cache_page} (
+        cid         VARCHAR2(255)                       NOT NULL,
+        data        CLOB          default EMPTY_CLOB(),
+        expire      NUMBER        default 0             NOT NULL,
+        created     NUMBER        default 0             NOT NULL,
+        headers     CLOB          default EMPTY_CLOB(),
+        serialized  NUMBER(5)     DEFAULT 0             NOT NULL,
+        PRIMARY KEY (cid)
+      )");
+      db_query("CREATE INDEX {cache_page}_idx ON {cache_page}(expire)");
+
+      // -- Table structure for cache_form 6.x New table
+      db_query("CREATE TABLE {cache_form} (
+        cid         VARCHAR2(255)                       NOT NULL,
+        data        CLOB          default EMPTY_CLOB(),
+        expire      NUMBER        default 0             NOT NULL,
+        created     NUMBER        default 0             NOT NULL,
+        headers     CLOB          default EMPTY_CLOB(),
+        serialized  NUMBER(5)     DEFAULT 0             NOT NULL,
+        PRIMARY KEY (cid)
+      )");
+      db_query("CREATE INDEX {cache_form}_idx ON {cache_form}(expire)");
+
+      // -- Table structure for comments
+      db_query("CREATE TABLE {comments} (
+        cid       NUMBER                              NOT NULL,
+        pid       NUMBER        default 0             NOT NULL,
+        nid       NUMBER        default 0             NOT NULL,
+        \"uid\"     NUMBER        default 0             NOT NULL,
+        subject   VARCHAR2(64),
+        \"comment\" CLOB          default EMPTY_CLOB(),
+        hostname  VARCHAR2(128),
+        timestamp NUMBER        default 0             NOT NULL,
+        score     NUMBER        default 0             NOT NULL,
+        status    NUMBER(5)     default 0             NOT NULL,
+        format    NUMBER(5)     default 0             NOT NULL,
+        thread    VARCHAR2(255) default '',
+        users     CLOB          default EMPTY_CLOB(),
+        name      VARCHAR2(60)  default NULL,
+        mail      VARCHAR2(64)  default NULL,
+        homepage  VARCHAR2(255) default NULL,
+        PRIMARY KEY (cid)
+      )");
+      db_query("CREATE INDEX {comments}_idx_1 ON {comments}(nid)");
+      db_query("CREATE INDEX {comments}_idx_2 ON {comments}(status)");
+      db_query("CREATE SEQUENCE {comments}_cid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {comments}_be_in
+        BEFORE INSERT ON {comments}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.cid IS NULL THEN
+            SELECT {comments}_cid_seq.NEXTVAL
+            INTO :NEW.cid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for node_comment_statistics
+      db_query('CREATE TABLE {node_comment_statistics} (
+        nid                     NUMBER                  NOT NULL,
+        last_comment_timestamp  NUMBER        default 0 NOT NULL,
+        last_comment_name       VARCHAR2(60),
+        last_comment_uid        NUMBER        default 0 NOT NULL,
+        comment_count           NUMBER        default 0 NOT NULL,
+        PRIMARY KEY (nid)
+      )');
+// ORA: Index name changed because identifiers can only be 31 charecters long
+      db_query("CREATE INDEX {node_comment_stat}_idx_1 ON {node_comment_statistics}(last_comment_timestamp)");
+      db_query("CREATE SEQUENCE {node_comment_stat}_nid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {node_comment_stat}_be_in
+        BEFORE INSERT ON {node_comment_statistics}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.nid IS NULL THEN
+            SELECT {node_comment_stat}_nid_seq.NEXTVAL
+            INTO :NEW.nid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for files
+      db_query('CREATE TABLE {files} (
+        fid       NUMBER          default 0 NOT NULL,
+        nid       NUMBER          default 0 NOT NULL,
+        filename  VARCHAR2(255),
+        filepath  VARCHAR2(255),
+        filemime  VARCHAR2(255),
+        filesize  NUMBER          default 0 NOT NULL,
+        PRIMARY KEY (fid)
+      )');
+      db_query("CREATE INDEX {files}_idx_1 ON {files}(nid)");
+      db_query("CREATE SEQUENCE {files}_fid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {files}_be_in
+        BEFORE INSERT ON {files}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.fid IS NULL THEN
+            SELECT {files}_fid_seq.NEXTVAL
+            INTO :NEW.fid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for file_revisions
+      db_query('CREATE TABLE {file_revisions} (
+        fid       NUMBER          default 0 NOT NULL,
+        vid       NUMBER          default 0 NOT NULL,
+        description  VARCHAR2(255),
+        list      NUMBER          default 0 NOT NULL,
+        PRIMARY KEY (fid, vid)
+      )');
+      db_query("CREATE INDEX {file_revisions}_idx_1 ON {file_revisions}(vid)");
+  
+      // -- Table structure for filter_formats
+      db_query('CREATE TABLE {filter_formats} (
+        format  NUMBER                  NOT NULL,
+        name    VARCHAR2(255),
+        roles   VARCHAR2(255),
+        cache   NUMBER(5)     default 0 NOT NULL,
+        PRIMARY KEY (format),
+        UNIQUE (name)
+      )');
+      db_query("CREATE SEQUENCE {filter_formats}_format_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {filter_formats}_be_in
+        BEFORE INSERT ON {filter_formats}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.format IS NULL THEN
+            SELECT {filter_formats}_format_seq.NEXTVAL
+            INTO :NEW.format
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+
+      // -- Table structure for filters
+      db_query('CREATE TABLE {filters} (
+        fid     NUMBER              NOT NULL,
+        format  NUMBER    default 0 NOT NULL,
+        module  VARCHAR2(64),
+        delta   NUMBER(5) default 0 NOT NULL,
+        weight  NUMBER(5) DEFAULT 0 NOT NULL,
+        PRIMARY KEY (fid)
+      )');
+      db_query("CREATE INDEX {filters}_idx_1 ON {filters}(weight)");
+      db_query("CREATE SEQUENCE {filters}_fid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {filters}_be_in
+        BEFORE INSERT ON {filters}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.fid IS NULL THEN
+            SELECT {filters}_fid_seq.NEXTVAL
+            INTO :NEW.fid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for flood
+      db_query('CREATE TABLE {flood} (
+        fid       NUMBER                  NOT NULL,
+        event     VARCHAR2(64),
+        hostname  VARCHAR2(128),
+        timestamp NUMBER        default 0 NOT NULL,
+        PRIMARY KEY (fid)
+      )');
+      db_query("CREATE SEQUENCE {flood}_fid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {flood}_be_in
+        BEFORE INSERT ON {flood}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.fid IS NULL THEN
+            SELECT {flood}_fid_seq.NEXTVAL
+            INTO :NEW.fid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for history
+      db_query('CREATE TABLE {history} (
+        "uid"     NUMBER default 0 NOT NULL,
+        nid       NUMBER default 0 NOT NULL,
+        timestamp NUMBER default 0 NOT NULL,
+        PRIMARY KEY ("uid",nid)
+      )');
+
+      // CHECKING POINT 2007-05-17-1804
+      // -- Table structure for menu_router - 6.x new table
+      db_query('CREATE TABLE {menu_router} (
+        path              VARCHAR2(255),
+        load_functions    VARCHAR2(255),
+        to_arg_functions  VARCHAR2(255),
+        access_callback   VARCHAR2(255),
+        access_arguments  CLOB,
+        page_callback     VARCHAR2(255),
+        page_arguments    CLOB,
+        fit               INTEGER       DEFAULT 0 NOT NULL,
+        number_parts      INTEGER       DEFAULT 0 NOT NULL,
+        tab_parent        varchar(255),
+        tab_root          varchar(255),
+        title             VARCHAR2(255),
+        title_callback    VARCHAR2(255),
+        title_arguments   VARCHAR2(255),
+        type              INTEGER       DEFAULT 0 NOT NULL,
+        block_callback    VARCHAR2(255),
+        description       VARCHAR2(255),
+        position          VARCHAR2(255),
+        weight            INTEGER       DEFAULT 0 NOT NULL,
+        PRIMARY KEY (path)
+      )');
+      db_query("CREATE INDEX {menu_router}_idx_1 ON {menu_router}(fit)");
+      db_query("CREATE INDEX {menu_router}_idx_2 ON {menu_router}(tab_parent)");
+
+      // -- Table structure for menu - 6.x new table
+      db_query('CREATE TABLE {menu_links} (
+        menu_name         VARCHAR2(64),
+        mlid              NUMBER                  NOT NULL,
+        plid              NUMBER        default 0 NOT NULL,
+        href              VARCHAR2(255),
+        router_path       VARCHAR2(255),
+        hidden            INTEGER       default 0 NOT NULL,
+        external          INTEGER       default 0 NOT NULL,
+        has_children      INTEGER       DEFAULT 0 NOT NULL,
+        expanded          INTEGER       DEFAULT 0 NOT NULL,
+        weight            INTEGER       DEFAULT 0 NOT NULL,
+        depth             INTEGER       DEFAULT 0 NOT NULL,
+        p1                INTEGER       DEFAULT 0 NOT NULL,
+        p2                INTEGER       DEFAULT 0 NOT NULL,
+        p3                INTEGER       DEFAULT 0 NOT NULL,
+        p4                INTEGER       DEFAULT 0 NOT NULL,
+        p5                INTEGER       DEFAULT 0 NOT NULL,
+        p6                INTEGER       DEFAULT 0 NOT NULL,
+        module            VARCHAR2(255),
+        link_title        VARCHAR2(255),
+        options           CLOB,
+        PRIMARY KEY (mlid)
+      )');
+      db_query("CREATE INDEX {menu_links}_idx_1 ON {menu_links}(plid, p1, p2, p3, p4, p5)");
+      db_query("CREATE INDEX {menu_links}_idx_2 ON {menu_links}(menu_name, href)");
+      db_query("CREATE INDEX {menu_links}_idx_3 ON {menu_links}(expanded, has_children)");
+
+      db_query("CREATE SEQUENCE {menu_links}_mlid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {menu_links}_be_in
+        BEFORE INSERT ON {menu_links}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.mlid IS NULL THEN
+            SELECT {menu_links}_mlid_seq.NEXTVAL
+            INTO :NEW.mlid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      
+      // -- Table structure for node
+      db_query('CREATE TABLE {node} (
+        nid       NUMBER                  NOT NULL,
+        vid       NUMBER        default 0 NOT NULL,
+        type      VARCHAR2(32),
+        language  VARCHAR2(12),
+        title     VARCHAR2(128),
+        "uid"     NUMBER        default 0 NOT NULL,
+        status    NUMBER        default 1 NOT NULL,
+        created   NUMBER        default 0 NOT NULL,
+        changed   NUMBER        default 0 NOT NULL,
+        "comment" NUMBER        default 0 NOT NULL,
+        promote   NUMBER        default 0 NOT NULL,
+        moderate  NUMBER        default 0 NOT NULL,
+        sticky    NUMBER        default 0 NOT NULL,
+        PRIMARY KEY (nid),
+        UNIQUE (nid, vid),
+        UNIQUE (vid)
+      )');
+      db_query("CREATE INDEX {node}_idx_1 ON {node}(type)");
+      db_query("CREATE INDEX {node}_idx_2 ON {node}(title,type)");
+      db_query("CREATE INDEX {node}_idx_3 ON {node}(status)");
+      db_query('CREATE INDEX {node}_idx_4 ON {node}("uid")');
+      db_query("CREATE INDEX {node}_idx_5 ON {node}(moderate)");
+      db_query('CREATE INDEX {node}_idx_6 ON {node}(promote, status)');
+      db_query("CREATE INDEX {node}_idx_7 ON {node}(created)");
+      db_query('CREATE INDEX {node}_idx_8 ON {node}(changed)');
+      db_query("CREATE INDEX {node}_idx_9 ON {node}(status,type,nid)");
+      db_query("CREATE SEQUENCE {node}_nid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {node}_be_in
+        BEFORE INSERT ON {node}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.nid IS NULL THEN
+            SELECT {node}_nid_seq.NEXTVAL
+            INTO :NEW.nid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for node_access
+      db_query('CREATE TABLE {node_access} (
+        nid           NUMBER        DEFAULT 0 NOT NULL,
+        gid           NUMBER        default 0 NOT NULL,
+        realm         VARCHAR2(255),
+        grant_view    NUMBER(5)     default 0 NOT NULL,
+        grant_update  NUMBER(5)     default 0 NOT NULL,
+        grant_delete  NUMBER(5)     default 0 NOT NULL,
+        PRIMARY KEY (nid,gid,realm)
+      )');
+
+      // CHECKING POINT 2007-05-17-1817
+      // -- Table structure for node_revisions
+      db_query('CREATE TABLE {node_revisions} (
+        nid       NUMBER                  NOT NULL,
+        vid       NUMBER                  NOT NULL,
+        "uid"     NUMBER        default 0 NOT NULL,
+        title     VARCHAR2(128),
+        body      CLOB,
+        teaser    CLOB,
+        log       CLOB,
+        timestamp NUMBER          default 0 NOT NULL,
+        format    int             default 0 NOT NULL,
+        PRIMARY KEY  (vid)
+      )');
+      db_query("CREATE INDEX {node_revisions}_idx_1 ON {node_revisions}(nid)");
+      db_query('CREATE INDEX {node_revisions}_idx_2 ON {node_revisions}("uid")');
+
+      // -- Table structure for table node_type
+      db_query('CREATE TABLE {node_type} (
+        type            VARCHAR2(32)      NOT NULL,
+        name            VARCHAR2(255),
+        module          VARCHAR2(255),
+        description     CLOB DEFAULT EMPTY_CLOB(),
+        help            CLOB DEFAULT EMPTY_CLOB(),
+        has_title       INTEGER           NOT NULL,
+        title_label     VARCHAR2(255),
+        has_body        INTEGER           NOT NULL,
+        body_label      VARCHAR2(255),
+        min_word_count  INTEGER           NOT NULL,
+        custom          INTEGER DEFAULT 0 NOT NULL,
+        modified        INTEGER DEFAULT 0 NOT NULL,
+        locked          INTEGER DEFAULT 0 NOT NULL,
+        orig_type       VARCHAR2(255),
+        PRIMARY KEY (type)
+      )');
+
+      // -- Table structure for table url_alias
+      db_query('CREATE TABLE {url_alias} (
+        pid       NUMBER        NOT NULL,
+        src       VARCHAR2(128),
+        dst       VARCHAR2(128),
+        language  VARCHAR2(12),
+        PRIMARY KEY (pid),
+        UNIQUE (dst,language)
+      )');
+      db_query('CREATE INDEX {url_alias}_idx_1 ON {url_alias}(src)');
+      db_query("CREATE SEQUENCE {url_alias}_pid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {url_alias}_be_in
+        BEFORE INSERT ON {url_alias}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.pid IS NULL THEN
+            SELECT {url_alias}_pid_seq.NEXTVAL
+            INTO :NEW.pid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for permission
+      db_query('CREATE TABLE {permission} (
+        pid   NUMBER            NOT NULL,
+        rid   NUMBER  default 0 NOT NULL,
+        perm  CLOB,
+        tid   NUMBER  default 0 NOT NULL,
+        PRIMARY KEY (pid)
+      )');
+      db_query('CREATE INDEX {permission}_idx_1 ON {permission}(rid)');
+      db_query("CREATE SEQUENCE {permission}_pid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {permission}_be_in
+        BEFORE INSERT ON {permission}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.pid IS NULL THEN
+            SELECT {permission}_pid_seq.NEXTVAL
+            INTO :NEW.pid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for role
+      db_query('CREATE TABLE {role} (
+        rid NUMBER NOT NULL,
+        name VARCHAR2(64),
+        PRIMARY KEY (rid),
+        UNIQUE (name)
+      )');
+      db_query("CREATE SEQUENCE {role}_rid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {role}_be_in
+        BEFORE INSERT ON {role}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.rid IS NULL THEN
+            SELECT {role}_rid_seq.NEXTVAL
+            INTO :NEW.rid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for blocks_roles
+      db_query('CREATE TABLE {blocks_roles} (
+        module  VARCHAR2(64)    NOT NULL,
+        delta   VARCHAR2(32)    NOT NULL,
+        rid     INTEGER         NOT NULL,
+        PRIMARY KEY (module, delta, rid)
+      )');
+
+      // -- Table structure for sessions
+      db_query('CREATE TABLE {sessions} (
+        "uid"     NUMBER not null,
+        sid       VARCHAR2(64),
+        hostname  VARCHAR2(128),
+        timestamp NUMBER default 0 NOT NULL,
+        cache     NUMBER default 0 NOT NULL,
+        "session" CLOB,
+        PRIMARY KEY (sid)
+      )');
+      db_query('CREATE INDEX {sessions}_idx_1 ON {sessions}("uid")');
+      db_query('CREATE INDEX {sessions}_idx_2 ON {sessions}(timestamp)');
+
+/* Only used for MySQL
+      db_query("CREATE TABLE {sequences} (
+        name  VARCHAR2(128),
+        id    NUMBER default 0 NOT NULL,
+        PRIMARY KEY (name)
+      )"); */
+
+      // -- Table structure for node_counter
+      db_query('CREATE TABLE {node_counter} (
+        nid         NUMBER default 0 NOT NULL,
+        totalcount  NUMBER default 0 NOT NULL,
+        daycount    NUMBER default 0 NOT NULL,
+        timestamp   NUMBER default 0 NOT NULL,
+        PRIMARY KEY (nid)
+      )');
+
+      // -- Table structure for system
+      db_query('CREATE TABLE {system} (
+        filename        VARCHAR2(255),
+        name            VARCHAR2(255),
+        type            VARCHAR2(255),
+        owner           VARCHAR2(255),
+        status          NUMBER    default 0   NOT NULL,
+        throttle        NUMBER(5) default 0   NOT NULL,
+        bootstrap       NUMBER    default 0   NOT NULL,
+        schema_version  NUMBER(5) default -1  NOT NULL,
+        weight          NUMBER(5) default 0   NOT NULL,
+        info            CLOB,
+        PRIMARY KEY (filename)
+      )');
+      db_query('CREATE INDEX {system}_idx_1 ON {system}(weight)');
+
+      // -- Table structure for term_data
+      db_query('CREATE TABLE {term_data} (
+        tid         NUMBER              NOT NULL,
+        vid         NUMBER    default 0 NOT NULL,
+        name        VARCHAR2(255),
+        description CLOB,
+        weight      NUMBER(5) default 0 NOT NULL,
+        PRIMARY KEY (tid)
+      )');
+      db_query('CREATE INDEX {term_data}_idx_1 ON {term_data}(vid)');
+      db_query("CREATE SEQUENCE {term_data}_tid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {term_data}_be_in
+        BEFORE INSERT ON {term_data}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.tid IS NULL THEN
+            SELECT {term_data}_tid_seq.NEXTVAL
+            INTO :NEW.tid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for term_hierarchy
+      db_query('CREATE TABLE {term_hierarchy} (
+        tid     NUMBER default 0 NOT NULL,
+        parent  NUMBER default 0 NOT NULL,
+        PRIMARY KEY (tid, parent)
+      )');
+      db_query('CREATE INDEX {term_hierarchy}_idx_1 ON {term_hierarchy}(tid)');
+      db_query('CREATE INDEX {term_hierarchy}_idx_2 ON {term_hierarchy}(parent)');
+
+      // -- Table structure for term_node
+      db_query('CREATE TABLE {term_node} (
+        nid NUMBER default 0 NOT NULL,
+        vid NUMBER DEFAULT 0 NOT NULL,
+        tid NUMBER default 0 NOT NULL,
+        PRIMARY KEY (tid,nid,vid)
+      )');
+      db_query('CREATE INDEX {term_node}_idx_1 ON {term_node}(nid)');
+      db_query('CREATE INDEX {term_node}_idx_2 ON {term_node}(vid)');
+      db_query('CREATE INDEX {term_node}_idx_3 ON {term_node}(tid)');
+
+      // -- Table structure for term_relation
+      db_query('CREATE TABLE {term_relation} (
+        trid  NUMBER            NOT NULL,
+        tid1  NUMBER  default 0 NOT NULL,
+        tid2  NUMBER  default 0 NOT NULL,
+        PRIMARY KEY (trid)
+      )');
+      db_query('CREATE INDEX {term_relation}_idx_1 ON {term_relation}(tid1)');
+      db_query('CREATE INDEX {term_relation}_idx_2 ON {term_relation}(tid2)');
+      db_query("CREATE SEQUENCE {term_relation}_trid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {term_relation}_be_in
+        BEFORE INSERT ON {term_relation}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.trid IS NULL THEN
+            SELECT {term_relation}_trid_seq.NEXTVAL
+            INTO :NEW.trid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for term_synonym
+      db_query('CREATE TABLE {term_synonym} (
+        tsid  NUMBER            NOT NULL,
+        tid   NUMBER  default 0 NOT NULL,
+        name  VARCHAR2(255),
+        PRIMARY KEY (tsid)
+      )');
+      db_query('CREATE INDEX {term_synonym}_idx_1 ON {term_synonym}(tid)');
+      db_query('CREATE INDEX {term_synonym}_idx_2 ON {term_synonym}(name)');
+      db_query("CREATE SEQUENCE {term_synonym}_tsid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {term_synonym}_be_in
+        BEFORE INSERT ON {term_synonym}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.tsid IS NULL THEN
+            SELECT {term_synonym}_tsid_seq.NEXTVAL
+            INTO :NEW.tsid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+  
+      // CHECKING POINT 2007-05-17-1845
+
+      // -- Table structure for users
+      db_query('CREATE TABLE {users} (
+        "uid"     NUMBER                NOT NULL,
+        name      VARCHAR2(60),
+        pass      VARCHAR2(32),
+        mail      VARCHAR2(64),
+        "mode"    NUMBER(5)   default 0 NOT NULL,
+        sort      NUMBER(5)   default 0,
+        threshold NUMBER(5)   default 0,
+        theme     VARCHAR2(255),
+        signature VARCHAR2(255),
+        created   NUMBER      default 0 NOT NULL,
+        "access"  NUMBER      default 0 NOT NULL,
+        login     NUMBER      default 0 NOT NULL,
+        status    NUMBER(5)   default 0 NOT NULL,
+        timezone  VARCHAR2(8) default NULL,
+        language  VARCHAR2(12),
+        picture   VARCHAR2(255),
+        init      VARCHAR2(64),
+        data      CLOB        default EMPTY_CLOB(),
+        PRIMARY KEY ("uid"),
+        UNIQUE (name)
+      )');
+      db_query('CREATE INDEX {users}_idx_1 ON {users}("access")');
+      db_query('CREATE INDEX {users}_idx_2 ON {users}(created)');
+      db_query("CREATE SEQUENCE {users}_uid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query('CREATE OR REPLACE TRIGGER {users}_be_in
+        BEFORE INSERT ON {users}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW."uid" IS NULL THEN
+            SELECT {users}_uid_seq.NEXTVAL
+            INTO :NEW."uid"
+            FROM dual;
+          END IF;
+        END
+        ;
+      ');
+
+      // -- Table structure for users_roles
+      db_query('CREATE TABLE {users_roles} (
+        "uid" NUMBER default 0 NOT NULL,
+        rid   NUMBER default 0 NOT NULL,
+        PRIMARY KEY ("uid", rid)
+      )');
+
+      // -- Table structure for variable
+      db_query("CREATE TABLE {variable} (
+        name      VARCHAR2(128),
+        value     CLOB,
+        language  VARCHAR2(12)  DEFAULT '',
+        UNIQUE (name, language)
+      )");
+
+      // -- Table structure for vocabulary
+      db_query('CREATE TABLE {vocabulary} (
+        vid         NUMBER              NOT NULL,
+        name        VARCHAR2(255),
+        description CLOB,
+        help        VARCHAR2(255),
+        relations   NUMBER(5) default 0 NOT NULL,
+        hierarchy   NUMBER(5) default 0 NOT NULL,
+        multiple    NUMBER(5) default 0 NOT NULL,
+        required    NUMBER(5) default 0 NOT NULL,
+        tags        NUMBER(5) default 0 NOT NULL,
+        module      VARCHAR2(255),
+        weight      NUMBER(5) default 0 NOT NULL,
+        PRIMARY KEY (vid)
+      )');
+      db_query("CREATE SEQUENCE {vocabulary}_vid_seq MINVALUE 1 INCREMENT BY 1 START WITH 1 NOCACHE NOORDER NOCYCLE");
+      db_query("CREATE OR REPLACE TRIGGER {vocabulary}_be_in
+        BEFORE INSERT ON {vocabulary}
+        FOR EACH ROW
+        BEGIN
+          IF :NEW.vid IS NULL THEN
+            SELECT {vocabulary}_vid_seq.NEXTVAL
+            INTO :NEW.vid
+            FROM dual;
+          END IF;
+        END
+        ;
+      ");
+
+      // -- Table structure for vocabulary_node_types
+      db_query('CREATE TABLE {vocabulary_node_types} (
+        vid   NUMBER        default 0 NOT NULL,
+        type  VARCHAR2(32),
+        PRIMARY KEY (vid, type)
+      )');
 
       break;
   }
diff -urN ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\user\user.module drupal-6.x-dev\modules\user\user.module
--- ..\drupal-6.x-dev-2007-05-17\drupal-6.x-dev\modules\user\user.module	Wed May 16 06:45:16 2007
+++ drupal-6.x-dev\modules\user\user.module	Mon May 21 00:35:50 2007
@@ -391,7 +391,9 @@
   global $user;
   static $perm = array();
 
-  if (is_null($account)) {
+  // checkpoint 02: $account exists but no uid ?
+  if ((is_null($account)) || !isset($account->uid)) {
+  // end 02
     $account = $user;
   }
 
@@ -1149,6 +1151,7 @@
  */
 function user_logout() {
   global $user;
+  global $active_db;
 
   watchdog('user', 'Session closed for %name.', array('%name' => $user->name));
 
@@ -1158,6 +1161,12 @@
 
   // Load the anonymous user
   $user = drupal_anonymous_user();
+
+  // checkpoint 01: need COMMIT to make logout works
+  if ($GLOBALS['db_type'] == 'oracle') {
+    OCICommit($active_db);
+  }
+  // end 01
 
   drupal_goto();
 }
