Re: Howto implement sxntax and semantic complie time chock for - Mailing list pgsql-general

From Marc Weber
Subject Re: Howto implement sxntax and semantic complie time chock for
Date
Msg-id 20080530194625.GA15194@gmx.de
Whole thread Raw
In response to Re: Howto implement sxntax and semantic complie time chock for  ("Albe Laurenz" <laurenz.albe@wien.gv.at>)
List pgsql-general
On Thu, May 29, 2008 at 01:34:22PM +0200, Albe Laurenz wrote:
> marco-oweber wrote:
> > I'd like to implement some query checking at compile time for haskell
> > using template haskell.
> >
> > Is there any query method such as
> > explain input and output types of query "SELECT (1,'string')"
> > or "INSERT INTO foo (a,b,c) VALUES (?,?,?)" ?
> > returning Int, String or such?
>
> Could you, erm, clarify that question?
> And add information like what version of PostgreSQL and which
> programming language you intend to use?
The programming language should be haskell.
In contrast to PHP, VB etc it's uncommon to use kind of variant type.
Evrything is either a String or an Int, or a custom defined data type.

Eg you can define a function

insertMyTable :: Int -> String -> DBAction()
insertMyTable i s = runStatement "INSERT INTO MyTable (id, text) VALUES (" ++ (intToStr i) ++ "," ++ (escapeString s)
++")" 

the first line telling it's a function taking two params: an integer and a string.
The next line does proper quoting etc (maybe register a prepared statement ..)

Another example:

queryMyStuff :: DBAction (Int, Int, String)
queryMyStuff = mapM (\(a,b,c) -> (asInt a, asInt b, asString) ) $ runQuery "SELECT int1, int2, text FROM FOO"

Now what happens if change the format of int1 having been int to String?
asInt will bounce at runtime. That's bad.. (when ? all cases? MySQL, PHP silently ignore all
non digits propably resulting in 0) I don't like this.

Now haskell has a nice feature called template haskell allowing you to
generate code on the fly (a preprocessor could be used as well)

Now I'd like to use not
tuples = queryMyStuff ..
but
tuples = $( automaticallyDeriveFunctionWithArgsFromQuery "SELECT int1, int2, text FROM FOO WHERE int1 = ?" ) 3
(3 is used to substitute the parameter)
Now the preprocessor or template haskell should verify that table FOO
exists and has columns int1, int2, text.
Then it should create the a function taking an int (because it's
compared against an int) returning a list of tuples having type
(Int, Int, String)

If you change a db field then the type of the function will be changed
as well and the compiler will neatly tell you all about all type
missmatches. This in turn makes refactoring much easier.

Of course this will never work for "SELECT a" ++ ( if option then ",b"
else "" ) ++ "FROM ...

A friend has showed me the C preprocessor. I'll have a look at that
because it comes close except that I think that you tell it which types
to use by defining vars (but I'm not sure yet) instead of letting them
be infered by the system from the db scheme automatically.

I hope I was able to illustrate what I'm dreaming about..

Marc Weber

pgsql-general by date:

Previous
From: "dvs"
Date:
Subject: cannot use result of (insert .. returning)
Next
From: Tino Wildenhain
Date:
Subject: Re: cannot use result of (insert .. returning)