[HUDI-1869] Upgrading Spark3 To 3.1 (#3844)
Co-authored-by: pengzhiwei <pengzhiwei2015@icloud.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hudi.spark3.internal;
|
||||
|
||||
import org.apache.spark.sql.catalyst.plans.logical.InsertIntoStatement;
|
||||
import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan;
|
||||
import scala.Option;
|
||||
import scala.collection.Seq;
|
||||
import scala.collection.immutable.Map;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
public class ReflectUtil {
|
||||
|
||||
public static InsertIntoStatement createInsertInto(boolean isSpark30, LogicalPlan table, Map<String, Option<String>> partition, Seq<String> userSpecifiedCols,
|
||||
LogicalPlan query, boolean overwrite, boolean ifPartitionNotExists) {
|
||||
try {
|
||||
if (isSpark30) {
|
||||
Constructor<InsertIntoStatement> constructor = InsertIntoStatement.class.getConstructor(
|
||||
LogicalPlan.class, Map.class, LogicalPlan.class, boolean.class, boolean.class);
|
||||
return constructor.newInstance(table, partition, query, overwrite, ifPartitionNotExists);
|
||||
} else {
|
||||
Constructor<InsertIntoStatement> constructor = InsertIntoStatement.class.getConstructor(
|
||||
LogicalPlan.class, Map.class, Seq.class, LogicalPlan.class, boolean.class, boolean.class);
|
||||
return constructor.newInstance(table, partition, userSpecifiedCols, query, overwrite, ifPartitionNotExists);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error in create InsertIntoStatement", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,10 +19,13 @@ package org.apache.spark.sql.adapter
|
||||
|
||||
import org.apache.hudi.Spark3RowSerDe
|
||||
import org.apache.hudi.client.utils.SparkRowSerDe
|
||||
import org.apache.hudi.spark3.internal.ReflectUtil
|
||||
import org.apache.spark.SPARK_VERSION
|
||||
import org.apache.spark.sql.Row
|
||||
import org.apache.spark.sql.catalyst.analysis.UnresolvedRelation
|
||||
import org.apache.spark.sql.catalyst.encoders.ExpressionEncoder
|
||||
import org.apache.spark.sql.catalyst.expressions.{Expression, Like}
|
||||
import org.apache.spark.sql.catalyst.parser.ParserInterface
|
||||
import org.apache.spark.sql.catalyst.plans.JoinType
|
||||
import org.apache.spark.sql.catalyst.plans.logical.{InsertIntoStatement, Join, JoinHint, LogicalPlan}
|
||||
import org.apache.spark.sql.catalyst.{AliasIdentifier, TableIdentifier}
|
||||
@@ -67,15 +70,16 @@ class Spark3Adapter extends SparkAdapter {
|
||||
override def getInsertIntoChildren(plan: LogicalPlan):
|
||||
Option[(LogicalPlan, Map[String, Option[String]], LogicalPlan, Boolean, Boolean)] = {
|
||||
plan match {
|
||||
case InsertIntoStatement(table, partitionSpec, query, overwrite, ifPartitionNotExists) =>
|
||||
Some((table, partitionSpec, query, overwrite, ifPartitionNotExists))
|
||||
case _=> None
|
||||
case insert: InsertIntoStatement =>
|
||||
Some((insert.table, insert.partitionSpec, insert.query, insert.overwrite, insert.ifPartitionNotExists))
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
override def createInsertInto(table: LogicalPlan, partition: Map[String, Option[String]],
|
||||
query: LogicalPlan, overwrite: Boolean, ifPartitionNotExists: Boolean): LogicalPlan = {
|
||||
InsertIntoStatement(table, partition, query, overwrite, ifPartitionNotExists)
|
||||
ReflectUtil.createInsertInto(SPARK_VERSION.startsWith("3.0"), table, partition, Seq.empty[String], query, overwrite, ifPartitionNotExists)
|
||||
}
|
||||
|
||||
override def createSparkParsePartitionUtil(conf: SQLConf): SparkParsePartitionUtil = {
|
||||
@@ -85,4 +89,8 @@ class Spark3Adapter extends SparkAdapter {
|
||||
override def createLike(left: Expression, right: Expression): Expression = {
|
||||
new Like(left, right)
|
||||
}
|
||||
|
||||
override def parseMultipartIdentifier(parser: ParserInterface, sqlText: String): Seq[String] = {
|
||||
parser.parseMultipartIdentifier(sqlText)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.apache.hudi.spark3.internal;
|
||||
|
||||
import org.apache.hudi.testutils.HoodieClientTestBase;
|
||||
|
||||
import org.apache.spark.sql.SparkSession;
|
||||
import org.apache.spark.sql.catalyst.analysis.UnresolvedRelation;
|
||||
import org.apache.spark.sql.catalyst.plans.logical.InsertIntoStatement;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* Unit tests {@link ReflectUtil}.
|
||||
*/
|
||||
public class TestReflectUtil extends HoodieClientTestBase {
|
||||
|
||||
@Test
|
||||
public void testDataSourceWriterExtraCommitMetadata() throws Exception {
|
||||
SparkSession spark = sqlContext.sparkSession();
|
||||
|
||||
String insertIntoSql = "insert into test_reflect_util values (1, 'z3', 1, '2021')";
|
||||
InsertIntoStatement statement = (InsertIntoStatement) spark.sessionState().sqlParser().parsePlan(insertIntoSql);
|
||||
|
||||
InsertIntoStatement newStatment = ReflectUtil.createInsertInto(
|
||||
spark.version().startsWith("3.0"),
|
||||
statement.table(),
|
||||
statement.partitionSpec(),
|
||||
scala.collection.immutable.List.empty(),
|
||||
statement.query(),
|
||||
statement.overwrite(),
|
||||
statement.ifPartitionNotExists());
|
||||
|
||||
Assertions.assertTrue(
|
||||
((UnresolvedRelation)newStatment.table()).multipartIdentifier().contains("test_reflect_util"));
|
||||
|
||||
if (!spark.version().startsWith("3.0")) {
|
||||
Assertions.assertTrue(newStatment.userSpecifiedCols().isEmpty());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user