@@ -117,6 +117,12 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
117
117
query.optionalMap(ctx.ctes)(withCTE)
118
118
}
119
119
120
+ override def visitDmlStatement (ctx : DmlStatementContext ): AnyRef = withOrigin(ctx) {
121
+ val dmlStmt = plan(ctx.dmlStatementNoWith)
122
+ // Apply CTEs
123
+ dmlStmt.optionalMap(ctx.ctes)(withCTE)
124
+ }
125
+
120
126
private def withCTE (ctx : CtesContext , plan : LogicalPlan ): LogicalPlan = {
121
127
val ctes = ctx.namedQuery.asScala.map { nCtx =>
122
128
val namedQuery = visitNamedQuery(nCtx)
@@ -129,11 +135,21 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
129
135
130
136
override def visitQueryWithFrom (ctx : QueryWithFromContext ): LogicalPlan = withOrigin(ctx) {
131
137
val from = visitFromClause(ctx.fromClause)
132
- validate(ctx.selectStatement.querySpecification.fromClause == null ,
133
- " Individual select statement can not have FROM cause as its already specified in the" +
134
- " outer query block" , ctx)
135
- withQuerySpecification(ctx.selectStatement.querySpecification, from).
136
- optionalMap(ctx.selectStatement.queryOrganization)(withQueryResultClauses)
138
+ val selects = ctx.selectStatement.asScala.map { select =>
139
+ validate(select.querySpecification.fromClause == null ,
140
+ " This select statement can not have FROM cause as its already specified upfront" ,
141
+ select)
142
+
143
+ withQuerySpecification(select.querySpecification, from).
144
+ // Add organization statements.
145
+ optionalMap(select.queryOrganization)(withQueryResultClauses)
146
+ }
147
+ // If there are multiple SELECT just UNION them together into one query.
148
+ if (selects.length == 1 ) {
149
+ selects.head
150
+ } else {
151
+ Union (selects)
152
+ }
137
153
}
138
154
139
155
override def visitNoWithQuery (ctx : NoWithQueryContext ): LogicalPlan = withOrigin(ctx) {
@@ -182,47 +198,21 @@ class AstBuilder(conf: SQLConf) extends SqlBaseBaseVisitor[AnyRef] with Logging
182
198
}
183
199
184
200
// If there are multiple INSERTS just UNION them together into one query.
185
- val insertPlan = inserts match {
186
- case Seq (query) => query
187
- case queries => Union (queries)
188
- }
189
- // Apply CTEs
190
- insertPlan.optionalMap(ctx.ctes)(withCTE)
191
- }
192
-
193
- override def visitMultiSelect (ctx : MultiSelectContext ): LogicalPlan = withOrigin(ctx) {
194
- val from = visitFromClause(ctx.fromClause)
195
-
196
- // Build the insert clauses.
197
- val selects = ctx.selectStatement.asScala.map {
198
- body =>
199
- validate(body.querySpecification.fromClause == null ,
200
- " Multi-select queries cannot have a FROM clause in their individual SELECT statements" ,
201
- body)
202
-
203
- withQuerySpecification(body.querySpecification, from).
204
- // Add organization statements.
205
- optionalMap(body.queryOrganization)(withQueryResultClauses)
206
- }
207
-
208
- // If there are multiple INSERTS just UNION them together into one query.
209
- val selectUnionPlan = selects match {
210
- case Seq (query) => query
211
- case queries => Union (queries)
201
+ if (inserts.length == 1 ) {
202
+ inserts.head
203
+ } else {
204
+ Union (inserts)
212
205
}
213
- // Apply CTEs
214
- selectUnionPlan.optionalMap(ctx.ctes)(withCTE)
215
206
}
216
207
217
208
/**
218
209
* Create a logical plan for a regular (single-insert) query.
219
210
*/
220
211
override def visitSingleInsertQuery (
221
212
ctx : SingleInsertQueryContext ): LogicalPlan = withOrigin(ctx) {
222
- val insertPlan = withInsertInto(ctx.insertInto(),
223
- plan(ctx.queryTerm).optionalMap(ctx.queryOrganization)(withQueryResultClauses))
224
- // Apply CTEs
225
- insertPlan.optionalMap(ctx.ctes)(withCTE)
213
+ withInsertInto(
214
+ ctx.insertInto(),
215
+ plan(ctx.queryTerm).optionalMap(ctx.queryOrganization)(withQueryResultClauses))
226
216
}
227
217
228
218
/**
0 commit comments