ftp://bond.edu.au/pub/Minerva/msql/faq.txt
or an HTML copy can be obtained via anonymous ftp from:
ftp://bond.edu.au/pub/Minerva/msql/faq.html
This FAQ is maintained by
Peter Samuel
<Peter.Samuel@uniq.com.au> and is produced independently of
Hughes Technologies (the developers of mSQL). While every attempt is made to ensure that the information contained in this FAQ is accurate, no guarantees of accuracy can or will be made.
This FAQ attempts to deal with mSQL. Because of time and space constraints, other applications, including value added applications provided with the mSQL distribution such as W3-mSQL and Lite, will not be covered in any great detail.
Third party applications mentioned in this FAQ may not be compatible with the current release of mSQL - by necessity their development will lag that of mSQL. If you have any questions concerning their status please contact the mSQL mailing list or the author of the application in question.
New questions in the FAQ are marked with (=). Questions that have been modified since the last release of the FAQ are marked with (-).
Note: BEFORE POSTING A QUESTION TO THE mSQL MAILING LIST, PLEASE READ THE SECTION "How do I post a question to the mSQL mailing list".
SQL is an acronym that stands for Structured Query Language. It is often pronounced "sequel". It was developed in the mid 1970s by IBM.
The American National Standards Institute (ANSI) and the International Standards Organisation (ISO) have adopted SQL as the standard language for relational database management systems.
SQL provides commands for a variety of tasks including:
While most relational database management systems - including mSQL - provide support for SQL, each vendor usually has their own unique extensions to the language that may hinder the portability of SQL procedures from one database platform to another.
C. J. Date
"An Introduction to Database Systems"
Vol I, Sixth Edition, 1995
Addison Wesley
ISBN 0-201-54329-X
C. J. Date and Hugh Darwen
"A Guide to Sql Standard"
Third Edition, 1993
Addison Wesley
ISBN 0-201-55822-X
Judith S. Bowman, Sandra L. Emerson and Marcy Darnovsky
"The Practical SQL Handbook: Using Structured Query Language"
Second Edition
Addison Wesley
ISBN 0-201-62623-3
G. M. Nijssen and T. A. Halpin
"Conceptual Schema and Relational Database Design"
1989
Prentice Hall
ISBN 0-7248-0151-0
Joe Celko
"Instant SQL Programming"
Martin Gruber
"Understanding SQL"
1990
Sybex Publishing
ISBN 0-89588-644-8
Jeff Rowe
"Building Internet Database Servers with CGI"
1996
New Riders Publishing
ISBN 1-56205-573-9
(see also http://cscsun1.larc.nasa.gov/~beowulf/db/mybook.html)
Perkins & Morgan
"Teach yourself SQL in 14 days"
SAMS Publishing
Connolly, Begg & Strachan
"Database Systems: A Practical Approach to Design,
Implementation and Management"
Addison-Wesley, 1996
Melton & Simon
"Understanding the New SQL: A Complete Guide"
Morgan Kaufmann 1993
Mike Morgan & Jeff Wandling
"Webmaster - Expert Solutions"
QUE books
ISBN 0-7897-0801-9
"mSQL has been released in the past under terms known as
'conscience-ware', the basic concept of which was that companies
that used the software could contribute a small amount to the
continued development of the software without any strict rules
being placed upon such 'donations'. Although the concept sounds
fair, it failed badly with only 3 contributions being made from
over 3,600 copies of mSQL-1.0.5 that were ftp'ed from my machine
alone. Over 1,000 of those copies went to commercial organisations
and I receive many questions a day from companies using mSQL behind
their WWW servers etc who are looking for free support.
In an attempt to balance this out and allow me to devote some time
to mSQL (rather than other pursuits that I do to generate an
income), mSQL is now shareware. I still believe in free software
over the Internet and cooperation in research so the new license is
designed not to hurt Universities, research groups and other people
that _should_ have free access to software. Commercial
organisations that are using this so that they don't have to buy an
Oracle or an Ingres will now have to buy mSQL (at a minute fraction
of the cost of one of the commercial offerings).
Please read the doc/License file to see if you are required to
register your copy. An invoice is included in both Postscript and
ASCII format to ease the generation of payments."
You may freely use mSQL if and only if you fall into the categories
outlined in the mSQL License file:
You can use this software free of charge if you are an educational
institution (excluding commercial training organisations),
non-commercial research organisation, registered charity,
registered not-for-profit organisation, or full-time student.
If you do not fall into any of these categories, you will have to pay
a license fee to use mSQL. As of release 1.0.16, the cost of mSQL is:
Commercial Installation - AUD $225
Private Installation - AUD $65
Exchange rates may vary wildly, but at the time of preparing this FAQ,
the Australian dollar was trading at about 0.75 US dollars. This
information is provided as an indication only. You MUST check your
local exchange rates before preparing to purchase mSQL. An online currency conversion system developed by Olsen & Associates is available at http://www.olsen.ch/cgi-bin/exmenu.
Another online currency conversion system is available from http://www.DynaMind-LLC.com/services/utilities/currency.cgi.
ftp://bond.edu.au/pub/Minerva/msql/
The latest beta version of 2.x can be found at:
http://hughes.com.au/software/msql2/current.htm
Thanks to Tobias Haecker <tobi@swl.fh-heilbronn.de>.
Thanks to Jeff Rowe <beowulf@cscsun4.larc.nasa.gov>.
Thanks to David Perry <deperry@nerosworld.com>.
Thanks to Sjoerd de Heer <sjoerd@cal038031.student.utwente.nl>.
Thanks to Davorin Bengez <Davorin.Bengez@sunsite.srce.hr>.
Thanks to Yiorgos Adamopoulos <adamo@noc.ntua.gr>.
Thanks to Jesper Hagen <hagen@iesd.auc.dk>
Thanks to David Perry <deperry@nerosworld.com>.
Thanks to Davorin Bengez <Davorin.Bengez@sunsite.srce.hr>.
The following sites mirror the mSQL 2.x software distribution:
Thanks to WorldOne http://www.worldone.com.
Thanks to David Perry <deperry@nerosworld.com>.
Thanks to Sjoerd de Heer <sjoerd@cal038031.student.utwente.nl>.
Thanks to Davorin Bengez <Davorin.Bengez@sunsite.srce.hr>.
Thanks to David Perry <deperry@nerosworld.com>.
It is available via anonymous ftp from:
ftp://bond.edu.au/pub/Minerva/msql/msql-1.0.16.tar.gz
(195705 bytes)
mSQL development is NOT David's primary role. He does this work in whatever spare time he has available so PLEASE don't pester him with requests about when we can expect future releases. Take the zen approach and just let it happen :)
A beta snapshot of mSQL version 2.0.x was released on April 11 1997. It is available from:
http://hughes.com.au/software/msql2/msql-2.0-B6.tar.gz
(371797 bytes)
It is also mirrored at a number of other sites. See the section above
titled "Are there any mirror sites for
mSQL?" for details on these mirror sites. More details on mSQL 2.0.x can be found by visiting the Hughes Technologies web pages at http://hughes.com.au.
(See http://www.cre.canon.co.uk/~neilb/weblint.html for more details on weblint).
If you want something added to the FAQ, it would be a great help if you could write a section and forward it to me - then I can simply insert it in the appropriate location.
Remember, I don't own the FAQ - I'm just its caretaker on your behalf.
The above not withstanding there is one unofficial patch that should be applied to mSQL version 1.0.16.
This patch comes from David Hughes <bambi@hughes.com.au> and fixes the very old and very obscure problem of the occasionally disappearing table.
David writes:
After sitting here banging my head against the old "missing table"
bug with my partner in crime Jason <jason@fan.net.au> , we've fixed
it !!!!! This is yet another very obscure bug. So, can it be
reproduced? Yup, once you know the problem.
o Fill the table cache
o Cause a reference to a table that doesn't exist
o The oldest cache entry will have the table definition list
set to NULL but with the name, DB, and age fields still set
We all owe a debt of thanks to Jason as it was his inability to type
table names correctly that found the problem :)
*** ./src/msql/msqldb.c.orig Sun Jul 7 16:47:09 1996
--- ./src/msql/msqldb.c Tue Jul 30 17:07:42 1996
***************
*** 1398,1403 ****
--- 1398,1406 ----
safeFree(entry->rowBuf);
safeFree(entry->keyBuf);
entry->def = NULL;
+ *(entry->DB) = 0;
+ *(entry->table) = 0;
+ entry->age = 0;
}
/*
To avoid conflicts with mismatched whitespace,
apply this patch using the
"-l" option of patch.
(That's an "el", NOT a "one" or an
"eye"). David assures us that this patch will be rolled into version 1.0.17.
The definition of NAME_LEN changed from version 1.0.10 to 1.0.12. It now seems that 18 characters is the maximum value for a table or field name. This problem exists in mSQL versions 1.0.12 and above.
David Hughes writes:
The reason it changed in 1.0.12 is because I had a couple of
field_name buffers that didn't have room for a trailing NULL. Now,
trying to fix that without altering the size of the struct implies
that you have to shorten the name of the field (to leave the
required room). I didn't want to force everyone out there to drop
and reload every database they have just because of a 1 byte buffer
over-run.
If this is a major problem for you then ....
o dump all your databases
o find the definition in question
o set it to a value you like
o rebuild everything
o reload everything
If you can work out what to change to get the extra field name
length then you know enough about what you are doing to do the rest
of what's required. I haven't provided a step-by-step because if
people can't find the value they have to change I'm sure they'd
still end up asking the list about this stuff after breaking
things.
At present there is NO patch to fix this problem. Possible
workarounds are David's method outlined above or to downgrade to
version 1.0.10.
The cleanup also changes the way in which other special characters can be searched. The tables in the section "What other characters need special treatment?" outline the differences for versions up to and including version 1.0.13 and 1.0.14 and above.
http://www.bitwizard.nl/sig11
Marty Picco writes:
I have a 200K+ record database running on a p90 with 96MB memory.
I have noticed that the first SELECT I do on this database after
msqld is started causes msqld to grab as much memory as it can...in
this case about 68MB. It appears that the memory is never released
until the daemon is restarted. Indeed, the SELECT does have an
ORDER clause.
David has said that he'll investigate this problem.
./targets/your-architecture/site.mm
and ensuring the mmap() directive reads:
MMAP=
and then compile and re-install the mSQL package.
Note: Some parts of this section have been compiled by Lloyd Parkes <Lloyd.Parkes@vuw.ac.nz>.
There are a few known problems with the current release of mSQL 2.0Bx. This list is undoubtedly incomplete and will probably remain so because of the "moving target" nature of new software.
msqldump -h dbhost -c dbname > db.dump
msql -h dbhost dbname < db.dump
Note: Simply relinking will NOT make the new functionality available - the third party application must take advantage of the new functions for you to make use of them. Relinking will only enable you to use your existing third party applications with the mSQL 2.x database server.
David Hughes writes:
TEXT fields will always be slower than CHAR fields because the data
is split over multiple buffers. As for the searching you can do
anything other than *LIKE testing at the moment. I'll try to work
out a way to do LIKE and CLIKE on TEXT fields. RLIKE is a
non-option.
msqldump -h dbhost -c dbname > db.dump
msqladmin drop dbname
msqladmin create dbname
msql -h dbhost dbname < db.dump
A patch is available from http://www.vuw.ac.nz/~lloyd/msql.
*** src/msql/msqldump.c.orig Tue Mar 25 09:49:57 1997
--- src/msql/msqldump.c Tue Mar 25 09:50:57 1997
***************
*** 346,352 ****
if (row[i])
{
if (field->type == CHAR_TYPE ||
! field->type == TEXT_TYPE)
{
tmp = escapeText(row[i]);
printf("\'%s\'", tmp);
--- 346,353 ----
if (row[i])
{
if (field->type == CHAR_TYPE ||
! field->type == TEXT_TYPE ||
! field->type == DATE_TYPE)
{
tmp = escapeText(row[i]);
printf("\'%s\'", tmp);
To avoid conflicts with mismatched whitespace,
apply this patch using the
"-l" option of patch.
(That's an "el", NOT a "one" or an
"eye").
More details are available from http://www.vuw.ac.nz/~lloyd/msql.
Brendan writes:
If you have a field that is full and you do a like/clike search
where the last character of the like string matches the last
character of the field, mSQL-2.0 b3 and 4 (at least) incorrectly
match.
Example
-------
mSQL > create table blah ( Organisation CHAR(50) ) \g
Query OK. 1 row(s) modified or retrieved.
mSQL > insert into blah Values ('1995 Hopman Cup Tennis Tournament, Perth
Western A') \g
Query OK. 1 row(s) modified or retrieved.
mSQL > select * from blah where Organisation clike '%abababa%' \g
Query OK. 1 row(s) modified or retrieved.
+----------------------------------------------------+
| Organisation |
+----------------------------------------------------+
| 1995 Hopman Cup Tennis Tournament, Perth Western A |
+----------------------------------------------------+
which of course is wrong.
Brendan also supplies a patch for this problem:
*** src/msql/types.c.orig Fri Apr 11 08:58:30 1997
--- src/msql/types.c Tue Apr 15 16:53:00 1997
***************
*** 138,144 ****
{
if (*cp1 == *cp2)
{
! if(likeTest(cp1,cp2,length-count)==1)
{
return(1);
}
--- 138,144 ----
{
if (*cp1 == *cp2)
{
! if(likeTest(cp1,cp2,length-count+1)==1)
{
return(1);
}
***************
*** 224,230 ****
{
if (toupper(*cp1) == toupper(*cp2))
{
! if(cLikeTest(cp1,cp2,length-count)==1)
{
return(1);
}
--- 224,230 ----
{
if (toupper(*cp1) == toupper(*cp2))
{
! if(cLikeTest(cp1,cp2,length-count+1)==1)
{
return(1);
}
To avoid conflicts with mismatched whitespace,
apply this patch using the
"-l" option of patch.
(That's an "el", NOT a "one" or an
"eye").
Robert writes:
LIKE & CLIKE
fixed problems with non-null terminated data.
fixed problems with _ handling.
fixed one other glitch that I don't have a good name for.
While my initial versions ran slightly slower than the original,
some recent optimisations seem to make this version very close
or better (especially for expressions with multiple %'s).
RLIKE
fixed problems with non-null terminated data.
added a larger expression cache that is a win for queries with
multiple RLIKE's or applications that repeatedly use the same
expressions. The cache size can be changed for installations
that would run better with a different size. See the code comments.
SLIKE
fixed problems with non-null terminated data.
General row matching:
fixed glitch in charMatch that would execute both the regular
and *LIKE code for the NOT *LIKE operators.
fixed glitches in rowMatch where the type checking could let
some of the *LIKE operators be applied to non-character types.
*** src/msql/types.c.orig Fri Apr 11 08:58:30 1997
--- src/msql/types.c Fri Apr 18 16:04:18 1997
***************
*** 1040,1046 ****
int matchVarChar(entry,data, cp, length, op)
cache_t *entry;
u_char *data;
! char *cp;
int length,
op;
{
--- 1040,1046 ----
int matchVarChar(entry,data, cp, length, op)
cache_t *entry;
u_char *data;
! char *cp; /* should be ok to assume this is nul-terminated */
int length,
op;
{
***************
*** 1050,1093 ****
dLen,
segLen,
cmp,
result;
u_int pos;
! bcopy(data,&dLen, sizeof(int));
! if (dLen == 0 && *cp == 0)
! return(1);
! if (dLen == 0 && *cp == 0)
! return(0);
! bcopy(data + sizeof(int) ,&pos, sizeof(u_int));
!
! cp1 = data + sizeof(int) + sizeof(u_int);
! cp2 = (u_char *)cp;
! segLen = count = dLen > length ? length : dLen;
! cmp = 0;
! while(dLen && *cp2)
{
! while(count)
{
! if ((cmp = *cp1 - *cp2) != 0)
break;
- if ( *cp1==0 || *cp2==0)
- break;
- count--;
- cp1++;
- cp2++;
- continue;
- }
- dLen -= segLen;
! if (dLen)
! {
! readOverflow(entry, pos, &pos, buf,
! dLen>OFB_SIZE? OFB_SIZE : dLen);
! cp1 = buf;
! count = segLen = dLen>OFB_SIZE? OFB_SIZE : dLen;
}
}
switch(op)
{
case EQ_OP:
--- 1050,1121 ----
dLen,
segLen,
cmp,
+ decided,
result;
u_int pos;
! cmp = 0; /* current value of match, initially equal */
! bcopy(data,&dLen, sizeof(int)); /* get length of TEXT data */
! if (*cp == 0 || dLen == 0)
{
! /* if either or both are zero length,
! * set cmp so that inequalities work.
! * Longer string is greater.
! */
! cmp = (*cp == 0) ? dLen : -1;
! }
! else
! {
! /* examine individual characters */
!
! bcopy(data + sizeof(int) ,&pos, sizeof(u_int));
!
! cp1 = data + sizeof(int) + sizeof(u_int);
! cp2 = (u_char *)cp;
! segLen = count = dLen > length ? length : dLen;
! decided = 0; /* set to 1 when final value is known */
! while(dLen && *cp2)
{
! while(count)
! {
! if ((cmp = *cp1 - *cp2) != 0)
! {
! decided = 1;
! break;
! }
! if ( *cp1==0 || *cp2==0)
! {
! decided = 1;
! break;
! }
! count--;
! cp1++;
! cp2++;
! }
!
! /* if inner loop decided the value, break this loop */
! if (decided)
break;
! dLen -= segLen;
!
! if (dLen)
! {
! readOverflow(entry, pos, &pos, buf,
! dLen>OFB_SIZE? OFB_SIZE : dLen);
! cp1 = buf;
! count = segLen = dLen>OFB_SIZE? OFB_SIZE : dLen;
! }
}
+ /* RNS:
+ * If TEXT fields are not nul-terminated, then we could run
+ * off of the end without deciding. Check here.
+ */
+ if (!decided)
+ cmp = '\0' - *cp2;
}
+
switch(op)
{
case EQ_OP:
To avoid conflicts with mismatched whitespace,
apply this patch using the
"-l" option of patch.
(That's an "el", NOT a "one" or an
"eye").
Some of these patches are for older releases of mSQL. They may have been rolled into subsequent releases of mSQL or they may not work with later releases of mSQL or they may break the successful operation of later releases of mSQL. Use them at your own risk.
A brief and no doubt incomplete list of these patches follows:
Available from:
ftp://ftp.uni-bremen.de/pub/unix/database/Minerva/patches/insert.msql-1.0.9
(593 bytes)
update account set balance = balance + 100 where nr = 12345;
Contributed by Michael Koehne
<kraehe@bakunin.north.de>. Available from:
ftp://ftp.uni-bremen.de/pub/unix/database/Minerva/patches/update.msql-1.0.9
(12677 bytes)
Available from:
ftp://ftp.uni-bremen.de/pub/unix/database/Minerva/patches/quote.msql-1.0.9
(1225 bytes)
Michael writes:
This patch includes the following features :
- Usage of double quotes for strings. I know this is not ISO
but a lot of other databases also allow double quotes and
some of my programs use double quotes.
- Speedup of regular expression.
- Simple expressions in update.
- auto primary key insert.
- Some bug fixes.
They are available via anonymous ftp from:
ftp://ftp.uni-bremen.de/pub/unix/database/Minerva/features-msql-1.0.16
(19297 bytes)
or
ftp://bond.edu.au/pub/Minerva/msql/Contrib/mSQLpatches/features.msql-1.0.16
(19297 bytes)
select name from table where name ilike 'Manu%'
Contributed by Benjamin Jacquard
<jacquard@lix.polytechnique.fr>. The patch is available via anonymous ftp from:
ftp://ftp.geo.tu-freiberg.de/pub/unix/msql/case-insensitive.patch
(8265 bytes)
The patch is available via anonymous ftp from:
ftp://ftp.infodrom.north.de/pub/mirror/msql/Patches/msqldump-1.0.16
(5275 bytes)
Robert writes:
1. Adjusted the deletion of backslashes during the mSQL to regexp
translator code to make treatment of special characters more
uniform. In other words, all regexp special characters except
backslash require only two backslashes in front of them to be
treated normally. (One is stripped by msql or the translator;
the second by the regexp package.) The backslash character
requires four backslashes because it is the escape character
for both the msql monitor and the regexp package. The single
quote, of course, remains the same needing only one backslash
because it is special only to mSQL.
So, you can all now search for \ and ^ and everything else. Or
so my ever expanding test set tells me.
2. The execution of some of the non-LIKE comparison code by the
NOT LIKE operator is fixed. (This should probably be a
miniscule performance increase--except that it might be eaten
by 1.)
*** src/msql/msqldb.c 1996/11/04 23:13:54 1.1
--- src/msql/msqldb.c 1996/11/05 01:02:01 1.2
***************
*** 3164,3176 ****
switch(*cp1)
{
case '\\':
! if (*(cp1+1) == '%' || *(cp1+1) == '_')
! {
! cp1++;
! *cp2 = *cp1;
}
- cp1++;
- cp2++;
break;
case '_':
--- 3164,3209 ----
switch(*cp1)
{
case '\\':
! /* RNS: The only time that we really want to
! drop backslashes is when they are escaping
! either % or _.
! */
! if (!*(cp1+1)) {
!
! /* keep backslash at the end of an expr. */
! *cp2 = *cp1;
! *cp1++; *cp2++;
!
! } else {
!
! if ((*(cp1+1) == '%') || (*(cp1+1) == '_')) {
!
! /* drop backslash when followed by
! % or _.
! */
! cp1++;
! *cp2 = *cp1;
! cp1++; cp2++;
!
! } else if (*(cp1+1) == '\\') {
!
! /* keep both backslashes when they escape
! themselves
! */
! *cp2 = *cp1;
! *cp1++; *cp2++;
! *cp2 = *cp1;
! *cp1++; *cp2++;
!
! } else {
!
! /* keep the backslash so it can escape
! some other regexp character.
! */
! *cp2 = *cp1;
! *cp1++; *cp2++;
! }
}
break;
case '_':
***************
*** 3351,3357 ****
REG char *c1,*c2;
REG int offset;
! if (op != LIKE_OP)
{
c1 = v1;
c2 = v2;
--- 3384,3394 ----
REG char *c1,*c2;
REG int offset;
! if ((op == LIKE_OP) || (op == NOT_LIKE_OP))
! {
! cmp = regexpTest( v1, v2, maxLen );
! }
! else
{
c1 = v1;
c2 = v2;
***************
*** 3395,3405 ****
break;
case LIKE_OP:
! result = regexpTest(v1,v2,maxLen);
break;
case NOT_LIKE_OP:
! result = !(regexpTest(v1,v2,maxLen));
break;
}
return(result);
--- 3432,3442 ----
break;
case LIKE_OP:
! result = cmp;
break;
case NOT_LIKE_OP:
! result = !cmp;
break;
}
return(result);
ftp://bond.edu.au/pub/Minerva/msql/Contrib/mSQLSSL/msql-1.0.16-patch.tar.gz
(7183 bytes)
Etienne writes:
I just want to share this little patch which solve the mmap problem
for NeXTSTEP. It apparently works (meaning all msql tests are OK)
for:
NSFIP 3.3 p1
NS Motorola 3.3 p1.
It does NOT work for HP 3.2
All other configurations are untested !
Thanks to the authors Fabien Roy and Robert Ehrlich for this patch !
Etienne Klein
Laboratoire de Chimie Analytique
Faculte de Pharmacie de Nancy
France
/*
* @(#)map.c 1.0 of 20 December 1996
*
* Copyright (c) 1996 by Fabien Roy.
* Written by Fabien Roy and Robert Ehrlich.
* Fabien_Roy@free.fdn.fr Robert.Ehrlich@inria.fr
* Not derived from licensed software.
*
* Permission is granted to anyone to use this software for any
* purpose on any computer system, and to redistribute it freely,
* subject to the following restrictions:
*
* 1. The author is not responsible for the consequences of use of
* this software, no matter how awful, even if they arise
* from defects in it.
*
* 2. The origin of this software must not be misrepresented, either
* by explicit claim or by omission.
*
* 3. Altered versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
*/
#include <sys/types.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <syscall.h>
caddr_t
mmap(caddr_t addr, size_t len, int prot, int flags, int fd, off_t off)
{
int pagelessone = getpagesize() -1;
int size;
caddr_t pageaddress;
/* round to next page size */
size = (len + pagelessone) & ~pagelessone;
/* allocate aligned pages */
if (!(pageaddress = (caddr_t) valloc(size)))
return (caddr_t) -1;
/* map it */
if (syscall(SYS_mmap, pageaddress, size, prot,
flags, fd, off)){
free(pageaddress);
return (caddr_t) -1;
}
return pageaddress;
}
void
munmap(caddr_t addr, size_t len)
{
syscall(SYS_munmap,addr,len);
free(addr);
}
The easiest way to apply these patches is to use Larry Wall's patch program:
Patch will take a patch file containing any of the four forms of
difference listing produced by the diff program and apply those
differences to an original file, producing a patched version. By
default, the patched version is put in place of the original, with
the original file backed up to the same name with the extension
".orig".
Patch is available from a number of anonymous ftp sites
worldwide. Latest versions of patch are being distributed by
the Free Software Foundation as part of the GNU suite of products. If you're having difficulty finding the latest version of patch, you can download version 2.1 via anonymous ftp from:
ftp://bond.edu.au/pub/Minerva/msql/Misc/patch-2.1.tar.gz
(74856 bytes)
While some patches are fairly simple - often involving minor changes
to a single line of code - others are quite complex and attempting to
apply these patches by hand is definitely NOT recommended. Use the
patch program whenever you need to apply a patch. To apply the patches listed in this FAQ, use this procedure:
You should be left with a file containing a number of sections similar to:
*** ./src/msql/net.c.orig Tue Oct 17 11:24:03 1995
--- ./src/msql/net.c Tue Dec 12 15:24:11 1995
***************
*** 66,72 ****
! void writePkt(fd)
int fd;
{
u_char *cp;
--- 66,72 ----
! int writePkt(fd)
int fd;
{
u_char *cp;
cd /usr/local/src/db/Minerva/msql/msql-1.0.16
patch -l < /tmp/msql-patch1
The "-l" option is used to tell patch
to ignore any whitespace mismatches between lines in the patch file
and lines in the mSQL source file. (That's an "el",
NOT a "one" or an "eye"). Patch will respond with output similar to:
Hmm... Looks like a new-style context diff to me...
The text leading up to this was:
--------------------------
|*** ./src/msql/net.c.orig Tue Oct 17 11:24:03 1995
|--- ./src/msql/net.c Tue Dec 12 15:24:11 1995
--------------------------
Patching file ./src/msql/net.c using Plan A...
Hunk #1 succeeded at 66.
Hunk #2 succeeded at 84.
done
If you have problems applying the patch, you may wish to consider
using some or all of the following arguments to patch:
forces patch to create a backup of the original file. By default it adds a .orig suffix to the original filename.
forces patch to ignore patches that it thinks are reversed or already applied.
forces patch to honour the full pathname of the files listed in the patch file.
http://Hughes.com.au
Jeff Rowe
<beowulf@cscsun4.larc.nasa.gov> has converted the mSQL
documentation to HTML format. It is available from:
http://cscsun1.larc.nasa.gov/~beowulf/msql/msql.html
Tim Finin <finin@umbc.edu>
has created an online mSQL tutorial. It is available from:
http://www.cs.umbc.edu/~finin/461/msql
Mike Carpenter
<mikec@emi.net> has begun to collate the available mSQL
documentation into a single site. He hopes to have a wide range of
resources available for value added mSQL products such as the Perl and
Java interfaces. His work can be found at:
http://www.emi.net/~mikec/tech/msql.html
To subscribe to the list, send the word "subscribe" in the body of your message to msql-list-request@bunyip.com.
To unsubscribe from the list send the word "unsubscribe" in the body of your message to msql-list-request@bunyip.com.
Postings should be addressed to msql-list@bunyip.com.
Archives of the mailing list are available via anonymous ftp from:
ftp://ftp.bunyip.com/pub/mailing-lists/msql-list.archive/
Each month's archive is stored in a file:
msql-list.archive.YYMM
where YYMM represents the year and month. So the archive for
October 1995 would be in the file:
msql-list.archive.9510
These files are also available from the
majordomo
mailing list server at bunyip.com.
To receive a list of the archive files available as well as the
majordomo help file send a message to
majordomo@bunyip.com with the
text:
index msql-list
help
END
in the body of the message. To reach a human for help regarding the mailing list send a note to:
owner-msql-list@bunyip.com
or
listmaster@bunyip.com
The mailing list discusses issues that arise from the use of mSQL and
W3-mSQL (both products developed by David Hughes). Often discussions on
contributed software arise but it is probably best to take these
discussions off line and summarise solutions back to the list. Traffic on the list is fairly high. There were approximately 1100 postings between April 1 1996 and May 31 1996 which gives an average of around 550 messages per month. (If you think this is high, try subscribing to the firewalls list - this has an average of around 1000 postings per month!)
Turn around times for postings can sometimes be a little slow. It is not unusual for messages sent from Australia to take a few hours to appear on the list. List subscribers from other countries have also reported similar turn around times. Please be patient.
To unsubscribe from the list digest send the words "unsubscribe msql-list-digest" in the body of your message to majordomo@bunyip.com.
| Archive Location | Features |
|---|---|
|
http://www.tryc.on.ca/msql.html (Thanks to Wojciech Tryc <wojtek@tryc.on.ca>). |
Threaded archives, monthly breakdown, recent archives, search facilities. |
|
http://tacyon.spectrum.com.au/mail/msql (Thanks to Matt Perkins <matt@spectrum.com.au>). |
Threaded archive, list archive, old list archives. |
|
http://cure.medinfo.org/lists/programming/index.html (Thanks to the folks at Medinfo http://cure.medinfo.org). |
Threaded archive, browse current month, search list archive. |
|
http://www.nexial.nl/cgi-bin/msql (Thanks to Kim Hendrikse <kim@nexial.nl>). |
Fuzzy searchable archive. |
This question comes up about every three months or so - usually from new subscribers to the mSQL mailing list who haven't seen the previous threads.
There seem to be two distinct groups of people involved in this discussion:
Nor does it preclude you from establishing a global news group. There are well defined channels established within the Usenet community for the creation of new news groups.
One publicly available mail/news gateway is available via anonymous ftp from:
ftp://ftp.vix.com/pub/inn/contrib/newsgate.tar.Z
(443025 bytes)
It includes the programs mail2news and news2mail.
Is there any way I can find the answer to this question myself?
If you can figure out a way to simply find the answer, then it will
probably be quicker than asking the list. If you think your answer
would be helpful to others then post a summary to the mailing list.
Postings should be addressed to msql-list@bunyip.com.
IF YOU POST A QUESTION TO THE LIST ASKING FOR HELP, YOU
MUST INCLUDE THE FOLLOWING INFORMATION!
Failure to include these details makes it almost impossible to pinpoint
the cause of your problem.
uname -a
msqladmin version
http://Hughes.com.au/product/msql/history.htm
If you want to report a bug, send a report to the mSQL bug reporting address at msql-bugs@hughes.com.au. You may also wish to copy your report to the mSQL mailing list at msql-list@bunyip.com.
When making your bug report, please include the following information:
msqld.c
Save the original file as follows:
cp ./src/msql/msqld.c ./src/msql/msqld.c.orig
Make your changes to the file:
./src/msql/msqld.c
diff -c ./src/msql/msqld.c.orig ./src/msql/msqld.c
ftp://bond.edu.au/pub/Minerva/msql/Incoming
then notify David at
<bambi@hughes.com.au>.
He will move your contribution to the mSQL
contributions
directory:
ftp://bond.edu.au/pub/Minerva/msql/Contrib
Note: The directory permissions for
ftp://bond.edu.au/pub/Minerva/msql/Incoming prohibit the
viewing of any files contained therein. This is a security feature
implemented by the system administration staff at
Bond University to eliminate recent
attempts to use the ftp server as a relay for the unauthorised transfer
of commercial software. If you upload any software to this directory,
you must notify
<bambi@hughes.com.au> to
have it moved to
ftp://bond.edu.au/pub/Minerva/msql/Contrib. You may like to discuss your proposed code with others on the mSQL mailing list. The subscribers to this list may be able to help you with improvements or modifications to your code or advise you of work already available in your area.
If you're writing code in other languages, have a look through the distribution of the mSQL language extension itself for examples. Another good place to look is the mSQL mailing list archives.
| Support Programs bundled with mSQL version 1.x | |
|---|---|
| msqld | the mSQL database server. |
| msqladmin | handles administrative details such as creation and deletion of databases, server shutdown etc. |
| msql | the mSQL monitor. It provides a user interface for making SQL queries on databases. |
| msqldump | Dumps a database in ASCII format. The dump takes the form of SQL commands so that the entire database can be re-created from the dump file. |
| relshow | The mSQL schema viewer. Shows table details for a given database. |
| Support Programs bundled with mSQL version 2.x | |
|---|---|
| msql2d | the mSQL database server. |
| msqladmin | handles administrative details such as creation and deletion of databases, server shutdown etc. |
| msql | the mSQL monitor. It provides a user interface for making SQL queries on databases. |
| msqldump | Dumps a database in ASCII format. The dump takes the form of SQL commands so that the entire database can be re-created from the dump file. |
| msqlexport | Dumps a database in ASCII format. The dump takes the form of user defined character delimited fields suitable for importing into other vendor's databases. |
| msqlimport | Loads a flat file in ASCII format into an mSQL database. |
| relshow | The mSQL schema viewer. Shows table details for a given database. |
| w3-msql | CGI program that allows users to embed mSQL statements in their HTML documents. |
| w3-auth | Access control and authentication module for use with w3-msql |
| lite | A stand alone mSQL scripting language. |
For more details on these programs see the documentation that comes with mSQL.
| mSQL version 1.x |
|---|
CREATE TABLE table_name (
col_name col_type [ not null | primary key ]
[, col_name col_type [ not null | primary key ] ]**
)
|
DROP TABLE table_name |
INSERT INTO table_name [ ( column [ , column ]** ) ]
VALUES (value [, value]** )
|
DELETE FROM table_name
WHERE column OPERATOR value
[ AND | OR column OPERATOR value ]**
OPERATOR can be <, >, =, <=, >=, <>, or LIKE
|
SELECT [ DISTINCT ] [table.]column [ , [table.]column ]**
FROM table [ = alias] [ , table [ = alias] ]**
[ WHERE [table.]column OPERATOR VALUE
[ AND | OR [table.]column OPERATOR VALUE]** ]
[ ORDER BY [table.]column [DESC] [, [table.]column [DESC] ] [LIMIT n]
OPERATOR can be <, >, =, <=, >=, <>, or LIKE
VALUE can be a literal value or a column name
|
UPDATE table_name SET column=value [ , column=value ]**
WHERE column OPERATOR value
[ AND | OR column OPERATOR value ]**
OPERATOR can be <, >, =, <=, >=, <>, or LIKE
|
For more details see the documentation that comes with mSQL version 1.x.
mSQL version 2.x supports the following SQL commands:
| mSQL version 2.x |
|---|
CREATE TABLE table_name (
col_name col_type [ not null ]
[, col_name col_type [ not null ] ]**
)
|
CREATE [ UNIQUE ] INDEX index_name ON table_name (
col_name [, col_name ]**
)
|
CREATE SEQUENCE ON table_name
[ STEP step_val ] [ VALUE initial_val ]
|
DROP TABLE table_name |
DROP INDEX index_name FROM table_name |
DROP SEQUENCE FROM table_name |
INSERT INTO table_name [ ( column [ , column ]** ) ]
VALUES (value [, value]** )
|
DELETE FROM table_name
WHERE column OPERATOR value
[ AND | OR column OPERATOR value ]**
OPERATOR can be <, >, =, <=, >=, <>, LIKE, RLIKE or CLIKE
|
SELECT [ DISTINCT ] [table.]column [ , [table.]column ]**
FROM table [ = alias] [ , table [ = alias] ]**
[ WHERE [table.]column OPERATOR VALUE
[ AND | OR [table.]column OPERATOR VALUE]** ]
[ ORDER BY [table.]column [DESC] [, [table.]column [DESC] ] [LIMIT n]
OPERATOR can be <, >, =, <=, >=, <>, LIKE, RLIKE or CLIKE
VALUE can be a literal value or a column name
WHERE clauses may contain parentheses () to nest conditions
|
UPDATE table_name SET column=value [ , column=value ]**
WHERE column OPERATOR value
[ AND | OR column OPERATOR value ]**
OPERATOR can be <, >, =, <=, >=, <>, LIKE, RLIKE or CLIKE
|
For more details see the documentation that comes with mSQL version 2.x.
Under mSQL version 1.x any single field of a table can be designated as the PRIMARY KEY. These keys are, by definition, unique. mSQL version 1.x does not support multiple keys within a table.
The creation of a PRIMARY KEY is made during the table declaration, for example:
CREATE TABLE employee (
employee_number INT PRIMARY KEY,
department CHAR(20),
first_name CHAR(20) NON NULL,
last_name CHAR(20) NON NULL
)
CREATE TABLE department (
department_name CHAR(20) PRIMARY KEY
)
For more details see the documentation that comes with mSQL version
1.x. mSQL version 2.x has disposed of the PRIMARY KEY in favour of an indexing mechanism.
An INDEX may be created for any field of a table at any time, for example:
CREATE UNIQUE INDEX idx1 ON employee(employee_number)
CREATE INDEX idx2 ON employee(first_name, last_name)
This examples shows that the first INDEX, idx1, is
unique. This is identical to the PRIMARY KEY concept used by
mSQL version 1.x. The second INDEX, idx2, need
not be unique. idx2 also spans two fields within a table which
will improve performance whenever a search is made based on these two
fields. These indices will be used automatically whenever a query is sent to the database engine that uses those fields in its WHERE clause. The user is not required to specify any special values in the query to ensure the indices are used to increase performance.
int (4 bytes) -2147483646 <= i <= 2147483647
real (8 bytes) 4.94E-324 <= x <= 1.79E+308, -1.79E+308 <= x <= -4.94E-324
char
The internal storage for types int and real is held at
4 bytes and 8 bytes respectively, regardless of the system architecture
you're using. So even on 64 bit Crays a real will be 8 bytes.
There is NO fixed limit on the size of a character field. Provided you declare it correctly when the table is defined, mSQL will handle fields of at least several thousand characters without problems. You may run into difficulty actually using fields of this size in whatever language you choose to interface to the mSQL database engine.
Note: If you declare a char field with a large size, each and every row in the table will allocate sufficient storage space for the char field - whether the full size of the field is used or not. This may lead to very large database tables indeed.
An example of each mSQL version 1.x datatype within a table declaration follows:
CREATE TABLE table_name (
field_name_1 INT PRIMARY KEY,
field_name_2 REAL,
field_name_3 CHAR(10) NOT NULL,
field_name_4 CHAR(80),
field_name_5 INT NOT NULL,
field_name_6 REAL
)
For more details see the documentation that comes with mSQL version
1.x. mSQL version 2.x supports the following datatypes:
int (4 bytes) -2147483646 <= i <= 2147483647
uint (4 bytes) 0 <= i <= 4294967295
real (8 bytes) 4.94E-324 <= x <= 1.79E+308, -1.79E+308 <= x <= -4.94E-324
char
text
date
time
money
The internal storage for types int/uint and real is
held at 4 bytes and 8 bytes respectively, regardless of the system
architecture you're using. So even on 64 bit Crays a real will
be 8 bytes. There is NO fixed limit on the size of a character field. Provided you declare it correctly when the table is defined, mSQL will handle fields of at least several thousand characters without problems. You may run into difficulty actually using fields of this size in whatever language you choose to interface to the mSQL database engine.
Note: If you declare a char field with a large size, each and every row in the table will allocate sufficient storage space for the char field - whether the full size of the field is used or not. This may lead to very large database tables indeed.
text (or other 8 bit data) fields are defined with an expected average length. Values longer than the specified length will be split between the data table and external overflow buffers. text fields are slower to access than char fields and cannot be used in an index or in LIKE tests.
An example of each mSQL version 2.x datatype within a table declaration follows:
CREATE TABLE table_name (
field_name_1 INT,
field_name_2 REAL,
field_name_3 CHAR(10) NOT NULL,
field_name_4 CHAR(80),
field_name_5 INT NOT NULL,
field_name_6 REAL,
field_name_7 TEXT(25),
field_name_8 DATE,
field_name_9 UINT,
field_name_10 TIME,
field_name_11 MONEY
)
Note: The storage of real numbers is highly machine dependent.
If you store the number 10.03 don't be surprised if it is
actually stored as either 10.03 or 10.03000000001 or
10.02999999999. Note: The upper and lower limits for real numbers are also highly machine dependent. Both mSQL version 1.x and 2.x obtain these values from the system include file:
/usr/include/limits.h
If you plan on storing very big numbers (positive or negative numbers
with exponents approaching 308) or very small numbers (positive or
negative numbers with exponents approaching -324) you MUST check
whether your operating system will support them. Note: When dealing with real numbers it might be advisable to either convert the real number to an integer if possible. For example if you are dealing with decimal currency, it may be preferable to work in units of cents rather than dollars - note that mSQL 2.x now has a MONEY type which handles this concept - or to perform some sort of delta check when retrieving values. The following logic demonstrates one possible application of this concept:
delta = 0.00001
select a real number from a table
if abs(number - expected value) < delta
then
proceed
else
fail
| mSQL version 1.x | ||
|---|---|---|
| Return Type | Prototype | Type |
| int | msqlConnect(char *host); | FUNCTION |
| int | msqlSelectDB(int sock, char *dbname); | FUNCTION |
| int | msqlQuery(int sock, char *query); | FUNCTION |
| m_result * | msqlStoreResult(); | FUNCTION |
| void | msqlFreeResult(m_result *result); | FUNCTION |
| m_row | msqlFetchRow(m_result *result); | FUNCTION |
| void | msqlDataSeek(m_result *result, int pos); | FUNCTION |
| int | msqlNumRows(m_result *result); | MACRO |
| m_field * | msqlFetchField(m_result *result); | FUNCTION |
| void | msqlFieldSeek(m_result *result, int pos); | FUNCTION |
| int | msqlNumFields(m_result *result); | MACRO |
| m_result * | msqlListDBs(int sock); | FUNCTION |
| m_result * | msqlListTables(int sock); | FUNCTION |
| m_result * | msqlListFields(int sock, char *tableName); | FUNCTION |
| void | msqlClose(int sock); | FUNCTION |
For more details see the documentation that comes with mSQL version 1.x.
Note: The PostScript documentation that comes with mSQL version 1.x lists the function msqlClose() as type int. This is incorrect. It is actually type void.
| mSQL version 2.x | ||
|---|---|---|
| Return Type | Prototype | Type |
| int | msqlConnect(char *host); | FUNCTION |
| int | msqlSelectDB(int sock, char *dbname); | FUNCTION |
| int | msqlQuery(int sock, char *query); | FUNCTION |
| m_result * | msqlStoreResult(); | FUNCTION |
| void | msqlFreeResult(m_result *result); | FUNCTION |
| m_row | msqlFetchRow(m_result *result); | FUNCTION |
| void | msqlDataSeek(m_result *result, int pos); | FUNCTION |
| int | msqlNumRows(m_result *result); | MACRO |
| m_field * | msqlFetchField(m_result *result); | FUNCTION |
| void | msqlFieldSeek(m_result *result, int pos); | FUNCTION |
| int | msqlNumFields(m_result *result); | MACRO |
| m_seq * | msqlGetSequenceInfo(int sock, char *table); | FUNCTION |
| m_result * | msqlListDBs(int sock); | FUNCTION |
| m_result * | msqlListTables(int sock); | FUNCTION |
| m_result * | msqlListFields(int sock, char *tableName); | FUNCTION |
| m_result * | msqlListIndex(int sock, char *tableName, char *index); | FUNCTION |
| void | msqlClose(int sock); | FUNCTION |
| char | msqlUnixTimeToDate(char *date); | FUNCTION |
| char | msqlUnixTimeToTime(char *date); | FUNCTION |
| time_t | msqlDateToUnixTime(char *date); | FUNCTION |
| time_t | msqlTimeToUnixTime(char *date); | FUNCTION |
For more details see the documentation that comes with mSQL version 2.x.
Note: The HTML documentation that comes with mSQL version 2.x lists the function msqlClose() as type int. This is incorrect. It is actually type void.
This feature may be included in mSQL version 2.
As an example, consider this method to find the list of grandparents from a child/parent tuple:
SELECT t1.parent, t2.child from parent_data=t1,parent_data=t2
WHERE t1.child=t2.parent
mSQL also supports the SQL standard method of table aliasing which uses
either a space character or the keyword AS instead of an = character.
So the above example can also be written as either:
SELECT t1.parent, t2.child from parent_data t1,parent_data t2
WHERE t1.child=t2.parent
or
SELECT t1.parent, t2.child from parent_data AS t1,parent_data AS t2
WHERE t1.child=t2.parent
mSQL has an access control file which allows the database administrator to control access on a user and host level.
For more details see the documentation that comes with mSQL.
mSQL does not support access control from within SQL commands.
The current release of mSQL has NO direct support for BLOBs. However, you can always store the path name of a file that points to the BLOB in one of the fields of your table. Then your application can deal with the file name appropriately.
If you're dealing with large blocks of text, you may also wish to consider this approach from Pascal Forget <pascal@wsc.com>:
Another possible hack would be to have the "block_text"
record contain a pointer to a "text_lines" table. This
table would contain a linked list of text lines like this:
CREATE TABLE text_lines (
line_id int primary key,
string char(80),
next_line int
)
Mike Eggleston
<mikee@sys8.wfc.com>
offers this solution:
What I prefer to do in databases where I have text fields containing
near infinite amounts of text is to define several tables like:
create table prog (
id int,
name char(40),
programmer char(40),
....
)\p\g
create table descript (
id int,
line int,
descript char(100)
)\p\g
Then in a program I break up the text as necessary and put one line
of text in each record of <descript>. When I want it back, by
program, I [use]
select line, descript from prog, descript
where prog.id = descript.id
and name = 'foobar' order by line\p\g
Later versions of mSQL may have support for BLOBs.
The mSQL server handles requests serially - that is only one user's request is handled at a time. Therefore there is no danger of a user reading from a table that is currently being updated by another user.
However, there is the possibility that the same read operations may straddle another user's write operation so that different data will be returned from each read.
mSQL version 2 will provide client initiated locking.
19 ----- \ \ i 52 * / 63 = 813621925049196536663393538834956800 / ----- i = 0Though in practise, many of these combinations will probably remain unused.
While not recommended, the default maximum name length value of 20 can be changed by editing the mSQL source code. However, if you change it AFTER you have already created ANY databases, the old databases will be unreadable. To avoid this problem, follow this procedure:
./src/msql/msql_priv.h
Change the line reading
#define NAME_LEN 19 /* Field/table name length */
to suit your needs. Ensure that you use a number that is one less
than the maximum value you desire. For example, if you wish to have
a name length of 36 you would change the line to read:
#define NAME_LEN 35 /* Field/table name length */
./src/msql/msql_priv.h
contains the definitions of the internal mSQL limits:
#define MAX_FIELDS 75 /* Max fields per query */
#define MAX_CON 24 /* Max connections */
#define BUF_SIZE (256*1024) /* Read buf size if no mmap() */
#define NAME_LEN 19 /* Field/table name length */
#define PKT_LEN (32*1024) /* Max size of client/server packet */
#define CACHE_SIZE 8 /* Size of table cache */
If you want to increase them you can just edit this file and recompile.
Don't change MAX_CON or CACHE_SIZE without understanding why these
limits are set (maximum file descriptors per process etc). Changing any of these parameters will almost certainly make any existing databases unreadable. To avoid this problem, follow this procedure:
./src/msql/msql_priv.h
changing the definitions to suit your needs.
Consider the SQL query:
SELECT something from somewhere WHERE
name='jan' or country='italy' and sex='female' or title='ms'
Under mSQL version 1.x, the parser will scan the condition
from left to right. So in this example the condition reads:
((name='jan' or country='italy') and sex='female') or title='ms'
mSQL version 1.x does NOT support parentheses in logical
expressions, so there is NO way to change this parsing. Ted Harding <Ted.Harding@nessie.mcc.ac.uk> provides some solutions for three component queries.
Ted writes:
Let's get something clear: ALL 3-component (or equivalent) queries
can be implemented in mSQL (without parentheses and using the mSQL
left-to-right evaluation). There are only the following:
(A and B) and C = A and (B and C) = A and B and C
(A or B) or C = A or (B or C) = A or B or C
(A and B) or C = A and B or C
A and (B or C) = (B or C) and A = B or C and A
(A or B) and C = A or B and C
A or (B and C) = (B and C) or A = B and C or A
Queries like A and B and C and (E or F) are the same as (A and B
and C) and (E or F) which is the same form as G and (E or F).
The trouble starts with 4-component queries such as (A or B) and (C
or D) for which there is no one-pass generally correct mSQL
representation.
mSQL version 2.x allows parentheses within logical expressions
so this limitation is eliminated.
In C, for example, see the manual pages on atoi().
Does SELECT return the rows always in order 'first inserted first',
if there is no ORDER statement given, and the rows are selected
from one table only, and there has been no DELETEs on that table?
It seems be so, but is it guaranteed?
David Hughes replied:
This is guaranteed. The only time the rows will be returned in
another order is if you have deleted a row and it's then filled by
a later insert.
I am new at mSQL, and have a beginner question: Is it possible to
create a table "normally", and to have the fields of one
of the column being[sic] another table?
David Hughes replied:
You can't nest tables in mSQL (don't think you can in ANSI SQL
either). What you can do is to use a common value as a key to join
the contents of two tables (eg. a part number or a user ID).
/usr/local/Minerva/
then the databases will be created in the directory:
/usr/local/Minerva/msqldb/
Note that this can be overridden by specifying the MSQL_HOME
environment variable when starting
msqld. Each table in the database is stored as a number of files:
For each field in a table, mSQL will also store an additional flag byte. mSQL also stores an additional flag byte for each row of the table.
Consider the following table:
CREATE TABLE test (
f0 char(13),
f1 int,
f2 real,
f3 real,
f4 real,
f5 real,
f6 int
)
Storage space for each row of this table would be:
(13 * char) + (2 * int) + (4 * double) + (7 * fields) + (1 * rows)
= (13 * 1) + (2 * 4) + (4 * 8) + (7 * 1) + 1
= 61 bytes
So if this table had 1000 records, it would occupy 61000 bytes of
disk space. (In reality it may occupy slightly more real disk space
because of the way the underlying file system behaves. This is
operating system specific and not really an issue to worry about.
If you do an 'ls -l' on the file it will show 61000
bytes).
The size of this file will be the size of the key plus one flag byte times the number of rows in the table. In the above example, if the table was defined as:
CREATE TABLE test (
f0 char(13) primary key,
f1 int,
f2 real,
f3 real,
f4 real,
f5 real,
f6 int
)
and the table had 1000 rows, the size of the data file would still
be 61000 bytes and the size of the key file would be:
((13 * char) + 1) * 1000
= ((13 * 1) + 1) * 1000
= 14 * 1000
= 14000 bytes
Each field in the table has a 64 byte definition. Using the example above, the table has 7 fields so the size of the definition file will be:
7 * 64 = 448 bytes
For every hole in the table, this file will contain a 4 byte integer indicating the row number of the hole. It is accessed like a stack. When a row is deleted, it's index is appended to the file. When an insert is done, the last 4 bytes are "popped" off the file and the file is truncated back 4 bytes.
If the table contains 20 holes, the size of the stack file will be:
20 * 4 = 80 bytes
If the table contains no holes then this file will have zero
length.
table_storage_requirements
= expected_max_rows *
(
number_of_fields + 1 + total_chars +
(4 * total_ints) + (8 * total_reals) +
(size_of_key + 1) +
(4 * expected_deletion_ratio)
) +
(total_fields * 64)
table_storage_requirements
= expected_max_rows *
(
number_of_fields + 1 + total_chars +
(4 * total_ints) + (8 * total_reals) +
(4 * expected_deletion_ratio)
) +
(total_fields * 64)
10000 *
(
7 + 1 + 13 +
(4 * 2) + (8 * 4) +
(13 + 1) +
(4 * 0.10)
) +
(7 * 64)
= 10000 * ( 21 + 8 + 32 + 14 + 0.4) + 448
= 754448 bytes
plus a handful of bytes to store file names in directories. Note that this is the maximum storage allocation. Unlike some other database systems, mSQL only uses disk space when it has data to add to a table - it does NOT allocate a large block of empty disk space and then proceed to fill it. If our example only had 1000 rows the storage requirements would only be 75848 bytes.
does msqld allocate more ram to itself as new db's are added? i.e.
is any part of the database held in ram or does it just access the
database files directly from disc? I need to do some planning, and
want to know if I need to plan to get more simms...
David Hughes replies:
If your OS supports mmap() (e.g. Solaris, SunOS, *BSD, BSDI, Linux
1.3.x, HP-UX >9.x) then the more memory you throw at it the
better things will get if you are using big databases. The data is
left on disk but is accessed via the virtual memory subsystem so it
will be in memory some of the time.
If you are not using mmap() then data is just read from disk as it
is needed. There's a small buffer in the read code to make things
faster but that's about it. It doesn't matter how many databases
you have defined it only uses 1 buffer.
Does performance degrade at all as the number of databases
increases? That is, say a query from database A took n seconds when
database A was the only one served by msqld. After adding databases
B, C, D and E, should the database A query take any longer? It
seems like 'no' from my experience, but...
David Hughes replies:
No. It will degrade if people are hitting the new databases at the
same time as they are hitting database A though. msqld only handles
1 query at a time so if 2 queries come in they are queued and
processed in order.
> To browse the database, I want mSQL to return me the first row
> in the database, and keep a pointer to it. Then sometime later
> I can ask it for the second row, and so on.
mSQL does not provide support for cursors.
You'll have to issue a SELECT query each time you want the next
row. mSQL has no provisions for modifying a result set once it has
been created. I suggest you add a field containing a unique
identifier for each row, then fetch the next row using:
SELECT ... FROM mytable where unique_field > last_id LIMIT 1
> How do I express this in sql?
If you find a way to express it, it most certainly won't be in
standard SQL, as the language has no support for cursors.
> I see that I could add an explicit field that was an arbitrary
> row number, and query for the current row number +/- 1, but over
> time with insertions and deletions there would be gaps and the
> query would break. How is this problem usually solved?
The select statement I gave you won't break even if there are gaps
in the unique identifiers. You can periodically "compact" the
numbers if you want.
Yes, as long as the client that fetches the characters knows what
character set you are using. I.e. there is no support in mSQL for
keeping track of the character set name, but mSQL is 8bit clean so
you can store 8bit characters (in whatever character set).
In Digger, the Whois++ server, we store UNICODE characters by
encoding them first into UTF-8 which is an 8bit encoding scheme
described in UNICODE 1.1.
Neil Bowers
<neilb@cre.canon.co.uk> has written a paper on
"Processing Japanese Text with mSQL and Perl". It is
available from:
http://www.cre.canon.co.uk/~neilb/jmSQL.html
AFS does not support some Unix file system behaviour that's needed
by mSQL. You cannot create Unix domain sockets in AFS space, and
mmap() does not work on at least some client-server combinations,
if not all.
You should install mSQL and its databases in NFS or local Unix
filesystems.
Other users have also reported problems when running mSQL from NFS
mounted partitions. To be absolutely safe you should only run
msqld from the same machine on which the physical disks
containing the mSQL databases are attached.
The solution to the problem with using the socket and then nsl
libraries with NIS in IRIX 5.2 is:
1. Do not link them if they are not needed :) This is the case for
mSQL.
or
2. link libc BEFORE the socket and the nsl libraries.
For those who didn't know, the problem is that if you use NIS and
link socket or nsl, the getpwuid() function doesn't work.
To ensure that the unnecessary libraries are avoided, edit
targets/your-architecture/site.mm and change the line
EXTRA_LIB= -lsocket -lnsl -lgen -ldl
so that it reads:
EXTRA_LIB=
Looks like the same thing that happens under HP-UX with background
processes in rc scripts. They are killed off on exit of the ksh
functions.
Create yourself a wrapper for msqld. In there you do a fork and
exit the parent process in the child process you do a call to
setsid() to get rid of the controlling terminal followed by a call
to execl() to launch msqld. You might also want to close all open
file descriptors before calling exec.
An alternative to this approach is to place the following in
/etc/inittab
msql:3:respawn:/usr/local/Minerva/bin/msqld </dev/console >/dev/console 2>&1
This assumes that your mSQL super user is "root".
The next version of the FAQ will attempt to address this issue in detail.
DEC Alphas running OSF/1 (Digital Unix): The original mSQL docs
recommended using cc rather than gcc on this platform. In my
experience this is still good advice. If you have gcc on the
machine, however, autoconf will find it and default to it. After
running 'setup' edit site.mm and change 'gcc' to 'cc' and
'bison -y' to yacc.
If you have an earlier version of Linux you can either upgrade or ensure that mmap() support in mSQL is disabled by running the 'setup' program and then editing
./targets/your-architecture/site.mm
and ensuring the mmap() directive reads:
MMAP=
and then recompile the mSQL package.
I just built msql-1.0.10 on hpux 9.05. It appears that you have
slain the mmap bug. Good job. The