12.2 Integrating SQL in SML#
We observe that SQL SELECT command is an expression that construct a table from a set of tables specified in FROM clause. In practice, SQL commands are usually evaluated against a particular database connection. Since database connection is conceptually a set of tables, if we generalize SQL as a language that takes a database connection and returns a relation, an SQL command can be regarded as a function that takes a set of tables and returns a table. As we have already observe that SQL SELECT is an algebraic expression. Then SQL is a functional language on tables.
Since tables are set of records, table value functions should be typable using record polymorphism. According to our analysis, there is one subtle point in typing beyond record polymorphism [14]. For this reason, SML# introduced the following special syntax for SQL query functions.
_sql db => select #P.name as name, #P.age as age
from #db.Persons as P
where #P.salary > 10000
_sql db => ... represent a function that takes a database connection through parameter db. > in a _sql expression is SQL primitive for numerical comparison operation defined in the SQL module that implement various SQL specific primitives. #P.Name selects Name field from P. #db.Persons selects Persons table from db. These correspond to #Name P and #Persons db in SML# expression. In _sql => expression, we choose these syntax that are closer to SQL SELECT commands.
For this expression, SML# infers the following polymorphic type.
val it = fn
: [’a#{Persons: ’b list},
’b#{age: ’c, name: ’e, salary: ’g},
’c::{int, intInf, word, char,...},
’d::{int, intInf, word, char,...},
’e::{int, intInf, word, char,...},
’f::{int, intInf, word, char,...},
’g::{int, intInf, ’h option},
’h::{int, intInf}.
’a SQL.conn -> {age: ’c, name: ’e} SQL.cursor]
This type indicates that this query is a function from a database connection of type ’a conn to a table of tuple {age: ’c, name: ’e}. ’a represents the structure of the input database.
This is indeed a most general polymorphic type of the above query, By the fact that SML# can infer a most general polymorphic type, we are guarantees that SQL can be used in SML# based on ML programming principle: “expressions are freely composed as far as they are type consistent”, i.e. SQL expressions can be freely combined with any other language construct of SML# as far as they are type consistent. This will open up flexible and type safe programming using databases.