diff --git a/Language/SQL/SimpleSQL/Parser.lhs b/Language/SQL/SimpleSQL/Parser.lhs
index 65cb1cb..4fc7678 100644
--- a/Language/SQL/SimpleSQL/Parser.lhs
+++ b/Language/SQL/SimpleSQL/Parser.lhs
@@ -128,6 +128,7 @@ digitse[+-]digits
 >   where
 >     letterOrUnderscore = char '_' <|> letter
 >     letterDigitOrUnderscore = char '_' <|> alphaNum
+
 > blacklist :: [String]
 > blacklist = ["as", "from", "where", "having", "group", "order"
 >             ,"inner", "left", "right", "full", "natural", "join"
@@ -142,7 +143,7 @@ to be.
 
 > dottedIden :: P ScalarExpr
 > dottedIden = Iden2 <$> identifierString
->                                <*> (symbol "." *> identifierString)
+>                    <*> (symbol "." *> identifierString)
 
 > star :: P ScalarExpr
 > star = choice [Star <$ symbol "*"
@@ -169,7 +170,7 @@ to be.
 > cast = parensCast <|> prefixCast
 >   where
 >     parensCast = try (keyword_ "cast") >>
->                  parens (Cast <$> scalarExpr
+>                  parens (Cast <$> scalarExpr'
 >                          <*> (keyword_ "as" *> typeName))
 >     prefixCast = try (CastOp <$> typeName
 >                              <*> stringLiteral)
@@ -181,11 +182,24 @@ to be.
 >     <*> return e
 >     <*> parens (choice
 >                 [InQueryExpr <$> queryExpr
->                 ,InList <$> commaSep1 scalarExpr])
+>                 ,InList <$> commaSep1 scalarExpr'])
 >   where
 >     inty = try $ choice [True <$ keyword_ "in"
 >                         ,False <$ keyword_ "not" <* keyword_ "in"]
 
+> betweenSuffix :: ScalarExpr -> P ScalarExpr
+> betweenSuffix e =
+>     makeOp
+>     <$> opName
+>     <*> return e
+>     <*> scalarExpr'' True
+>     <*> (keyword_ "and" *> scalarExpr')
+>   where
+>     opName = try $ choice
+>              ["between" <$ keyword_ "between"
+>              ,"not between" <$ keyword_ "not" <* keyword_ "between"]
+>     makeOp n a b c = Op n [a,b,c]
+
 > subquery :: P ScalarExpr
 > subquery =
 >     choice
@@ -215,6 +229,11 @@ to be.
 > binOpKeywordNames :: [String]
 > binOpKeywordNames = ["and", "or", "like"]
 
+used for between parsing
+
+> binOpKeywordNamesNoAnd :: [String]
+> binOpKeywordNamesNoAnd = filter (/="and") binOpKeywordNames
+
 > unOpKeywordNames :: [String]
 > unOpKeywordNames = ["not"]
 
@@ -224,14 +243,23 @@ to be.
 
 > unaryOp :: P ScalarExpr
 > unaryOp =
->     makeOp <$> opSymbol <*> scalarExpr
+>     makeOp <$> opSymbol <*> scalarExpr'
 >   where
 >     makeOp nm e = Op nm [e]
 >     opSymbol = choice (map (try . symbol) unOpSymbolNames
 >                       ++ map (try . keyword) unOpKeywordNames)
 
 > scalarExpr' :: P ScalarExpr
-> scalarExpr' = factor >>= trysuffix
+> scalarExpr' = scalarExpr'' False
+
+the bexpr is to deal with between x and y
+
+when we are parsing the scalar expr for x, we don't allow and as a
+binary operator except nested in parens. This is taken from how
+postgresql handles this
+
+> scalarExpr'' :: Bool -> P ScalarExpr
+> scalarExpr'' bExpr = factor >>= trysuffix
 >   where
 >     factor = choice [literal
 >                     ,scase
@@ -245,10 +273,14 @@ to be.
 >     trysuffix e = try (suffix e) <|> return e
 >     suffix e0 = choice
 >                 [makeOp e0 <$> opSymbol <*> factor
->                 ,inSuffix e0 
+>                 ,inSuffix e0
+>                 ,betweenSuffix e0
 >                 ] >>= trysuffix
 >     opSymbol = choice (map (try . symbol) binOpSymbolNames
->                       ++ map (try . keyword) binOpKeywordNames)
+>                       ++ map (try . keyword)
+>                          (if bExpr
+>                           then binOpKeywordNamesNoAnd
+>                           else binOpKeywordNames))
 >     makeOp e0 op e1 = Op op [e0,e1]
 
 > sparens :: P ScalarExpr
diff --git a/Language/SQL/SimpleSQL/Pretty.lhs b/Language/SQL/SimpleSQL/Pretty.lhs
index c3adfcf..e680137 100644
--- a/Language/SQL/SimpleSQL/Pretty.lhs
+++ b/Language/SQL/SimpleSQL/Pretty.lhs
@@ -29,6 +29,15 @@ back into SQL source text. It attempts to format the output nicely.
 > scalarExpr (Star2 q) = text q <> text "." <> text "*"
 
 > scalarExpr (App f es) = text f <> parens (commaSep (map scalarExpr es))
+
+special cases
+
+> scalarExpr (Op nm [a,b,c]) | nm `elem` ["between", "not between"] =
+>   sep [scalarExpr a
+>       ,text nm <+> scalarExpr b
+>       ,text "and" <+> scalarExpr c]
+
+
 > scalarExpr (Op f [e]) = text f <+> scalarExpr e
 > scalarExpr (Op f [e0,e1]) =
 >     sep [scalarExpr e0, text f, scalarExpr e1]
diff --git a/Tests.lhs b/Tests.lhs
index 4fee678..233f71a 100644
--- a/Tests.lhs
+++ b/Tests.lhs
@@ -147,8 +147,12 @@
 > miscOps = Group "unaryOperators" $ map (uncurry TestScalarExpr)
 >     [("a in (1,2,3)"
 >      ,In True (Iden "a") $ InList $ map NumLit ["1","2","3"])
->     --,("a between b and c", Op "not" [])
->     --,("a not between b and c", Op "not" [])
+>     ,("a between b and c", Op "between" [Iden "a"
+>                                         ,Iden "b"
+>                                         ,Iden "c"])
+>     ,("a not between b and c", Op "not between" [Iden "a"
+>                                                 ,Iden "b"
+>                                                 ,Iden "c"])
 >     --,("a is null", Op "not" [])
 >     --,("a is not null", Op "not" [])
 >     --,("a is distinct from b", Op "not" [])