I generate SQL queries in Haskell and send them to the SQLite (3) database using HDBC. Now this function returns a request:
import Database.HDBC.Sqlite3 import Database.HDBC data UmeQuery = UmeQuery String [SqlValue] deriving Show tRunUmeQuery :: UmeQuery -> FilePath -> IO [[SqlValue]] tRunUmeQuery (UmeQuery q args) dbFile = do conn <- connectSqlite3 dbFile stat <- prepare conn q s <- execute stat args res <- fetchAllRows' stat disconnect conn return $ res selectPos targetlt parentlt op pos = let q= "select TARGET.* from levels tl, labeltypes tlt, segments TARGET, (select TARGET.session_id session_id,SECONDARY.labeltype_id labeltype_id, SECONDARY.label_id label_id,min(TARGET.label_id) min_childlabel_id from levels tl, labeltypes tlt, segments TARGET, segments SECONDARY, labeltypes slt, levels sl where TARGET.session_id = SECONDARY.session_id and ((SECONDARY.start <= TARGET.start and TARGET.end <= SECONDARY.end) or (TARGET.start <= SECONDARY.start and SECONDARY.end <= TARGET.end)) and tl.name = ? and sl.name = ? and SECONDARY.label ' != '' and tl.id = tlt.level_id and sl.id = slt.level_id and tlt.id = TARGET.labeltype_id and slt.id = SECONDARY.labeltype_id group by TARGET.session_id, TARGET.labeltype_id, SECONDARY.label_id) SUMMARY, segments SECONDARY, labeltypes slt, levels sl where TARGET.session_id = SECONDARY.session_id and TARGET.session_id = SUMMARY.session_id and ((SECONDARY.start <= TARGET.start and TARGET.end <= SECONDARY.end) or (TARGET.start <= SECONDARY.start and SECONDARY.end <= TARGET.end)) and tl.name = ? and sl.name = ? and tl.id = tlt.level_id and tlt.id = TARGET.labeltype_id and SUMMARY.labeltype_id = SECONDARY.labeltype_id and SUMMARY.label_id = SECONDARY.label_id and sl.id = slt.level_id and slt.id = SECONDARY.labeltype_id and (TARGET.label_id - SUMMARY.min_childlabel_id +1) = 2 " a = [toSql targetlt, toSql parentlt, toSql targetlt, toSql parentlt ] in UmeQuery qa
which, when applied to the database, returns the right thing:
> let a =selectPos "Word" "Utterance" "=" 2 > let b = tRunUmeQuery a testdb > b
outputs:
[[SqlByteString "1", SqlByteString "2", SqlByteString "3", SqlByteString "0.149383838383838", SqlByteString "0.312777777777778", SqlByteString "second"], [SqlByteString, 2nd, SqlByteString, 2q, 1q, 2q "0.507488888888889", SqlByteString "0.655905050505051", SqlByteString "fourth"], [SqlByteString "2", SqlByteString "2", SqlByteString "3", SqlByteString "0.149383838383838", SqlByteString "0.312777777777778", SqlByteString "second"], [SqlByteString " 2 ", SqlByteString" 2 ", SqlByteString" 6 ", SqlByteString" 0.507488888888889 ", SqlByteString" 0.655905050505051 ", SqlByteString" fourth "], SqlByteString" 3 ", Sql3838, 38t38, 38t38, 38138, 38138, 38138, 38138, 38138, 38138, 3813838, 381 SqlByteString "0.312777777777778", SqlByteString "second"], [SqlByteString "3", SqlByteString "2", SqlByteString "6", SqlByteString "0.50748888888888989", SqlBy50ring50 “50th50] 50q50B50te50ring50y5050te5050t50qt50] 50q50b50te50ring50y5050te5050te5050te5050t50] 50t5050t50]
Now that I need to insert a couple of small dynamic parts into the query, like this (sorry, you need to scroll to the end of the line to see this):
selectPos targetlt parentlt op pos = let q= "select TARGET.* from levels tl, labeltypes tlt, segments TARGET, (select TARGET.session_id session_id,SECONDARY.labeltype_id labeltype_id, SECONDARY.label_id label_id,min(TARGET.label_id) min_childlabel_id from levels tl, labeltypes tlt, segments TARGET, segments SECONDARY, labeltypes slt, levels sl where TARGET.session_id = SECONDARY.session_id and ((SECONDARY.start <= TARGET.start and TARGET.end <= SECONDARY.end) or (TARGET.start <= SECONDARY.start and SECONDARY.end <= TARGET.end)) and tl.name = ? and sl.name = ? and SECONDARY.label != '' and tl.id = tlt.level_id and sl.id = slt.level_id and tlt.id = TARGET.labeltype_id and slt.id = SECONDARY.labeltype_id group by TARGET.session_id, TARGET.labeltype_id, SECONDARY.label_id) SUMMARY, segments SECONDARY, labeltypes slt, levels sl where TARGET.session_id = SECONDARY.session_id and TARGET.session_id = SUMMARY.session_id and ((SECONDARY.start <= TARGET.start and TARGET.end <= SECONDARY.end) or (TARGET.start <= SECONDARY.start and SECONDARY.end <= TARGET.end)) and tl.name = ? and sl.name = ? and tl.id = tlt.level_id and tlt.id = TARGET.labeltype_id and SUMMARY.labeltype_id = SECONDARY.labeltype_id and SUMMARY.label_id = SECONDARY.label_id and sl.id = slt.level_id and slt.id = SECONDARY.labeltype_id and (TARGET.label_id - SUMMARY.min_childlabel_id +1) " ++ op ++ " ? " a = [toSql targetlt, toSql parentlt, toSql targetlt, toSql parentlt , toSql pos] in UmeQuery qa
and do the same, I get:
> let a =selectPos "Word" "Utterance" "=" 2 > let b = tRunUmeQuery a testdb > b
[]
Why does the second query return nothing (or, in fact, something in fact)?
Any ideas?
Edit:
Ive explored this further, thinking that this may be due to the lazy somehow. So now it has been changed:
selectPos :: String -> String -> String -> Integer -> [[SqlValue]] selectPos targetlt parentlt op pos = let q= foldl' (++) [] ["select TARGET.* from levels tl, labeltypes tlt, segments TARGET, (select TARGET.session_id session_id,SECONDARY.labeltype_id labeltype_id,SECONDARY.label_id label_id,min(TARGET.label_id) min_childlabel_id from levels tl, labeltypes tlt, segments TARGET, segments SECONDARY, labeltypes slt, levels sl where TARGET.session_id = SECONDARY.session_id " ,matchstring , " and tl.name = ? and sl.name = ? and SECONDARY.label != '' and tl.id = tlt.level_id and sl.id = slt.level_id and tlt.id = TARGET.labeltype_id and slt.id = SECONDARY.labeltype_id group by TARGET.session_id, TARGET.labeltype_id, SECONDARY.label_id) SUMMARY, segments SECONDARY, labeltypes slt, levels sl where TARGET.session_id = SECONDARY.session_id and TARGET.session_id = SUMMARY.session_id " , matchstring , " and tl.name = ? and sl.name = ? and tl.id = tlt.level_id and tlt.id = TARGET.labeltype_id and SUMMARY.labeltype_id = SECONDARY.labeltype_id and SUMMARY.label_id = SECONDARY.label_id and sl.id = slt.level_id and slt.id = SECONDARY.labeltype_id and (TARGET.label_id - SUMMARY.min_childlabel_id +1) " , op , " ? "] a = [toSql targetlt, toSql parentlt, toSql targetlt, toSql parentlt , toSql (pos :: Integer)] in UmeQuery qa
Unfortunately, this does not help (and when I: sprint the return value of a function in ghci, it is still not appreciated). So laziness may be a problem somehow, but I don’t know how to make it fully appreciated ..? Please have any ideas?