Support for DB2 databases?
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Another place that is affected by the BIT_OR change: gallery2/modules/core/test/phpunit/ModuleTest.class, _fetchPermissionBitsForItem(): list ($ret, $bitOr) = $storage->getFunctionSql('BIT_OR', // array('[GalleryAccessMap::permission]')); array('[GalleryAccessSubscriberMap::itemId]', '[GalleryAccessMap::permission]')); |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
good that there is a solution. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
I doubt it... the combination of ID and Permissions is not unique, and DB2 does not have a built-in concept of "row id"... we could use a SEQUENCE column, but that's going a little overboard. Would it be possible to hard-code the '[GalleryAccessSubscriberMap::itemId]' in Db2Storage.class? //LJM $sql = 'MAX(G2_BIT_OR (' . $args[0] . '))'; $sql = 'MAX(G2_BIT_OR ([GalleryAccessSubscriberMap::itemId], ' . $args[0] . '))'; Update: I've tested the 'hard-coding' solution and it seems to work, at least so far (unit tests are still running). |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
All Unit tests have run (with only core, search, and 4 graphics modules installed), and I get only 4 errors: IndexDotPhpTest.testHttpRedirect All of which you've said were likely not database related. Once we've finalized what to do about the BIT_OR UDF issue (requiring the G_ITEMID as well), I'll grab the latest build and try again with all modules installed. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
BTW, I don't know if this is related to the 4 outstanding errors, but... I don't know if you noticed, but I specify a port number (:800) in my Gallery URL. This is to distinguish it from my 'production' server. Could that be related to these 4 errors? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
right now there's only 1 use of this BIT_OR and we use GROUP BY there. changes committed. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
@port 800: |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> what if we use it in another query without GROUP BY? then your UDF wouldn't work anymore, Sort of. DB2 locates UDF code based on its 'signature' (schema, name, and datatype of args), so this UDF will not work at all without the exact args "int, varchar(32)". So yes, we will need to always specify *some* integer in arg 1, but it is meaningless to specify any fixed integer. It defeats the grouping logic in the UDF itself. For example, given a table with only the following data: C:\MyServer>db2 select * from g2_AccessMap G_ACCESSLISTID G_USERORGROUPID G_PERMISSION -------------- --------------- ------------------------------------------------------------------- 13 4 x'3030303030303030303030303030303030303030303030303030303030313131' 28 4 x'3030303030303030303030303030303030303030303030303030303030313131' 13 10 x'3030303030303030303030303030303030303030303030303030303131303030' 28 10 x'3030303030303030303030303030303030303030303030303130303131303030' 4 record(s) selected. Running the UDF with hard-coded "1" as arg #1 is simply a cumulative BIT ORing of all values in the G_PERMISSION column, regardless of whatever integer is specified in the invocation. C:\MyServer>db2 select G2_BIT_OR(1, g_permission) from g2_AccessMap 1 ------------------------------------------------------------------- x'3030303030303030303030303030303030303030303030303030303030313131' x'3030303030303030303030303030303030303030303030303030303030313131' x'3030303030303030303030303030303030303030303030303030303131313131' x'3030303030303030303030303030303030303030303030303130303131313131' 4 record(s) selected. So if we need to do a BIT OR with no GROUP BY, a separate UDF (like the previous version of G2_BIT_OR) might be required. > make sure your webserver has port 800 in its configuration Yes, it does. I mentioned this only in case you might have thought it related to the errors. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Hey Valiant, did you ever speak to John Lim about the 'ibm_db2'-based ADOdb driver? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
no, i haven't. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Nobody has ever responded to my 'Support Request' on their web site. I haven't tried to contact him directly... last time you and I discussed it you said you were going to contact him in an official 'Gallery' capacity. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
Ok, posted a new topic: |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Thanks Valiant. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Valiant, I just grabbed the current nightly build, and the Installer fails to install the core. The problem is: 2006-02-09 12:58:28 [TMP_SESSION_ID_DI_NOISSES_PMT] db2 error: [42611: [IBM][CLI Driver] [DB2/NT] SQL0604N The length, precision, or scale attribute for column, distinct type, structured type, attribute of structured type, function, or type mapping "G_VALUE" is not valid. SQLSTATE=42611 SQLCODE=-604] in EXECUTE ("CREATE TABLE g2_CacheMap( g_key VARCHAR(32) NOT NULL, g_value CLOB(4G), g_userId INTEGER NOT NULL, g_itemId INTEGER NOT NULL, g_type VARCHAR(32) NOT NULL, g_timestamp INTEGER NOT NULL )") I compared that to my previous generate-sql.php, and I see that there is a new "'TEXT-LARGE' => 'CLOB(4G)',". I don't remember ever deciding that we would use CLOB. If we want to use CLOB then as you can see there will be further porting required, and offhand I don't know how large an effort that will be. Do you want to do this, or go back to VARCHAR(8000) for the time being? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
yes, that's new. the new caching table is for storing cached pages. that can be just 10kbyte or 1mbyte of binary data encoded as string. what's the problem with CLOB? or with 4G ? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
Another thing: for mysql, we're doing something similar as drupal did: |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> what's the problem with CLOB? or with 4G ? The problem is that it's a different datatype, and like I said, will require more porting (I don't know how much). > UTF8 I don't know very much about it, but I think it needs to be specified at database creation time. I'll do some more research on it. I guess this pretty much slams the door on getting DB2 support sanctioned in 2.1. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
maybe you can figure out the CLOB stuff for RC-2 of G2.1. RC 1 will be released in maybe 30h. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> CLOB / long TEXT / how ever it's called in different DBMS is something that we need I just wish I'd known this a lot earlier. Oh well, c'est la vie. I'll let you know how it goes, but I have a very bad feeling about this. > UTF-8 Like I said, I'm not that knowledgeable about unicode, but if I understand the DB2 doc correctly, then in order for a DB2 database to handle unicode, that must be specified at database creation time: C:\Program Files\IBM\SQLLIB>db2 create database utfdb using codeset utf-8 territory us DB20000I The CREATE DATABASE command completed successfully. (Note: the "us" territory would be whatever territory code the User wants (see 'http://publib.boulder.ibm.com/infocenter/db2luw/v8/topic/com.ibm.db2.udb.doc/admin/r0004565.htm'. I'm not sure what the other impacts of specifying other territories might be... National Language Support was never my area of expertise.) > DB2 in G2.1 I think we're probably screwed anyway, because I still haven't gotten anyone to test it on Linux or Unix. I had one volunteer, but haven't heard back from them. I suspect I'm going to have to cough up some bucks for a Linux system so I can do it myself, but being unemployed for the last 10 months, money is a luxury of which I don't have much. And I'll be damned if I'm going to shell out for a Sun, HP, AIX, or other UNIX box. ;-) |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
I've found that the maximum CLOB size in DB2 is 2G. I'll make that change to 'generate-sql.php' and see how that goes. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Good news, it actually worked pretty well. I installed the 'Search' module and the 4 graphics modules, and got only 5 unit test failures. Only 1 of them was one that I was previously getting ('IndexDotPhpTest.testHttpRedirect')... the other 4 were new. Unfortunately I lost the output, so have to re-run them all again. But 3 of the new ones were all session-related, and the 4th new one was 'StorageTest.testEncodeDecodeBlob' The change I made in 'generate-sql.php' is: //LJM 'TEXT-LARGE' => 'CLOB(4G)', 'TEXT-LARGE' => 'CLOB(2G) NOT LOGGED', Note the 'NOT LOGGED'. This is required for CLOBs over 1G in size. The explanation of this clause from the DB2 doc: Quote:
NOT LOGGED has no effect on a commit or rollback operation; that is, the database's Oh, I forgot to mention... for this run I'm also using a unicode database:
|
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
FYI, I've put the output of the 5 failures here: I'm working on them. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
I've chosen SessionTest.testAcquireNewPersistentSessionRetryOnCollision to look at first, as it is the only one with a "db2 error". I enabled 'buffered' debugging but it still wasn't telling me the exact DB2 error message. So I enabled 'immediate' debugging and now I finally get the DB2 error: Quote:
db2 error: [23505: [IBM][CLI Driver][DB2/NT] SQL0803N One or more values in the INSERT The constraint on G2_SESSIONMAP is a Primary Key on column g_id. When I look for that g_id in the debug trace (http://cpe0013102da23b-cm0f0079804905.cpe.net.cable.rogers.com/misc/Gallery%20Unit%20Tests%20-%20utf-8%20-%20testAcquireNewPersistentSessionRetryOnCollision.htm) it does appear twice, in fact twice in a row immediately before the DB2 error. Any idea why this row is being inserted twice? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
@session acquireNewPersistentSessionRetryOnCollision: @clob: @testing on linux: |
|
sphericus
Joined: 2005-11-06
Posts: 55 |
![]() |
Hi, Sorry about that, I will test it on Linux for you, infact I just rebuilt my linux box the other day. I will test it very shortly. I went and downloaded the Zend-Core php pack for IBM DB2. Is that something good to use with G2? Also, if you are in need of testing on AIX boxes, I can try to see if I can help you there as well. |
|
sphericus
Joined: 2005-11-06
Posts: 55 |
![]() |
With respect to unicode, if it is specified at database creation time, then unicode data will be stored correctly. However, I only have ever used unicode with JDBC. But from testing, as soon as the db is created with unicode, it all works without incident. The NLS stuff, that I am aware of is more for things like sorting, and date interpreations. Also things like decimal delimiters, etc. You could say that it has a similar effect to what it has on the OS. Where change the territory, and it changes time format, date format, and decimal delimiters, etc. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> we need to add the exact php warning output to the sessiontest.class at the end of the file to the exceptions Sorry, I don't quite follow you. > right now fighting with other things Yeah, I know, and I apologize for hitting you with questions right now. I can handle it if you're too busy to worry about DB2. > dual boot A bunch of reasons. Disk space, dedicated system usage, yadda yadda yadda... Plus, the last time I tried to do so (using FreeBSD Linux) I fragged my system's master boot record. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Hey, Sphericus, good to hear from you. No problem, your work comes first. I can dig it. The only part of the Zend-Core pack that is needed for G2 is the 'ibm_db2' PHP extension. But even so, the one shipped with Zend-Core might not be current enough, because I've been having Dan Scott fix bugs that I've been finding in it. See the comments in: http://codex.gallery2.org/index.php/Gallery2:DB2 Thanks, Sphericus. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
@unicode: sessiontest.class: function SessionTest_error_handler($errno, $errstr, $errfile, $errline) { if ($errno == 2) { global $gallery; $storage =& $gallery->getStorage(); if ($storage) { $expected1 = sprintf('{pg_exec().*: Query failed: ERROR: duplicate key violates ' . 'unique constraint "%ssessionmap_pkey"}', $storage->_tablePrefix); $expected2 = '{pg_exec().*: Query failed: ERROR: current transaction is aborted,' . ' commands ignored until end of transaction block}'; if (preg_match($expected1, $errstr) || preg_match($expected2, $errstr)) { return; } } } else if ($errno == 1) { if (preg_match('{db2_exec\(\).*: Statement Execute Failed}', $errstr)) { return; } } /* Else call our default error_handler */ return PHPUnit_error_handler($errno, $errstr, $errfile, $errline); } does the session stuff then pass? |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> codex doc Already done. Let me know if that's not sufficient. > sessionTest.class Done. It still fails. The only errors I see are these constraint violation errors. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
please change your last function of SessionTest.class to: function SessionTest_error_handler($errno, $errstr, $errfile, $errline) { if ($errno == 2) { global $gallery; $storage =& $gallery->getStorage(); if ($storage) { $expected1 = sprintf('{pg_exec().*: Query failed: ERROR: duplicate key violates ' . 'unique constraint "%ssessionmap_pkey"}', $storage->_tablePrefix); $expected2 = '{pg_exec().*: Query failed: ERROR: current transaction is aborted,' . ' commands ignored until end of transaction block}'; if (preg_match($expected1, $errstr) || preg_match($expected2, $errstr)) { return; } } } print "errno: $errno, errstr: $errstr, errfile: $errfile, errline: $errline<br>\n"; exit; /* Else call our default error_handler */ return PHPUnit_error_handler($errno, $errstr, $errfile, $errline); } then run the test again and copy the generated line from the html source to here. the browser doesn't display all spaces etc. thus we need the html source. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
OK, that's a little more informative: <hr> (db2): SELECT g2_SessionMap.g_id, g2_SessionMap.g_userId, g2_SessionMap.g_remoteIdentifier,g2_SessionMap.g_creationTimestamp, g2_SessionMap.g_modificationTimestamp, g2_SessionMap.g_data FROM g2_SessionMap WHERE g2_SessionMap.g_id = '1b370a8bc63928ab7350617193203023' <code></code> <hr> getParameter id.anonymousUser for core plugin errno: 2048, errstr: Non-static method ADOConnection::outp() should not be called statically, errfile: C:\MyServer\Gallery2\lib\adodb\adodb-lib.inc.php, errline: 926<br> |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
are you calling ADOConnection::outp() ? |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Hmm, I did find one "::outp" call in my driver, but that's not where the error is occurring (plus, it shouldn't be there anyway, so I removed it... could you also remove it from CVS? (Just remove the whole "if(...)", lines 114 - 116.) The error is occurring in one of the other ADOdb files... "adodb-lib.inc.php", function _adodb_debug_execute(). I presume that the reason we go into that is because debugging is enabled in the test script. I presume there's nothing wrong with being in debug mode in the test script. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
CLOB(2G) NOT LOGGED is in RC1. RC1 is frozen, no changes go in now. but there will be an RC2 too. so the code freeze is soon over. Quote:
could you also remove it from CVS? (Just remove the whole "if(...)", lines 114 - 116.) you mean Quote:
if ($this->debug && $argDatabasename) { ? |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Yes, that's the one... that's a left-over from the ODBC driver, and should be removed. Thanks. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
I found a web site that explains "static" versus "non-static" in PHP context. Using that knowledge, I changed a couple of lines in 'adodb-lib.php.inc': //LJM ADOConnection::outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." <code>$ss</code>\n<hr>\n",false); $zthis->outp( "<hr>\n($dbt): ".htmlspecialchars($sqlTxt)." <code>$ss</code>\n<hr>\n",false); } else { ADOConnection::outp("-----\n($dbt): ".$sqlTxt."\n-----\n",false); } $qID = $zthis->_query($sql,$inputarr); /* Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion */ if ($zthis->databaseType == 'mssql') { // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6 if($emsg = $zthis->ErrorMsg()) { if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg); } } else if (!$qID) { //LJM ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg()); $zthis->outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg()); And I eliminated those "should not be called statically" errors. Then I removed the "exit;" from your code, so that the test runs to completion. But now all I see is the constraint violations. And if I understand you correctly, they're expected? |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
I think I'm making progress. I jammed a bunch of debug info into the the test, and the fatal error seems to be happening here: /* 6th persistent session has 5 collisions, should fail with error */ $gallery->_phpVm = new SessionTestPhpVm($sessionIds); $session->_sessionId = ''; $ret = $session->_acquireNewPersistentSession(); if ($ret) { // We do go into here, $ret->getErrorCode() is "3". $this->assertEquals(ERROR_COLLISION | GALLERY_ERROR, $ret->getErrorCode(), 'error code'); if ( !($ret->getErrorCode() & ERROR_COLLISION) ) { // We do not go into here return $this->failWithStatus($ret->wrap(__FILE__, __LINE__)); } } else { $this->assert(false, 'should have returned a ERROR_COLLISION, but got no error at all'); } } Am I right in believing that this should be the fatal error, but is never being reported? If so, I'll dig into the assertEquals() code. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
@ static vs nonsttatic. @session test: |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> Adodb files I'm gonna expose my lack of self-confidence now, but... are we even sure that my hack is the right thing to do? It wouldn't be the first time I came to the wrong conclusion about something. > we just need to add the properbtw Care to try that again? "the proper... " what? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
in the error_handler at the end of SessionTest.class, we just need to add the proper error strings / error code that we expect from db2. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> Adodb file So what are we going to do in this case? If I could get someone to verify that's really the right fix, then we can open the bug report for ADOdb. > SessionTest.class Ah, I see now. According to your debug code, $errstmt is: Quote:
db2_exec() [<a href='function.db2-exec'>function.db2-exec</a>]: Statement Execute Failed So I added the check for that pattern: $expected3 = "/db2_exec\(\) \[<a href='function.db2-exec'>function.db2-exec<\/a>]: Statement Execute Failed/"; //LJM if (preg_match($expected1, $errstr) || preg_match($expected2, $errstr)) { if (preg_match($expected1, $errstr) || preg_match($expected2, $errstr) || preg_match($expected3, $errstr)) { And SessionTest.testAcquireNewPersistentSessionRetryOnCollision now runs clean. But that $errstr strikes me as being a little generic. I mean, any DB2 error would generate that same error... we're not certain that it was a constraint violation. I think that text comes from the 'ibm_db2' driver itself. I'll mention it to Dan, but I suspect it's like that intentionally. The 'ibm_db2' driver provides db2_stmt_error() and db2_stmt_errormsg() APIs to get specific error msg info, but I'm not sure how they could help us in this case. Thanks. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
Hmm, thinking about the $errstr a bit more... I guess if that SessionTest_error_handler() function is used to handle all kinds of errors, then by necessity it needs to be generic. Same would be true of all RDBMSes. I presume you're aware of that, so I won't worry too much about it. |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
I've now started looking into SessionTest.testSessionCookieHeaderAndPersistence. There are 4 errors in it (actually, looks like 2 sets of the same 2 errors). The first one I'm looking at is: Quote:
imageframe.CSS, bar isPersistent I put more debug info in the source code, and have verified that in the 'imageframe.CSS' / 'bar' test, when it calls assertEquals(), $session->isPersistent() is true (it should be false), but I don't see where that is being set. Any suggestions? (P.S.: I'm a little concerned about these new session failures. Why did they not happen before? Other than moving to a new build of g2, I'm pretty sure the only thing different in the database is that it is now UTF-8, but that shouldn't affect the session tests, should it? Or are these tests new?) |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
the session tests are new. we changed the session management about 2 weeks ago from a file to a database based system. |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
@unspecific error: |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
OK, that's good, I feel better about it now. I know you're busy, but whenever you get a chance... Any suggestions re the SessionTest.testSessionCookieHeaderAndPersistence error? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
@ ADOConnection::outp: |
|
Larry Menard
![]()
Joined: 2005-10-01
Posts: 757 |
![]() |
> ADOConnection::outp: Hmm, I only see the "static" error if I back out my fix (re-break SessionTest.testAcquireNewPersistentSessionRetryOnCollision test) and enable the debug printing of "$errstr" that you suggested. When I fix the test, it never goes into the error handler, therefore there's no $errstr to print. So this might not ever be an issue in the future. Wanna just leave it for now then? |
|
valiant
Joined: 2003-01-04
Posts: 32509 |
![]() |
yeah, let's leave the ::outp thing for now. @testAcquireNewPersistentSessionRetryOnCollision |
|