diff --git a/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4 b/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
index 547013c23fd78c1f21fcf6baf00f352a14bcdf93..4584aea6196a6d029bd787f4e272c6d9556d2a74 100644
--- a/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
+++ b/sql/catalyst/src/main/antlr4/org/apache/spark/sql/catalyst/parser/SqlBase.g4
@@ -473,7 +473,7 @@ identifierComment
 
 relationPrimary
     : tableIdentifier sample? tableAlias                   #tableName
-    | '(' queryNoWith ')' sample? (AS? strictIdentifier)   #aliasedQuery
+    | '(' queryNoWith ')' sample? (AS? strictIdentifier)?  #aliasedQuery
     | '(' relation ')' sample? (AS? strictIdentifier)?     #aliasedRelation
     | inlineTable                                          #inlineTableDefault2
     | functionTable                                        #tableValuedFunction
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
index 5f34d0777d5a19eedbb8f5f103fe1ed75f00a916..4eb5560155781bd6d050d047127916b102bd38cf 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala
@@ -749,6 +749,13 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
    * hooks.
    */
   override def visitAliasedQuery(ctx: AliasedQueryContext): LogicalPlan = withOrigin(ctx) {
+    // The unaliased subqueries in the FROM clause are disallowed. Instead of rejecting it in
+    // parser rules, we handle it here in order to provide better error message.
+    if (ctx.strictIdentifier == null) {
+      throw new ParseException("The unaliased subqueries in the FROM clause are not supported.",
+        ctx)
+    }
+
     aliasPlan(ctx.strictIdentifier,
       plan(ctx.queryNoWith).optionalMap(ctx.sample)(withSample))
   }
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
index 7a5357eef8f94622a5af2a277743ef4c27868e96..3a26adaef9db068a4b39cababda0664108f11c06 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/parser/PlanParserSuite.scala
@@ -448,13 +448,15 @@ class PlanParserSuite extends PlanTest {
   }
 
   test("aliased subquery") {
+    val errMsg = "The unaliased subqueries in the FROM clause are not supported"
+
     assertEqual("select a from (select id as a from t0) tt",
       table("t0").select('id.as("a")).as("tt").select('a))
-    intercept("select a from (select id as a from t0)", "mismatched input")
+    intercept("select a from (select id as a from t0)", errMsg)
 
     assertEqual("from (select id as a from t0) tt select a",
       table("t0").select('id.as("a")).as("tt").select('a))
-    intercept("from (select id as a from t0) select a", "extraneous input 'a'")
+    intercept("from (select id as a from t0) select a", errMsg)
   }
 
   test("scalar sub-query") {
diff --git a/sql/core/src/test/resources/sql-tests/inputs/subquery/subquery-in-from.sql b/sql/core/src/test/resources/sql-tests/inputs/subquery/subquery-in-from.sql
new file mode 100644
index 0000000000000000000000000000000000000000..1273b56b6344b906b39292843bff6f5fea9c771f
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/inputs/subquery/subquery-in-from.sql
@@ -0,0 +1,14 @@
+-- Aliased subqueries in FROM clause
+SELECT * FROM (SELECT * FROM testData) AS t WHERE key = 1;
+
+FROM (SELECT * FROM testData WHERE key = 1) AS t SELECT *;
+
+-- Optional `AS` keyword
+SELECT * FROM (SELECT * FROM testData) t WHERE key = 1;
+
+FROM (SELECT * FROM testData WHERE key = 1) t SELECT *;
+
+-- Disallow unaliased subqueries in FROM clause
+SELECT * FROM (SELECT * FROM testData) WHERE key = 1;
+
+FROM (SELECT * FROM testData WHERE key = 1) SELECT *;
diff --git a/sql/core/src/test/resources/sql-tests/results/subquery/subquery-in-from.sql.out b/sql/core/src/test/resources/sql-tests/results/subquery/subquery-in-from.sql.out
new file mode 100644
index 0000000000000000000000000000000000000000..14553557d1ffc73b17db0c478f8bc9950107a408
--- /dev/null
+++ b/sql/core/src/test/resources/sql-tests/results/subquery/subquery-in-from.sql.out
@@ -0,0 +1,62 @@
+-- Automatically generated by SQLQueryTestSuite
+-- Number of queries: 6
+
+
+-- !query 0
+SELECT * FROM (SELECT * FROM testData) AS t WHERE key = 1
+-- !query 0 schema
+struct<key:int,value:string>
+-- !query 0 output
+1	1
+
+
+-- !query 1
+FROM (SELECT * FROM testData WHERE key = 1) AS t SELECT *
+-- !query 1 schema
+struct<key:int,value:string>
+-- !query 1 output
+1	1
+
+
+-- !query 2
+SELECT * FROM (SELECT * FROM testData) t WHERE key = 1
+-- !query 2 schema
+struct<key:int,value:string>
+-- !query 2 output
+1	1
+
+
+-- !query 3
+FROM (SELECT * FROM testData WHERE key = 1) t SELECT *
+-- !query 3 schema
+struct<key:int,value:string>
+-- !query 3 output
+1	1
+
+
+-- !query 4
+SELECT * FROM (SELECT * FROM testData) WHERE key = 1
+-- !query 4 schema
+struct<>
+-- !query 4 output
+org.apache.spark.sql.catalyst.parser.ParseException
+
+The unaliased subqueries in the FROM clause are not supported.(line 1, pos 14)
+
+== SQL ==
+SELECT * FROM (SELECT * FROM testData) WHERE key = 1
+--------------^^^
+
+
+-- !query 5
+FROM (SELECT * FROM testData WHERE key = 1) SELECT *
+-- !query 5 schema
+struct<>
+-- !query 5 output
+org.apache.spark.sql.catalyst.parser.ParseException
+
+The unaliased subqueries in the FROM clause are not supported.(line 1, pos 5)
+
+== SQL ==
+FROM (SELECT * FROM testData WHERE key = 1) SELECT *
+-----^^^