SML# Document Version 4.0.0
22 SQL Expressions and Commands

22.8 SQL Library: The SQL Structure

SML# provides the types and functions related to SQL as a library. All of them are included in the SQL structure provided by the sql.smi interface file. An SML# source file that uses the SQL feature must include the following lines in its interface file so that it refers to sql.smi:

_require "sql.smi"

The following is the signature of the SQL structure:

structure SQL : sig
  type bool3
  type numeric
  type decimal = numeric
  type backend
  type ’a server
  type ’a conn
  type ’a cursor
  type (’a, ’b) exp
  type (’a, ’b) whr
  type (’a, ’b) from
  type (’a, ’b) orderby
  type (’a, ’b, ’c) select
  type (’a, ’b) query
  type (’a, ’b) command
  type (’a, ’b) db
  exception Exec
  exception Connect
  exception Link
  val postgresql : string -> backend
  val mysql : string -> backend
  val odbc : string -> backend
  val sqlite3 : string -> backend
  structure SQLite3 :
(see Section 22.8.1)
  val connect : ’a server -> ’a conn
  val connectAndCreate : ’a server -> ’a conn
  val closeConn : ’a conn -> unit
  val fetch : ’a cursor -> ’a option
  val fetchAll : ’a cursor -> ’a list
  val closeCursor : ’a cursor -> unit
  val queryCommand : (’a list, ’b) query -> (’a cursor, ’b) command
  val toy : ((’a, ’c) db -> (’b, ’c) query) -> ’a -> ’b
  val commandToString : ((’a,’c) db -> (’b,’c) command) -> string
  val queryToString : ((’a,’c) db -> (’b,’c) query) -> string
  val expToString : (’a,’c) exp -> string
  Structure Op :
(see Section 22.9)
  Structure Numeric : see Section 22.9
  Structure Decimal = Numeric
end

These definitions are categorized by their purposes. Each of the following subsections describes the definitions belonging to a category.

22.8.1 Connecting to a database server

  • exception Connect of string

    The exception of a database connection error. string is the error message.

  • exception Link of string

    The exception indicating the mismatch of database schema and SML# programs. string is the error message.

  • type backend

    The type of the untyped connection information to a database, which is a part of the _sqlserver expression. One of the following function can be used to write an expression of this type.

  • val postgresql : string -> backend

    SQL.postgresql param returns an connection information to a PostgreSQL server. The string param is the connection string of libpq, the PostgreSQL library. See the PostgreSQL manual for defails of the connection string. If param is not valid, the SQL.Connect exception is raised.

    The correspondence between the PostgreSQL and SML# types is the following:

    PostgreSQL SML#
    INT, INT4 int
    BOOLEAN bool
    TEXT, VARCHAR string
    FLOAT8 real
    FLOAT4 real32
  • val mysql : string -> backend

    SQL.mysql param returns a connection information to a MySQL server. The string param consists of the sequences of “key=value” separated by whitespaces. The keys avaliable and their meanings are the following:

    Key Description
    host The hostname of a MySQL server
    port The port number of a MySQL server
    user The user name to log in a MySQL server
    password The password of the user
    dbname The name of the target database
    unix_socket The filename of a UNIX socket
    flags The flags of the communication protocol in decimal

    dbname is mandatory. See the MySQL manual for details of these parameters. If param is not valid, the SQL.Connect exception is raised.

    The correspondence between the MySQL and SML# types are the following:

    MySQL SML#
    TINYINT, SMALLINT, MEDIUMINT, INT int
    TINYTEXT, TEXT, VARCHAR string
    DOUBLE real
    FLOAT real32
  • val sqlite3 : string -> backend
    val sqlite3’ : SQL.SQLite3.flags * string -> backend

    SQL.sqlite3 filename and SQL.sqlite3 (flags, filename) return a connection information to an SQLite3 database file. The string filename indicates the filename. Note that SQLite3 interprets the filenames beginning with “:” in a special way.

    flags is a record consisting of the following four fields:

    • mode: the open mode of the file, which is one of the following:

      • *

        SQL.SQLite3.SQLITE_OPEN_READONLY

      • *

        SQL.SQLite3.SQLITE_OPEN_READWRITE

      • *

        SQL.SQLite3.SQLITE_OPEN_READWRITE_CREATE

    • threading: the threading mode, which is one of the following:

      • *

        SQL.SQLite3.SQLITE_OPEN_NOMUTEX

      • *

        SQL.SQLite3.SQLITE_OPEN_FULLMUTEX

    • cache: the cache mode, which is one of the following:

      • *

        SQL.SQLite3.SQLITE_OPEN_SHAREDCACHE

      • *

        SQL.SQLite3.SQLITE_OPEN_PRIVATECACHE

    • uri: the way to interpret the filename, which may be the following:

      • *

        SQL.SQLite3.SQLITE_OPEN_URI

    See the SQLite3 C/C++ API manual for details of these flags. These constants are defined in the SQL.SQLite3 structure. In addition, SQL.SQLite3 provides the default flag SQL.SQLite3.flags, which is used if flags is omitted. A partially modified version of SQL.SQLite3.flags can be obatained by using the field update expression.

    The correspondence between SQLite3’s type affinities and SML#’s type is the following:

    Type affinity SML#
    INT int
    REAL real
    STRING string
    NUMERIC numeric
    BLOB (unsupported)

    Each type of columns specified in CREATE TABLE statement is interpreted to a type affinity as described in the SQLite3 manual.

  • val odbc : string -> backen

    SQL.odbc param returns a connection information to an ODBC server. The string param consists of a DSN name, user name, and password in this order separated by whitespaces. If param is not valid, the SQL.Connect exception is raised.

    The correspondence between the ODBC and SML# types is the following

    ODBC SML#
    CHAR string
    INTEGER, SMALLINT int
    FLOAT real32
    DOUBLE real
    VARCHAR, LONGVARCHAR, NVARCHAR string
  • val connect : ’a server -> ’a conn

    SQL.connect server establishes a connection to the server indicated by the connection description server. If the connection is established and the schema of the connected database subsumes the schema represented by server, it returns a connection handle. If a connection error occurs, the SQL.Exec exception is raised. If the two schemas are not matched, the SQL.Link exception is raised.

    The type of the connection description server represts the type of the tables and views that the SML# program deals with through this connection. SQL.connect checks the system catalog of the database so that all tables and views in the type of server exists in the database. The names of tables and views are case-insensitive during this check. The database may contain tables and views other than those specified in the type of server. In contrast, for each table in server, its column set must exactly matches with the actual table definition.

    At the first time to connect to a database server, an external library is dynamically linked according to the kind of the database server. The default name of such libraries are hard-coded. If the library name is not appropriate, it can be changed by setting environment variables. The following table shows the default name and environment vairable name for each server kind:

    Database Library name Environment variable
    PostgreSQL libpq.so.5 SMLSHARP_LIBPQ
    MySQL libmysqlclient.16.so SMLSHARP_LIBMYSQLCLIENT
    ODBC libodbc.so.2 SMLSHARP_LIBODBC
    SQLite3 libsqlite3.so.0 SMLSHARP_LIBSQLITE3
  • val connectAndCreate : ’a server -> ’a conn

    Same as SQL.connect except for the following: SQL.connectAndCreate creates the tables that are indicated in the argument type but do not exist in the database by issueing the CREATE TABLE commands. If a table to be created includes an unsupported type, it raises the SQL.Link exception. If a CREATE TABLE command fails, it raises the SQL.Exec exception.

  • val closeConn : ’a conn -> unit

    SQL.closeConn conn closes a database connection. Any connection established by SQL.connect must be closed by SQL.closeConn.

22.8.2 executing SQL queries and retrieving their results

  • exception Exec of string

    The exception indicating that an error occur during a query execution on a database server. string is the error message.

  • val fetch : ’a cursor -> ’a option

    SQL.fetch cursor reads one row pointed by the cursor cursor and move the cursor to the next row. If the cursor reaches to the end of a table, it returns NONE. If the cursor is already closed, the SQL.Exec exception is raised.

  • val fetchAll : ’a cursor -> ’a list

    SQL.fetchAll cursor reads all rows between the cursor cursor and the end of the table and closes the cursor. If the cursor is already closed, the SQL.Exec exception is raised.

  • closeCursor : ’a cursor -> unit

    closeCursor cursor closes the given cursor. All cursors must be closed by this function or fetchAll.

22.8.3 Utilities for SQL Queries

  • val queryCommand : (’a list, ’b) query -> (’a cursor, ’b) command

    SQL.queryCommand query converts the given SELECT query to a SQL command. This function performs the same thing as what an SQL execution function _sql pat => select...(exp) does for a query (see Section 22.7) except for the query execution.

  • val toy : ((’a, ’c) db -> (’b, ’c) query) -> ’a -> ’b

    SQL.toy query data regards data as a database and evaluates the query query on it. The evaluation is carried out in SML# without involving any server communication. This function executes a toy program that the SML# compiler generates for the typecheck of SQL queries. Note that the performance of the toy program is not considered and therefore this function may be seriously slow.

  • val commandToString : ((’a,’c) db -> (’b,’c) command) -> string

    SQL.commandToString command returns the serialized string of the SQL command the function command returns. The string this function returns is identical to the string sent to the server when the command is executed.

  • val queryToString : ((’a,’c) db -> (’b,’c) query) -> string

    SQL.queryToString query returns the serialized string of the SELECT query the function query returns. The string this function returns is identical to the string sent to the server when the query is executed.

  • val expToString : (’a,’c) exp -> string

    SQL.expToString exp returns the serialized string of the SQL value expression exp.