mysql5.lsp

Started by Dmi, May 01, 2008, 02:21:45 PM

Previous topic - Next topic

Dmi

Here is a diff for mysql5.lsp to run on amd64/Debian



I think it should go in other 64 bit systems. There is a two places in original file, where sizeof(int)=4 was assumed. They are changed to 8.

Enjoy ;-)


--- /usr/share/newlisp/modules/mysql5.lsp       2008-03-23 02:37:50.000000000 +0300
+++ mysql5-64.lsp       2008-05-02 01:16:28.000000000 +0400
@@ -122,11 +122,12 @@
 ; check endianess of the host CPU
 (set 'big-endian (= (pack ">ld" 1) (pack "ld" 1)))

+(constant 'INT_SIZE 8) ; 4 for 32 bit, 8 for 64 bit
 (constant 'NUM_ROWS_OFFSET (if big-endian 4 0))
-(constant 'NUM_FIELDS_OFFSET 60)
-(constant 'ERROR_OFFSET 85)
-(constant 'INSERT_ID_OFFSET (if big-endian 708 704))
-(constant 'AFFECTED_ROWS_OFFSET (if big-endian 700 696))
+(constant 'NUM_FIELDS_OFFSET 96)
+(constant 'ERROR_OFFSET 141)
+(constant 'INSERT_ID_OFFSET (if big-endian 708 832))
+(constant 'AFFECTED_ROWS_OFFSET (if big-endian 700 824))

 ;; @syntax (MySQL:init)
 ;; @return 'true' on success, 'nil' on failure.
@@ -185,7 +186,7 @@
   ; The field type is the 20th field of the MySQL_FIELD structure
   ; since fields 1-19 are all 4 byte fields we get the enum value
   ; like so
-  (set 'data (get-int (int (+ type_ptr (* 19 4)))))
+  (set 'data (get-int (int (+ type_ptr (* 19 INT_SIZE)))))
   ; Consult 'enum_field_types' in mysql_com.h for values
   (if (= data 1) ;; boolean
         (get-string field_addr)
@@ -215,7 +216,7 @@
     (begin
       (set 'row '())
       (dotimes (field (num-fields))
-            (set 'field_addr (get-int (int (+ rdata (* field 4)))))
+            (set 'field_addr (get-int (int (+ rdata (* field INT_SIZE)))))
             (if (= field_addr 0)
               (push nil row -1) ;; what to do when the field contains NULL
               (push (keep-type MYSQL_RES field_addr field) row -1)))
WBR, Dmi

Dmi

#1
Dmytry Krasilnikov, working with me, found another bug in mysql5.lsp:


(define (fetch-all)
  (dotimes (x (num-rows)) (push (fetch-row) all))
  (reverse all))

symbol 'all is global and here was no reset for it.


(define (fetch-all , all)
should correct this.
WBR, Dmi

Lutz

#2
Nice job Dmitry. I mean both of you ;-)



Just for clarification:



Is this for newLISP normal 32-bit compile which does handle 64-bit integers? This would be compiled using makefile_linux64 or makefile_linux64ILP32 (same, but one with the other without readline support)?



Or is this for newlisp compiled as a 64-bit app using makefile_linux64LP64 ?



I assume that it is the first, so basically your modifications to the existing mysql5.lsp let you access bigger than 2G databases? and on a 64-bit Linux system.



Also, what version of libmysql.so does it use? And last not least, you are aware that there is also a mysql51.lsp in the distribution? It was missing in the installation script of version 9.3.0, but has recently been added, and it only changes offsets.

Dmi

#3
Hi, Lutz!



Hmm... my one is compiled from makefile_debian (as standard package).

The compile options are:
gcc -Wall -pedantic -Wno-uninitialized -Wno-strict-aliasing -Wno-long-long -c -g -DREADLINE -DLINUX  -O2 newlisp.c

Compiled and runs on dual core amd64 thurion in 64bit mode.

No problems in newlisp found.



mysql version is 5.0.51a-3

I haven't test it with 2G+ databases : Do you looking for test?



For offsets I have compiled ad ran sql.c.

Changing offset multiplier from 4 to 8 was intuitive bug fix lookup ;-)
WBR, Dmi

Lutz

#4
Ok, so this is just a normal compile on normal 32-bit applications Linux running on a 64-bit CPU.

Dmi

#5
Ho! It's new for me! But you're right:
void main(void){printf("%in",sizeof(int));}
prints 4, not 8 as I've expected



But linux distro is 64-bit, so, I suspect, mysql is compiled in 64bit mode.
WBR, Dmi

Lutz

#6
There is also types.c in newlisp-x.x.x/util. If you compile it on Mac OS X running on a 64-bit Intel CPU, but with 32-bit  applications libraries, you get this:


~> gcc types.c
~> ./a.out

type      bytes
---------------
char        1
char *      4
void *      4
short int   2
int         4
long        4
long int    4
long long   8
size_t      4
float       4
double      8
long double 16
wchar_t     4
...






Ps: I deleted the second part of the output showing formatting of 32 and 64-bit integers