dblog.module try to use GROUP BY with field message, which is created as text:big within dblog.schema:

<?php
/**
 * Menu callback; generic function to display a page of the most frequent
 * dblog events of a specified type.
 */
function dblog_top($type) {

  $header = array(
    array('data' => t('Count'), 'field' => 'count', 'sort' => 'desc'),
    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);

  $rows = array();
  while ($dblog = db_fetch_object($result)) {
    $rows[] = array($dblog->count, truncate_utf8(_dblog_format_message($dblog), 56, TRUE, TRUE));
  }

  if (empty($rows)) {
    $rows[] = array(array('data' => t('No log messages available.'), 'colspan' => 2));
  }

  $output  = theme('table', $header, $rows);
  $output .= theme('pager', NULL, 30, 0);

  return $output;
}
?>

this patch will change both field message and variable into text:medium, as grouping a field with maximum 4GB size is not reasonable. although there will be a trade off about record sizing, it keep the overall performance.

on the other hand, as oracle driver (http://drupal.org/node/39260) will only map text:big as CLOB and other text type as VARCHAR2, changing this 2 field into medium can keep most of the functionality (as text:medium mapped as VARCHAR2 with maximum 4000 characters) of dblog.module.

Comments

hswong3i’s picture

Status: Active » Needs review
hswong3i’s picture

Assigned: Unassigned » hswong3i
StatusFileSize
new2.08 KB

this patch include v1.0, in addition modify the GROUP BY query into more formal format.

the original query trying to get variables from GROUP BY result, without locate it within GROUP BY. although it is function within mysql, but it is not oracle friendly; on the other hand, the patched version should give out the same result as original.

dries’s picture

Status: Needs review » Fixed

Good catch. Committed. :)

recidive’s picture

Wouldn't this require an update function?

hswong3i’s picture

i check dblog.install but:

<?php
// $Id: dblog.install,v 1.3 2007/05/25 12:46:44 dries Exp $

/**
 * Implementation of hook_install().
 */
function dblog_install() {
  // Create tables.
  drupal_install_schema('dblog');
}

/**
 * Implementation of hook_uninstall().
 */
function dblog_uninstall() {
  // Remove tables.
  drupal_uninstall_schema('dblog');
}
?>

seems the update of watchdog table from previous version is still not yet handle currently... i have no idea about how to do so ;)

ChrisKennedy’s picture

Status: Fixed » Needs review
StatusFileSize
new1010 bytes

The change to GROUP BY in dblog.module broke the query on MySQL - parentheses cannot be encapsulate the variables. Here is a fix.

hswong3i’s picture

thanks for bug fix, patch also function under oracle :)

hswong3i’s picture

Status: Needs review » Reviewed & tested by the community
dries’s picture

Status: Reviewed & tested by the community » Needs work

I've committed the patch in #6. Thanks Chris.

hswong3i’s picture

Status: Needs work » Fixed
Anonymous’s picture

Status: Fixed » Closed (fixed)
bjaspan’s picture

Status: Closed (fixed) » Needs review
StatusFileSize
new1.25 KB

Prior to this patch, watchdog.message was type 'text:big' (more accurately, it was created explicitly as mysql type 'longtext' and pgsql 'text'). watchdog.variables did not exist in D5.

This patch declared both as text:medium for "Oracle compatibility." For reasons described in http://drupal.org/node/147947, that is not the correct change to achieve the desired goal. Also, this patch did not provide a database update for watchdog.message's change in size. Unlike in http://drupal.org/node/147947 we cannot simply back out this patch because of its GROUP BY fixes.

I have attached a new patch which sets both fields to 'text:big'. Honestly, just normal 'text' would probably be fine, but 'text:big' is the status quo.

If this patch is committed, system_update_6010() will need to be updated to create watchdog.variables correctly. If this patch is not committed, we will need to add a new update to change watchdog.message from 'text:big' to 'text:medium'.

hswong3i’s picture

Status: Needs review » Needs work

@bjaspan: agree about your point of view, but some more question: as LOBs patch is now almost ready (http://drupal.org/node/147947#comment-278902), should "message" and "variables" using "clob:big", rather than "text:big"?

we will face some conflict, if using "text:big". in case of MySQL, it means we are allowing a GROUP BY action with huge data (text:big => longtext => max. 4GB), queries may need to be review in order to prevent such actions; on the other hand, in case of latest version of Oracle driver implementation (http://drupal.org/node/39260#comment-278926), we will only have 4000 characters size for storage ("text:big" => VARCHAR2(4000) => max. 4000 characters), which may be not enough for our log message :(

according to LOBs patch, we may choose "clob:big" as alternative, but still need some changes. "clob:big" provide enough storage space within all DB driver implementation (MySQL's "clob:big" => longtext => max. 4GB; Oracle's "clob:big" => CLOB => max. 128TB), but also means we should never use it for SELECT DISTINCT, ORDER BY or GROUP BY queries (please refer to "Restrictions on LOBs"). similar as above problem, we still need to rewrite some core queries, for those GROUP BY actions.

my suggestions: 1. fields should reset as suitable type, to prevent conflict with old DB schema; 2. queries should also review, to prevent GROUP BY with huge data (not enterprise friendly...); 3. "clob:big" may also be a good choice: to clarify its storage nature, with suitable handling :)

hswong3i’s picture

i use the following code to check the current status of my blob's "watchdog" table, and it return $length as 3361. i keep logs for 8 weeks, so this checking should be meaningful:

<?php
$result = db_query("SELECT message FROM {watchdog}");
$length = 0;
while ($row = db_fetch_array($result)) {
  if ($length < strlen($row['message'])) {
    $length = strlen($row['message']);
  }
}
print_r($length);
?>

if this checking is meaningful, setting watchdog's fields as "text:big" should be acceptable: 1. record size is small enough, according to GROUP BY query (it is not query friendly, but acceptable...); 2. it will be suitable for oracle implementation, as "text:big" => VARCHAR2(4000), which support maximum 4000 characters (will not generate error message...)

P.S. we shall consider about change these fields into CLOB type and rewrite some queries, if it is possible to record somethings larger than 4000 characters into "watchdog" :)

hswong3i’s picture

Priority: Normal » Critical

such "3361" error message is generated by aggregator.module, beased on duplicate insert (the error message include the feed body without any trimming...). as we never know how large of incoming feed (what will happened if we face duplicate insert of feed with 10000+ characters?), it may be a needs for changing fields into CLOB and rewrite some queries into query friendly :(

P.S. some minor suggestion: may be don't log the "complete" message, but just part of it? it will be much query friendly, if we trim log message into acceptable size :)

hswong3i’s picture

Category: feature » bug
Status: Needs work » Reviewed & tested by the community

patch in #12 should be acceptable within MySQL, and latest oracle driver implementation (http://drupal.org/node/39260#comment-280402). it should be ready for commit, and rollback the incorrect data type for backward compatibility.

it is no longer a problem, at least for oracle driver rc4. since oracle driver map all "text" type into VARCHAR2(4000) (the best that oracle can handle...), rc4 try to trim all %s substitution into maximum 4000 characters. no error message will be generated even inserting a dblog with 10000+ characters, oracle can handle first 4000 only, and so do it :)

on the other hand, i try to review the GROUP BY query: it is purely based on "message" and "variables", which is "text:big" in size. as we all understand the trade-off for running GROUP BY with something which MAYBE in maximum size of 4GB (within MySQL implementation), but still implement such new feature within dblog, just feel free to keep it on going :)

in case of MySQL, it is an existing implementation. we choose functionality even understanding the trade off, so just let it be; in case of oracle, it can't handle something larger than 4000, so we can only try the best, to save log message as long as it can. this will no longer become a "query friendly" problem for oracle, since trimmed data will within acceptable sizing, based on oracle limitation :(

dries’s picture

Status: Reviewed & tested by the community » Fixed

I've committed bjaspan's patch for now. Thanks.

Anonymous’s picture

Status: Fixed » Closed (fixed)