blob: 1ec64077b48bd7ccd3ba4cc0e94a26d71c05bcac [file]
#
# 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.
#
library(testthat)
context("SparkSQL Arrow optimization")
sparkSession <- sparkR.session(
master = sparkRTestMaster,
enableHiveSupport = FALSE,
sparkConfig = list(spark.sql.execution.arrow.sparkr.enabled = "true"))
test_that("createDataFrame/collect Arrow optimization", {
skip_if_not_installed("arrow")
conf <- callJMethod(sparkSession, "conf")
arrowEnabled <- sparkR.conf("spark.sql.execution.arrow.sparkr.enabled")[[1]]
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", "false")
tryCatch({
expected <- collect(createDataFrame(mtcars))
},
finally = {
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", arrowEnabled)
})
expect_equal(collect(createDataFrame(mtcars)), expected)
})
test_that("createDataFrame/collect Arrow optimization - many partitions (partition order test)", {
skip_if_not_installed("arrow")
expect_equal(collect(createDataFrame(mtcars, numPartitions = 32)),
collect(createDataFrame(mtcars, numPartitions = 1)))
})
test_that("createDataFrame/collect Arrow optimization - type specification", {
skip_if_not_installed("arrow")
rdf <- data.frame(list(list(a = 1,
b = "a",
c = TRUE,
d = 1.1,
e = 1L,
f = as.Date("1990-02-24"),
g = as.POSIXct("1990-02-24 12:34:56"))))
arrowEnabled <- sparkR.conf("spark.sql.execution.arrow.sparkr.enabled")[[1]]
conf <- callJMethod(sparkSession, "conf")
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", "false")
tryCatch({
expected <- collect(createDataFrame(rdf))
},
finally = {
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", arrowEnabled)
})
expect_true(all(collect(createDataFrame(rdf)) == expected))
})
test_that("dapply() Arrow optimization", {
skip_if_not_installed("arrow")
df <- createDataFrame(mtcars)
conf <- callJMethod(sparkSession, "conf")
arrowEnabled <- sparkR.conf("spark.sql.execution.arrow.sparkr.enabled")[[1]]
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", "false")
tryCatch({
ret <- dapply(df,
function(rdf) {
stopifnot(is.data.frame(rdf))
rdf
},
schema(df))
expected <- collect(ret)
},
finally = {
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", arrowEnabled)
})
ret <- dapply(df,
function(rdf) {
stopifnot(is.data.frame(rdf))
# mtcars' hp is more then 50.
stopifnot(all(rdf$hp > 50))
rdf
},
schema(df))
actual <- collect(ret)
expect_equal(actual, expected)
expect_equal(count(ret), nrow(mtcars))
})
test_that("dapply() Arrow optimization - type specification", {
skip_if_not_installed("arrow")
# Note that regular dapply() seems not supporting date and timestamps
# whereas Arrow-optimized dapply() does.
rdf <- data.frame(list(list(a = 1,
b = "a",
c = TRUE,
d = 1.1,
e = 1L)))
# numPartitions are set to 8 intentionally to test empty partitions as well.
df <- createDataFrame(rdf, numPartitions = 8)
conf <- callJMethod(sparkSession, "conf")
arrowEnabled <- sparkR.conf("spark.sql.execution.arrow.sparkr.enabled")[[1]]
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", "false")
tryCatch({
ret <- dapply(df, function(rdf) { rdf }, schema(df))
expected <- collect(ret)
},
finally = {
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", arrowEnabled)
})
ret <- dapply(df, function(rdf) { rdf }, schema(df))
actual <- collect(ret)
expect_equal(actual, expected)
})
test_that("dapply() Arrow optimization - type specification (date and timestamp)", {
skip_if_not_installed("arrow")
rdf <- data.frame(list(list(a = as.Date("1990-02-24"),
b = as.POSIXct("1990-02-24 12:34:56"))))
df <- createDataFrame(rdf)
ret <- dapply(df, function(rdf) { rdf }, schema(df))
expect_true(all(collect(ret) == rdf))
})
test_that("gapply() Arrow optimization", {
skip_if_not_installed("arrow")
df <- createDataFrame(mtcars)
conf <- callJMethod(sparkSession, "conf")
arrowEnabled <- sparkR.conf("spark.sql.execution.arrow.sparkr.enabled")[[1]]
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", "false")
tryCatch({
ret <- gapply(df,
"gear",
function(key, grouped) {
if (length(key) > 0) {
stopifnot(is.numeric(key[[1]]))
}
stopifnot(is.data.frame(grouped))
grouped
},
schema(df))
expected <- collect(ret)
},
finally = {
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", arrowEnabled)
})
ret <- gapply(df,
"gear",
function(key, grouped) {
if (length(key) > 0) {
stopifnot(is.numeric(key[[1]]))
}
stopifnot(is.data.frame(grouped))
stopifnot(length(colnames(grouped)) == 11)
# mtcars' hp is more then 50.
stopifnot(all(grouped$hp > 50))
grouped
},
schema(df))
actual <- collect(ret)
expect_equal(actual, expected)
expect_equal(count(ret), nrow(mtcars))
})
test_that("gapply() Arrow optimization - type specification", {
skip_if_not_installed("arrow")
# Note that regular gapply() seems not supporting date and timestamps
# whereas Arrow-optimized gapply() does.
rdf <- data.frame(list(list(a = 1,
b = "a",
c = TRUE,
d = 1.1,
e = 1L)))
df <- createDataFrame(rdf)
conf <- callJMethod(sparkSession, "conf")
arrowEnabled <- sparkR.conf("spark.sql.execution.arrow.sparkr.enabled")[[1]]
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", "false")
tryCatch({
ret <- gapply(df,
"a",
function(key, grouped) { grouped }, schema(df))
expected <- collect(ret)
},
finally = {
callJMethod(conf, "set", "spark.sql.execution.arrow.sparkr.enabled", arrowEnabled)
})
ret <- gapply(df,
"a",
function(key, grouped) { grouped }, schema(df))
actual <- collect(ret)
expect_equal(actual, expected)
})
test_that("gapply() Arrow optimization - type specification (date and timestamp)", {
skip_if_not_installed("arrow")
rdf <- data.frame(list(list(a = as.Date("1990-02-24"),
b = as.POSIXct("1990-02-24 12:34:56"))))
df <- createDataFrame(rdf)
ret <- gapply(df,
"a",
function(key, grouped) { grouped }, schema(df))
expect_true(all(collect(ret) == rdf))
})
test_that("Arrow optimization - unsupported types", {
skip_if_not_installed("arrow")
expect_error(checkSchemaInArrow(structType("a FLOAT")), "not support float type")
expect_error(checkSchemaInArrow(structType("a BINARY")), "not support binary type")
expect_error(checkSchemaInArrow(structType("a ARRAY<INT>")), "not support array type")
expect_error(checkSchemaInArrow(structType("a MAP<INT, INT>")), "not support map type")
expect_error(checkSchemaInArrow(structType("a STRUCT<a: INT>")),
"not support nested struct type")
})
test_that("SPARK-32478: gapply() Arrow optimization - error message for schema mismatch", {
skip_if_not_installed("arrow")
df <- createDataFrame(list(list(a = 1L, b = "a")))
expect_error(
count(gapply(df, "a", function(key, group) { group }, structType("a int, b int"))),
"expected IntegerType, IntegerType, got IntegerType, StringType")
})
test_that("SPARK-43789: Automatically pick the number of partitions based on Arrow batch size", {
skip_if_not_installed("arrow")
conf <- callJMethod(sparkSession, "conf")
maxRecordsPerBatch <- sparkR.conf("spark.sql.execution.arrow.maxRecordsPerBatch")[[1]]
callJMethod(conf, "set", "spark.sql.execution.arrow.maxRecordsPerBatch", "10")
tryCatch({
expect_equal(getNumPartitionsRDD(toRDD(createDataFrame(mtcars))), 4)
},
finally = {
callJMethod(conf, "set", "spark.sql.execution.arrow.maxRecordsPerBatch", maxRecordsPerBatch)
})
})
sparkR.session.stop()