                                The mSQL FAQ

$Revision: 1.24 $

$Date: 1996/12/16 11:22:25 $

                                  Preamble

A text copy of this FAQ can be obtained via anonymous ftp from:

    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

It may take a couple of days for the new versions of the FAQ to be moved
into the mSQL area. If you're desperate for the latest FAQ try looking for:

    ftp://bond.edu.au/pub/Minerva/msql/Incoming/faq.txt

        or

    ftp://bond.edu.au/pub/Minerva/msql/Incoming/faq.html

This FAQ is maintained by Peter Samuel <Peter.Samuel@uniq.com.au>.

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.

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".

----------------------------------------------------------------------------
          ---------------------------------------------------------

                                  Contents

   * General Information
       1. What is SQL?
       2. (=) Books on SQL and mSQL?
       3. What is mSQL?
       4. What platforms will it run on?
       5. (-) Is it free?
       6. Where can I get it?
       7. (=) Are there any mirror sites for mSQL?
       8. What is the latest version?
       9. (-) When will the next version be released?
      10. Why is David called Bambi?
      11. (-) How is this FAQ prepared?

   * Help and Support
       1. Are there any recommended patches to the latest version?
       2. (-) Are there any known bugs or problems with the current release
          of mSQL?
       3. (-) Are there any other patches available?
       4. How do I apply patches to the mSQL source?
       5. (-) Is online documentation available?
       6. Is there a mailing list for mSQL?
       7. Is there a mailing list digest for mSQL?
       8. Is there a news group for mSQL?
       9. How do I post a question to the mSQL mailing list? (PLEASE READ
          THIS!)
      10. I've found a bug. How can I tell if it's been fixed yet?
      11. How do I report a bug in mSQL?
      12. How do I contribute a patch to mSQL?
      13. How do I contribute code to the mSQL community?
      14. Where can I find examples of code that interface with mSQL?

   * Features and Limitations
       1. What support programs are bundled with mSQL?
       2. (-) What datatypes are supported?
       3. What SQL commands are supported?
       4. Does mSQL support keys?
       5. What functions does the mSQL API provide?
       6. Are views or virtual tables supported?
       7. Does mSQL support table aliasing?
       8. Are column constraints supported?
       9. Are stored procedures supported?
      10. Are access privileges supported?
      11. Does mSQL support BLOBs?
      12. Are the transaction commands, BEGIN, COMMIT, and ROLLBACK
          supported?
      13. What are the limits on table and field names?
      14. What other limits can be modified?
      15. How much data can mSQL address?
      16. (-) Are there any limitations in the way mSQL handles logical
          expressions?
      17. How does mSQL return values?
      18. How does SELECT return rows?
      19. Can mSQL nest tables?
      20. What storage overheads does mSQL have?
      21. Does msqld allocate more RAM to itself as new databases are added?
      22. Does performance degrade as the number of databases increase?
      23. Does mSQL support cursors?
      24. Does mSQL support different character sets?

   * Installation Problems
       1. Under Irix (SGI) I get problems relating to my username
       2. On OSF/1 or HP-UX I have trouble starting msqld at boot time
       3. Should I use cc or gcc when building mSQL on my Dec Alpha running
          OSF/1?
       4. Does mSQL work with Linux mmap()?
       5. Does mSQL work with HP-UX?
       6. I'm having trouble compiling MsqlPerl-1.03 with mSQL under HP-UX
       7. How can I install mSQL on a SCO Unix system?
       8. Why does setup fail when building mSQL on a Linux system?
       9. (=) Why won't my third party applications compile under Solaris
          2.x?
      10. Why can't I run setup under Linux?
      11. (=) Why do I get errors about sys/bitypes.h when compiling under
          Solaris 2.5?

   * Runtime Problems
       1. msqladmin will not let me create a database
       2. When I start msqld it complains about an ACL file
       3. When I start msqld it complains about a PID file
       4. I've just installed the latest version of mSQL and now my own
          applications won't work!
       5. Access control doesn't work with my setuid applications
       6. Why do I see an "Address already in use" error message when I
          attempt to start msqld?
       7. (-) How can I avoid running out of space when doing certain
          complex table joins?
       8. msqld is suddenly dumping core and complaining about bzero()
       9. (-) Why does relshow drop the first two characters from its
          output?
      10. Why won't msqladmin work?
      11. Why does msqld crash when attempting to display real numbers on
          64-bit SGI platforms?
      12. Why won't mSQL work with the compressed file system under AIX?
      13. (=) Why do I see "Protocol mismatch" errors under HP-UX?
      14. (=) Why do I see "Can't start server : UNIX Bind : Invalid
          argument" errors running msqld under a MachTen BSD Unix system?

   * How do I ....?
       1. How do I embed single quotes in a field?
       2. (-) What other characters need special treatment?
       3. How do I handle null fields?
       4. How do I perform case insensitive matches?
       5. (-) How do I add a column to an existing table?
       6. When should I call msqlConnect() in a parent/child situation?
       7. Can I use mSQL reserved words as field or table names?
       8. How do I find the maximum or minimum value in a table?
       9. How can I determine the structure of a database?
      10. What happens when the mSQL server goes down between requests?
      11. Can I run more than one copy of msqld on the same CPU?
      12. (-) How can I automatically ensure that each record receives a
          unique primary key?
      13. How can I avoid compiler redefinition errors when compiling my own
          mSQL applications?
      14. (=) How do I link the mSQL library with my own code?
      15. (=) How can I find the number of rows in a table?

   * (-) Contributed Code and Third Party Applications

   * (-) Web sites using mSQL

----------------------------------------------------------------------------
          ---------------------------------------------------------

                             General Information

What is SQL?

The following section is based on chapter 1 of "Oracle7 Server - SQL
Language Reference Manual" - Oracle Corporation, December 1992, part number
778-70-1292.

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:

   * querying data
   * inserting, updating and deleting rows in a table
   * creating, replacing, altering and dropping objects
   * controlling access to the database and its objects
   * guaranteeing database consistency and integrity

SQL provides easy to learn commands that are both consistent and applicable
for all users.

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.

----------------------------------------------------------------------------

Books on SQL and mSQL

There are countless books available on database design and SQL. Some good
starting point (in no particular order) are:

    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

    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

----------------------------------------------------------------------------

What is mSQL?

mSQL is mini SQL, a light weight database engine developed by David J.
Hughes <bambi@hughes.com.au> at Bond University, Australia. It has been
designed to provide fast access to stored data with low memory requirements.
As its name implies mSQL offers a subset of SQL as its query interface.
Although it only supports a subset of SQL, everything it supports is in
accordance with the ANSI SQL specification.

----------------------------------------------------------------------------

What platforms will it run on?

mSQL has been developed under Sun OS 4.1.1 but has been tested under Solaris
2.x (release 2.3, 2.4 and 2.5), Ultrix 4.3, Linux, and OSF/1 (cc not gcc).
That said, it should "autoconf" and build on most BSD derived systems, SVR4
based systems or POSIX O/S's (that should cover most of them). It has been
reported that it works out-of-the-box on HP-UX, NeXT, SCO, Sequent, Cray,
Tandem, *BSD and a few others.

----------------------------------------------------------------------------

Is it free?

David Hughes writes:

    "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.

----------------------------------------------------------------------------

Where can I get it?

mSQL can be obtained via anonymous ftp from Bond University, Australia. The
latest version can be found in the directory:

    ftp://bond.edu.au/pub/Minerva/msql/

----------------------------------------------------------------------------

Are there any mirror sites for mSQL?

The following sites mirror the mSQL FAQ:

   * http://www.swl.fh-heilbronn.de/msql

     Thanks to Tobias Haecker tobi@swl.fh-heilbronn.de.

   * http://cscsun1.larc.nasa.gov/~beowulf/msql/msql_faq.html

     Thanks to Jeff Rowe <beowulf@cscsun4.larc.nasa.gov>.

The following sites mirror the mSQL software distribution:

   * ftp://ftp.ntua.gr/pub/databases/msql/

     Thanks to Yiorgos Adamopoulos <adamo@noc.ntua.gr>.

   * ftp://sunsite.auc.dk/pub/databases/msql

     Thanks to Jesper Hagen <hagen@iesd.auc.dk>

   * ftp://ftp.nerosworld.com/pub/SQL/msql

     Thanks to David Perry <deperry@nerosworld.com>.

----------------------------------------------------------------------------

What is the latest version?

At the time of compiling this FAQ, the latest released version was 1.0.16.
The much talked about version 2 was still being developed.

It is available via anonymous ftp from:

    ftp://bond.edu.au/pub/Minerva/msql/msql-1.0.16.tar.gz
    (195705 bytes)

----------------------------------------------------------------------------

When will the next version be released?

David has suspended all development work on mSQL version 1.x and is
concentrating his efforts on version 2. However, he will continue to provide
any necessary bug fixes for the current release of mSQL.

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 version 2. Take the zen approach and just let it happen
:)

A beta snapshot of mSQL version 2.0 should be released on or around December
16, 1996. Just to whet your appetite, here is the general information file
from the beta release of mSQL version 2.0. The information was current as of
December 11 1996.

David Hughes writes:

                                    Mini SQL 2.0

                                       Beta 1

                                 General Information

    Introduction

         Mini SQL 2.0 is the second generation of the mSQL database system.
         The first generation product, mSQL 1.x, was designed to provide
         high speed access to small data sets. The original goal was to
         perform 100 basic operations per second on an average UNIX
         workstation with small data sets using very few system resources
         (i.e. memory and CPU cycles). The original design goal was met and
         the software has proven to be popular because of this
         functionality.

         During mSQL's life, people have used it for applications far
         beyond the scope of the original design. These high-end
         applications, containing up to 1 million rows of data, showed a
         need for better handling of complex queries and large data sets if
         the package was to be used in this way. The second generation of
         the mSQL server has been designed to suit these high-end
         applications while maintaining the original design goals of mSQL
         1. It has been designed to meet three main criteria

                 * Provide comparable performance for simple
                   operations as mSQL 1.x.
                 * Provide rapid access to large databases and complex
                   operations.
                 * Provide more of the functionality outlined in the
                   ANSI SQL specification.

    Enhanced Indexing

         One of the major flaws of mSQL 1.0 when used for larger
         applications was the simplistic indexing support. The original
         server supported only a single primary key per table and the key
         could consist of only one field. The internal use of the key was
         restricted to queries using a simple equality condition. As such,
         the vast majority of queries were processed without the aid of the
         key.

         mSQL 2.0 provides much more sophisticated indexing support. Each
         table can have multiple indices defined for it's data, with each
         index consisting of one to ten fields. Any index can be designated
         as a unique or non-unique index. The index information is stored
         in a series of AVL Tree structures that are mapped into the
         virtual memory address space of the mSQL server process. The use
         of AVL Trees in this way ensures that access to key data is
         extremely fast.

         Although the Beta 1 release of mSQL 2.0 includes only the AVL
         indexing scheme, the database engine itself has been written to
         support multiple indexing formats. The underlying format of the
         index can be specified in the SQL command used to create the
         index. Other indexing schemes are under development and will be
         made available in subsequent releases of mSQL 2.0.

         To aid in the use of the indices during query execution, a layer
         of abstraction know as the "candidate rows" system has been
         introduced into the server. The concept of the candidate rows
         abstraction is that during query processing, the module performing
         the query requests the next row from the data table that is a
         candidate for the selection criteria specified in the query. The
         requesting module is not aware of the mechanisms used to determine
         how that row was chosen or accessed. The "candidate row" routines
         are responsible for determining the best access method (based on
         the conditions specified in the where clause) and for retrieving
         the data rows as they are requested. This ensures that the optimum
         access method is used whenever a row of data is accessed without
         replicating the access logic in each module and without any
         "special case" algorithms.

         Because the candidate row abstraction provides a single logic path
         for the acquisition of data rows, it can also be used to optimise
         the query. A simple query optimiser has been included in the
         candidate row abstraction and the functionality of the optimiser
         will be enhanced over time.

    Data Types

         Another of the limiting factors of the performance of mSQL 1.0 was
         the size to which tables grew. Given an increasing number of rows,
         the amount of data that needed to be manipulated in memory
         increased proportionally. Unfortunately, the fixed length field
         structure of mSQL 1.0 usually forced a lot of white space and
         field padding to be included in the data.

         To overcome this problem, mSQL 2.0 includes support for a variable
         length char type (text). The text type allows an unrestricted
         amount of data to be inserted into a field by using an overflow
         buffer scheme to hold data beyond the specified size of the field.
         This provides the best of both worlds in that the database
         designer can specify the average size of a char field ensuring
         that in most cases, the data will be held in the data table. If a
         value is inserted that is longer than average, it will be split
         between that data table and the overflow buffers. This eliminates
         the need to specify overly large fields (e.g. 255 character) for
         storage of URLs and filenames.

         To provide a more complete SQL environment future releases of mSQL
         will include more of the "standard" data types defined by the SQL
         standard. These will include date/time, currency, and various
         other types that are provided by the larger database systems.

    System Variable / Pseudo Fields

         The 2.0 engine includes a framework for supporting system variable
         or pseudo fields. These fields are data elements maintained by the
         engine itself but are accessed using a normal select call. Some of
         the data pertains to an entire table, some to a particular row,
         and some to the current session. The 2.0 engine provides support
         for the following system variables

             Name                            Description

                     An internal value used to identify a row based on its
          _rowid     location. The _rowid field can be used in where clauses
                     during updates and deletes to specify a particular row.

          _timestamp An internal value indicating when the row was last
                     modified

                     The current time and date on the machine running the
          _sysdate   database engine returned in standard UNIX time format
                     (e.g. seconds since the epoch)

          _user      The username associated with the session over which the
                     query was submitted

    Sequences

         To overcome the problem of trying to manage sequences in client
         application code, mSQL 2.0 provides in-build, atomic operations
         for accessing an managing sequences. A sequence is a numeric
         counter that is automatically adjusted to the next value in the
         sequence each time it is accessed. The sequence is created using a
         version of the SQL CREATE command and can be created with a user
         defined initial value and also a user defined step value (i.e. the
         value added to the sequence after each access.

         Any table can have a sequence created for it but a table can only
         contain a single sequence. Once the sequence has been created,
         accessing the sequence value is achieved using the _seq system
         variable, that is by using a query such as

         select _seq from foo

         The current sequence value is returned and the sequence is updated
         to the next value in the sequence. Access to and modification of
         the sequence is atomic.

    Complex Expressions

         Unlike version 1.x of mSQL, 2.0 supports the notion of complex
         expressions in where clauses (i.e. the use of parenthesis and sub
         conditions in a condition). This removes a major limitation in
         mSQL as it was impossible to perform queries like

         SELECT name FROM staff
                 WHERE (staff_id < 100 OR staff_id > 200)
                 AND dept = 'finance'

         mSQL 2.0 supports the nesting of sub-conditions to any depth and
         there can be any number of sub-conditions in the where clause.

    Regular Expressions

         ANSI SQL defines a very simple regular expression language for use
         in matching data with the LIKE operator. mSQL 1.x implemented a
         superset of this functionality by providing access to the complete
         UNIX regular expression syntax in a LIKE clause. Processing a UNIX
         regular expression is far more "expensive" that processing the
         simplistic functionality defined in the ANSI specification and as
         such LIKE based searching was quite slow in 1.x. To improve this,
         mSQL 2.0 provides a standard SQL LIKE operator and also offers the
         extended UNIX syntax via u the RLIKE (i.e. regexp LIKE) operator.
         Most queries will require only the simple functionality offered by
         the standard SQL LIKE but the extended functionality is retained
         for compatibility. It should be noted that the new LIKE operator
         is much faster than the full UNIX version offered by 1.x.

         One of the main uses of the UNIX regular expression syntax in 1.x
         was for performing case insensitive searches. In standard SQL, the
         way to perform case insensitive searches is to use functions like
         UPCASE() in the query. 2.0 does not yet provide functions and
         performing function calls on each comparison is going to reduce
         performance greatly. To overcome this problem, 2.0 offers a
         non-standard operator known as CLIKE which implements a
         case-insensitive version of the standard SQL LIKE operator which
         both solves the problem and provides much better performance.

    ORDER BY and DISTINCT

         Most "real-world" applications utilise the sorting and DISTINCT
         functionality of an SQL server when presenting a list of data
         returned from the database. The implementation of ORDER BY and
         DISTINCT in mSQL 1.x proved to be a performance bottleneck for
         serious applications. To overcome this, 2.0 offers a new sorting
         implementation (based on the quicksort algorithm) and also has a
         faster DISTINCT implementation.

    Client Connections

         As the popularity of mSQL for use behind web servers increased it
         became apparent that the limit of 24 simultaneous client
         connections was a major problem. 2.0 overcomes this by
         reconfiguring the server's internal client connection tables at
         run-time to handle the maximum number of connections possible
         based on the operating system and the way the kernel is
         configured. On an average OS, mSQL 2.0 will reconfigure itself to
         handle over 200 simultaneous client connections.

    Run-time Configuration

         Configuration details, such as the location of the UNIX and TCP
         ports etc., was hard-coded into the server and API library in mSQL
         1.x. To provide more flexibility, all configuration details are
         now included in a configuration file that is loaded at run-time by
         both the server and any client applications that talk to the
         server. By modifying a value in the config file, all applications
         will use the new value when they are next executed. All programs
         also offer a run-time flag to allow the loading of a non-default
         configuration file to allow for testing of new servers or
         applications.

         To reduce the risk associated with root-owned daemon processes,
         mSQL 2.0 can be configured to run as any user (via the config
         file). By default, the server will run as a user called msql once
         it has started. If the server is run as root it will call setuid()
         to change to the desired user once it has initialised itself and
         performed any startup operations.

    Lite & W3-mSQL 2.0

         mSQL 2.0 is bundled with a couple of new tools to aid in the
         development of applications. W3-mSQL 2.0, the second generation
         WWW interface package is included as a standard tool. The new
         W3-mSQL code provides a complete scripting language, with full
         access to the mSQL API, within an HTML tag. This tool can be used
         to develop sophisticated GUI based applications that are platform
         independent and available as shared resources on a network. Along
         with the mSQL API, a library of nearly 60 other functions,
         including file I/O, strings handling and date/time manipulated are
         available to the scripts within a W3-mSQL enhanced web page.

         To fill another problem associated with delivering "real"
         applications over the web, W3-mSQL provides an enhanced and
         flexible authentication system. Any page that is accessed via
         W3-mSQL is subjected to the new W3-auth access scrutiny. Access
         can be restricted via a combination of username/passwd and
         requesting host. Configuration of the security system, including
         management of user groups, definition of secure areas, and
         creation of authorised users, is via a graphical interface
         accessed via a web page.

         Access to mSQL from scripting languages has become popular and
         virtually all major scripting languages provide an interface to
         the original mSQL server. Support for script based access to mSQL
         becomes standard in mSQL 2.0 with the inclusion of it's own
         scripting language. The language, called Lite, is a stand-alone
         version of the language provided by W3-mSQL (i.e. the language
         that W3-mSQL offers inside the special HTML tags is Lite) and
         includes access to the mSQL API and the other function mentioned
         above. Lite, as it's name implies, is a light weight language yet
         provides a powerful and flexible programming environment. The
         syntax of the language will be very familiar to C programmers (and
         ESL programmers) and provides shell like ease of use. A future
         release of Lite will include support for ASCII forms to provide a
         rapid development environment for non graphical mSQL based
         applications.

    Other tools

         mSQL 2.0 is bundled with a couple of new tools to aid in the
         development To aid migration of data to and from mSQL, two new
         utilities have been added to the distribution for the 2.0 release.
         msqlimport and msqlexport provide a mechanism for the import and
         export of data as formatted text files. Migrating data from other
         databases into mSQL 2.0 will require just a simple export from the
         source database and a subsequent import into the new mSQL
         database. The tools have been developed to be flexible enough to
         support virtually any text based formatting of the exported data.

         Other familiar tools have been modified to reflect the
         functionality of mSQL 2.0. Relshow can provide detailed
         information about all the table structure elements, including the
         indices defined on tables. msqladmin has been modified to provide
         statistical information on a per connection basis (so you can
         monitor who's doing what and when).

    2.0 feature not in Beta 1

         A multi-process server is currently under design and will appear
         in a later Beta of 2.0. This will allow multiple queries to be
         processed at the same time (with the appropriate locking etc).

         The framework for value functions (such as UPCASE etc.) and
         aggregate functions (such as COUNT etc.) has been written but
         support for functions has not been completed.

         Value expressions (such as 'UPDATE foo SET baa = baa + 1') are not
         in the Beta 1 release.

         Enhanced security and access control has not yet been added to the
         2.0 code base but will be in a later release.

----------------------------------------------------------------------------

Why is David called Bambi?

Bambi is a nickname that David acquired quite a long time ago. He claims
there are no derogatory implications associated with the name. If you'd like
to find out more send him some mail at <bambi@hughes.com.au>.

----------------------------------------------------------------------------

How is this FAQ prepared?

The FAQ is written in HTML and proofread using version 3.01Gold of the
Netscape Navigator running under Solaris 2.5.1. The HTML syntax is checked
using version 1.017 of Neil Bowers' <neilb@khoral.com> weblint package. Text
versions of the FAQ are created by saving the document as a text file from
within the Netscape Navigator.

(See http://www.khoral.com/staff/neilb/weblint.html for more details on
weblint).

----------------------------------------------------------------------------
          ---------------------------------------------------------

                              Help and Support

Are there any recommended patches to the latest version?

There are no official patches to any release of mSQL. If modifications need
to be made, a new version of mSQL will be released.

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.

----------------------------------------------------------------------------

Are there any known bugs or problems with the current release of mSQL?

Since the release of mSQL 1.0.12, several problems have been reported to the
mSQL mailing list. These are outlined below.

   * Problems with table/field name lengths

     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 regular expression code in version 1.0.14 and above has been
     cleaned up with the unfortunate side affect of making it impossible to
     search for the special characters ^ and \.

     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.

   * There are still isolated reports of msqld crashing with SIGSEGV
     (segmentation violation) errors under Linux. These occurrences have
     diminished but have not disappeared. There has been one report that the
     problem lies not within mSQL or Linux but in the hardware in use. An
     upgrade of the hardware may eliminate the SIGSEGV conditions. For more
     non mSQL specific details on this problem see:

         http://www.bitwizard.nl/sig11

   * Some users have reported the msqld consumes large amounts of memory
     when doing ORDERed selects:

     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.

   * There are still isolated reports of mSQL behaving strangely under HP-UX
     9.x. Any strangeness is more than likely a symptom of a broken mmap()
     implementation. Try recompiling mSQL without mmap() support by editing

         ./targets/your-architecture/site.mm

     and ensuring the mmap() directive reads:

         MMAP=

     and then recompile and re-install the mSQL package.

----------------------------------------------------------------------------

Are there any other patches available?

This FAQ only details those recommended patches that are necessary for the
general operation of mSQL. There are a number of other user contributed
patches that enhance the operation of mSQL. Some of these patches are
available via anonymous ftp while others are available from the mSQL mailing
list archives.

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:

   * When you insert a NULL as a primary key integer field, mSQL chooses a
     unique sequence number. Contributed by Jens-Peter Haack
     <peter@netcs.com>

     Available from:

         ftp://ftp.uni-bremen.de/pub/unix/database/Minerva/patches/insert.msql-1.0.9
         (593 bytes)

   * Mathematical updates. You can use statements like:

         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)

   * You can now use double quotes where quotes are allowed. Contributed by
     Michael Koehne <kraehe@bakunin.north.de>.

     Available from:

         ftp://ftp.uni-bremen.de/pub/unix/database/Minerva/patches/quote.msql-1.0.9
         (1225 bytes)

   * Michael Koehne <kraehe@bakunin.north.de> has bundled his value added
     patches to mSQL, which include the two mentioned above as well as some
     others.

     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/features.msql-1.0.16
         (19297 bytes)

   * Case insensitive searching. You can use statements like:

         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)

   * Martin Schulze <joey@finlandia.Infodrom.North.DE> has modified msqldump
     to let it insert or remove fields while dumping. Using this patch fixes
     the problem where the table definition cannot be modified after filling
     it with data.

     The patch is available via anonymous ftp from:

         ftp://ftp.infodrom.north.de/pub/mirror/msql/Patches/msqldump-1.0.16
         (5275 bytes)

   * Denis Ballant <brdbb@brus.wec.com> has rewritten the acl.c file from
     the mSQL distribution so that it will accept the wild card characters *
     and ? anywhere within an entry. Details of this patch are available
     from the mSQL mailing list archives for the month of August 1996.

   * Robert Sum <sumrn@ce-toolkit.crd.ge.com> has a patch for mSQL version
     1.0.16 that will restore the LIKE operation to its former glory - that
     is you can now search for the characters \ and ^.

     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.)

     *** msqldb.c    1996/11/04 23:13:54     1.1
     --- 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);

   * Vivek Khera <khera@kci.kciLink.com> has a patch for increasing the
     number of connections that can be queued by msqld. The patch is
     available from the mSQL mailing list archives for the month of December
     1996.

   * Sascha Kettler <kettler@rummelplatz.uni-mannheim.de> has patched mSQL
     version 1.0.16 such that it supports the Secure Sockets Layer - SSL -
     protocol. The patch is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/msql-1.0.16-patch.tar.gz
         (7183 bytes)

----------------------------------------------------------------------------

How do I apply patches to the mSQL source?

Patches are distributed as context based difference listings. That is the
line by line differences between the original file and the new file are
listed with surrounding lines of code to provide some context information.
They are usually generated by using a program such as diff.

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:

  1. Save the patch to a file - say /tmp/msql-patch1. Only save the patch
     information - the patch program can usually determine which parts of
     the file are patches and which parts are not but its easier for you to
     strip out any unnecessary information before running patch.

     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;

  2. Change directories to your mSQL source repository. For example:

         cd /usr/local/src/db/Minerva/msql/msql-1.0.16

  3. Apply the patch as follows:

         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:

        o -b

          forces patch to create a backup of the original file. By default
          it adds a .orig suffix to the original filename.

        o -N

          forces patch to ignore patches that it thinks are reversed or
          already applied.

        o -p0 (That's a "zero", NOT an "oh").

          forces patch to honour the full pathname of the files listed in
          the patch file.

  4. Recompile mSQL. If you have third party applications that use the mSQL
     library, you'll probably have to recompile them as well.

----------------------------------------------------------------------------

Is online documentation available?

A set of WWW pages for mSQL, w3-msql, ESL and Minerva are now available from

    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

----------------------------------------------------------------------------

Is there a mailing list for mSQL?

Yes.

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/

and

    http://cure.medinfo.org/lists/programming/index.html

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.

Wojciech Tryc <wojtek@tryc.on.ca> has begun to archive the mailing list
messages in HTML format. They are available from:

    http://www.tryc.on.ca

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.

----------------------------------------------------------------------------

Is there a mailing list digest for mSQL?

Yes. To subscribe to the list digest, send the words "subscribe
msql-list-digest" in the body of your message to majordomo@bunyip.com.

To unsubscribe from the list digest send the words "unsubscribe
msql-list-digest" in the body of your message to majordomo@bunyip.com.
----------------------------------------------------------------------------

Is there a news group for mSQL?

No.

This question comes up about every three months or so - usually from new
subscribers who haven't seen the previous threads.

There seem to be two distinct groups of people involved in this discussion:

  1. Those who prefer the mailing list.

        o News turn around times can be horrendously slow. It is not
          uncommon for messages to appear in Australia up to seven (7) days
          after they were originally posted. Considering that mSQL is
          developed and supported in Australia, a news group would pose an
          unacceptable delay in providing support for mSQL.

        o The mailing list is well established and even if a news group were
          created, the mailing list would still live on. Creation of a news
          group would mean that users would need to track both forums in
          order to keep abreast of current developments in mSQL.

        o Newsgroup messages expire - if you happen to be away for an
          extended period you run the risk of losing valuable information
          that may have expired while you were away.

        o News groups are often subject to "spamming" whereas mailing lists
          are less vulnerable.

        o Signal to noise ratios on news groups tend to be higher than
          mailing lists (even when instances of "spamming" are discounted.

        o Not everyone who subscribes to the mSQL mailing list has a news
          feed. Establishment of a news group would immediately isolate
          those mSQL users from any discussions carried out within the news
          group.

        o Not everyone has access to a full news feed. Some people have
          difficulty in obtaining permission to receive new news groups.
          Establishment of a news group would immediately isolate those mSQL
          users from any discussions carried out within the news group.
  2. Those who would prefer a news group.

        o A news group allows mSQL related messages to be isolated from
          other messages. This can be resolved by using mail filtering or
          threaded mail readers. Examples of mail filtering include procmail
          and filter (which is distributed with the Elm mail reader).
          Release 2.x and above of the Netscape Navigator includes a
          threaded mail reader.

        o The volume of messages on the mSQL list is increasing, making it
          difficult to keep track of threads. This can be alleviated using
          the methods described above.

        o It is often more cost effective for some users to receive blocks
          of news rather than individual mail messages. Similar behaviour
          can be achieved by subscribing to the mSQL mailing list digest.

While opinion is divided among these camps, the dominant force at present is
for the mailing list to continue without the establishment of a global
newsgroup. However, this does not preclude you from setting up a local
news/mail gateway such that incoming mail items are sent to a local
newsgroup at your site and outgoing news postings are sent to the mailing
list. Consult your nntp documentation for more details.

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.

----------------------------------------------------------------------------

How do I post a question to the mSQL mailing list?

Before you post a question to the mSQL mailing list, read the manual that
came with the mSQL distribution as well as the rest of this FAQ. Also, ask
yourself the following question:

    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!

  1. The operating system you are using - for example Solaris 2.4 or Linux
     1.3.1. On Unix like systems, this can usually be obtained by running
     the command:

         uname -a

  2. The processor type - for example sparc, Intel 386, HP PA-RISC, mc68020.
     Often the same operating system may run on different processors.

  3. The output of the command:

         msqladmin version

  4. Which, if any, unofficial patches you have applied to the version of
     mSQL you're using.

  5. The name and version details of any third party application you are
     using with mSQL.

Failure to include these details makes it almost impossible to pinpoint the
cause of your problem.

----------------------------------------------------------------------------

I've found a bug. How can I tell if it's been fixed yet?

The status of the development is reflected in the HISTORY file. An on-line
copy of the HISTORY file is kept on the Hughes Technology web pages. This
file is updated as each modification is made to the sources. Any bugs that
have been fixed in the code since it was last release will be mentioned in
the on-line release history information. You can access this file on the web
as:

    http://Hughes.com.au/product/msql/history.htm


----------------------------------------------------------------------------

How do I report a bug in mSQL?

The first thing to remember is that you should NOT mail David Hughes (aka
Bambi) directly with your questions - this just makes the process slower.
Any questions you have should be sent to the mSQL mailing list.

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:

   * the operating system and version - for example Solaris 2.4 or HP-UX
     9.05
   * the processor you are using - for example sparc or Intel 486
   * include the output of "msqladmin version"
   * which, if any, unofficial patches you have applied to the version of
     mSQL you're using
   * include a dump of a test database using msqldump
   * include an mSQL script that will show the bug

You should also ensure that you are running the latest (stable) version of
mSQL before posting a bug report as David fixes bugs in every version.

----------------------------------------------------------------------------

How do I contribute a patch to mSQL?

Following this procedure will standardise the manner in which unofficial
mSQL patches are distributed to the mSQL user community.

  1. Ensure that you are patching the latest version of mSQL.

  2. Ensure that you have applied any necessary unofficial recommended
     patches to the latest version.

  3. Make your changes to the "src" hierarchy of mSQL. For example, if you
     need to patch the file:

         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

  4. Test, double test and triple test your patch to make sure it REALLY
     fixes a problem.

  5. Generate a difference listing suitable for use by Larry Wall's patch
     program:

         diff -c ./src/msql/msqld.c.orig ./src/msql/msqld.c

  6. Post this difference listing and an explanation of the patch to the
     mSQL mailing list.

If at all possible, try to avoid posting 'monster' patches. If your patch
modifies a number of separate aspects of mSQL, split each of these into
different patches. This makes it easier for people to apply feature specific
patches to mSQL while avoiding unwanted feature patches.

----------------------------------------------------------------------------

How do I contribute code to the mSQL community?

Contributed code can be uploaded to the ftp server at Bond University
Australia. Place your code in the directory:

    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

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.

----------------------------------------------------------------------------

Where can I find examples of code that interface with mSQL?

If you're writing code in the C programming language, examine the mSQL
distribution itself. All the auxiliary programs use the mSQL API in a
variety of ways. Pay particular attention to:

   * ./src/msql/msql.c
   * ./src/msql/relshow.c
   * ./src/msql/msqldump.c
   * ./src/msql/msqladmin.c

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.

----------------------------------------------------------------------------
          ---------------------------------------------------------

                          Features and Limitations

What support programs are bundled with mSQL?

mSQL is bundled with the following programs:

          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.

                   Dumps a database in ASCII format. The dump takes
         msqldump  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.

For more details see the documentation that comes with mSQL.

----------------------------------------------------------------------------

What datatypes are supported?

mSQL supports the following datatypes:

    char
    int         (4 bytes)       -2147483647 <= i <= 2147483648
    real        (8 bytes)       -9223372036854775807 <= x <= 9223372036854775808

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.

For more details see the documentation that comes with mSQL.

mSQL version 2 will support more data types.

Note: The storage of real numbers is highly machine dependent. If you store
the number 10.0 don't be surprised if it is actually stored as either 10 or
10.00000000001 or 9.99999999999.

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) 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

----------------------------------------------------------------------------

What SQL commands are supported?

mSQL supports the following SQL commands:

  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 [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.

mSQL version 2 will support more SQL commands.

----------------------------------------------------------------------------

Does mSQL support keys?

Yes. Any single field of a table can be designated as the primary key. These
keys are, by definition, unique. In its current implementation, mSQL does
not support multiple keys within a table.

For more details see the documentation that comes with mSQL.

----------------------------------------------------------------------------

What functions does the mSQL API provide?

The mSQL API provides the following functions and macros:

       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.

Note: The PostScript documentation that comes with mSQL lists the function
msqlClose() as type int. This is incorrect. It is actually type void.

----------------------------------------------------------------------------

Are views or virtual tables supported?

No.

This feature may be included in mSQL version 2.

----------------------------------------------------------------------------

Does mSQL support table aliasing?

Yes.

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

----------------------------------------------------------------------------

Are column constraints supported?

No.

----------------------------------------------------------------------------

Are stored procedures supported?

No - that's getting beyond the scope of Mini SQL (see Oracle :)

----------------------------------------------------------------------------

Are access privileges supported?

Yes.

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.

----------------------------------------------------------------------------

Does mSQL support BLOBs?

BLOBs are Binary Large OBjects. Typical examples would be large blocks of
text, graphics or audio data.

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.

----------------------------------------------------------------------------

Are the transaction commands, BEGIN, COMMIT, and ROLLBACK supported?

No, and they will probably never be supported (once again that's beyond the
scope of mSQL).

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.

----------------------------------------------------------------------------

What are the limits on table and field names?

A table or field name MUST begin with an alphabetic character. The remainder
of the name may be any of the following 63 characters:

   * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
   * a b c d e f g h i j k l m n o p q r s t u v w x y z
   * 0 1 2 3 4 5 6 7 8 9
   * _ (that's an "underbar" NOT a "dash")

The maximum name length is set to 20 characters. That's for a table or a
field in a table. This allows for 813621925049196536663393538834956800
possible naming combinations using the characters listed above. For the
mathematically inclined that's:

           19
         -----
         \
          \        i
   52 *   /      63   =   813621925049196536663393538834956800
         /
         -----
         i = 0

Though 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:

  1. Dump your old databases to ASCII files using msqldump.

  2. Drop your old databases using msqladmin.

  3. Shutdown the mSQL database server msqld using msqladmin.

  4. Edit the mSQL source and modify

         ./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 */

  5. Recompile and install the modified mSQL.

  6. Start the new mSQL database server msqld.

  7. Create new databases using msqladmin.

  8. Repopulate your databases using msql and the ASCII dumps from step 1.

----------------------------------------------------------------------------

What other limits can be modified?

The file

    ./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:

  1. Dump your old databases to ASCII files using msqldump.

  2. Drop your old databases using msqladmin.

  3. Shutdown the mSQL database server msqld using msqladmin.

  4. Edit the mSQL source and modify

         ./src/msql/msql_priv.h

     changing the definitions to suit your needs.

  5. Recompile and install the modified mSQL.

  6. Start the new mSQL database server msqld.

  7. Create new databases using msqladmin.

  8. Repopulate your databases using msql and the ASCII dumps from step 1.

----------------------------------------------------------------------------

How much data can mSQL address?

mSQL can theoretically address tables with a maximum size of 4 gigabytes. In
practise you'll probably run up against operating system limitations well
before this theoretical limit.

----------------------------------------------------------------------------

Are there any limitations in the way mSQL handles logical expressions?

Yes.

Consider the SQL query:

    SELECT something from somewhere WHERE
        name='jan' or country='italy' and sex='female' or title='ms'

Under the current release of mSQL, 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'

The current release of mSQL 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.

Future versions of mSQL may support user defined levels of associativity.

----------------------------------------------------------------------------

How does mSQL return values?

mSQL returns all values as ASCII strings. If, for example, you are expecting
an integer result you may have to do some internal conversions depending on
the language you're using.

In C, for example, see the manual pages on atoi().

----------------------------------------------------------------------------

How does SELECT return rows?

On Tue, 4 Jul 1995, Karri-Pekka Laakso wrote:

    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.

----------------------------------------------------------------------------

Can mSQL nest tables?

On Tue, 25 Jul 1995, Jerome Stoller wrote:

    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).

----------------------------------------------------------------------------

What storage overheads does mSQL have?

mSQL stores each database in its own directory under the 'msqldb' directory
of wherever you specified mSQL should be installed. For example if you
specified that mSQL should be installed in:

    /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:

   * dbname/table.dat - table data. This file contains the data for all the
     rows in the table.

     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).

   * dbname/table.key - table keys. This file will only exist if the table
     has a primary key. It contains the key pointers into the table data
     file.

     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

   * dbname/table.def - table definition. This file contains the table
     structure definition.

     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

   * dbname/table.stk - table stack. This file keeps track of the holes or
     empty rows in the table.

     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.

Therefore to calculate the storage requirements for a table, use one of the
following formulae:

Tables with a primary key:

         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)

Tables without a primary key:

         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)

Using the keyed table above, if we expect it to contain a maximum of 10000
rows and we expect to have a 10 percent deletion ratio (that is at any one
time we expect that 10 percent of our rows have been deleted but not
replaced by new rows), we should allow for:

    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 databases are added?

On Fri, 11 Aug 1995, Andrew Waegel wrote:

    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 as the number of databases increase?

On Fri, 11 Aug 1995, Andrew Waegel wrote:

    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.

----------------------------------------------------------------------------

Does mSQL support cursors?

Pascal Forget replies to a posting by Brian Bartholomew:

    > 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.

----------------------------------------------------------------------------

Does mSQL support different character sets?

Patrik Faltstrom writes:

    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.

----------------------------------------------------------------------------
          ---------------------------------------------------------

                            Installation Problems

Under Irix (SGI) I get problems relating to my username

Colin Surprenant reports:

    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.

----------------------------------------------------------------------------

On OSF/1 or HP-UX I have trouble starting msqld at boot time

David-Michael Lincke reports:

    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.

----------------------------------------------------------------------------

Should I use cc or gcc when building mSQL on my Dec Alpha running OSF/1?

Rick Beebe writes:

    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.

----------------------------------------------------------------------------

Does mSQL work with Linux mmap()?

Version 1.3 or greater of the Linux operating system has full mmap()
support. If you're using such a version of Linux, mSQL will work perfectly
well using mmap().

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.

----------------------------------------------------------------------------

Does mSQL work with HP-UX?

Arley Carter (via David Hughes) writes:

    I just built msql-1.0.10 on hpux 9.05. It appears that you have
    slain the mmap bug. Good job. The only mods I [made] are in site.mm

        CC= cc -Ae +O3 +Z

    Remove -g flags also or you'll get a lot of annoying messages about
    opt not compatible with debug. The test suites for msql and
    msqlperl ran flawlessly.

----------------------------------------------------------------------------

I'm having trouble compiling MsqlPerl-1.03 with mSQL under HP-UX

Arley Carter writes:

    This problem has to do with the way HP-UX deals with shared
    libraries.

    Ensure the EXTRA_CFLAGS option in the file:

        ./targets/your-architecture/site.mm

    reads:

        EXTRA_CFLAGS= -Ae +O3 +Z

    and recompile mSQL.

    The +Z option ensures that "position independent
    code" is used when creating object files. For more information
    see the manual pages on your compiler.

----------------------------------------------------------------------------

How can I install mSQL on a SCO Unix system?

NOTE: This fix has had some conflicting results. Please let me
(<Peter.Samuel@uniq.com.au>) know if it works OR fails. If it fails, let me
know exactly where (if possible) and how you fixed it (if you did).

The following is a summary of the efforts required by Andrew Cash
<cash_a@sls.co.uk> to install mSQL version 1.0.8 on a SCO Unix system. It
should work perfectly well for version 1.0.9 as well.

   * Unpack the source code and create the site dependent files as follows:

         gunzip -c msql-1.0.9.tar.gz | tar xvf -
         cd msql-1.0.9
         make target
         cd targets/your-architecture
         ./setup
             answer questions

   * In the file:

         ./common/config.h

     ensure the lines referring to the sys/select.h include file are
     commented out as follows:

         /* Defined if you have sys/select.h  */
         /* #define HAVE_SYS_SELECT_H 1 */

   * NOTE: The step should only be applied if you use gcc and bison. These
     compilation tools will attempt to use alloca() instead of malloc()
     which will fail under SCO Unix. If you do not use bison, you should
     skip this step.

     SCO Unix doesn't have an alloca() library function so you'll have to
     use malloc(). You need to generate the file:

         ./msql/msql_yacc.c

     so run:

         make

     until it completes (or fails). Ensure that the msql_yacc.c file has
     been created. If it has, apply the following patch to the file. (Use
     the "-l" option of patch to avoid any problems with mismatched
     whitespace. That's an "el", NOT a "one" or an "eye").

     This patch ensures that <malloc.h> is explicitly included and that all
     references to alloca() are changed to malloc(). Note: This patch has
     been generated based on the output from the bison compiler compiler
     from GNU. It should NOT be applied to an msql_yacc.c that has been
     generated by yacc - such a file already uses malloc().

*** msql/msql_yacc.c.orig       Fri Jan  5 13:07:02 1996
--- msql/msql_yacc.c    Fri Jan  5 13:09:34 1996
***************
*** 329,362 ****
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */


- #ifndef alloca
- #ifdef __GNUC__
- #define alloca __builtin_alloca
- #else /* not GNU C.  */
- #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
- #include <alloca.h>
- #else /* not sparc */
- #if defined (MSDOS) && !defined (__TURBOC__)
- #include <malloc.h>
- #else /* not MSDOS, or __TURBOC__ */
- #if defined(_AIX)
  #include <malloc.h>
-  #pragma alloca
- #else /* not MSDOS, __TURBOC__, or _AIX */
- #ifdef __hpux
- #ifdef __cplusplus
- extern "C" {
- void *alloca (unsigned int);
- };
- #else /* not __cplusplus */
- void *alloca ();
- #endif /* not __cplusplus */
- #endif /* __hpux */
- #endif /* not _AIX */
- #endif /* not MSDOS, or __TURBOC__ */
- #endif /* not sparc.  */
- #endif /* not GNU C.  */
- #endif /* alloca not defined.  */

  /* This is the parser code that is written into each bison parser
    when the %semantic_parser declaration is not specified in the grammar.
--- 329,335 ----
***************
*** 607,618 ****
        yystacksize *= 2;
        if (yystacksize > YYMAXDEPTH)
        yystacksize = YYMAXDEPTH;
!       yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
        __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
!       yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
        __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
  #ifdef YYLSP_NEEDED
!       yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
        __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
  #endif
  #endif /* no yyoverflow */
--- 580,591 ----
        yystacksize *= 2;
        if (yystacksize > YYMAXDEPTH)
        yystacksize = YYMAXDEPTH;
!       yyss = (short *) malloc (yystacksize * sizeof (*yyssp));
        __yy_bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp));
!       yyvs = (YYSTYPE *) malloc (yystacksize * sizeof (*yyvsp));
        __yy_bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp));
  #ifdef YYLSP_NEEDED
!       yyls = (YYLTYPE *) malloc (yystacksize * sizeof (*yylsp));
        __yy_bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp));
  #endif
  #endif /* no yyoverflow */

   * Rebuild msqld with the modified msql_yacc.c file by running:

         make

   * If you are NOT going to be running mSQL as root, then you'll need to
     ensure that msqld can be installed correctly. Edit the makefile:

         ./msql/Makefile.full

     and comment out the mode change line for msqld as follows:

         # chmod 4750 $(INST_DIR)/bin/msqld

     Failure to make this change will result in an error during the install
     phase.

   * Install mSQL by running:

         make install

----------------------------------------------------------------------------

Why won't my third party applications compile under Solaris 2.x?

Solaris 2.x is an SVR4 version of unix. When compiling programs that require
network support (this includes any program that uses the mSQL library), you
must explicitly reference the networking libraries socket and nsl:

    gcc -o prog prog.c -Imsql_install_dir/include \
        -Lmsql_install_dir/lib -lmsql -lsocket -lnsl

----------------------------------------------------------------------------

Why does setup fail when building mSQL on a Linux system?

Did you install the Linux kernel sources?

If you installed Slackware and didn't get the K series disks then you will
be missing a lot of C header files that you need to compile mSQL. Go back
and grab the kernel sources disks and install them on your box.

----------------------------------------------------------------------------

Why can't I run setup under Linux?

This problem involves an interaction between the Linux setup program, the
mSQL setup program and your $PATH environment variable.

After unpacking the mSQL distribution and running the make target command,
the next step in installing mSQL is to change directories to:

    targets/target

and run the setup command. If you have /sbin in your $PATH ahead of ., or
you don't have . in your $PATH at all (which is a good idea if you happen to
be root) then your shell will attempt to run the Linux setup program ahead
of the mSQL setup program.

This can be avoided (for all flavours of Unix) by issuing the command as:

    ./setup

This will force your shell to run the setup program in the current working
directory, regardless of the contents of your $PATH.

----------------------------------------------------------------------------

Why do I get errors about sys/bitypes.h when compiling under Solaris 2.5?

Paul Gregg <pgregg@tibus.net> writes:

    Q: When I try to "make all" mSQL on Solaris (2.5 confirmed) it
    fails with the error:
        ../makedepend/makedepend: warning: msqld.c (reading /usr/include/arpa/inet.h,
        line 68): cannot find include file "sys/bitypes.h"
            not in /usr/include/arpa/sys/bitypes.h
            not in ../sys/bitypes.h
            not in /usr/include/sys/bitypes.h
        ../makedepend/makedepend: warning: msqld.c (reading /usr/include/arpa/inet.h,
        line 72): cannot find include file "sys/cdefs.h"
            not in /usr/include/arpa/sys/cdefs.h
            not in ../sys/cdefs.h
            not in /usr/include/sys/cdefs.h

    A: You have installed BIND 4.9 on your system. Bind replaces your existing
    /usr/include/netdb.h, but forgets to include the compatability includes
    cdefs.h and bitypes.h

    Solution: locate the cdefs.h and bitypes.h files in your BIND source code

        bind/compat/include/sys/cdefs.h
        bind/compat/include/sys/bitypes.h

    and copy these two files to /usr/include/src mSQL should now make
    cleanly.

    Credit should be given to Emir Mulabegovic <mulabego@mcs.anl.gov> for this
    answer.


----------------------------------------------------------------------------
          ---------------------------------------------------------

                              Runtime Problems

msqladmin will not let me create a database

This one is straight from the manual section on msqladmin. It states that
the only person who is allowed to create a database is the person nominated
as the "root user" during installation. If you indicated that the database
would be running as root then you must be root to create a database.

If you indicated that it would not be running as root, you would have then
nominated a username for the "root user". In that case, you must be logged
in as the user you nominated before you can perform admin functions like
creation of databases.

The manual also states that you can only perform the admin functions of
msqladmin (i.e. any function other than 'version') from the local host. For
security reasons you cannot perform administrative functions in a
client/server manner of a network.

----------------------------------------------------------------------------

When I start msqld it complains about an ACL file

The ACL file is the file that contains Access Control Lists for mSQL. It is
located in the installation directory and is called msql.acl (e.g.
/usr/local/Minerva/msql.acl). The warning indicates that msqld couldn't
locate an ACL file. This doesn't stop mSQL from operating, it just implies
that everyone on every machine on your network has read/write access to your
databases.

A sample ACL file is installed in the installation directory. You could copy
this file to msql.acl and edit it to reflect the access you want to offer to
your databases.

----------------------------------------------------------------------------

When I start msqld it complains about a PID file

The PID file is just a file in which msqld writes its process ID. If it
can't write to the PID file, msqld will still function correctly.

If you are seeing an error regarding the PID file, then one of the following
could be the cause:

   * The directory in which msqld is attempting to create the PID file does
     not exist.

   * The directory in which msqld is attempting to create the PID file does
     not have sufficient permissions.

During the installation, the setup program asked you where to store the PID
file:

    Top of install tree ? [/usr/local/Minerva]
    Will this installation be running as root ? [y] n
    What username will it run under ?  peters
    Directory for pid file ? [/var/adm]

You must ensure that this directory exists. The mSQL installation procedure
will NOT create this directory for you.

If you did not specify root as the mSQL administration user when you
answered the questions:

    Will this installation be running as root ? [y] n
    What username will it run under ?  peters

you must ensure that the user you specified has write permissions in the
directory in which msqld will store its PID file.

Under Irix 5.3 the /var/adm directory can only be written to by the root
user, so if your mSQL administration user is NOT root then you'll have to
choose some other location such as /var/tmp or /var/share.

If you need to change the location of this directory, you can either rerun
the setup program, or edit the file:

    ./targets/your_architecture/site.mm

and change the line:

    PID_DIR= /var/adm

to suit your needs.

----------------------------------------------------------------------------

I've just installed the latest version of mSQL and now my own applications
won't work!

Whenever you install a new version of mSQL you MUST remember to recompile
any third party applications - including those you developed yourself - to
ensure that they are linked with the new version of libmsql.a. You should
also recompile third party applications after installing any patches to
mSQL.

Failure to do this will almost certainly guarantee that your applications
will fail at some stage while talking to the new mSQL database server. You
may also miss out on some new feature provided by the new mSQL API.

----------------------------------------------------------------------------

Access control doesn't work with my setuid applications

Note: This only applies to mSQL version 1.0.10 and previous versions. mSQL
version 1.0.12 (and above) does NOT suffer from this problem. This section
will be removed in future versions of the FAQ. It is included in this
release to accommodate the transitional period following the recent release
of version mSQL 1.0.12.

Consider the following scenario:

   * User peters is the ONLY user given read and write access to the
     database test by the appropriate additions to the msql.acl file.

   * An application is created to manipulate the test database and is saved
     such that it is a setuid peters application:

         -rwsr-xr-x   1 peters   db         24576 Nov 13  1995 db_app

   * User markp wishes to use the test database using the db_app
     application. Instead of the setuid nature of the application allowing
     markp access to the database, all that happens is the error message:

         Access to database denied

This occurs because of the way in which mSQL passes user information to the
database server. It uses the getuid() system call which returns the real
user id of the calling process rather than the effective user id.

mSQL version 2 will have radically different security mechanisms.

----------------------------------------------------------------------------

Why do I see an "Address already in use" error message when I attempt to
start msqld?

If you're running Linux or SCO Unix, this message can be seen if you killed
the msqld process WITHOUT executing:

    msqladmin shutdown

The TCP/IP port will remain bound for about 90 seconds or so. After this
time the port should be available and msqld can be started successfully.

Another possibility to consider is that something is already using the
TCP/IP port that msqld is trying to use. For a default installation these
port numbers are 1112 for a root user or 4333 for an ordinary user. In this
case user means the name of the user you entered when answering the setup
question(s):

    Will this installation be running as root ?
    What username will it run under ?

There are a number of ways you can check for something using the TCP/IP
port:

   * msql

     If the mSQL monitor program msql can connect to the mSQL database
     server msqld then you KNOW that the database server is already running.

   * Telnet

     Telnet to the database server and specify the mSQL TCP/IP port number
     using one of the following commands:

         telnet dbhost 1112

     or

         telnet dbhost 4333

     You'll see the following types of messages:

        o Nothing is using that port or something is using the port
          exclusively:

              Trying 127.0.0.1 ...
              telnet: connect: Connection refused
              telnet>

        o msqld version 1.0.10 running protocol version 6 is using the port:

              Trying 127.0.0.1 ...
              Connected to localhost.
              Escape character is '^]'.

              0:6:1.0.10

        o Something else is using the port (or a client process is still
          communicating with a running msqld process:

              Trying 127.0.0.1 ...
              Connected to localhost.
              Escape character is '^]'.

   * netstat

     If your operating system has the netstat command, you can use it to
     display the contents of various network related data structures in
     various formats, depending on the options you select. Some of the
     options that may be helpful are:

        o To determine if something is listening on port 4333, use:

              netstat -a | grep 4333

          If you see output similar to:

                *.4333    *.*     0       0       0       0       LISTEN

          then something is using that port.

        o To see if msqld is using the port, use:

              netstat -f unix

          Output similar to the following will indicate that msqld is
          already running:

              Active UNIX domain sockets
              Address  Type          Vnode     Conn Addr
              fcf8bca8 stream-ord      231        0 /tmp/msql.sock

          This may not work for all operating systems. - the above examples
          were taken from a Solaris 2.4 system. Variations on this command
          include:

              netstat -f inet

          or

              netstat -f local

If you found something using the TCP/IP port that msqld would like to use,
examine the output of your operating system's ps command to check if you
already have a running msqld process. If you have then shut it down it by
executing:

    msqladmin shutdown

If you don't have a running msqld process then something else may be using
the port that msqld is trying to use. Examine /etc/inetd.conf and
/etc/services (or the services NIS map if you're running NIS) to see if
anything else is using the port. The output from one of the netstat commands
listed above may be helpful.

If you find such a program you have two options:

  1. Change the port number the other program is using so that it doesn't
     conflict with mSQL

  2. Ensure that mSQL uses a different port number. This can be done by
     either:

        o starting msqld with the environment variable MSQL_TCP_PORT set to
          another port number. You'll also have to ensure that client
          applications use the new port number too.

        o modifying the ./src/common/site.h file and changing the section

              /*
              ** TCP port for the MSQL daemon
              */

              #ifdef ROOT_EXEC
              #define MSQL_PORT       1112
              #else
              #define MSQL_PORT       4333
              #endif

          to suit your needs. Then recompile and reinstall mSQL.

----------------------------------------------------------------------------

How can I avoid running out of space when doing certain complex table joins?

Some mSQL operations involving table joins can consume large amounts of
temporary disk space. You can change the location of this temporary storage
area using the following procedure:

   * Shutdown the mSQL database server.

         msqladmin shutdown

   * Remove the msqldb/.tmp directory from your mSQL installation directory.
     For example, if you installed mSQL in /usr/local/Minerva run the
     following command:

         rm -rf /usr/local/Minerva/msqldb/.tmp

   * Create a symbolic link from a directory with lots of space to the
     msqldb/.tmp directory:

         ln -s /lots/of/space /usr/local/Minerva/msqldb/.tmp

   * Restart the mSQL database server.

         msqld &

----------------------------------------------------------------------------

msqld is suddenly dumping core and complaining about bzero()

Rasmus Lerdorf writes:

    This looks to me like you have compiled your msqld binary on a
    machine with bzero() in your libc but you are running it on a
    machine that does not have the bzero() function in its libc. Could
    it be that you compiled on a Solaris 2.5 box, but you are running
    it on a Solaris 2.4 machine? Sun made the brilliant decision to add
    bzero, bcopy and rindex to the Solaris 2.5 libc which means that
    Solaris 2.5 and 2.4 are not completely binary compatible anymore.
    When you compile msql on Solaris 2.5 it will see that bzero and
    bcopy are available and thus try to use them.

    The fix is to either link your msqld statically with the Solaris
    2.5 libc, or perhaps more preferable, recompile msql to not use the
    silly bzero, bcopy, bcmp and rindex functions.

    Edit common/config.h and make sure you do not have HAVE_BCOPY and
    HAVE_RINDEX defined. If you do, comment out these definitions and
    recompile. The resulting binary should then run on both target
    machines.

The exact error message you'll see when running a Solaris 2.5 compiled msqld
on a Solaris 2.4 machine is:

    peters@wheel[710] ./msqld

    mSQL Server 1.0.10 starting ...

    ld.so.1: ./msqld: fatal: relocation error: symbol not found: bzero:
    referenced in ./msqld
    Killed

----------------------------------------------------------------------------

Why does relshow drop the first two characters from its output?

Desmond writes:

    Wonder if anyone encountered this weird display while using relshow?

    relshow bookmarks

    Database = bookmarks

    +---------------------+
    |       Table         |
    +---------------------+
    | okmarks             |
    | st                  |
    +---------------------+

    notice that the first two letters of the table names are missing.
    Please help. Thanks in advance!

David Hughes replies:

    I've seen this on Solaris if you link against the oh so broken BSD
    compatibility library (libbsd.a). Please make sure that libbsd.a
    isn't mentioned in your site.mm file.

And from the comp.unix.solaris FAQ:

    6.19) Why doesn't readdir work?  It chops the first two characters of
        all filenames.

        You're probably linking with libucb and didn't read question
        6.18. Readdir in libucb.so wants you to include sys/dir.h,
        but many SunOS 4.1.x programs included <dirent.h>,
        consequently, you're mixing native <dirent.h> struct dirent
        with libucb readdir(). The symptom of this mixup is that the
        first two characters of each filename are missing. Make sure
        you use the native compiler (default /opt/SUNWspro/bin/cc,
        which may not be in your PATH), and not /usr/ucb/cc.

If you haven't shelled out the cash for Sun's compiler you can substitute
gcc for /opt/SUNWspro/bin/cc above.

----------------------------------------------------------------------------

Why won't msqladmin work?

When running msqladmin you may occasionally see error messages:

    mSQL command failed!
    Server error = Permission denied

msqladmin has the following restrictions:

  1. it can only be run by the msql root user. That is the user you
     specified when you compiled msql. This is a security feature.

  2. it can only be run on the machine on which msqld is running - it will
     NOT work via tcp/ip connections. This is a security feature.

The exception to the above restrictions is

    msqladmin version

this command can be run by any user, even over a network connection.

----------------------------------------------------------------------------

Why won't mSQL work with the compressed file system under AIX?

It seems that mSQL will corrupt its database files if they are stored using
the compressed file system running under AIX. The reasons are not yet clear
but may be related to AIX's implementation of mmap().

The corruption can be avoided by ensuring that the database files are not
stored in a compressed file system.

----------------------------------------------------------------------------

Why do I see "Protocol mismatch" errors under HP-UX?

The following error message:

    Protocol mismatch. Server Version = 0 Client Version = 6

may indicate that the version of index() being used is broken. This is true
with some implementations of HP-UX 9.x.

mSQL's autoconf build procedure will use index() if it finds it. The fix is
to modify:

    ./targets/your_architecture/common/config.h

and remove (or comment out) the line that reads:

    #define HAVE_RINDEX 1

----------------------------------------------------------------------------

Why do I see "Can't start server : UNIX Bind : Invalid argument" errors
running msqld under a MachTen BSD Unix system?

Mark Murphy <markm@desktop.tyrell.com>A writes:

    At 12:10 PM 9/17/96, I wrote:
    >I'm trying to install mSQL on a MachTen BSD unix system and am having
    >problems. The compile and installation went great (with only a warning
    >that it could not detect 'uname' on the system). But when I tried to start
    >the server from root with:
    >
    >/usr/local/Minerva/bin/msqld&
    >
    >I get the following:
    >
    >Can't start server : UNIX Bind : Invalid argument
    >
    >Anyone have any suggestions on what I am doing wrong or what is missing?


    Thought I'd let everyone know what the problem was in case anyone else is
    thinking of using MachTen BSD Unix

    There's a bug in the <sys/un.h> file.  It reads:

    /*
     * Definitions for UNIX IPC domain.
     */
    struct  sockaddr_un {
            short   sun_family;             /* AF_UNIX */
            char    sun_path[108];          /* path name (gag) */
    };


    And it should be:

    /*
     * Definitions for UNIX IPC domain.
     */
    struct  sockaddr_un {
            short   sun_family;             /* AF_UNIX */
            char    sun_path[106];          /* path name (gag) */
    };


    It seems sun_path was a little too long and the call to 'bind' in msqld
    does a check on the parameter's structure size... thus giving an invalid
    argument error.

    On another note....

    After I got that bug fixed, the server started, but when exercising the
    tests, msql crashed MachTen!  YES... I mean crash!  So much for protected
    memory!

    But the real problem is yet another bug with MachTen.

    It seems MachTen's mmap function "has not been fully
    tested" (as one tech support person finally admitted). So
    while mmap exists, it really doesn't work.

    Borrowing from the msql FAQ:

        >Version 1.3 or greater of the Linux operating system has full mmap support.
        >If you're using such a version of Linux, mSQL will work perfectly well using
        >mmap.
        >
        >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.

    This also works for MachTen since it seems mmap is "not fully tested"...
    and in reality it damn well crashed the machine.

    These two issues took two full days to resolve.... with calls to Tenon tech
    support in the morning, suggestions that were nowhere near fixing the
    problem during the day... and the "real" answers coming near 5pm when tech
    support closes... that these are bugs in MachTen.

    While their tech support staff was always nice and tried to be very
    helpful, I wish they would have been able to answer my questions when I
    first called.  It would have saved me two days of work on these issues.

    They had me try all kinds of things until the call was elevated to another
    tech (he doesn't get in until late afternoon) who had the answers... it's a
    MachTen bug!

    Very frustrating.

    However on a positive point, MachTen has been running very good as my
    internet server for the past six months or so without a glitch.


----------------------------------------------------------------------------
          ---------------------------------------------------------

                                How do I ...?

How do I embed single quotes in a field?

To handle a single quote, escape it with a backslash character. So the
string

    'Bambi's'

would be entered as

    'Bambi\'s'.

Note: This applies when using msql - the database monitor program. If you're
developing your own application you may have to escape other characters that
are special to the language you're using - for example perl, C or tcl.

----------------------------------------------------------------------------

What other characters need special treatment?

When specifying table or field names or when inserting values into fields,
the only other character that requires special handling is the mSQL escape
character backslash. To handle a backslash, escape it with another
backslash. So the string

    c:\windows\system\

would be entered as

    'c:\\windows\\system\\'

When using regular expressions in queries of the form:

    SELECT table.column FROM table WHERE table.column LIKE 'regexp'

the following rules apply:

             Use this table for mSQL versions 1.0.13 and below

     To search for   Use this or this  To search for   Use this  or this
    this character   string   string  this character   string    string

           $          \\\\$    [$]           [          \\\\[     [[]

           %           \\%     [%]           \        \\\\\\\\   [\\\\]

           '               \'                ^          \\\\^     [^]

           (          \\\\(    [(]           _               \\_

           )          \\\\)    [)]           |          \\\\|     [|]

           ?          \\\\?    [?]

             Use this table for mSQL versions 1.0.14 and above

         To search for  Use this  To search for        Use this
        this character  string   this character        string

              $           [$]           [                [[]

              %          [\\%]          \        cannot be searched

              '           \'            ^        cannot be searched

              (           [(]           _                \\_

              )           [)]           |                [|]

              ?           [?]           ]                []]

Note: This applies when using msql - the database monitor program. If you're
developing your own application you may have to escape other characters that
are special to the language you're using - for example perl, C or tcl.

If you are using mSQL via web interfaces, you may wish to use special HTML
characters instead. For example, a single quote can be represented as:

    &#39;

A complete list of the HTML coded characters can be found at:

    http://www.w3.org/pub/WWW/MarkUp/html-spec/html-spec_13.html

While we're on the topic of regular expressions, this explanation from
Robert Sum <sumrn@ce-toolkit.crd.ge.com> may shed some light on what happens
inside mSQL:

Robert writes:

    In mSQL 1.0.x, any time you use LIKE, you use an unusual form of
    "regular expressions" which are the way they are because of some
    historical implementation decisions that, in retrospect, were,
    perhaps, not the right ones. Consequently, mSQL 1.0.x does the
    following for a LIKE pattern which is somewhere between globbing
    and full regular expressions:

    1. it tries to force a match of the whole data string by implicitly
       prepending the pattern with the beginning-of-pattern operator ^
       and appending the end-of-pattern operator $ to the pattern
       (which makes the use/non-use of these operators a little quirky
       [see below]),
    2. it does NOT allow the ., *, and + regexps (they are plain characters),
    3. it does allow character classes using [] (i.e., any single
       character within the [] is matched unless the first char is ^ in
       which case any single character not in the [] is matched),
    4. it does allow alternation using |,
    5. it does allow grouping using (),
    6. it does allow optional characters or groups using ?,
    7. it allows _ to represent any single character (what would
       ordinarily be the . above),
    8. it allows % to represent any string of characters (what would
       ordinarily be the combination .*),

    As you can derive from above, the characters

        ^, $, [, ], |, (, ), ?, _, %, \

    are all special in one way or another. There is a way to search for
    everything, it just might not be completely obvious. For instance,
    using the msql program, one can use

       \\_ to match _
       \\% to match %
       \\^ to match ^
       \\$ to match $
       \\\\ to match \

    Basically, there are three places where \ is used as the escape
    character:

      1. The msql program (always treats \ as an escape character),
      2. The translation process (treats \ as an escape only when
         followed by % or _), and
      3. The regular expression evaluator (always treats \ as an escape
         character).

    In the first two examples above, steps 1 and 2 strip backslashes.
    In the next three examples, steps 1 and 3 strip backslashes.
    Things are actually a bit more consistent than folks realize, I
    think. (Note:  If you are using Perl or Tcl or some such, then
    replace 1. with appropriate activity of that application.)

    Furthermore, a recent message asked about

        SELECT * FROM doc_info
        WHERE foo LIKE 'x' or foo LIKE 'y' or foo LIKE 'z'
        and bar LIKE 'a' or bar LIKE 'b' or bar LIKE 'c'

    to which I replied, try

        SELECT * FROM doc_info
        WHERE foo LIKE '(x)|(y)|(z)'
        AND bar LIKE '(a)|(b)|(c)'

    Well, I forgot about rule number 1. above, which means this
    conversion may not be quite right and the original sender may need
    to fudge things a bit using either an additional set of parenthesis
    to force a match of the whole data string as in

        SELECT * FROM doc_info
        WHERE foo LIKE '((x)|(y)|(z))'
        AND bar LIKE '((a)|(b)|(c))'

    or if he really wants a match anywhere within the string

        SELECT * FROM doc_info
        WHERE foo LIKE '$|(x)|(y)|(z)|^'
        AND foo <> ''
        AND bar LIKE '$|(a)|(b)|(c)|^'
        AND bar <> ''

    then this should work, but as noted, one must be careful about the
    empty string. (If you want the empty string, just leave out the
    not equal clauses.)

----------------------------------------------------------------------------

How do I handle null fields?

For the NULL values, just use the NULL keyword.

For example

    insert into foo values ( NULL, 1, 2, 'some text' )

----------------------------------------------------------------------------

How do I perform case insensitive matches?

mSQL uses Henry Spencer's regular expression library with a few
modifications. To perform case insensitive searches, your query should take
the form

    SELECT * FROM my_table WHERE my_field LIKE '[Ss][Oo][Mm][Ee]
    [Vv][Aa][Ll][Uu][Ee]'

Sol Katz's <skatz@blm.gov> Object Oriented HTML API includes a C routine
that converts a string into its case insensitive form. You may wish to use
this in any C code that you write. See the section below on "Contributed
Code and Third Party Applications"

Alternatively, you can create an additional field in each table that will
hold a single case version of the information you are likely to be searching
for.

For perl users, Michael Cowden <cowden@leithaus.leitess.com> has contributed
this code example:

    The following statement turns mSQL into [mM][sS][qQ][lL]

    $string = "mSQL";
    $string =~ s/(.)/\[\L$1\E\U$1\E\]/g;

Vivek Khera <khera@kci.kciLink.com> suggests a simpler method for perl
users:

    Personally, I use this in Perl, as there is no need to complicate
    the regular expression with non-alpha characters.

       $string =~ s/([A-Za-z])/\[\L$1\U$1\]/gi;

Rasmus Lerdorf's <rasmus@vex.net> Personal Home Page Construction Kit
includes built in operations for case insensitive searches by way of its
msql_RegCase(string) command.

Version 2 of mSQL will support functions similar to upper() and lower()
which will obviate the need for the above.

----------------------------------------------------------------------------

How do I add a column to an existing table?

You can't! Once a table is created it must stay the way it is.

One possible solution is to use msqldump to create an ASCII dump of the
entire database. Then edit this dump file by hand and add the extra field to
the CREATE clause. You'll also need to edit each INSERT clause to ensure
that the new field is referenced. Once you've modified the dump file, drop
and recreate the database using msqladmin and repopulate the new database
using the dump file and msql.

This procedure could be automated by a shell or perl script.

NOTE: Use the -c option to msqldump to ensure that a complete dump of the
table is produced.

As an example consider this output from msqldump

    #
    # mSQL Dump  (requires mSQL-1.0.6 or better)
    #
    # Host: localhost    Database: test
    #--------------------------------------------------------


    #
    # Table structure for table 'test'
    #
    CREATE TABLE test (
      name CHAR(40),
      num INT
    ) \g


    #
    # Dumping data for table 'test'
    #

    INSERT INTO test VALUES ('item 999',999)\g
    ...
    INSERT INTO test VALUES ('item 0',0)\g

If you wish to insert a field, say "discount", then you will need to modify
the dump file as follows:

    #
    # mSQL Dump  (requires mSQL-1.0.6 or better)
    #
    # Host: localhost    Database: test
    #--------------------------------------------------------


    #
    # Table structure for table 'test'
    #
    CREATE TABLE test (
      name CHAR(40),
      num INT,
      discount REAL
    ) \g


    #
    # Dumping data for table 'test'
    #

    INSERT INTO test VALUES ('item 999',999,0.0)\g
    ...
    INSERT INTO test VALUES ('item 0',0,0.0)\g

Notice that every insert clause MUST be changed as well as the table
definition.

----------------------------------------------------------------------------

When should I call msqlConnect() in a parent/child situation?

If both the parent and child processes want to talk to the mSQL server then
you must call msqlConnect() AFTER you fork. They mustn't share the same
socket.

----------------------------------------------------------------------------

Can I use mSQL reserved words as field or table names?

No. The mSQL parser gets very confused if you attempt to use reserved words
as the name of a table or field. The full list of reserved words (as
obtained from msql_lex.c) is:

          <  >=   by     distinct integer not      real     update

          <= all  char   drop     into    null     select   values

          <> and  create from     key     or       set      where

          =  as   delete insert   like    order    smallint

          >  asc  desc   int      limit   primary  table

Remember that mSQL reserved words are case insensitive so UPPER case or
MiXeD cAsE reserved words are also forbidden in table or field names.

----------------------------------------------------------------------------

How do I find the maximum or minimum value in a table?

To obtain the maximum value use:

    SELECT number FROM table ORDER BY number DESC LIMIT 1

To obtain the minimum value use:

    SELECT number FROM table ORDER BY number LIMIT 1

This will only work with mSQL 1.0.9 and above unless you have applied the
unofficial LIMIT patch to earlier versions. See the mSQL mailing list
archives for details on this patch. (Before searching for this unofficial
patch, you should seriously consider upgrading to the latest version of
mSQL).

Note: Rasmus Lerdorf writes:

    The LIMIT statement limits the number of records actually
    transferred from the server to the client. It doesn't limit the
    scope of the search at all in any way. That means that if you are
    looking for the maximum value in a table with 30,000 entries, the
    query will first build the entire sorted result in memory in the
    server, but when it comes time to transferring the result to the
    client, it only sends the first item.

    In many cases, especially when you have a lot of fields, or long
    fields, the time it takes to transfer the data from the server to
    the client is actually many times that of the actual search. And
    the msqld daemon is tied up and not available to other clients
    while it is wasting time sending result records that will never be
    used. So, if you do queries and you know you will only be looking
    at the first couple of them, you should use the limit clause and
    cut down on the amount of useless records being sent across the
    socket.

----------------------------------------------------------------------------

How can I determine the structure of a database?

Use the relshow application that comes bundled with the mSQL software
distribution.

   * To discover which databases are available use:

         relshow

     or

         relshow -h host

     This will return output similar to:

             +-----------------+
             |    Databases    |
             +-----------------+
             | test            |
             | photos          |
             | patches         |
             +-----------------+

   * To discover which tables are contained within a database use:

         relshow dbname

     or

         relshow -h host dbname

     This will return output similar to:


         Database = test

             +---------------------+
             |       Table         |
             +---------------------+
             | test_table          |
             | addresses           |
             | telephone           |
             +---------------------+

   * To discover the structure of a particular table use:

         relshow dbname tablename

     or

         relshow -h host dbname tablename

     This will return output similar to:

         Database = test

         Table    = test_table

             +-----------------+----------+--------+----------+-----+
             |     Field       |   Type   | Length | Not Null | Key |
             +-----------------+----------+--------+----------+-----+
             | name            | char     | 40     | N        | N   |
             | num             | int      | 4      | N        | N   |
             +-----------------+----------+--------+----------+-----+

----------------------------------------------------------------------------

What happens when the mSQL server goes down between requests?

If the mSQL database server process, msqld, dies and is subsequently
restarted, or the host on which it was running is rebooted, any processes
that were connected to the mSQL database server MUST be reconnected. This is
not unique to mSQL, the Oracle database server behaves in a similar manner.

Programs that were connected to the mSQL database server should be either
restarted or have some internal mechanism whereby they notice the server has
died and attempt a reconnection.

One possible method for checking the status of the database server would be
to examine the return status of the msqlSelectDB() call.

----------------------------------------------------------------------------

Can I run more than one copy of msqld on the same CPU?

Steve A. Olson writes:

    I'm looking for a way to provide the full 25 connections to each of
    many mSQL databases running on a single box. Here's an idea, will
    it work? or is there a better way?

    (korn shell example)
    $ export MSQL_TCP_PORT=3000; msqld
    $ export MSQL_TCP_PORT=3001; msqld
    $ export MSQL_TCP_PORT=3002; msqld

    Then connect to the database as follows:
    $ export MSQL_TCP_PORT=3000; msql db_a

    While the above runs, another user connects:
    $ export MSQL_TCP_PORT=3001; msql db_b

David Hughes replies:

    Well, sort of. By running 'msql db_a' you are using the local UNIX
    socket not the TCP socket so you'd have to use MSQL_UNIX_PORT not
    MSQL_TCP_PORT.

    The other thing is that you should run 3 MSQL_HOME areas
    (/usr/local/Minerva for example). If two of these servers __ever__
    access the same database at the same time then you are stuffed.

    So, something like

    export MSQL_UNIX_PORT=/dev/msql_1; export MSQL_HOME=/Minerva1; msqld&
    export MSQL_UNIX_PORT=/dev/msql_2; export MSQL_HOME=/Minerva2; msqld&

    and

    export MSQL_UNIX_PORT=/dev/msql_1; msql db_a
    export MSQL_UNIX_PORT=/dev/msql_2; msql db_b

    would do the job.

----------------------------------------------------------------------------

How can I automatically ensure that each record receives a unique primary
key?

mSQL version 1.x does not have an automatic key assignment functionality. A
number of solutions to this problem are available.

   * Use Pascal Forget's unique sequence number generator.

   * Build the unique key assignment and management into your application.

     One suggestion on how to implement this comes from Vivek Khera
     <khera@kci.kciLink.com>.

     Vivek writes:

         What I do is take some of the fields in the record, tack on a salt
         like the current time and generate a hash (either SHA or MD5) of
         it. I use part of the the hash string value as the key.

     Another solution is provided by Rasmus Lerdorf <rasmus@vex.net>.

     Rasmus writes:

         The issue here is not so much how to generate a key, but how to
         ensure it is unique. The way I have done it in the past is to
         associate a lock file with each table. Each table has a counter
         record. With the table locked, I pull out the current counter
         value, increment it, and put it back. Then I unlock the table. This
         is not the most efficient way to do it, but it does work nicely for
         systems that do not get pounded with queries.

     Others have suggested using a timestamp with milli second granularity.
     This approach has its pitfalls.

        o Not all client side operating systems have access to the
          gettimeofday() calls (or its equivalent).
        o Not all systems can determine the system time to the milli second.
        o Because the timestamps are being determined by the clients, it is
          possible for two clients to arrive at the same timestamp. This
          problem is amplified if you have a number of clients running on
          different machines which are not synchronised. This can be avoided
          by recalculating the timestamp if an insert operation fails due to
          a duplicate key error.
        o Clocks may drift backwards causing old timestamps to be reused.
          Sites that use time synchronisation methods such as rdate or xntp
          may be prone to this.

   * Use a patch provided Jochem Wiedmann <wiedmann@wiedmann.neckar-alb.de>.
     This patch allows you to declare a key as:

         AUTO PRIMARY KEY

     This patch is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Incoming/msql-auto-pkey.patch.gz
         (6329 bytes)

mSQL 2 will include this feature.

----------------------------------------------------------------------------

How can I avoid compiler redefinition errors when compiling my own mSQL
applications?

When building your own mSQL applications you may encounter compiler errors
similar to:

    /usr/local/Minerva/include/msql.h:30: redefinition of `m_row'
    /usr/local/Minerva/include/msql.h:32: redefinition of `struct field_s'

This occurs because the mSQL header file msql.h has been included more than
once.

To avoid this, apply the following patch to msql.h contributed by Vesa Tuomi
<vesa@cardinal.fi>

*** ./src/msql/msql.h.orig Wed Mar  6 09:27:20 1996
--- ./src/msql/msql.h      Thu Mar  7 10:29:46 1996
***************
*** 16,21 ****
--- 16,23 ----
  **
  */

+ #ifndef       __MSQL_H__
+ #define       __MSQL_H__

  #if defined(__STDC__) || defined(__cplusplus)
  #  define __ANSI_PROTO(x)     x
***************
*** 109,111 ****
--- 111,115 ----
  #ifdef __cplusplus
        }
  #endif
+
+ #endif        /* __MSQL_H__ */

and rerun the make install phase of the mSQL installation procedure. This
will remake all the core mSQL applications and install the modified msql.h
file in your installation include directory. It will also reinstall the core
mSQL applications in your installation bin directory. There is NO need to
recompile any other third party applications.

----------------------------------------------------------------------------

How do I link the mSQL library with my own code?

Most compilers will search a well defined list of standard directories for
include and library files. These are typically /usr/include, /usr/lib, /lib
and occasionally /usr/local/include and /usr/local/lib. If you wish to use
files that are outside these locations you must tell your compiler which
directories to search.

Most C compilers understand the command line arguments:

    -Iinclude_directory

and

    -Llibrary_directory

to mean "search the directory include_directory for include files and search
the directory library_directory for libraries".

If you wish to compile a program that will communicate with the mSQL
database server you must tell the compiler where the mSQL include and
library files were installed. Assuming you installed mSQL in
/usr/local/Minerva and you use gcc, the syntax would resemble:

    gcc -c -I/usr/local/Minerva/include your_prog.c
    gcc -o your_prog your_prog.o -L/usr/local/Minerva -lmsql

NOTE: that the mSQL library name has been truncated. The actual mSQL library
file name is libmsql.a. However, the compiler (and the link loader) only
need the unique part of the file name so the lib and .a components should be
removed when passing the library name on the command line.

If you are using an SVR4 version of Unix (such as Solaris 2.x) you may also
have to include some networking libraries:

    gcc -o your_prog your_prog.o -lsocket -lnsl -L/usr/local/Minerva -lmsql

----------------------------------------------------------------------------

How can I find the number of rows in a table?

If you're writing code in C, the following will work:

    msqlQuery(dbsocket, "SELECT * from blah");
    result = msqlStoreResult();
    number = msqlNumRows(result);
    msqlFreeResult(result);

----------------------------------------------------------------------------
          ---------------------------------------------------------

                Contributed Code and Third Party Applications

A number of people have contributed additional software that works with
mSQL. The contributed software falls into two categories - that developed by
David Hughes (mSQL's author) and that developed by others.

Note: Please consult the documentation that comes with each of these
applications to determine the licensing obligations that may be involved in
their use.

Note: There is often a delay of a day or so for files to be moved from the
Incoming directory to the Contrib directory on the ftp server bond.edu.au.
If you can't find the software in the Contrib directory, try the Incoming
directory.

       ESL                          mSQL Tools

       w3-msql                      mSQL User Interface for Windows

       Addf-Secure                  MS Windows

       Apache                       NeXTSTEP EOF

       Backup Script                Object Oriented HTML API

       Bind                         OCX

       Command Line Tool            ODBC

       Dbadmin                      Onyx

       DBASE                        OS/2

       DBI/DBD                      Perl

       DBunk                        PTS

       Dbview                       Python

       Digger                       REXX

       Emacs                        Simple SQL

       Flat File Importer           SQLBase

       Home Page Construction Kit   Tcl

       HTML Interface to mSQL       Time and date utilities

       ICI                          tkmSQL

       Jate                         Unique sequence number generator

       Java                         VirtuFlex

       LISP/Scheme                  Visual Basic

       Meta-HTML                    WDB

       MS Access and dBase III      Websql

       mSQL CGI                     Wojciech Tryc's Repository

       mSQLexpire                   XfSQL

       mSQL Export                  Xsqlmenu

       mSQL Summary                 Z Classes for C++

ESL
     David developed mSQL as the database component of a larger network
     management project called Minerva (Minerva was the Roman goddess of
     knowledge and information). Another component of Minerva is an
     Extensible Scripting Language called ESL. This has a C like syntax and
     provides support for the complete mSQL API as well as full SNMP
     support. It is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/esl/esl-0.3.tar.gz
         (407046 bytes)

w3-msql
     David has also developed w3-msql which is an interface between the
     World-Wide Web and mSQL. It is a mechanism that can be used to greatly
     simplify the use of an SQL database behind a web server. Using w3-msql,
     you can embed SQL queries within your pages and have the results
     generated on the fly. It is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/w3-msql/w3-msql-1.0.tar.gz
         (30203 bytes)

     At the time of compiling this FAQ, version 1.1 was being prepared.

Addf-Secure
     Max Levchin <mlevchin@ampere.scale.uiuc.edu> has written a utility that
     will allow you to securely add a new column to an mSQL table. More
     details can be found at:

         http://ampere.scale.uiuc.edu/~mlevchin/addf

Apache
     Dirk van Gulik <Dirk.vanGulik@jrc.it> has developed some code for use
     with HTML and HTTP servers with specific reference to the Apache HTTP
     server. It is available via anonymous ftp from:

         ftp://ftp.ceo.org/pub/ewse-mSQL-apache-demos/apache-msql-demo.1.0.1.tar.gz
         (12723 bytes)

     If you require a module that allows the Apache httpd daemon to perform
     authentication via an mSQL database, grab the file:

         http://www.apache.org/dist/contrib/modules/mod_auth_msql.c
         (9269 bytes)

Backup Script
     C Latham <clatham@nerosworld.com> has written a shell script that will
     backup mSQL databases. It is reprinted here in full:

         #!/bin/sh
         #       $Id: faq.html,v 1.24 1996/12/16 11:22:25 psamuel Exp $
         #       by: clatham@nerosworld.com
         #
         #       usage: msqlbckp [-h host] 'backup directory'
         #
         #   This script creates daily backups of mSQL databases. Input parameters are
         #   host machine (if msqld is not running on local machine) and the pathname
         #   of a directory where the backups will be made. The backups will be named:
         #   {table name}.{day of week}.gz  (They are gzipped).
         #
         #   The structure of the backup files are in a format that can be read
         #   by the 'msql' program to completely restore the database, by first
         #   dropping the corrupt table, then recreating the table and populating it
         #   with data (it is required that the database itself already exists, which
         #   may require the database administrator to use msqladmin to create the
         #   database in extreme circumstances).
         #
         #   Access is required to msqldump, relshow and gzip.
         #
         #   Set crontab to execute this script at, say, 4 am every day, every other
         #   day, or however often you want backups of your databases.
         #

         err( ) {
                 echo usage: msqlbckp [-h host] 'backup directory'
                 exit 1
         }

         case $# in
         1)
                 bdir=$1
                 ;;
         3)
                 if [ $1 = "-h" ]
                 then
                         host="-h "$2
                 else
                         err
                 fi
                 bdir=$3
                 ;;
         *)
                 err
                 ;;
         esac

         dow=`date '+%A'`   # Get the day of the week

         # Use relshow to get a list of the available databases, and pare that down
         # into a file listing one database name per line...
         relshow ${host} | \
                 sed -n -e '/^....[ \-].*/d' -e 's/  \| //' -e 's/ *\|//p' \
                 >${bdir}/db.names

         # Get each database name from the file for table processing
         dbline=1
         while [ 1 ]     # Do forever until no more db names
         do
                 dodb=`cat ${bdir}/db.names | sed -n "${dbline}p"`
                 if [ "${dodb}" = "" ]   # if no more db names to do
                 then
                         break
                 fi

                 cf=${bdir}/${dodb}.${dow}       # Define current working file

         echo "#
         # mSQL Dump of Database: ${dodb}
         #
         # Begin by dropping all tables
         #---------------------------------------------

         " > ${cf}

                 # Now add commands to 'drop' each table in the database
                 relshow ${host} ${dodb} | \
                 sed -n -e '/^....[ \-].*/d' -e 's/  \| //' -e 's/ *\|//p' | \
                 awk '($0 !~ /^$/) { print "DROP TABLE", $1, "\\g" }' >> ${cf}

                 echo " " >> ${cf}

                 # Dump the database structure and data into the backup file
                 msqldump ${host} ${dodb} >> ${cf}

                 # Finally, gzip the file
                 gzip -f ${cf}

                 # Next database name
                 dbline=`expr ${dbline} + 1`
         done

         rm ${bdir}/db.names     # Get rid of temp file

Bind
     Chris Seawood <mgrcls@nextwork.rose-hulman.edu> has extended the DNS
     naming service - BIND - to support mSQL databases. It is available in
     the contrib/msql directory of the current release of BIND which can be
     obtained via anonymous ftp from:

         ftp://ftp.vix.com/pub/bind/release/bind-4.9.3-REL.tar.gz
         (1682741 bytes)

Command Line Tool
     Kai Mysliwiec <kvm@camelot.de> has developed an mSQL tool that allows
     you to send SQL queries from the command line. It is available from:

         http://www.camelot.de/~kvm/progs/sql.tar.gz
         (14083 bytes)

Dbadmin
     James Harrell <gt4960a@prism.gatech.edu> has developed a CGI
     application that allows database administration using a web based form
     interface. A demonstration can be seen at:

         http://bauhaus.skiles.gatech.edu/~jharrell

     Source code is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/dbadmin_v1.0.1.tar.gz

DBASE
     Maarten Boekhold <M.Boekhold@et.tudelft.nl> has written a dbase to mSQL
     conversion utility. It handles the dbf data types string, num, real and
     date. It does not yet handle memo-fields because mSQL 1.x lacks support
     for variable length char fields. Maarten is aware that this may be
     insufficient for some users' needs but he is releasing the utility as
     'do-whatever-you-want' software. It is available via anonymous ftp
     from:

         ftp://ftp.nerosworld.com/pub/SQL/dbf2sql/dbf2sql-2.2.tar.gz
         (18207 bytes)

DBI/DBD
     Tim Bunce <Tim.Bunce@ig.co.uk> is working on a generic database driver
     (DBI) which allows perl to interface to any database in a standardised
     way. Details of Tim's work are available from:

         http://www.hermetica.com

     Alligator Decartes <descarte@hermetica.com> has added an mSQL driver to
     Tim's work and his contributions can be obtained via anonymous ftp
     from:

         ftp://ftp.mcqueen.com/pub/dbperl

     It is also available from any CPAN (Comprehensive Perl Archive Network)
     site in the "modules" directory. For more information about CPAN see:

         ftp://ftp.funet.fi/pub/languages/perl/CPAN/CPAN

     The latest blurb describing Alligator's work can be obtained from:

         http://www.hermetica.com/technologia/DBI

DBunk
     Dave Shevett <shevett@homeport.org> has written DBunk - a Java based
     graphical front end to mSQL. Source code is available from:

         http://www.homeport.org/~shevett/dbunk.tar.gz

Dbview
     Gian Paolo Ciceri <gp.ciceri@it.net> has written a utility similar to
     relshow.

     It shows the structure of an mSQL database as well as indicating the
     number of records in the tables.

     It is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/dbview-0.7.tar.gz
         (28557 bytes)

Digger
     The folks at Bunyip Information Services (the current maintainers of
     the mSQL mailing list) have used mSQL as the database component of
     their Digger system.

     Digger is a Distributed Directory Service for the Internet based on
     Whois++ technology. For more information about digger send mail to
     <digger-info@bunyip.com> or have a look at Bunyip's web pages:

         http://www.bunyip.com/products/digger

Emacs
     Igor Romanenko <igor@frog.kiev.ua> has contributed some lisp code to
     provide emacs with hooks into mSQL. It allows the msql monitor to run
     in an emacs window, so you can use emacs for editing and command
     recall. It is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/sql-mode.tar.gz
         (6883 bytes)

Flat File Importer
     Pascal Forget <pascal@wsc.com> has contributed a program that will
     import flat file databases directly into mSQL databases. It is
     available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/msql-import-0.1.2.tar.gz
         (14154 bytes)

     or

         ftp://ftp.wsct.wsc.com/pub/incoming/msql-import-0.1.3.tar.gz
         (14154 bytes)

Home Page Construction Kit - PHP
     Rasmus Lerdorf <rasmus@vex.net> has developed a package that allows
     users to create WWW sites with mSQL databases.

     Rasmus writes:

         PHP/FI is a server-side html-embedded scripting language with
         built-in access logging, access restriction, as well as support for
         ndbm, gdbm and mSQL databases. It also implements the RFC-1867
         standard for form-based file uploads.

         The mSQL support is just a small set of functions supported by the
         package. A full set of string manipulation, regular expression,
         directory and file routines complement the script language.

     The source distribution as well as more information is available at:

         http://www.vex.net/php

HTML Interface to mSQL
     Sol Katz <skatz@blm.gov> has written some C code that demonstrates an
     HTML interface to mSQL. Unlike other applications, this program does
     not need to be modified when new mSQL tables or databases are created.
     All required information is contained in the html. It is available via
     anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/msqlc2.zip
         (29002 bytes)

     and also from:

         ftp://ftp.blm.gov/pub/gis/msqlc2.zip
         (29002 bytes)

     It can be seen in operation at:

         http://www.blm.gov/gis/msql/vertical/test2.html

ICI
     Yiorgos Adamopoulos <Y.Adamopoulos@noc.ntua.gr> has written an mSQL
     extension for the ICI programming language. It is available via
     anonymous ftp from:

         ftp://ftp.ntua.gr/pub/lang/ici/iciMsql.tar.gz
         (249077 bytes)

     Yiorgos has set up a mailing list for iciMsql. Questions can be sent
     to:

         iciMsql@noc.ntua.gr

Jate
     Josef <ht@aiace.lnf.infn.it>A has developed Jate - a CGI program that
     builds HTML interfaces to mSQL databases. More details can be found at:

         http://aiace.lnf.infn.it/~ht/JATE.html

Java
     Darryl Collins <darryl@minmet.uq.oz.au> has developed a version of the
     mSQL API for the Java programming language. It is available via
     anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/MsqlJava-1.1.0.tar.Z
         (15611 bytes)

     or

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/MsqlJava-1.1.0.zip
         (20346 bytes)

     For more details see:

         http://www.minmet.uq.oz.au/msqljava

     George Reese <borg@imaginary.com> has developed a Java Database
     Connection (JDBC) class library using MsqlJava. It is available via
     anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/mSQL-JDBC.0.9.3.tar.gz
         (33365 bytes)

LISP/Scheme
     George J. Carrette <gjc@world.std.com> has developed SIOD which is "a
     small-footprint implementation of the Scheme programming language that
     is provided with some database, unix programming and cgi scripting
     extensions". SIOD provides interfaces to Oracle, Sybase, mSQL and
     Digital RDB databases.

     Details of the current release of SIOD can be found at:

         ftp://ftp.std.com/pub/gjc/siod.html

     The latest copy of SIOD can usually be found at:

         ftp://ftp.std.com/pub/gjc/siod_tar.gz
         (155080 bytes)

Meta-HTML
     Universal Access Inc has released a version of their Meta-HTML
     scripting language which has extensions for connecting to mSQL
     databases.

     Henry Minsky <hqm@ua.com> writes:

         <Meta-HTML> is a programming language specifically designed
         for working within the World Wide Web environment. Although it is a
         genuine programming language, suitable for large-scale symbolic
         manipulation, it provides the most commonly wanted Web
         functionality as built-in primitives, so you don't have to write
         them.

     More details (including source code) can be found at:

         http://www.metahtml.com

     There is also an anonymous ftp site for those of you without web
     access:

         ftp://ftp.metahtml.com/pub

MS Access & dBase III
     Brian Bartholemew <bb@wizard.pn.com> has written some scripts that
     translate dBase III tables saved from MS Access into tab-separated
     formats.

     Brian writes:

         Here are three scripts, the first two are clean ones that break out
         tables saved from access in dBaseIII format into a tab-separated
         format that a set of database-operator scripts called rdb can use.
         The first breaks out .dbf files and the second breaks out .dbt
         files which contain the text of variable-length-text memo fields;
         the .dbf and .dbt can be joined by the block offset number given in
         the text field. These scripts have only been tested on the field
         types my database happens to have. Since the first one breaks out
         the table definitions it's the obvious candidate to generate table
         definitions for msql. The third script is a hack to get data into
         msql so I can play with msql, but it's a starting point. The first
         two scripts were written to be free of data-dependent bugs, the
         third is somehow confused about null fields in Pascal's msql-import
         program which I've hacked around to enter the complaining fields as
         the text "NULL"; debugging is welcomed. The third script
         needs rdb, available from rand.org:/pub/RDB-hobbs. I do MS Access
         -> rdb -> msql because I use rdb as a prototyping tool, the
         format is trivial to generate and modify, I have a forms-based
         emacs front-end to rdb, and the tables compress nicely in rcs.
         However, someone may wish to modify these scripts, (a) so that they
         generate msql dump files instead of rdb files, thereby bypassing
         the msql-import bug and the rdb dependency and probably some data
         dependencies with maximum portability, or (b) so that they talk to
         the database directly. If so please post diffs. Trigger the new
         behaviour by a command-line option so the non-msql-perl behaviour
         continues to run under vanilla perl. These programs are gpl'ed.

     They are available from the mSQL mailing list archives for the month of
     February 1996.

mSQL CGI
     Alex Tang <altitude@petrified.cic.net> has written an mSQL front end as
     a CGI program. For more details see:

         http://petrified.cic.net/MsqlCGI

mSQLexpire
     Scott Burkett <scottb@dcicorp.com> has developed an mSQL utility that
     provides a mechanism for automatic expiration of records based on age.
     Further details can be seen at:

         http://www.dcicorp.com/~scottb/projects/msqlexpire

mSQL-Export
     Kerry Garrison <garrison@delta.net> has developed a Perl script that
     will export an mSQL table to a delimited text file. Further details can
     be seen at:

         http://www.delta-design.com/msqltools

mSQL Summary
     David Perry <deperry@nerosworld.com> had someone write a program for
     him that takes an SQL select statement (such as select distinct
     fieldname, fieldname2, fieldnameN from tablename order by fieldname)
     and propagates a second table with the results. It is available via
     anonymous ftp from:

         ftp://ftp.nerosworld.com/pub/msql/Contrib/mSQL_summary.tar

mSQL Tools
     Kerry Garrison <garrison@delta.net> has setup a site that catalogues a
     number of mSQL tools. It can be found at:

         http://www.delta-design.com/msqltools

mSQL User Interface for Windows
     Chris Mai <chrissde@aol.com> has developed a user interface for
     Microsoft Windows that will connect to mSQL databases. It is available
     via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/msql-ui.zip

MS Windows
     Dean Fuqua <fuqua@niehs.nih.gov> has contributed an mSQL API for MS
     Windows platforms. To use this software you need some Winsock compliant
     stack. (i.e. Trumpet Winsock, MS TCP/IP-32, Chameleon, etc.) It is
     available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/winapi.zip
         (87211 bytes)

     Not included in winapi.zip is an msql.ini file. Its contents should
     resemble

         [Server]
         IP=your.server.host.name
         Port=1112
         Username=YourUsername

     There also appears to be a later version of Dean's work which includes
     compiled executables in

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/winmsql7.zip
         (306827 bytes)

     Peter Tillemans <pti@net4all.be> has taken Dirk Ohme's
     <dohme@transtec.de> OS/2 port of mSQL and used it to produce a Windows
     95/NT version of mSQL. This port can be obtained via anonymous ftp
     from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/msql116b-w32.zip
         (755355 bytes)

NeXTSTEP EOF
     Mark Onyschuk <ask-oa@oa.guild.org> has developed an NeXTSTEP EOF
     adaptor for mSQL.

     An Enterprise Object Framework (EOF) is an object framework that allows
     object oriented access to relational databases, where each row is
     considered an object. Besides a few limitations, it basically makes a
     relational database look like an OO database to the developer. By means
     of an adaptor, EOF can be used with virtually any database. The adaptor
     is responsible to transform the generic OO messages in database
     specific queries by subclassing a generic adaptor and modifying its
     behaviour.

Object Oriented HTML API
     Sol Katz <skatz@blm.gov> has developed an object oriented HTML API for
     mSQL.

     It is available via anonymous ftp from:

         ftp://ftp.blm.gov/pub/gis/msql_api.tar.gz
         (10317 bytes)

     An example can be found at

         http://www.blm.gov/gis/msql/dbs6.html

OCX
     Shayne Hughes <shayne@vgl.ucdavis.edu> has created a 32-bit OCX control
     that exposes all of the mSQL API (based on 1.0.12) with only slight
     modifications to make it work with pointer impaired languages like
     Visual Basic. It is available via anonymous ftp from:

         ftp://vgl.ucdavis.edu/pub/mSQL/ocxmsql-0.90.zip
         (1685189 bytes)

     Chin-Jin Phua <jojo@ttsh.gov.sg> has also developed a mSQL 32-bit OCX
     for Windows95 and WinNT. He has only tested it for Visual Basic.

         ftp://Bond.edu.au/pub/Minerva/msql/Contrib/msqlocx.zip
         (17409 bytes)

ODBC
     Dean Fuqua <fuqua@niehs.nih.gov> has developed a collection of ODBC
     files which are available via anonymous ftp from:

         ftp://ftp.comed.com/pub/msql/odbc

     For more information on Dean's work see:

         http://alfred.niehs.nih.gov

     Kevin Gill <kgill@kindle.ie> has extended Dean's work and developed
     ODBC software for connecting Visual Basic 3.0 to an mSQL server. His
     work can be obtained via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC

     and

         ftp://bond.edu.au/pub/Minerva/msql/Contrib

     The following file gives some out of date general information about the
     gorta software:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/gorta.faq
         (27450 bytes)

     The gorta software operates as either a 32 bit or a 16 bit ODBC driver.
     Different libraries/programs are required for each.

     For the 16 bit version (Windows 3.1 and 3.11) install:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/wmsqlrts.zip
         (11693 bytes)       - Mini-SQL API DLL (Must install First)
         ftp://bond.edu.au/pub/Minerva/msql/Contrib/gorta-rts.2.10.0.6.zip
         (17014 bytes)       - Gorta Driver

     For the 32 bit version (Windows 95) install:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/wmsqlr32-rts.zip
         (43193 bytes)       - Mini-SQL API 32 bit DLL (Must Install First)
         ftp://bond.edu.au/pub/Minerva/msql/Contrib/gorta32-rts.2.10.0.6.zip
         (22260 bytes)       - Gorta 32 bit driver

     The following test tools are available. (These are 16 bit but should
     work with the 32 bit drivers).

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/wmslqrs.zip
         (20257 bytes)       - A DOS/Windows version of the relshow program
         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/gortars.1.0.zip
         (23756 bytes)       - An ODBC version of the relshow program

     To install the ODBC driver for the first time requires the use of an
     install disk. This installs version 2.10.0.3 of the gorta drivers.
     Install from this and then overwrite the gorta dll (in the
     windows/system directory) with the one in the gorta 2.10.0.6 zip file.
     The install disk installs both the 16 and 32 bit versions of ODBC.

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/installd.zip
         (225019 bytes)

     The install disk tends to replace dlls with older versions. This is a
     problem if you have ODBC already running. Check the DLLs on the disk,
     and make a copy of your dlls before starting.

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/gortars.1.0.zip
         (23756 bytes)
         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/gortarts.2.10.0.3.zip
         (17480 bytes)
         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/gortasrc.2.10.0.3.zip
         (51770 bytes)
         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/installd.zip
         (225019 bytes)
         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/msql-1.12-dump.tar.gz
         (158282 bytes)
         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/wmsqlrs.zip
         (20257 bytes)
         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/wmsqlrts.zip
         (11693 bytes)
         ftp://bond.edu.au/pub/Minerva/msql/Contrib/ODBC/wmsqlsrc.zip
         (15089 bytes)

Onyx
     Michael Koehne <kraehe@bakunin.north.de> has developed a rapid
     prototyping tool for database applications called Onyx.

     Onyx consists of a transaction manager, a shell like 4GL and a Simple
     Database Transaction Protocol engine.

     "Onyx is designed by the Model-View-Controller paradigm, so tables are
     the model, masks are the views and transactions are the controllers
     which can be bound to an input field, a menu, function keys or the
     change of the current record in a cursor."

     It is available via anonymous ftp from:

         ftp://ftp.uni-bremen.de/pub/unix/database/Onyx/Onyx.2.45.src.tar.gz
         (195872 bytes)

OS/2
     Dirk Ohme <dohme@transtec.de> has ported mSQL 1.0.16 to OS/2. This
     version now includes an ODBC-compliant manager/driver within the
     package. It is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/msql116b_os2.lsm
         (1969 bytes)

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/msql116b_os2.zip
         (1297974 bytes)

     or

         http://www.fh-albsig.de/~ohme/FILES/msql116b.lsm
         (1969 bytes)

         http://www.fh-albsig.de/~ohme/FILES/msql116b.zip
         (1297974 bytes)

Perl
     Andreas Koenig <a.koenig@mind.de> has contributed a Perl 5 module which
     allows perl to interface to mSQL databases. The latest version is
     available via anonymous ftp from any of the CPAN archives, for example:

         ftp://ftp.funet.fi/pub/languages/perl/CPAN/modules/by-category/07_Database_Interfaces/Msql

     For more information about CPAN see:

         ftp://ftp.funet.fi/pub/languages/perl/CPAN/CPAN

PTS
     Dave Shevett <shevett@homeport.org> has developed a web based project
     tracking system - PTS. It used mSQL and PHP/FI. For more details see:

         http://www.homeport.org/~shevett/pts

Python
     Anthony Baxter <anthony.baxter@aaii.oz.au> has provided an mSQL
     extension to the Python language. It is available via anonymous ftp
     from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/PymSQL.tar.gz
         (7581 bytes)

REXX
     Mark Hessling <m.hessling@qut.edu.au> has provided an mSQL extension to
     REXX under Un*x and OS/2. It is available via anonymous ftp from the
     following sites:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib
         ftp://ftp.qut.edu.au/src/REXXSQL
         ftp://ftp.xylogics.com/pub/misc/REXXSQL

     You'll need to download the following files:

         rxsqldoc13.lsm (1014 bytes)
         rxsqldoc13.zip (39170 bytes)
         rxsqlmin13.lsm (1001 bytes)
         rxsqlmin13.zip (156525 bytes)
         rxsqlsam13.lsm (1014 bytes)
         rxsqlsam13.zip (25299 bytes)

Simple SQL
     Brian Jepson <bjepson@janus.saturn.net> has developed a fairly
     full-featured database management system toolkit using PHP and mSQL. It
     is available from:

         http://www.saturn.net/~bjepson/simple.html

SQLBase
     Klaus Thiele <kth@oblib.teuto.de> has provided a wrapper to allow
     SQLBase users to interface to mSQL databases. It is available via
     anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/mSQLBase-1.00.tgz

     which is a symbolic link to

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/msqlb-1.00.tgz
         (38136 bytes)

Tcl
     Hakan Soderstrom <hs@soderstrom.se> has provided an mSQL extension to
     the Tcl language. It has been tested with Tcl 7.5, Tk 4.1 and mSQL
     1.0.16 under SunOS 4.1.4. Successful ports to several other platforms
     have been reported. It is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/msqltcl-1.99.tar.gz
         (69356 bytes)

     Brad Pepers <pepersb@cuug.ab.ca> has also provided an mSQL extension to
     Tcl. According to the documentation it supports tcl7.3 and tk3.6. It is
     available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/tcl_msql.tar.gz
         (7998 bytes)

Time and date utilities
     Pascal Forget <pascal@wsc.com> has contributed a library of time and
     date conversion utilities. It is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/time_library.tar.gz
         (7989 bytes)

tkmSQL
     Alligator Decartes <descarte@hermetica.com> is developing an mSQL
     interface that uses Perl 5, Tk, and DBD/DBD-mSQL. It is currently in
     alpha release for developers only but Alligator would appreciate
     feedback.

     tkmSQL requires:

        o perl 5.001m or above
        o Tk-b8

          Note: This is a perl Tk module and is NOT to be confused with Tk
          itself. It can be obtained via anonymous ftp from:

              ftp://ftp.wpi.edu/perl5

          There is also a FAQ available from:

              http://w4.lns.cornell.edu/~pvhp/ptk/ptkFAQ.html

        o DBI-0.65
        o DBD::mSQL-0.60pl9

     You may obtain tkmSQL via anonymous ftp from:

         ftp://ftp.mcqueen.com/pub/databases/dbatools/tkmSQL

Unique sequence number generator
     Pascal Forget <pascal@wsc.com> has contributed a unique sequence number
     generator that can be used by mSQL applications (and others) to provide
     unique identifiers. It is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/sgs-1.0.0.tar.gz
         (24216 bytes)

VirtuFlex
     VirtuFlex Software has added mSQL support to their web/database
     development tool VirtuFlex. More details can be seen at:

         http://www.virtuflex.com

Visual Basic
     Jim Gerace <kasi@dreamscape.com> has implemented a Visual Basic client
     API for MS Windows and mSQL. It is available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/msqlcvb.zip
         (42192 bytes)

WDB
     Bo Frese Rasmussen <bfr@dtv.dk> has developed a Web database interface
     called WDB.

     WDB is a software tool set that tremendously simplifies the integration
     of SQL based databases into the World Wide Web. WDB lets you provide
     WWW access to the contents of databases without writing a single line
     of code!

     At the moment WDB supports Sybase, Informx and mSQL. However it is
     relatively easy to port it to other SQL based databases.

     For more details on WDB see:

         http://www.dtv.dk/~bfr/wdb

     Jeff Rowe <beowulf@cscsun4.larc.nasa.gov> has published a tutorial on
     enhancing WDB. Details can be found at:

         http://cscsun1.larc.nasa.gov/~beowulf/tutor/index.html

Websql
     Henry Minsky <hqm@ua.com> has developed an mSQL Table WWW browser
     interface.

     "This is a C web CGI script to examine and modify rows in tables of an
     mSQL database. You should use Netscape or another browser which
     supports HTML 3.0 tables."

     More details and sample output are available from:

         http://www.ua.com/websql

     Source code is available from:

         http://www.ua.com/websql/websql.tar.gz
         (24225 bytes)

Wojciech Tryc's Repository
     Wojciech Tryc <wojtek@tryc.on.ca> has established a repository of mSQL
     and PHP contributed software. It can be found at:

         http://solaris.tryc.on.ca/files/files.phtml

XfSQL
     Mark Loveland <mark@zeus.mysticgrp.com> has developed an X interface to
     mSQL using the Xforms package. Mark's work is available via anonymous
     ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/xfsql.tar.gz
         (74596 bytes)

     Xforms is available for a number of different platforms via anonymous
     ftp from either of the following locations:

         ftp://laue.phys.uwm.edu/pub/xforms/test
         ftp://ftp.cs.ruu.nl/pub/XFORMS/test

Xsqlmenu
     Kees Lemmens <lemmens@dv.twi.tudelft.nl> has also developed an X
     interface to mSQL using the Xforms package. Xsqlmenu can be obtained
     via anonymous ftp from:

         ftp://ta.twi.tudelft.nl/pub/dv/lemmens/xsqlmenu_1.02s.tar.gz
         (14973 bytes)

     A precompiled binary for Linux is also available via anonymous ftp
     from:

         ftp://ta.twi.tudelft.nl/pub/dv/lemmens/xsqlmenu_1.02LinuxBin.tar.gz
         (130945 bytes)

     Xforms is available for a number of different platforms via anonymous
     ftp from either of the following locations:

         ftp://laue.phys.uwm.edu/pub/xforms/test
         ftp://ftp.cs.ruu.nl/pub/XFORMS/test

Z Classes for C++
     Dean Fuqua <fuqua@niehs.nih.gov> has also contributed a set of C++
     classes to provide access to both Oracle and mSQL databases. It is
     available via anonymous ftp from:

         ftp://bond.edu.au/pub/Minerva/msql/Contrib/zmsql-2.1.tar
         (40960 bytes)

----------------------------------------------------------------------------

                            Web sites using mSQL

The following web sites are using mSQL as the database component of their
pages.

                            Web sites using mSQL

       3D Planet                        ISP Listing

       Bishop Museum, Honolulu          Nerosworld

       Borsen                           Paulina Springs Book Company

       CanadaIT                         Physics Pilot

       Conservation Ecology             QMS

       Dave 'Gizmo' Gymer               The Railway Exchange

       European Wide Service Exchange   Used gear price list

3D Planet
     Mark Mazur <mark@opencad.com> uses mSQL and The Personal Home Page
     Construction Kit to enable users to find the nearest 3D Planet store.
     This page can be seen at:

         http://www.3dplanet.com/d5.html

Bishop Museum, Honolulu
     Jeffrey Sue <jysue@aloha.net> has used mSQL and Rasmus Lerdorf's PHP
     package to create the first of several web based biology related
     databases. The first database is the arthropod checklist, a list of all
     known arthropods found in the Hawaiian Islands. The next databases will
     be additional checklists, starting with flowering plants. It can be
     seen at:

         http://www.bishop.hawaii.org/bishop/HBS/arthrosearch.html

Borsen
     This German site uses mSQL as its databases for searches. I can't give
     more information as it is all in German and my German is truly awful.
     For more details visit:

         http://www.borsen.dk

CanadaIT
     CanadaIT limited uses mSQL. Their web page can be seen at:

          http://www.CanadaIT.com

Conservation Ecology Journal
     Darryl Staflund <dstaflun@ccs.carleton.ca> uses mSQL behind the online
     journal Conservation Ecology. It can be seen at:

         http://www.consecol.org

Dave 'Gizmo' Gymer
     Dave Gymer <dgymer@gdcarc.co.uk> has used mSQL and Dean Fuqua's zclass
     C++ classes to provide a web based database system for his collection
     of compact discs. The CD collection and the source code can be seen at:

         http://www.mal.com/~dgymer/gizmo/music.html

European Wide Service Exchange
     The European Wide Service Exchange uses mSQL extensively. Apart from a
     user registration and customization service, complex relational tables
     allow context sensitive searching, both by geographic area as well as
     by 'free text'. Further functionality relying on mSQL includes urn->urc
     resolution services, calendars and an automatic 'what is new page'.
     What makes this site unique however is the ability for the user to add,
     modify or remove data entries from the databases through a web
     interface.

ISP Listing
     Rasmus Lerdorf <rasmus@vex.net> has used mSQL and PHP/FI to maintain a
     list of Internet Service Providers. His work can be seen at:

         http://www.vex.net/isp

Nerosworld
     David Perry <deperry@nerosworld.com> uses mSQL extensively to drive his
     web server. Examples of his work can be seen at:

         http://www.nerosworld.com/realestate/
         http://www.nerosworld.com/business/
         http://www.nerosworld.com/tradingpost/
         http://www.nerosworld.com/fstop/
         http://www.nerosworld.com/nero/zipcode.htm
         http://www.nerosworld.com/romancing_the_web/


Paulina Springs Book Company
     The Paulina Springs Book Company uses mSQL and PHP/FI to help drive
     it's web site. Visit it at:

         http://www.paulinasprings.com


Physics Pilot
     Kenneth Holmlund <Kenneth.Holmlund@TP.UmU.SE> from the Department of
     Theoretical Physics at Umee University in Sweden has used mSQL and The
     Personal Home Page Construction Kit to create the "The Internet Pilot
     to Physics". It can be seen at:

         http://www.tp.umu.se/TIPTOP

QMS
     James Hill <james_hill@iscclink.is.qms.com> has used mSQL and The
     Personal Home Page Construction Kit to create a searchable web based
     FAQ for QMS printers. It can be seen at:

         http://www.qms.com/www/faq

     James has made the source code available via anonymous ftp. It can be
     downloaded from:

         ftp://ftp.qms.com/pub/mktg/outgoing/SupportBase.tar.gz
         (5509 bytes)

The Railway Exchange
     Lester Hightower <hightowe@scri.fsu.edu> uses mSQL to power his web
     pages on model railway equipment. They can be seen at:

         http://www.railwayex.com/

Used gear price list
     Neil Bradley <neil@synthcom.com> has used mSQL to provide a price list
     for second hand music equipment. A demonstration of this system is
     available at

         http://www.synthcom.com/cgi-bin/gear

     and the source code can be obtained via anonymous ftp from:

         ftp://ftp.synthcom.com/pub/stuff

----------------------------------------------------------------------------
----------------------------------------------------------------------------
