diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala
index d3b1070a58d58332a88bb97e1a9f952220444318..919bf4dbc824c48a237ee2cfe9ed35d359c4aa5b 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala
@@ -51,7 +51,9 @@ class SqlParser extends StandardTokenParsers {
   }
 
   protected case class Keyword(str: String)
-  protected implicit def asParser(k: Keyword): Parser[String] = k.str
+
+  protected implicit def asParser(k: Keyword): Parser[String] =
+    allCaseVersions(k.str).map(x => x : Parser[String]).reduce(_ | _)
 
   protected class SqlLexical extends StdLexical {
     case class FloatLit(chars: String) extends Token {
@@ -133,7 +135,17 @@ class SqlParser extends StandardTokenParsers {
       .filter(_.getReturnType == classOf[Keyword])
       .map(_.invoke(this).asInstanceOf[Keyword])
 
-  lexical.reserved ++= reservedWords.map(_.str)
+  /** Generate all variations of upper and lower case of a given string */
+  private def allCaseVersions(s: String, prefix: String = ""): Stream[String] = {
+    if (s == "") {
+      Stream(prefix)
+    } else {
+      allCaseVersions(s.tail, prefix + s.head.toLower) ++
+        allCaseVersions(s.tail, prefix + s.head.toUpper)
+    }
+  }
+
+  lexical.reserved ++= reservedWords.flatMap(w => allCaseVersions(w.str))
 
   lexical.delimiters += (
     "@", "*", "+", "-", "<", "=", "<>", "!=", "<=", ">=", ">", "/", "(", ")",
diff --git a/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala b/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala
index 656d89c644b702456f27bae74dcc9daec6d0d740..6371fa296ac45e73e055436504b3286b6bdcc019 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/SQLQuerySuite.scala
@@ -200,9 +200,9 @@ class SQLQuerySuite extends QueryTest {
       sql(
         """
           |SELECT * FROM
-          |  (SELECT * FROM upperCaseData WHERE N <= 4) left FULL OUTER JOIN
-          |  (SELECT * FROM upperCaseData WHERE N >= 3) right
-          |    ON left.N = right.N
+          |  (SELECT * FROM upperCaseData WHERE N <= 4) leftTable FULL OUTER JOIN
+          |  (SELECT * FROM upperCaseData WHERE N >= 3) rightTable
+          |    ON leftTable.N = rightTable.N
         """.stripMargin),
       (1, "A", null, null) ::
       (2, "B", null, null) ::
@@ -211,4 +211,21 @@ class SQLQuerySuite extends QueryTest {
       (null, null, 5, "E") ::
       (null, null, 6, "F") :: Nil)
   }
-}
\ No newline at end of file
+
+  test("mixed-case keywords") {
+    checkAnswer(
+      sql(
+        """
+          |SeleCT * from
+          |  (select * from upperCaseData WherE N <= 4) leftTable fuLL OUtER joiN
+          |  (sElEcT * FROM upperCaseData whERe N >= 3) rightTable
+          |    oN leftTable.N = rightTable.N
+        """.stripMargin),
+      (1, "A", null, null) ::
+      (2, "B", null, null) ::
+      (3, "C", 3, "C") ::
+      (4, "D", 4, "D") ::
+      (null, null, 5, "E") ::
+      (null, null, 6, "F") :: Nil)
+  }
+}