diff --git a/Database/HSparql/Connection.hs b/Database/HSparql/Connection.hs
--- a/Database/HSparql/Connection.hs
+++ b/Database/HSparql/Connection.hs
@@ -1,11 +1,18 @@
 module Database.HSparql.Connection
     ( Database.HSparql.Connection.EndPoint
     , BindingValue(..)
+    -- * submit queries using HSparql DSL
     , selectQuery
     , constructQuery
     , askQuery
     , updateQuery
     , describeQuery
+    -- * submit queries using raw SPARQL strings
+    , selectQueryRaw
+    , constructQueryRaw
+    , askQueryRaw
+    , updateQueryRaw
+    , describeQueryRaw
     )
 where
 
@@ -81,11 +88,36 @@
   | s == "" = True
   | otherwise = error $ "Unexpected Update response: " ++ s
 
+
 -- |Connect to remote 'EndPoint' and find all possible bindings for the
---  'Variable's in the 'SelectQuery' action.
+-- 'Variable's in the 'SelectQueryRaw action.
 selectQuery :: Database.HSparql.Connection.EndPoint -> Query SelectQuery -> IO (Maybe [[BindingValue]])
-selectQuery ep q = do
-  let uri = ep ++ "?" ++ urlEncodeVars [("query", createSelectQuery q)]
+selectQuery ep q = selectQueryRaw ep (createSelectQuery q)
+
+-- |Connect to remote 'EndPoint' and find all possible bindings for the
+--  'Variable's in the 'SelectQueryRaw action.
+askQuery :: Database.HSparql.Connection.EndPoint -> Query AskQuery -> IO Bool
+askQuery ep q = askQueryRaw ep (createAskQuery q)
+
+-- |Connect to remote 'EndPoint' and find all possible bindings for the
+--  'Variable's in the 'SelectQueryRaw action.
+updateQuery :: Database.HSparql.Connection.EndPoint -> Query UpdateQuery -> IO Bool
+updateQuery ep q = updateQueryRaw ep (createUpdateQuery q)
+
+-- |Connect to remote 'EndPoint' and construct 'TriplesGraph' from given
+--  'ConstructQueryRaw action. /Provisional implementation/.
+constructQuery :: (RDF.Rdf a) => Database.HSparql.Connection.EndPoint -> Query ConstructQuery -> IO (RDF.RDF a)
+constructQuery ep q = constructQueryRaw ep (createConstructQuery q)
+
+-- |Connect to remote 'EndPoint' and construct 'TriplesGraph' from given
+--  'ConstructQueryRaw action. /Provisional implementation/.
+describeQuery :: (RDF.Rdf a) => Database.HSparql.Connection.EndPoint -> Query DescribeQuery -> IO (RDF.RDF a)
+describeQuery ep q = describeQueryRaw ep (createDescribeQuery q)
+
+
+selectQueryRaw :: Database.HSparql.Connection.EndPoint -> String -> IO (Maybe [[BindingValue]])
+selectQueryRaw ep q = do
+  let uri = ep ++ "?" ++ urlEncodeVars [("query", q)]
       h1 = mkHeader HdrAccept "application/sparql-results+xml"
       h2 = mkHeader HdrUserAgent "hsparql-client"
       request = Request { rqURI = fromJust $ parseURI uri
@@ -96,11 +128,9 @@
   response <- simpleHTTP request >>= getResponseBody
   return $ structureContent response
 
--- |Connect to remote 'EndPoint' and find all possible bindings for the
---  'Variable's in the 'SelectQuery' action.
-askQuery :: Database.HSparql.Connection.EndPoint -> Query AskQuery -> IO Bool
-askQuery ep q = do
-  let uri = ep ++ "?" ++ urlEncodeVars [("query", createAskQuery q)]
+askQueryRaw :: Database.HSparql.Connection.EndPoint -> String -> IO Bool
+askQueryRaw ep q = do
+  let uri = ep ++ "?" ++ urlEncodeVars [("query", q)]
       hdr1 = Header HdrUserAgent "hsparql-client"
       hdr2 = Header HdrAccept "text/plain"
       hdr3 = Header HdrAccept "text/boolean"
@@ -109,12 +139,10 @@
   response <- simpleHTTP request >>= getResponseBody
   return $ parseAsk response
 
--- |Connect to remote 'EndPoint' and find all possible bindings for the
---  'Variable's in the 'SelectQuery' action.
-updateQuery :: Database.HSparql.Connection.EndPoint -> Query UpdateQuery -> IO Bool
-updateQuery ep q = do
+updateQueryRaw :: Database.HSparql.Connection.EndPoint -> String -> IO Bool
+updateQueryRaw ep q = do
   let uri = ep
-      body = createUpdateQuery q
+      body = q
       h1 = mkHeader HdrContentLength $ show (length body)
       h2 = mkHeader HdrContentType "application/sparql-update"
       h3 = mkHeader HdrUserAgent "hsparql-client"
@@ -127,21 +155,17 @@
 --    return $ structureContent response
   return $ parseUpdate response
 
--- |Connect to remote 'EndPoint' and construct 'TriplesGraph' from given
---  'ConstructQuery' action. /Provisional implementation/.
-constructQuery :: (RDF.Rdf a) => Database.HSparql.Connection.EndPoint -> Query ConstructQuery -> IO (RDF.RDF a)
-constructQuery ep q = do
-  let uri = ep ++ "?" ++ urlEncodeVars [("query", createConstructQuery q)]
+constructQueryRaw :: (RDF.Rdf a) => Database.HSparql.Connection.EndPoint -> String -> IO (RDF.RDF a)
+constructQueryRaw ep q = do
+  let uri = ep ++ "?" ++ urlEncodeVars [("query", q)]
   rdfGraph <- httpCallForRdf uri
   case rdfGraph of
     Left e -> error $ show e
     Right graph -> return graph
 
--- |Connect to remote 'EndPoint' and construct 'TriplesGraph' from given
---  'ConstructQuery' action. /Provisional implementation/.
-describeQuery :: (RDF.Rdf a) => Database.HSparql.Connection.EndPoint -> Query DescribeQuery -> IO (RDF.RDF a)
-describeQuery ep q = do
-  let uri = ep ++ "?" ++ urlEncodeVars [("query", createDescribeQuery q)]
+describeQueryRaw :: (RDF.Rdf a) => Database.HSparql.Connection.EndPoint -> String -> IO (RDF.RDF a)
+describeQueryRaw ep q = do
+  let uri = ep ++ "?" ++ urlEncodeVars [("query", q)]
   rdfGraph <- httpCallForRdf uri
   case rdfGraph of
     Left e -> error $ show e
diff --git a/Database/HSparql/QueryGenerator.hs b/Database/HSparql/QueryGenerator.hs
--- a/Database/HSparql/QueryGenerator.hs
+++ b/Database/HSparql/QueryGenerator.hs
@@ -20,6 +20,7 @@
   , describeIRI, describeIRI_
   , optional, optional_
   , union, union_
+  , exists, notExists
   , filterExpr, filterExpr_
   , bind, bind_
   , subQuery, subQuery_
@@ -63,6 +64,7 @@
   , min_
   , max_
   , avg
+  , groupConcat
 
   -- ** Builtin Functions
   , str
@@ -76,6 +78,19 @@
   , isBlank
   , isLiteral
   , regex, regexOpts
+  , strlen
+  , substr
+  , ucase, lcase
+  , strstarts, strends
+  , contains
+  , strbefore, strafter
+  , abs_
+  , round_
+  , ceil
+  , floor_
+  , concat_
+  , replace
+  , rand
 
   -- * Printing Queries
   , qshow
@@ -263,6 +278,18 @@
 union_ :: Query a -> Query b -> Query ()
 union_ a b = void $ union a b
 
+exists :: Query a -> Query Pattern
+exists q = do
+  let p = execQuery0 q pattern
+      exists' = ExistsPattern p
+  return exists'
+
+notExists :: Query a -> Query Pattern
+notExists q = do
+  let p = execQuery0 q pattern
+      notExists' = NotExistsPattern p
+  return notExists'
+
 -- |Restrict results to only those for which the given expression is true.
 filterExpr :: (TermLike a) => a -> Query Pattern
 filterExpr e = do
@@ -526,6 +553,10 @@
 notExpr = NegatedExpr . expr
 
 -- Builtin Functions
+type BuiltinFunc0 = Expr
+builtinFunc0 :: Function -> BuiltinFunc0
+builtinFunc0 f = BuiltinCall f []
+
 type BuiltinFunc1 = forall a . (TermLike a) => a -> Expr
 builtinFunc1 :: Function -> BuiltinFunc1
 builtinFunc1 f x = BuiltinCall f [expr x]
@@ -538,27 +569,102 @@
 builtinFunc3 :: Function -> BuiltinFunc3
 builtinFunc3 f x y z = BuiltinCall f [expr x, expr y, expr z]
 
+-- | Aggregate by count
 count :: BuiltinFunc1
 count = builtinFunc1 CountFunc
 
+-- | Aggregate by sum
 sum_ :: BuiltinFunc1
 sum_ = builtinFunc1 SumFunc
 
+-- | Aggregate by minimum value
 min_ :: BuiltinFunc1
 min_ = builtinFunc1 MinFunc
 
+-- | Aggregate by maximum value
 max_ :: BuiltinFunc1
 max_ = builtinFunc1 MaxFunc
 
+-- | Aggregate by average
 avg :: BuiltinFunc1
 avg = builtinFunc1 AvgFunc
 
+-- | Cast as a string
 str :: BuiltinFunc1
 str = builtinFunc1 StrFunc
 
+-- | Get the language of this element
 lang :: BuiltinFunc1
 lang = builtinFunc1 LangFunc
 
+-- | strlen ( string ) - get the length of a string
+strlen :: BuiltinFunc1
+strlen = builtinFunc1 StrLenFunc
+
+-- | substr ( string beginPosition stringLength ) - get a substring
+substr :: BuiltinFunc1
+substr = builtinFunc1 SubStrFunc
+
+-- | ucase ( string ) - convert to upper case
+ucase :: BuiltinFunc1
+ucase = builtinFunc1 UcaseFunc
+
+-- | lcase ( string ) - convert to lower case
+lcase :: BuiltinFunc1
+lcase = builtinFunc1 LcaseFunc
+
+-- | strstarts ( string x ) - return true if x matches the beginning of string
+strstarts :: BuiltinFunc2
+strstarts = builtinFunc2 StrStartsFunc
+
+-- | strends ( string x ) - return true if x matches the end of string
+strends :: BuiltinFunc2
+strends = builtinFunc2 StrEndsFunc
+
+-- | contains ( string x ) - return true if x matches anywhere in string
+contains :: BuiltinFunc2
+contains = builtinFunc2 ContainsFunc
+
+-- | strbefore ( string x ) - return the string preceding a match to x
+strbefore :: BuiltinFunc2
+strbefore = builtinFunc2 StrBeforeFunc
+
+-- | strafter ( string x ) - return the string after a match to x
+strafter :: BuiltinFunc2
+strafter = builtinFunc2 StrAfterFunc
+
+-- | concat_ ( x y ) - concatenate strings x and y
+concat_ :: BuiltinFunc2
+concat_ = builtinFunc2 ConcatFunc
+
+-- | replace ( string p r ) - replace literal p with literal r in string
+replace :: BuiltinFunc3
+replace = builtinFunc3 ReplaceFunc
+
+-- | abs_ ( x ) - take the absolute value of number x
+abs_ :: BuiltinFunc1
+abs_ = builtinFunc1 AbsFunc
+
+-- | round ( x ) - round x to the nearest integer
+round_ :: BuiltinFunc1
+round_ = builtinFunc1 RoundFunc
+
+-- | ceil ( number ) - round x up to the nearest integer
+ceil :: BuiltinFunc1
+ceil = builtinFunc1 CeilFunc
+
+-- | floor ( number ) - round x down to the nearest integer
+floor_ :: BuiltinFunc1
+floor_ = builtinFunc1 FloorFunc
+
+-- | rand ( ) - produce a random number between 0 and 1
+rand :: BuiltinFunc0
+rand = builtinFunc0 RandFunc
+
+-- | Aggregate a column by string concatenation with a separator.
+groupConcat :: (TermLike a) => a -> String -> Expr
+groupConcat x sep = ParameterizedCall GroupConcat [expr x] [("separator", "\"" ++ sep ++ "\"")]
+
 langMatches :: BuiltinFunc2
 langMatches = builtinFunc2 LangMatchesFunc
 
@@ -704,13 +810,19 @@
 data Relation = Equal | NotEqual | LessThan | GreaterThan | LessThanOrEqual | GreaterThanOrEqual
               deriving (Show)
 
-data Function = CountFunc| SumFunc | MinFunc | MaxFunc | AvgFunc
+data Function = CountFunc | SumFunc | MinFunc | MaxFunc | AvgFunc
               | StrFunc | LangFunc | LangMatchesFunc
               | DataTypeFunc | BoundFunc | SameTermFunc
               | IsIRIFunc | IsURIFunc | IsBlankFunc | IsLiteralFunc
               | RegexFunc
+              | StrLenFunc | SubStrFunc | UcaseFunc | LcaseFunc
+              | StrStartsFunc | StrEndsFunc | ContainsFunc | StrBeforeFunc
+              | StrAfterFunc | ConcatFunc | ReplaceFunc
+              | AbsFunc | RoundFunc | CeilFunc | FloorFunc | RandFunc
               deriving (Show)
 
+data ParameterizedFunction = GroupConcat deriving (Show)
+
 data Expr = OrExpr [Expr]
           | AndExpr [Expr]
           | NegatedExpr Expr
@@ -718,6 +830,7 @@
           | NumericExpr NumericExpr
           | BuiltinCall Function [Expr]
           | VarOrTermExpr VarOrTerm
+          | ParameterizedCall ParameterizedFunction [Expr] [(String, String)]
           deriving (Show)
 
 data SelectExpr = SelectExpr Expr Variable
@@ -733,6 +846,8 @@
              | OptionalGraphPattern GroupGraphPattern
              | UnionGraphPattern GroupGraphPattern GroupGraphPattern
              | SubQuery QueryData
+             | ExistsPattern GroupGraphPattern
+             | NotExistsPattern GroupGraphPattern
 
 data GroupGraphPattern = GroupGraphPattern [Pattern]
 
@@ -887,7 +1002,26 @@
   qshow IsBlankFunc     = "isBlank"
   qshow IsLiteralFunc   = "isLiteral"
   qshow RegexFunc       = "REGEX"
+  qshow StrLenFunc      = "STRLEN"
+  qshow SubStrFunc      = "SUBSTR"
+  qshow UcaseFunc       = "UCASE"
+  qshow LcaseFunc       = "LCASE"
+  qshow StrStartsFunc   = "STRSTARTS"
+  qshow StrEndsFunc     = "STARTENDS"
+  qshow ContainsFunc    = "CONTAINS"
+  qshow StrBeforeFunc   = "STRBEFORE"
+  qshow StrAfterFunc    = "STRAFTER"
+  qshow ConcatFunc      = "CONCAT"
+  qshow ReplaceFunc     = "REPLACE"
+  qshow AbsFunc         = "ABS"
+  qshow RoundFunc       = "ROUND"
+  qshow CeilFunc        = "CEIL"
+  qshow FloorFunc       = "FLOOR"
+  qshow RandFunc        = "RAND"
 
+instance QueryShow ParameterizedFunction where
+  qshow GroupConcat = "GROUP_CONCAT"
+
 instance QueryShow Expr where
   qshow = qshow'
     where qshow' (VarOrTermExpr vt) = qshow vt
@@ -897,8 +1031,11 @@
           qshow' (RelationalExpr rel e1 e2) = wrap $ qshow e1 ++ qshow rel ++ qshow e2
           qshow' (NumericExpr e')   = wrap $ qshow e'
           qshow' (BuiltinCall f es) = wrap $ qshow f ++ "(" ++ intercalate ", " (map qshow es) ++ ")"
+          qshow' (ParameterizedCall f es kwargs) = wrap $ qshow f ++ "(" ++ intercalate ", " (map qshow es) ++ " ; " ++ (intercalate "," $ map pair kwargs) ++ ")"
           wrap e = "(" ++ e ++ ")"
+          pair (k, v) = k ++ "=" ++ v
 
+
 instance QueryShow SelectExpr where
   qshow (SelectVar v) = qshow v
   qshow (SelectExpr e v) = mconcat ["(", qshow e, " AS ", qshow v, ")"]
@@ -912,6 +1049,8 @@
   qshow (Bind e v)      = "BIND(" ++ qshow e ++ " AS " ++ qshow v ++ ")"
   qshow (OptionalGraphPattern p)  = "OPTIONAL " ++ qshow p
   qshow (UnionGraphPattern p1 p2) = qshow p1 ++ " UNION " ++ qshow p2
+  qshow (ExistsPattern p) = "EXISTS" ++ qshow p
+  qshow (NotExistsPattern p) = "NOT EXISTS" ++ qshow p
   qshow (SubQuery qd)   = intercalate " " ["{", qshow qd, "}"]
 
 instance QueryShow [Pattern] where
diff --git a/hsparql.cabal b/hsparql.cabal
--- a/hsparql.cabal
+++ b/hsparql.cabal
@@ -1,6 +1,5 @@
 Name:          hsparql
-Homepage:      https://github.com/robstewart57/hsparql
-Version:       0.3.5
+Version:       0.3.6
 Synopsis:      A SPARQL query generator and DSL, and a client to query a SPARQL server.
 Category:      Database
 Description:
