diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,30 @@
+Copyright (c) 2013, Kei Hibino
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Kei Hibino nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/sql-words.cabal b/sql-words.cabal
new file mode 100644
--- /dev/null
+++ b/sql-words.cabal
@@ -0,0 +1,38 @@
+name:                sql-words
+version:             0.0.1.0
+synopsis:            Simple idea SQL keywords data constructor into OverloadedString
+description:         This package contiains SQL keywords constructors defined as
+                     OverloadedString literals and helper functions to concate these.
+homepage:            http://twitter.com/khibino
+license:             BSD3
+license-file:        LICENSE
+author:              Kei Hibino
+maintainer:          ex8k.hibino@gmail.com
+copyright:           Copyright (c) 2013 Kei Hibino
+category:            Database
+build-type:          Simple
+cabal-version:       >=1.10
+
+library
+  exposed-modules:
+                        Language.SQL.Keyword.Type
+                        Language.SQL.Keyword.Concat
+                        Language.SQL.Keyword
+
+  other-modules:
+                        Language.SQL.Keyword.Internal.Type
+
+  build-depends:          base <5
+  hs-source-dirs:       src
+  ghc-options:          -Wall
+
+  default-language:     Haskell2010
+
+
+source-repository head
+  type:       git
+  location:   https://github.com/khibino/haskell-relational-record
+
+source-repository head
+  type:       mercurial
+  location:   https://bitbucket.org/khibino/haskell-relational-record
diff --git a/src/Language/SQL/Keyword.hs b/src/Language/SQL/Keyword.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/SQL/Keyword.hs
@@ -0,0 +1,20 @@
+-- |
+-- Module      : Language.SQL.Keyword
+-- Copyright   : 2013 Kei Hibino
+-- License     : BSD3
+--
+-- Maintainer  : ex8k.hibino@gmail.com
+-- Stability   : experimental
+-- Portability : unknown
+--
+-- SQL keyword representation using Haskell data constructors.
+-- Integrated module.
+module Language.SQL.Keyword (
+  -- * Module which includes keyword type definition
+  module Language.SQL.Keyword.Type,
+  -- * Module which includes functions to concatinate keywords
+  module Language.SQL.Keyword.Concat
+  ) where
+
+import Language.SQL.Keyword.Type
+import Language.SQL.Keyword.Concat
diff --git a/src/Language/SQL/Keyword/Concat.hs b/src/Language/SQL/Keyword/Concat.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/SQL/Keyword/Concat.hs
@@ -0,0 +1,169 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+-- |
+-- Module      : Language.SQL.Keyword.Concat
+-- Copyright   : 2013 Kei Hibino
+-- License     : BSD3
+--
+-- Maintainer  : ex8k.hibino@gmail.com
+-- Stability   : experimental
+-- Portability : unknown
+--
+-- Concatinations on 'Keyword' types
+module Language.SQL.Keyword.Concat (
+  -- * List concatination functions
+  -- $listConcatination
+  unwords',
+
+  sepBy, parenSepBy,
+
+  -- * Binary operators
+  -- $binaryOperators
+  defineBinOp,
+
+  strBinOp,
+
+  as, (<.>), (|*|),
+
+  (.||.),
+  (.=.), (.<.), (.<=.), (.>.), (.>=.), (.<>.),
+  and, or, in',
+
+  fold,
+
+  -- * Unary operator
+  defineUniOp, paren,
+  strUniOp
+  ) where
+
+import Prelude hiding (and, or, not)
+import Data.List (intersperse)
+import Data.Monoid (mempty, mconcat)
+
+import Language.SQL.Keyword.Internal.Type (Keyword (..), word, wordShow, toDString, fromDString)
+
+
+{- $listConcatination
+Functions to concatinate 'Keyword' list.
+-}
+
+-- | Separate 'Keyword' list with delimiter 'Keyword' and map to 'String' list.
+sepBy' :: [Keyword] -> Keyword -> [String]
+ws `sepBy'` d =  map wordShow . intersperse d $ ws
+
+-- | Concatinate 'Keyword' list like unwords on 'String' list.
+unwords' :: [Keyword] -> Keyword
+unwords' =  mconcat
+
+-- | Concatinate 'String' list into one 'Keyword'.
+concatStr :: [String] -> Keyword
+concatStr =  word . concat
+
+-- | Separate 'Keyword' list with delimiter 'Keyword' and concatinate into one 'Keyword'.
+sepBy :: [Keyword] -> Keyword -> Keyword
+ws `sepBy` d = concatStr $ ws `sepBy'` d
+
+-- | Do 'sepBy' and enclose by paren
+parenSepBy :: [Keyword] -> Keyword -> Keyword
+ws `parenSepBy` d = concatStr $ "(" : (ws `sepBy'` d) ++ [")"]
+
+{- $binaryOperators
+Binary operators on SQL. Result is concatinated into one 'Keyword'.
+-}
+
+concat' :: [Keyword] -> Keyword
+concat' =  fromDString . mconcat . map toDString
+
+-- | Define binary operator on 'Keyword' type.
+--   Result is not delimited by whitespace like concat on 'String' list.
+defineBinOp' :: Keyword -> Keyword -> Keyword -> Keyword
+defineBinOp' op a b = concat' [a, op, b]
+
+-- | Define binary operator on 'Keyword' type.
+--   Result is delimited by whitespace like unwords on 'String' list.
+defineBinOp :: Keyword -> Keyword -> Keyword -> Keyword
+defineBinOp op a b = mconcat [a, op, b]
+
+-- | Binary operator to create qualified name on SQL.
+(<.>) :: Keyword -> Keyword -> Keyword
+(<.>)  =  defineBinOp' "."
+
+-- | Binary operator to create comma separated words.
+(|*|) :: Keyword -> Keyword -> Keyword
+(|*|)  =  defineBinOp' ", "
+
+-- | Binary operator for SQL string expression concatination.
+(.||.) :: Keyword -> Keyword -> Keyword
+(.||.) =  defineBinOp "||"
+
+-- | Binary eq operator for SQL expression.
+(.=.) :: Keyword -> Keyword -> Keyword
+(.=.)  =  defineBinOp "="
+
+-- | Binary not eq operator for SQL expression.
+(.<>.) :: Keyword -> Keyword -> Keyword
+(.<>.) =  defineBinOp "<>"
+
+-- | Binary lt operator for SQL expression.
+(.<.) :: Keyword -> Keyword -> Keyword
+(.<.)  =  defineBinOp "<"
+
+-- | Binary le operator for SQL expression.
+(.<=.) :: Keyword -> Keyword -> Keyword
+(.<=.) =  defineBinOp "<="
+
+-- | Binary gt operator for SQL expression.
+(.>.) :: Keyword -> Keyword -> Keyword
+(.>.)  =  defineBinOp ">"
+
+-- | Binary ge operator for SQL expression.
+(.>=.) :: Keyword -> Keyword -> Keyword
+(.>=.) =  defineBinOp ">="
+
+-- | Binary operator for SQL name alias.
+as :: Keyword -> Keyword -> Keyword
+as     =  defineBinOp AS
+
+-- | Binary `AND` operator for SQL boolean expression.
+and :: Keyword -> Keyword -> Keyword
+and    =  defineBinOp AND
+
+-- | Binary `OR` operator for SQL boolean expression.
+or :: Keyword -> Keyword -> Keyword
+or     =  defineBinOp OR
+
+-- | Fold operation using binary operator with empty result of zero length case.
+fold :: (Keyword -> Keyword -> Keyword) -- ^ Binary operator used in fold
+     -> [Keyword]                       -- ^ List to fold
+     -> Keyword                         -- ^ Result
+fold op =  d  where
+  d []       = mempty
+  d xs@(_:_) = foldr1 op xs
+
+-- | Define unary operator on 'Keyword' type represeted by specified 'Keyword'.
+--   Result is delimited by whitespace like unwords on 'String' list.
+defineUniOp :: Keyword -> Keyword -> Keyword
+defineUniOp op e = mconcat [op, e]
+
+-- | Uni operator to create Parend words.
+paren :: Keyword -> Keyword
+paren w = concat' ["(", w, ")"]
+
+-- | Binary `IN` operator for SQL.
+in' :: Keyword -> Keyword -> Keyword
+in'    =  defineBinOp IN
+
+infixr 5 .||.
+infixr 4 .=., .<., .<=., .>., .>=., .<>.
+infix  4 `in'`
+infixr 3 `and`
+infixr 2 `or`
+infixr 1 |*|
+
+-- | Define uni operator of string from 'Keyword' uni operator.
+strUniOp :: (Keyword -> Keyword) -> String -> String
+strUniOp u = wordShow . u . word
+
+-- | Define binary operator of string from 'Keyword' binary operator.
+strBinOp :: (Keyword -> Keyword -> Keyword) -> String -> String -> String
+strBinOp op a b = wordShow $ op (word a) (word b)
diff --git a/src/Language/SQL/Keyword/Internal/Type.hs b/src/Language/SQL/Keyword/Internal/Type.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/SQL/Keyword/Internal/Type.hs
@@ -0,0 +1,141 @@
+-- |
+-- Module      : Language.SQL.Keyword.Internal.Type
+-- Copyright   : 2013 Kei Hibino
+-- License     : BSD3
+--
+-- Maintainer  : ex8k.hibino@gmail.com
+-- Stability   : experimental
+-- Portability : unknown
+--
+-- This module defines package internal types.
+module Language.SQL.Keyword.Internal.Type (
+  -- * SQL keyword type interface.
+  Keyword (..), word, wordShow,
+
+  -- * Low-level diff string interface.
+  fromDString, toDString,
+  DString, dString, showDString, isEmptyDString
+  ) where
+
+import Data.String (IsString(..))
+import Data.List (find)
+import Data.Monoid (Monoid (..), (<>))
+
+
+-- | Diff String type for low-cost concatination.
+newtype DString = DString (String -> String)
+
+-- | Make 'DString' from 'String'
+dString :: String -> DString
+dString =  DString . (++)
+
+-- | Show 'DString' into 'String'
+showDString :: DString -> String
+showDString (DString f) = f []
+
+-- | 'DString' is empty or not.
+isEmptyDString :: DString -> Bool
+isEmptyDString = null . showDString
+
+instance Show DString where
+  show = showDString
+
+instance Read DString where
+  readsPrec _ s = [(dString s, [])]
+
+instance Monoid DString where
+  mempty  = DString id
+  DString f `mappend` DString g = DString $ f . g
+
+dspace :: DString
+dspace =  dString " "
+
+-- | Type represent SQL keywords.
+data Keyword = SELECT | ALL | DISTINCT | ON
+             | GROUP | COUNT | SUM | AVG | MAX | MIN | EVERY | ANY | SOME
+             | ORDER | BY | ASC | DESC
+             | CUBE | ROLLUP | GROUPING | SETS | HAVING
+             | FOR
+
+             | LIMIT
+             | FETCH | FIRST | NEXT | ROW | ROWS | ONLY
+
+             | UNION | EXCEPT | INTERSECT
+
+             | DELETE | USING | RETURNING
+
+             | FROM | AS | WITH
+             | JOIN | INNER | LEFT | RIGHT | FULL | NATURAL | OUTER
+
+             | UPDATE | SET | DEFAULT
+
+             | WHERE
+
+             | INSERT | INTO | VALUES
+
+             | MERGE
+
+             | OVER | PARTITION
+             | DENSE_RANK | RANK | ROW_NUMBER
+             | PERCENT_RANK | CUME_DIST
+             | LAG | LEAD | FIRST_VALUE | LAST_VALUE
+
+             | CASE | END | WHEN | ELSE | THEN
+
+             | LIKE | SIMILAR
+             | AND | OR | NOT
+             | EXISTS
+
+             | IS | NULL | IN
+
+             | DATE | TIME | TIMESTAMP | INTERVAL
+
+             | Sequence !DString
+             deriving (Read, Show)
+
+             {-
+                  | (:?)
+                  | (:+) | (:-) | (:*) | (:/)
+                  | OPEN | CLOSE
+             -}
+
+
+-- | Wrap 'DString' into 'Keyword'
+fromDString :: DString -> Keyword
+fromDString =  Sequence
+
+-- | Unwrap 'Keyword' into 'DString'
+toDString :: Keyword -> DString
+toDString = d  where
+  d (Sequence ds) = ds
+  d  w            = dString $ show w
+
+-- | Make 'Keyword' from String
+word :: String -> Keyword
+word =  fromDString . dString
+
+-- | 'Keyword' type with OverloadedString extension,
+--   can be involved same list with string literals.
+--
+-- > selectFoo = [SELECT, "a, b, c", FROM, "foo"]
+--
+instance IsString Keyword where
+  fromString s' = found (find ((== "") . snd) (reads s')) s'  where
+   found  Nothing      s = word s
+   found (Just (w, _)) _ = w
+
+-- | 'Keyword' default concatination separate by space.
+instance Monoid Keyword where
+  mempty  = fromDString mempty
+  a `mappend` b = fromDString $ toDString a `append'` toDString b  where
+    append' p q
+      | isEmptyDString p = q
+      | isEmptyDString q = p
+      | otherwise        = p <> dspace <> q
+
+
+-- | Show 'Keyword'
+wordShow :: Keyword -> String
+wordShow =  d  where
+  d (Sequence s)   = showDString s
+  d w              = show w
diff --git a/src/Language/SQL/Keyword/Type.hs b/src/Language/SQL/Keyword/Type.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/SQL/Keyword/Type.hs
@@ -0,0 +1,24 @@
+-- |
+-- Module      : Language.SQL.Keyword.Type
+-- Copyright   : 2013 Kei Hibino
+-- License     : BSD3
+--
+-- Maintainer  : ex8k.hibino@gmail.com
+-- Stability   : experimental
+-- Portability : unknown
+--
+-- SQL keyword representation using Haskell data constructors.
+module Language.SQL.Keyword.Type (
+  Keyword (..),
+
+  word,
+  wordShow, unwordsSQL
+  ) where
+
+import Data.Monoid (mconcat)
+import Language.SQL.Keyword.Internal.Type (Keyword (..), word, wordShow)
+
+
+-- | Concatinate keywords into 'String' like unwords
+unwordsSQL :: [Keyword] -> String
+unwordsSQL =  wordShow . mconcat
