-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-16278][SPARK-16279][SQL] Implement map_keys/map_values SQL functions #13967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
8a639bc
8c1ea5b
c0dac4b
8db1e65
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…ctions
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,56 @@ case class Size(child: Expression) extends UnaryExpression with ExpectsInputType | |
| } | ||
| } | ||
|
|
||
| /** | ||
| * Returns an unordered array containing the keys of the map. | ||
| */ | ||
| @ExpressionDescription( | ||
| usage = "_FUNC_(map) - Returns an unordered array containing the keys of the map.") | ||
| case class MapKeys(child: Expression) | ||
| extends UnaryExpression with ExpectsInputTypes { | ||
|
|
||
| override def inputTypes: Seq[AbstractDataType] = Seq(MapType) | ||
|
|
||
| override def dataType: DataType = ArrayType(child.dataType.asInstanceOf[MapType].keyType) | ||
|
|
||
| override def foldable: Boolean = child.foldable | ||
|
|
||
| override def nullSafeEval(map: Any): Any = { | ||
| map.asInstanceOf[MapData].keyArray().copy() | ||
| } | ||
|
|
||
| override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = { | ||
| nullSafeCodeGen(ctx, ev, c => s"${ev.value} = ($c).keyArray().copy();") | ||
| } | ||
|
|
||
| override def prettyName: String = "map_keys" | ||
| } | ||
|
|
||
| /** | ||
| * Returns an unordered array containing the values of the map. | ||
| */ | ||
| @ExpressionDescription( | ||
| usage = "_FUNC_(map) - Returns an unordered array containing the values of the map.") | ||
|
||
| case class MapValues(child: Expression) | ||
| extends UnaryExpression with ExpectsInputTypes { | ||
|
|
||
| override def inputTypes: Seq[AbstractDataType] = Seq(MapType) | ||
|
|
||
| override def dataType: DataType = ArrayType(child.dataType.asInstanceOf[MapType].valueType) | ||
|
|
||
| override def foldable: Boolean = child.foldable | ||
|
|
||
| override def nullSafeEval(map: Any): Any = { | ||
| map.asInstanceOf[MapData].valueArray().copy() | ||
|
||
| } | ||
|
|
||
| override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = { | ||
| nullSafeCodeGen(ctx, ev, c => s"${ev.value} = ($c).valueArray().copy();") | ||
| } | ||
|
|
||
| override def prettyName: String = "map_values" | ||
| } | ||
|
|
||
| /** | ||
| * Sorts the input array in ascending / descending order according to the natural ordering of | ||
| * the array elements and returns it. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,6 +44,16 @@ class CollectionFunctionsSuite extends SparkFunSuite with ExpressionEvalHelper { | |
| checkEvaluation(Literal.create(null, ArrayType(StringType)), null) | ||
| } | ||
|
|
||
| test("MapKeys/MapValues") { | ||
| val m0 = Literal.create(Map("a" -> "1", "b" -> "2"), MapType(StringType, StringType)) | ||
| val m1 = Literal.create(Map[String, String](), MapType(StringType, StringType)) | ||
|
||
|
|
||
| checkEvaluation(MapKeys(m0), Seq("a", "b")) | ||
| checkEvaluation(MapValues(m0), Seq("1", "2")) | ||
| checkEvaluation(MapKeys(m1), Seq()) | ||
| checkEvaluation(MapValues(m1), Seq()) | ||
| } | ||
|
|
||
| test("Sort Array") { | ||
| val a0 = Literal.create(Seq(2, 1, 3), ArrayType(IntegerType)) | ||
| val a1 = Literal.create(Seq[Integer](), ArrayType(IntegerType)) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2760,6 +2760,22 @@ object functions { | |
| */ | ||
| def size(e: Column): Column = withExpr { Size(e.expr) } | ||
|
|
||
| /** | ||
| * Returns the key array of the map. | ||
| * | ||
| * @group collection_funcs | ||
| * @since 2.1.0 | ||
| */ | ||
| def map_keys(e: Column): Column = withExpr { MapKeys(e.expr) } | ||
|
||
|
|
||
| /** | ||
| * Returns the key array of the map. | ||
| * | ||
| * @group collection_funcs | ||
| * @since 2.1.0 | ||
| */ | ||
| def map_values(e: Column): Column = withExpr { MapValues(e.expr) } | ||
|
|
||
| /** | ||
| * Sorts the input array for the given column in ascending order, | ||
| * according to the natural ordering of the array elements. | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the default of
UnaryExpressionThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep.