Skip to content
Snippets Groups Projects
Commit 81455a9c authored by Takuya UESHIN's avatar Takuya UESHIN Committed by Reynold Xin
Browse files

[SPARK-17703][SQL] Add unnamed version of addReferenceObj for minor objects.

## What changes were proposed in this pull request?

There are many minor objects in references, which are extracted to the generated class field, e.g. `errMsg` in `GetExternalRowField` or `ValidateExternalType`, but number of fields in class is limited so we should reduce the number.
This pr adds unnamed version of `addReferenceObj` for these minor objects not to store the object into field but refer it from the `references` field at the time of use.

## How was this patch tested?

Existing tests.

Author: Takuya UESHIN <ueshin@happy-camper.st>

Closes #15276 from ueshin/issues/SPARK-17703.
parent f327e168
No related branches found
No related tags found
No related merge requests found
......@@ -84,6 +84,21 @@ class CodegenContext {
*/
val references: mutable.ArrayBuffer[Any] = new mutable.ArrayBuffer[Any]()
/**
* Add an object to `references`.
*
* Returns the code to access it.
*
* This is for minor objects not to store the object into field but refer it from the references
* field at the time of use because number of fields in class is limited so we should reduce it.
*/
def addReferenceObj(obj: Any): String = {
val idx = references.length
references += obj
val clsName = obj.getClass.getName
s"(($clsName) references[$idx])"
}
/**
* Add an object to `references`, create a class member to access it.
*
......
......@@ -517,7 +517,10 @@ case class AssertTrue(child: Expression) extends UnaryExpression with ImplicitCa
override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
val eval = child.genCode(ctx)
val errMsgField = ctx.addReferenceObj("errMsg", errMsg)
// Use unnamed reference that doesn't create a local field here to reduce the number of fields
// because errMsgField is used only when the value is null or false.
val errMsgField = ctx.addReferenceObj(errMsg)
ExprCode(code = s"""${eval.code}
|if (${eval.isNull} || !${eval.value}) {
| throw new RuntimeException($errMsgField);
......
......@@ -906,7 +906,9 @@ case class AssertNotNull(child: Expression, walkedTypePath: Seq[String])
override protected def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
val childGen = child.genCode(ctx)
val errMsgField = ctx.addReferenceObj("errMsg", errMsg)
// Use unnamed reference that doesn't create a local field here to reduce the number of fields
// because errMsgField is used only when the value is null.
val errMsgField = ctx.addReferenceObj(errMsg)
val code = s"""
${childGen.code}
......@@ -941,7 +943,9 @@ case class GetExternalRowField(
private val errMsg = s"The ${index}th field '$fieldName' of input row cannot be null."
override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
val errMsgField = ctx.addReferenceObj("errMsg", errMsg)
// Use unnamed reference that doesn't create a local field here to reduce the number of fields
// because errMsgField is used only when the field is null.
val errMsgField = ctx.addReferenceObj(errMsg)
val row = child.genCode(ctx)
val code = s"""
${row.code}
......@@ -979,7 +983,9 @@ case class ValidateExternalType(child: Expression, expected: DataType)
private val errMsg = s" is not a valid external type for schema of ${expected.simpleString}"
override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
val errMsgField = ctx.addReferenceObj("errMsg", errMsg)
// Use unnamed reference that doesn't create a local field here to reduce the number of fields
// because errMsgField is used only when the type doesn't match.
val errMsgField = ctx.addReferenceObj(errMsg)
val input = child.genCode(ctx)
val obj = input.value
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment