You are viewing a plain text version of this content. The canonical link for it is here.
Posted to reviews@spark.apache.org by viirya <gi...@git.apache.org> on 2018/04/30 13:36:11 UTC

[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

GitHub user viirya opened a pull request:

    https://github.com/apache/spark/pull/21193

    [SPARK-24121][SQL] Add API for handling expression code generation

    ## What changes were proposed in this pull request?
    
    This patch implements this [proposal](https://github.com/apache/spark/pull/19813#issuecomment-354045400) to add an API for handling expression code generation. It should allow us to manipulate how to generate codes for expressions.
    
    ## How was this patch tested?
    
    Added tests.


You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/viirya/spark-1 SPARK-24121

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/spark/pull/21193.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #21193
    
----

----


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2838/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90176 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90176/testReport)** for PR 21193 at commit [`d138ee0`](https://github.com/apache/spark/commit/d138ee05541bc1976442c5f1170ba7a7f3f5114c).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/3034/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r187033550
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    +        ${castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast)}
    --- End diff --
    
    We can use `ExprValue` and `Block` around everywhere in `Cast` here (I did in a local branch), just it increases some code diff, so I'm not sure if we want it be here or as a follow-up if it's easier for review.
    
    Inputs to `Cast` should be only `eval.value` and `eval.isNull` as it's only child expression to `Cast`. We add generated codes here but they are not actually input expressions to `Cast`. So for now I manually let `eval.value` and `eval.isNull` be tracked.
    
    



---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    thanks, merging to master!


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90104 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90104/testReport)** for PR 21193 at commit [`5fe425c`](https://github.com/apache/spark/commit/5fe425c2d2837f00bdfe9ba5e6f446829fba32c1).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r188830465
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,113 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    --- End diff --
    
    Not sure the order among those `ExprValue`s will be useful or not. Sounds a `Set` is good.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r188959114
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = {
    +    blockInputs.flatMap {
    --- End diff --
    
    I think `foldLeft` has better performance but I am not sure whether the difference can be significant here


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90858 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90858/testReport)** for PR 21193 at commit [`2ca9741`](https://github.com/apache/spark/commit/2ca974190527f3ac1ade1feddf9bd2b953fabdd7).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r187612068
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,113 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    --- End diff --
    
    I'd make it a `Set` rather than a `Seq`. What do you think?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90941/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90241/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/3389/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by asfgit <gi...@git.apache.org>.
Github user asfgit closed the pull request at:

    https://github.com/apache/spark/pull/21193


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90251 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90251/testReport)** for PR 21193 at commit [`5945c15`](https://github.com/apache/spark/commit/5945c156b2df7aa2f61df57d86f07279b6959e2a).
     * This patch **fails Spark unit tests**.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186250678
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    +      case _ => Seq.empty
    +    }
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    var buf = new StringBuffer(strings.next)
    --- End diff --
    
    Oh. yes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/3028/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90169 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90169/testReport)** for PR 21193 at commit [`53daaf3`](https://github.com/apache/spark/commit/53daaf36587b29b542e10a473f6909c1f7a20b63).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90833/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by kiszk <gi...@git.apache.org>.
Github user kiszk commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186251067
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    +      case _ => Seq.empty
    +    }
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    var buf = new StringBuffer(strings.next)
    --- End diff --
    
    `StringBuilder` is better since it does not have sychronization.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r188907963
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,113 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    --- End diff --
    
    isn't it enough to compare `exprValues` with a `Set` containing the expected  elements instead of comparing them one by one?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2847/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90104 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90104/testReport)** for PR 21193 at commit [`5fe425c`](https://github.com/apache/spark/commit/5fe425c2d2837f00bdfe9ba5e6f446829fba32c1).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class ExprCode(var code: Block, var isNull: ExprValue, var value: ExprValue)`
      * `trait Block extends JavaCode `
      * `  implicit class BlockHelper(val sc: StringContext) extends AnyVal `
      * `case class CodeBlock(codeParts: Seq[String], exprValues: Seq[Any]) extends Block `
      * `case class Blocks(blocks: Seq[Block]) extends Block `
      * `trait ExprValue extends JavaCode `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90941 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90941/testReport)** for PR 21193 at commit [`96c594a`](https://github.com/apache/spark/commit/96c594a26af966d406f6c6f6786e486c0e04847d).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[JavaCode]) extends Block `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    LGTM, can we fix the conflict?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189206126
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/inputFileBlock.scala ---
    @@ -42,8 +43,8 @@ case class InputFileName() extends LeafExpression with Nondeterministic {
     
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val className = InputFileBlockHolder.getClass.getName.stripSuffix("$")
    -    ev.copy(code = s"final ${CodeGenerator.javaType(dataType)} ${ev.value} = " +
    -      s"$className.getInputFilePath();", isNull = FalseLiteral)
    +    ev.copy(code = code"final ${CodeGenerator.javaType(dataType)} ${ev.value} = " +
    +      code"$className.getInputFilePath();", isNull = FalseLiteral)
    --- End diff --
    
    the `Blocks.code` is defined as `override def code: String = blocks.map(_.toString).mkString("\n")`, is it OK here?
    
    maybe we can do
    ```
    val typeDef = s"final ${CodeGenerator.javaType(dataType)}"
    ev.code(code = code"$typeDef ${ev.value} = $className.getInputFilePath();", ...)
    ```


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90004/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186679018
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,113 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    --- End diff --
    
    Like:
    ```scala
      code"""
       | val ...
       | ...
      """.stripMargin
    ```
    
    It's basically for compatibility. We can remove this and disallow `stripMargin(customPrefix)`. WDYT?
    



---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90414 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90414/testReport)** for PR 21193 at commit [`72faac3`](https://github.com/apache/spark/commit/72faac3209beb8bc38938f8788de6338e9b2ffae).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by hvanhovell <gi...@git.apache.org>.
Github user hvanhovell commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186356233
  
    --- Diff: sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/codegen/ExprValueSuite.scala ---
    @@ -17,6 +17,8 @@
     
     package org.apache.spark.sql.catalyst.expressions.codegen
     
    +import scala.collection.mutable
    --- End diff --
    
    ???


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90009 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90009/testReport)** for PR 21193 at commit [`8e2db8b`](https://github.com/apache/spark/commit/8e2db8b66ec01ec83992ace1e4f1799f57a3da10).
     * This patch **fails Spark unit tests**.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class ExprCode(var code: Block, var isNull: ExprValue, var value: ExprValue)`
      * `trait Block extends JavaCode `
      * `  implicit class BlockHelper(val sc: StringContext) extends AnyVal `
      * `case class CodeBlock(codeParts: Seq[String], exprValues: Seq[Any]) extends Block `
      * `case class Blocks(blocks: Seq[Block]) extends Block `
      * `trait ExprValue extends JavaCode `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL][WIP] Add API for handling expr...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r185794699
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -120,13 +216,15 @@ object JavaCode {
     trait ExprValue extends JavaCode {
       def javaType: Class[_]
       def isPrimitive: Boolean = javaType.isPrimitive
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = ExprValue.exprValueToString(this)
     }
     
     object ExprValue {
    -  implicit def exprValueToString(exprValue: ExprValue): String = exprValue.toString
    +  implicit def exprValueToString(exprValue: ExprValue): String = exprValue.code
    --- End diff --
    
    Because `toString` will call `exprValueToString`. We should have only one place to convert an `ExprValue` to string.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r188904786
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,113 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    --- End diff --
    
    One issue I just found is, I can use the `ExprValues` order to do test easily.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90931 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90931/testReport)** for PR 21193 at commit [`96c594a`](https://github.com/apache/spark/commit/96c594a26af966d406f6c6f6786e486c0e04847d).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r187058702
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    --- End diff --
    
    @hvanhovell @cloud-fan Do you think we should continue to ban `String` in the code block string context (option 2) in a follow-up? This is a quite big PR for now.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    >  one question: no impact on compilation time for a large expression tree?
    
    The string interpolation in `CodeBlock` is not different to default [`StringContext`](https://github.com/scala/scala/blob/v2.12.6/src/library/scala/StringContext.scala#L123).  So seems to me `CodeBlock` shouldn't be a significant impact on compilation time. 
    
    One thing I noticed is the doc of `s` interpolator of `StringContext` notes there might be possible optimization from Scala compiler on it. If we really care about this, I think we can still leverage `s` to to string interpolation job. `CodeBlock`'s purpose for now is holding the inputs to the block and allow us to transform the inputs on demand in more structure way, instead of direct string manipulation on a flat code string.
    
    I'll leave it as it's for now and we can optimize it if needed later.
    



---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90430 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90430/testReport)** for PR 21193 at commit [`72faac3`](https://github.com/apache/spark/commit/72faac3209beb8bc38938f8788de6338e9b2ffae).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2874/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90092 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90092/testReport)** for PR 21193 at commit [`5fe425c`](https://github.com/apache/spark/commit/5fe425c2d2837f00bdfe9ba5e6f446829fba32c1).
     * This patch **fails due to an unknown error code, -9**.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class ExprCode(var code: Block, var isNull: ExprValue, var value: ExprValue)`
      * `trait Block extends JavaCode `
      * `  implicit class BlockHelper(val sc: StringContext) extends AnyVal `
      * `case class CodeBlock(codeParts: Seq[String], exprValues: Seq[Any]) extends Block `
      * `case class Blocks(blocks: Seq[Block]) extends Block `
      * `trait ExprValue extends JavaCode `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL][WIP] Add API for handling expr...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r185794875
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,102 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), exprValues = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A block of java code which involves some expressions represented by `ExprValue`.
    + */
    +trait Block extends JavaCode {
    +  def exprValues: Seq[Any]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    --- End diff --
    
    Ok.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189264892
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Set(e)
    +      case _ => Set.empty[ExprValue]
    +    }.toSet
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +    buf append StringContext.treatEscapes(strings.next)
    +    while (strings.hasNext) {
    +      buf append inputs.next
    +      buf append StringContext.treatEscapes(strings.next)
    +    }
    +    buf.toString
    +  }
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(Seq(this, c))
    +    case b: Blocks => Blocks(Seq(this) ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +case class Blocks(blocks: Seq[Block]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = blocks.flatMap(_.exprValues).toSet
    +  override def code: String = blocks.map(_.toString).mkString("\n")
    --- End diff --
    
    Yeah, I think so. Ideally I think `JavaCode` should be immutable. Once we change code in it, we should have a new object instead of chancing current one.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by kiszk <gi...@git.apache.org>.
Github user kiszk commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186251147
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    +      case _ => Seq.empty
    +    }
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    var buf = new StringBuffer(strings.next)
    --- End diff --
    
    Can we increase the initial size of this `StringBuffer`? This is because reallocating a buffer would occur frequently in the following loop if the initial size is small. It may lead to memory copy and GC.
    
    For example, 
    ```
    val buf = new StringBuilder(string.next)
    buf.ensureCapacity(512)
    ```


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90430 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90430/testReport)** for PR 21193 at commit [`72faac3`](https://github.com/apache/spark/commit/72faac3209beb8bc38938f8788de6338e9b2ffae).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2953/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90169 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90169/testReport)** for PR 21193 at commit [`53daaf3`](https://github.com/apache/spark/commit/53daaf36587b29b542e10a473f6909c1f7a20b63).
     * This patch **fails Spark unit tests**.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90004 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90004/testReport)** for PR 21193 at commit [`369242a`](https://github.com/apache/spark/commit/369242a017fd503e21e076cf010f3935d162b90b).
     * This patch **fails to build**.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class ExprCode(var code: Block, var isNull: ExprValue, var value: ExprValue)`
      * `trait Block extends JavaCode `
      * `  implicit class BlockHelper(val sc: StringContext) extends AnyVal `
      * `case class CodeBlock(codeParts: Seq[String], exprValues: Seq[Any]) extends Block `
      * `case class Blocks(blocks: Seq[Block]) extends Block `
      * `trait ExprValue extends JavaCode `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2775/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90835/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/3086/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/3364/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186661027
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    --- End diff --
    
    I already replaced string to `Block` in `Cast` locally (not committed yet). I'm fine to work with a manual block anyway for now in this case. We can address this in follow-ups.
    
    Indeed, I'm afraid that it's a bit tedious to identify references and fill them in correct order.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90139 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90139/testReport)** for PR 21193 at commit [`162deb2`](https://github.com/apache/spark/commit/162deb2f4de0b4d6fee3641ce79fbab424dd8e9b).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2888/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by ueshin <gi...@git.apache.org>.
Github user ueshin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186674665
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    --- End diff --
    
    nit: how about moving `eval.code` into the following `code` interpolation?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/3438/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90059 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90059/testReport)** for PR 21193 at commit [`5fe425c`](https://github.com/apache/spark/commit/5fe425c2d2837f00bdfe9ba5e6f446829fba32c1).
     * This patch **fails SparkR unit tests**.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class ExprCode(var code: Block, var isNull: ExprValue, var value: ExprValue)`
      * `trait Block extends JavaCode `
      * `  implicit class BlockHelper(val sc: StringContext) extends AnyVal `
      * `case class CodeBlock(codeParts: Seq[String], exprValues: Seq[Any]) extends Block `
      * `case class Blocks(blocks: Seq[Block]) extends Block `
      * `trait ExprValue extends JavaCode `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r188857554
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,113 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    --- End diff --
    
    yes, I think it is not and we are keeping here the order of the first occurrence (so for instance if we want to check which is the last reference we can't really know). I think a `Set` would be better since it enforces what we are keeping here, it avoids all the distinct (which we may forget to add somewhere getting a bad result...)


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90964 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90964/testReport)** for PR 21193 at commit [`00cc564`](https://github.com/apache/spark/commit/00cc564d0c6d6af2c443153f55705ec491fdfa1d).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class TaskKilled(`
      * `trait HasValidationIndicatorCol extends Params `
      * `trait DivModLike extends BinaryArithmetic `
      * `case class Divide(left: Expression, right: Expression) extends DivModLike `
      * `case class Remainder(left: Expression, right: Expression) extends DivModLike `
      * `case class MapEntries(child: Expression) extends UnaryExpression with ExpectsInputTypes `
      * `class ReadOnlySQLConf(context: TaskContext) extends SQLConf `
      * `class TaskContextConfigProvider(context: TaskContext) extends ConfigProvider `
      * `case class ContinuousShuffleReadPartition(index: Int, queueSize: Int) extends Partition `
      * `class ContinuousShuffleReadRDD(`
      * `trait ContinuousShuffleReader `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90357 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90357/testReport)** for PR 21193 at commit [`53b329a`](https://github.com/apache/spark/commit/53b329a3b4e72d423cf503af2982d545848bece8).
     * This patch **fails due to an unknown error code, -9**.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186618412
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    --- End diff --
    
    I'd like to clean this part further. The generated codes in `Cast` are tangled now, IMHO. 


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/3026/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186250659
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    --- End diff --
    
    I feels it's more like an illegal argument to string interpolator for now. I'm open for others ideas on this.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186616773
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,19 +114,128 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    --- End diff --
    
    `lazy val`? this might be expensive.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186263241
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/complexTypeCreator.scala ---
    @@ -64,7 +64,7 @@ case class CreateArray(children: Seq[Expression]) extends Expression {
         val (preprocess, assigns, postprocess, arrayData) =
           GenArrayData.genCodeToCreateArrayData(ctx, et, evals, false)
         ev.copy(
    -      code = JavaCode.block(preprocess + assigns + postprocess),
    +      code = code"$preprocess" + code"$assigns" + code"$postprocess",
    --- End diff --
    
    nit: can this be `code"${preprocess}${assigns}${postprocess}"`?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    cc @cloud-fan @kiszk @maropu @hvanhovell 


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL][WIP] Add API for handling expr...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r185763081
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,102 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), exprValues = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A block of java code which involves some expressions represented by `ExprValue`.
    + */
    +trait Block extends JavaCode {
    +  def exprValues: Seq[Any]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue => true
    +          case _: Int | _: Long | _: Float | _: Double | _: String => true
    +          case _: Block => true
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code.
    + */
    +case class CodeBlock(codeParts: Seq[String], exprValues: Seq[Any]) extends Block {
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val expressions = exprValues.iterator
    +    var buf = new StringBuffer(strings.next)
    +    while (strings.hasNext) {
    +      if (expressions.hasNext) {
    --- End diff --
    
    this is not needed (especially if we add the `checkLengths`), because if it is not true we are in a bad situation


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189206358
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/inputFileBlock.scala ---
    @@ -88,7 +89,7 @@ case class InputFileBlockLength() extends LeafExpression with Nondeterministic {
     
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val className = InputFileBlockHolder.getClass.getName.stripSuffix("$")
    -    ev.copy(code = s"final ${CodeGenerator.javaType(dataType)} ${ev.value} = " +
    -      s"$className.getLength();", isNull = FalseLiteral)
    +    ev.copy(code = code"final ${CodeGenerator.javaType(dataType)} ${ev.value} = " +
    --- End diff --
    
    ditto


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by maropu <gi...@git.apache.org>.
Github user maropu commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90139/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186250676
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    --- End diff --
    
    I'd like to limit the types of objects we can interpolate at the first. So there will be less cases I'm not aware of. Can be open to all others later.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90355/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by kiszk <gi...@git.apache.org>.
Github user kiszk commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r185995523
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    +      case _ => Seq.empty
    +    }
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    var buf = new StringBuffer(strings.next)
    +    while (strings.hasNext) {
    +      buf append inputs.next
    +      buf append strings.next
    +    }
    +    buf.toString
    +  }
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(Seq(this, c))
    +    case b: Blocks => Blocks(Seq(this) ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +case class Blocks(blocks: Seq[Block]) extends Block {
    +  override def exprValues: Seq[ExprValue] = blocks.flatMap(_.exprValues)
    +  override def code: String = blocks.map(_.toString).mkString
    --- End diff --
    
    I am just curious whether `mkString` may lead to 64KB limit issue.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by hvanhovell <gi...@git.apache.org>.
Github user hvanhovell commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186670675
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,113 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    --- End diff --
    
    These are the inputs right?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186624071
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    --- End diff --
    
    During changing to `Block` in `Cast`, I do think of this again.
    
    `eval` is the only expression for `Cast`, thus it should be the only `ExprValue` input to `Cast`'s code block we need to take care.
    
    Other `ExprValue` like the children of `eval.value` should be taken care in the block 
    `eval.code`.



---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90083/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by rednaxelafx <gi...@git.apache.org>.
Github user rednaxelafx commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189786155
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -167,9 +170,40 @@ object Block {
               case other => throw new IllegalArgumentException(
                 s"Can not interpolate ${other.getClass.getName} into code block.")
             }
    -        CodeBlock(sc.parts, args)
    +
    +        val (codeParts, blockInputs) = foldLiteralArgs(sc.parts, args)
    +        CodeBlock(codeParts, blockInputs)
    +      }
    +    }
    +  }
    +
    +  // Folds eagerly the literal args into the code parts.
    +  private def foldLiteralArgs(parts: Seq[String], args: Seq[Any]): (Seq[String], Seq[Any]) = {
    +    val codeParts = ArrayBuffer.empty[String]
    +    val blockInputs = ArrayBuffer.empty[Any]
    +
    +    val strings = parts.iterator
    +    val inputs = args.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +
    +    buf append strings.next
    +    while (strings.hasNext) {
    --- End diff --
    
    Looks good


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90941 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90941/testReport)** for PR 21193 at commit [`96c594a`](https://github.com/apache/spark/commit/96c594a26af966d406f6c6f6786e486c0e04847d).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189767747
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -167,9 +170,40 @@ object Block {
               case other => throw new IllegalArgumentException(
                 s"Can not interpolate ${other.getClass.getName} into code block.")
             }
    -        CodeBlock(sc.parts, args)
    +
    +        val (codeParts, blockInputs) = foldLiteralArgs(sc.parts, args)
    +        CodeBlock(codeParts, blockInputs)
    +      }
    +    }
    +  }
    +
    +  // Folds eagerly the literal args into the code parts.
    +  private def foldLiteralArgs(parts: Seq[String], args: Seq[Any]): (Seq[String], Seq[Any]) = {
    +    val codeParts = ArrayBuffer.empty[String]
    +    val blockInputs = ArrayBuffer.empty[Any]
    +
    +    val strings = parts.iterator
    +    val inputs = args.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +
    +    buf append strings.next
    --- End diff --
    
    Ok.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r188955270
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = {
    +    blockInputs.flatMap {
    --- End diff --
    
    I think `flatMap` looks simpler.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90732 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90732/testReport)** for PR 21193 at commit [`c378ce2`](https://github.com/apache/spark/commit/c378ce2a1982b2c5453b15fbc1de06851033ac1d).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90835 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90835/testReport)** for PR 21193 at commit [`2ca9741`](https://github.com/apache/spark/commit/2ca974190527f3ac1ade1feddf9bd2b953fabdd7).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2772/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2895/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186263675
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/complexTypeCreator.scala ---
    @@ -64,7 +64,7 @@ case class CreateArray(children: Seq[Expression]) extends Expression {
         val (preprocess, assigns, postprocess, arrayData) =
           GenArrayData.genCodeToCreateArrayData(ctx, et, evals, false)
         ev.copy(
    -      code = JavaCode.block(preprocess + assigns + postprocess),
    +      code = code"$preprocess" + code"$assigns" + code"$postprocess",
    --- End diff --
    
    oh, yes. Will update it in next commit. Thanks.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189279129
  
    --- Diff: sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeBlockSuite.scala ---
    @@ -0,0 +1,130 @@
    +/*
    + * 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.spark.sql.catalyst.expressions.codegen
    +
    +import org.apache.spark.SparkFunSuite
    +import org.apache.spark.sql.catalyst.expressions.codegen.Block._
    +import org.apache.spark.sql.types.{BooleanType, IntegerType}
    +
    +class CodeBlockSuite extends SparkFunSuite {
    +
    +  test("Block can interpolate string and ExprValue inputs") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val code = code"boolean ${isNull} = ${JavaCode.defaultLiteral(BooleanType)};"
    +    assert(code.toString == "boolean expr1_isNull = false;")
    +  }
    +
    +  test("Block.stripMargin") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val value = JavaCode.variable("expr1", IntegerType)
    +    val code1 =
    +      code"""
    +           |boolean $isNull = false;
    +           |int $value = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin
    +    val expected =
    +      s"""
    +        |boolean expr1_isNull = false;
    +        |int expr1 = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin.trim
    +    assert(code1.toString == expected)
    +
    +    val code2 =
    +      code"""
    +           >boolean $isNull = false;
    +           >int $value = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin('>')
    +    assert(code2.toString == expected)
    +  }
    +
    +  test("Block can capture input expr values") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val value = JavaCode.variable("expr1", IntegerType)
    +    val code =
    +      code"""
    +           |boolean $isNull = false;
    +           |int $value = -1;
    +          """.stripMargin
    +    val exprValues = code.exprValues
    +    assert(exprValues.size == 2)
    +    assert(exprValues === Set(value, isNull))
    +  }
    +
    +  test("concatenate blocks") {
    +    val isNull1 = JavaCode.isNullVariable("expr1_isNull")
    +    val value1 = JavaCode.variable("expr1", IntegerType)
    +    val isNull2 = JavaCode.isNullVariable("expr2_isNull")
    +    val value2 = JavaCode.variable("expr2", IntegerType)
    +    val literal = JavaCode.literal("100", IntegerType)
    +
    +    val code =
    +      code"""
    +           |boolean $isNull1 = false;
    +           |int $value1 = -1;""".stripMargin +
    +      code"""
    +           |boolean $isNull2 = true;
    +           |int $value2 = $literal;""".stripMargin
    +
    +    val expected =
    +      """
    +       |boolean expr1_isNull = false;
    +       |int expr1 = -1;
    +       |boolean expr2_isNull = true;
    +       |int expr2 = 100;""".stripMargin.trim
    +
    +    assert(code.toString == expected)
    +
    +    val exprValues = code.exprValues
    +    assert(exprValues.size == 5)
    +    assert(exprValues === Set(isNull1, value1, isNull2, value2, literal))
    +  }
    +
    +  test("Throws exception when interpolating unexcepted object in code block") {
    +    val obj = TestClass(100)
    +    val e = intercept[IllegalArgumentException] {
    +      code"$obj"
    +    }
    +    assert(e.getMessage().contains(s"Can not interpolate ${obj.getClass.getName}"))
    +  }
    +
    +  test("replace expr values in code block") {
    +    val statement = JavaCode.expression("1 + 1", IntegerType)
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val exprInFunc = JavaCode.variable("expr1", IntegerType)
    +
    +    val code =
    +      code"""
    +           |callFunc(int $statement) {
    +           |  boolean $isNull = false;
    +           |  int $exprInFunc = $statement + 1;
    +           |}""".stripMargin
    +
    +    val aliasedParam = JavaCode.variable("aliased", statement.javaType)
    +    val aliasedInputs = code.asInstanceOf[CodeBlock].blockInputs.map {
    +      case _: SimpleExprValue => aliasedParam
    +      case other => other
    +    }
    +    val aliasedCode = CodeBlock(code.asInstanceOf[CodeBlock].codeParts, aliasedInputs).stripMargin
    --- End diff --
    
    Actually I just think about this and have initial idea. I'd prototype it locally and make follow up for your review after this.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r188950746
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Set(e)
    +      case _ => Set.empty[ExprValue]
    +    }.toSet
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +    buf append StringContext.treatEscapes(strings.next)
    +    while (strings.hasNext) {
    +      buf append inputs.next
    +      buf append StringContext.treatEscapes(strings.next)
    +    }
    +    buf.toString
    +  }
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(Seq(this, c))
    +    case b: Blocks => Blocks(Seq(this) ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +case class Blocks(blocks: Seq[Block]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = blocks.flatMap(_.exprValues).toSet
    --- End diff --
    
    `toSet` is redundant I think


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90357/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90362 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90362/testReport)** for PR 21193 at commit [`53b329a`](https://github.com/apache/spark/commit/53b329a3b4e72d423cf503af2982d545848bece8).
     * This patch **fails Spark unit tests**.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186627928
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    --- End diff --
    
    I prefer 2. Explicitly specifying the references sounds a bit verbose to me.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90726 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90726/testReport)** for PR 21193 at commit [`d040676`](https://github.com/apache/spark/commit/d04067635ca5785e262afb65781faab5ca737d93).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by hvanhovell <gi...@git.apache.org>.
Github user hvanhovell commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186670840
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,113 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    --- End diff --
    
    When do we need this?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189259397
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Set(e)
    +      case _ => Set.empty[ExprValue]
    +    }.toSet
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +    buf append StringContext.treatEscapes(strings.next)
    +    while (strings.hasNext) {
    +      buf append inputs.next
    +      buf append StringContext.treatEscapes(strings.next)
    +    }
    +    buf.toString
    --- End diff --
    
    ah i see


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by HyukjinKwon <gi...@git.apache.org>.
Github user HyukjinKwon commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90174 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90174/testReport)** for PR 21193 at commit [`d138ee0`](https://github.com/apache/spark/commit/d138ee05541bc1976442c5f1170ba7a7f3f5114c).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Anymore comments on this? @hvanhovell @cloud-fan @kiszk @maropu @ueshin @mgaido91 


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90092/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by maropu <gi...@git.apache.org>.
Github user maropu commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186247026
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    --- End diff --
    
    Runtime exception? `sys.error`?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189208302
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Set(e)
    +      case _ => Set.empty[ExprValue]
    +    }.toSet
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +    buf append StringContext.treatEscapes(strings.next)
    +    while (strings.hasNext) {
    +      buf append inputs.next
    +      buf append StringContext.treatEscapes(strings.next)
    +    }
    +    buf.toString
    +  }
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(Seq(this, c))
    +    case b: Blocks => Blocks(Seq(this) ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +case class Blocks(blocks: Seq[Block]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = blocks.flatMap(_.exprValues).toSet
    +  override def code: String = blocks.map(_.toString).mkString("\n")
    --- End diff --
    
    shall we also make it lazy val?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    @cloud-fan Thanks. Fixed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186626823
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    --- End diff --
    
    Oh, sorry for misunderstanding. No I don't see any other like `Cast`.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90726 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90726/testReport)** for PR 21193 at commit [`d040676`](https://github.com/apache/spark/commit/d04067635ca5785e262afb65781faab5ca737d93).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    @viirya actually I had just one last comment: https://github.com/apache/spark/pull/21193#discussion_r187612068


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186617171
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,19 +114,128 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    +      case _ => Seq.empty
    +    }
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +    buf append StringContext.treatEscapes(strings.next)
    +    while (strings.hasNext) {
    +      buf append inputs.next
    +      buf append StringContext.treatEscapes(strings.next)
    +    }
    +    buf.toString
    +  }
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(Seq(this, c))
    +    case b: Blocks => Blocks(Seq(this) ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +case class Blocks(blocks: Seq[Block]) extends Block {
    +  override def exprValues: Seq[ExprValue] = blocks.flatMap(_.exprValues)
    +  override def code: String = blocks.map(_.toString).mkString("\n")
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(blocks :+ c)
    +    case b: Blocks => Blocks(blocks ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +object EmptyBlock extends Block with Serializable {
    +  override def code: String = ""
    +  override def exprValues: Seq[ExprValue] = Seq.empty
    +
    +  override def + (other: Block): Block = other
    +}
    +
     /**
      * A typed java fragment that must be a valid java expression.
      */
     trait ExprValue extends JavaCode {
       def javaType: Class[_]
       def isPrimitive: Boolean = javaType.isPrimitive
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = ExprValue.exprValueToString(this)
    --- End diff --
    
    why is it needed? `JavaCode` already defines `override def toString: String = code`


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90858/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r187036570
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala ---
    @@ -56,19 +57,19 @@ import org.apache.spark.util.{ParentClassLoader, Utils}
      * @param value A term for a (possibly primitive) value of the result of the evaluation. Not
      *              valid if `isNull` is set to `true`.
      */
    -case class ExprCode(var code: String, var isNull: ExprValue, var value: ExprValue)
    +case class ExprCode(var code: Block, var isNull: ExprValue, var value: ExprValue)
     
     object ExprCode {
       def apply(isNull: ExprValue, value: ExprValue): ExprCode = {
    -    ExprCode(code = "", isNull, value)
    +    ExprCode(code = code"", isNull, value)
    --- End diff --
    
    Ok.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90362/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90104/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90174/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90120 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90120/testReport)** for PR 21193 at commit [`00bef6b`](https://github.com/apache/spark/commit/00bef6bb2559d93e68266d2605ef4403f4d8d2af).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189206338
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/inputFileBlock.scala ---
    @@ -65,8 +66,8 @@ case class InputFileBlockStart() extends LeafExpression with Nondeterministic {
     
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val className = InputFileBlockHolder.getClass.getName.stripSuffix("$")
    -    ev.copy(code = s"final ${CodeGenerator.javaType(dataType)} ${ev.value} = " +
    -      s"$className.getStartOffset();", isNull = FalseLiteral)
    +    ev.copy(code = code"final ${CodeGenerator.javaType(dataType)} ${ev.value} = " +
    --- End diff --
    
    ditto


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by kiszk <gi...@git.apache.org>.
Github user kiszk commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    LGTM


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90083 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90083/testReport)** for PR 21193 at commit [`5fe425c`](https://github.com/apache/spark/commit/5fe425c2d2837f00bdfe9ba5e6f446829fba32c1).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by kiszk <gi...@git.apache.org>.
Github user kiszk commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Overall, I like this direction to have Java code in a structure instead of flat string.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    @hvanhovell Thanks for your comment!
    
    I tried to add new JavaCode abstraction `Block` which holds the code to generate. I hope this approach can be less side effect. Please comment if you have time to take a look. I'll be in vacation in next few days, but I will try to follow your comment if any. Thanks!


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    ping @hvanhovell @cloud-fan 


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186618899
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,19 +114,128 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    --- End diff --
    
    Ok.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by hvanhovell <gi...@git.apache.org>.
Github user hvanhovell commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    @viirya I just glanced over this. We currently use a lot of mutable code for in code generation with - TBH - way too complex side effects. Your proposal adds another layer of side effects.
    
    Why don't we add a bit more structure to the JavaCode abstraction, and figure out that we need splitting from that? It will probably be more involved than this because you probably cannot fix the names upfront.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2893/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186627099
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    --- End diff --
    
    I feel it's a little fragile to depend on the `StringContext` to collect references. 2 proposal:
    1. ask the code builder to explicitly specify the references, like `JavaCode.block(code = xxx, ref1, ref2, ...)`
    2. ban `String` in the code block string context, and create a special class to insert `String` literal to code block, so that we won't mistakently pass code as string and lose references.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by kiszk <gi...@git.apache.org>.
Github user kiszk commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2814/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186617013
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,19 +114,128 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    --- End diff --
    
    is it possible that a `ExprValue` is referenced twice in the code string?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/3447/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186251251
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    +      case _ => Seq.empty
    +    }
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    var buf = new StringBuffer(strings.next)
    --- End diff --
    
    Then how about ask for `StringBuilder` with larger initial capacity?  Like:
    ```scala
        val buf = new StringBuilder(512)
        buf append string.next
    ```


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by maropu <gi...@git.apache.org>.
Github user maropu commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r187978104
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    --- End diff --
    
    +1 for the second one, too. (@hvanhovell 's comment sounds reasonable to me.)


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189207159
  
    --- Diff: sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeBlockSuite.scala ---
    @@ -0,0 +1,130 @@
    +/*
    + * 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.spark.sql.catalyst.expressions.codegen
    +
    +import org.apache.spark.SparkFunSuite
    +import org.apache.spark.sql.catalyst.expressions.codegen.Block._
    +import org.apache.spark.sql.types.{BooleanType, IntegerType}
    +
    +class CodeBlockSuite extends SparkFunSuite {
    +
    +  test("Block can interpolate string and ExprValue inputs") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val code = code"boolean ${isNull} = ${JavaCode.defaultLiteral(BooleanType)};"
    +    assert(code.toString == "boolean expr1_isNull = false;")
    +  }
    +
    +  test("Block.stripMargin") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val value = JavaCode.variable("expr1", IntegerType)
    +    val code1 =
    +      code"""
    +           |boolean $isNull = false;
    +           |int $value = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin
    +    val expected =
    +      s"""
    +        |boolean expr1_isNull = false;
    +        |int expr1 = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin.trim
    +    assert(code1.toString == expected)
    +
    +    val code2 =
    +      code"""
    +           >boolean $isNull = false;
    +           >int $value = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin('>')
    +    assert(code2.toString == expected)
    +  }
    +
    +  test("Block can capture input expr values") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val value = JavaCode.variable("expr1", IntegerType)
    +    val code =
    +      code"""
    +           |boolean $isNull = false;
    +           |int $value = -1;
    +          """.stripMargin
    +    val exprValues = code.exprValues
    +    assert(exprValues.size == 2)
    +    assert(exprValues === Set(value, isNull))
    +  }
    +
    +  test("concatenate blocks") {
    +    val isNull1 = JavaCode.isNullVariable("expr1_isNull")
    +    val value1 = JavaCode.variable("expr1", IntegerType)
    +    val isNull2 = JavaCode.isNullVariable("expr2_isNull")
    +    val value2 = JavaCode.variable("expr2", IntegerType)
    +    val literal = JavaCode.literal("100", IntegerType)
    +
    +    val code =
    +      code"""
    +           |boolean $isNull1 = false;
    +           |int $value1 = -1;""".stripMargin +
    +      code"""
    +           |boolean $isNull2 = true;
    +           |int $value2 = $literal;""".stripMargin
    +
    +    val expected =
    +      """
    +       |boolean expr1_isNull = false;
    +       |int expr1 = -1;
    +       |boolean expr2_isNull = true;
    +       |int expr2 = 100;""".stripMargin.trim
    +
    +    assert(code.toString == expected)
    +
    +    val exprValues = code.exprValues
    +    assert(exprValues.size == 5)
    +    assert(exprValues === Set(isNull1, value1, isNull2, value2, literal))
    +  }
    +
    +  test("Throws exception when interpolating unexcepted object in code block") {
    +    val obj = TestClass(100)
    --- End diff --
    
    we can simply use a Tuple2 here, like `1 -> 1`


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90723 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90723/testReport)** for PR 21193 at commit [`72faac3`](https://github.com/apache/spark/commit/72faac3209beb8bc38938f8788de6338e9b2ffae).
     * This patch **fails to build**.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90135 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90135/testReport)** for PR 21193 at commit [`00bef6b`](https://github.com/apache/spark/commit/00bef6bb2559d93e68266d2605ef4403f4d8d2af).
     * This patch **fails to build**.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by kiszk <gi...@git.apache.org>.
Github user kiszk commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186251439
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    --- End diff --
    
    It is OK to prepare `stripMargin` API for backward compatibility.
    Can we do stripping operation regarding `|` inside `Block` as default. Then, we can eliminate `Margin` method in new code.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189208663
  
    --- Diff: sql/core/src/main/scala/org/apache/spark/sql/execution/WholeStageCodegenExec.scala ---
    @@ -259,8 +260,8 @@ trait CodegenSupport extends SparkPlan {
        * them to be evaluated twice.
        */
       protected def evaluateVariables(variables: Seq[ExprCode]): String = {
    -    val evaluate = variables.filter(_.code != "").map(_.code.trim).mkString("\n")
    -    variables.foreach(_.code = "")
    +    val evaluate = variables.filter(_.code.toString != "").map(_.code.toString).mkString("\n")
    --- End diff --
    
    nit: `_.code.toString.nonEmpty`


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90833 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90833/testReport)** for PR 21193 at commit [`2ca9741`](https://github.com/apache/spark/commit/2ca974190527f3ac1ade1feddf9bd2b953fabdd7).
     * This patch **fails Spark unit tests**.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186618877
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,19 +114,128 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    +      case _ => Seq.empty
    +    }
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +    buf append StringContext.treatEscapes(strings.next)
    +    while (strings.hasNext) {
    +      buf append inputs.next
    +      buf append StringContext.treatEscapes(strings.next)
    +    }
    +    buf.toString
    +  }
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(Seq(this, c))
    +    case b: Blocks => Blocks(Seq(this) ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +case class Blocks(blocks: Seq[Block]) extends Block {
    +  override def exprValues: Seq[ExprValue] = blocks.flatMap(_.exprValues)
    +  override def code: String = blocks.map(_.toString).mkString("\n")
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(blocks :+ c)
    +    case b: Blocks => Blocks(blocks ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +object EmptyBlock extends Block with Serializable {
    +  override def code: String = ""
    +  override def exprValues: Seq[ExprValue] = Seq.empty
    +
    +  override def + (other: Block): Block = other
    +}
    +
     /**
      * A typed java fragment that must be a valid java expression.
      */
     trait ExprValue extends JavaCode {
       def javaType: Class[_]
       def isPrimitive: Boolean = javaType.isPrimitive
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = ExprValue.exprValueToString(this)
    --- End diff --
    
    Forgot to revert this change. In previous commit, I need `ExprValue.exprValueToString` as the only entry for tracking `ExprValue`. This should be reverted now.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189768074
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -167,9 +170,40 @@ object Block {
               case other => throw new IllegalArgumentException(
                 s"Can not interpolate ${other.getClass.getName} into code block.")
             }
    -        CodeBlock(sc.parts, args)
    +
    +        val (codeParts, blockInputs) = foldLiteralArgs(sc.parts, args)
    +        CodeBlock(codeParts, blockInputs)
    +      }
    +    }
    +  }
    +
    +  // Folds eagerly the literal args into the code parts.
    +  private def foldLiteralArgs(parts: Seq[String], args: Seq[Any]): (Seq[String], Seq[Any]) = {
    +    val codeParts = ArrayBuffer.empty[String]
    +    val blockInputs = ArrayBuffer.empty[Any]
    --- End diff --
    
    Ok. `JavaCode` is better.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90241 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90241/testReport)** for PR 21193 at commit [`ee9a4c0`](https://github.com/apache/spark/commit/ee9a4c03a2da8a01f588c1283500f3412e356875).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90964/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    @cloud-fan @rednaxelafx Your last comments are addressed. Please check if you have other comments. Thanks for review.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by hvanhovell <gi...@git.apache.org>.
Github user hvanhovell commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186669860
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala ---
    @@ -119,7 +121,7 @@ abstract class Expression extends TreeNode[Expression] {
     
       private def reduceCodeSize(ctx: CodegenContext, eval: ExprCode): Unit = {
         // TODO: support whole stage codegen too
    -    if (eval.code.trim.length > 1024 && ctx.INPUT_ROW != null && ctx.currentVars == null) {
    +    if (eval.code.toString.length > 1024 && ctx.INPUT_ROW != null && ctx.currentVars == null) {
    --- End diff --
    
    Can you add a method to `code` that produces the size directly?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by maropu <gi...@git.apache.org>.
Github user maropu commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186247824
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    +      case _ => Seq.empty
    +    }
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    var buf = new StringBuffer(strings.next)
    --- End diff --
    
    nit: `val`.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189208129
  
    --- Diff: sql/core/src/main/scala/org/apache/spark/sql/execution/ColumnarBatchScan.scala ---
    @@ -58,14 +59,14 @@ private[sql] trait ColumnarBatchScan extends CodegenSupport {
         }
         val valueVar = ctx.freshName("value")
         val str = s"columnVector[$columnVar, $ordinal, ${dataType.simpleString}]"
    -    val code = s"${ctx.registerComment(str)}\n" + (if (nullable) {
    -      s"""
    +    val code = code"${ctx.registerComment(str)}\n" + (if (nullable) {
    --- End diff --
    
    the `\n` is not needed now, since we always add `\n` between code blocks.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189202465
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala ---
    @@ -100,17 +101,18 @@ abstract class Expression extends TreeNode[Expression] {
         ctx.subExprEliminationExprs.get(this).map { subExprState =>
           // This expression is repeated which means that the code to evaluate it has already been added
           // as a function before. In that case, we just re-use it.
    -      ExprCode(ctx.registerComment(this.toString), subExprState.isNull, subExprState.value)
    +      ExprCode(ctx.registerComment(this.toString), subExprState.isNull,
    +        subExprState.value)
    --- End diff --
    
    unnecessary change


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90083 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90083/testReport)** for PR 21193 at commit [`5fe425c`](https://github.com/apache/spark/commit/5fe425c2d2837f00bdfe9ba5e6f446829fba32c1).
     * This patch **fails SparkR unit tests**.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class ExprCode(var code: Block, var isNull: ExprValue, var value: ExprValue)`
      * `trait Block extends JavaCode `
      * `  implicit class BlockHelper(val sc: StringContext) extends AnyVal `
      * `case class CodeBlock(codeParts: Seq[String], exprValues: Seq[Any]) extends Block `
      * `case class Blocks(blocks: Seq[Block]) extends Block `
      * `trait ExprValue extends JavaCode `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by rednaxelafx <gi...@git.apache.org>.
Github user rednaxelafx commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189229229
  
    --- Diff: sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeBlockSuite.scala ---
    @@ -0,0 +1,130 @@
    +/*
    + * 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.spark.sql.catalyst.expressions.codegen
    +
    +import org.apache.spark.SparkFunSuite
    +import org.apache.spark.sql.catalyst.expressions.codegen.Block._
    +import org.apache.spark.sql.types.{BooleanType, IntegerType}
    +
    +class CodeBlockSuite extends SparkFunSuite {
    +
    +  test("Block can interpolate string and ExprValue inputs") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val code = code"boolean ${isNull} = ${JavaCode.defaultLiteral(BooleanType)};"
    +    assert(code.toString == "boolean expr1_isNull = false;")
    +  }
    +
    +  test("Block.stripMargin") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val value = JavaCode.variable("expr1", IntegerType)
    +    val code1 =
    +      code"""
    +           |boolean $isNull = false;
    +           |int $value = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin
    +    val expected =
    +      s"""
    +        |boolean expr1_isNull = false;
    +        |int expr1 = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin.trim
    +    assert(code1.toString == expected)
    +
    +    val code2 =
    +      code"""
    +           >boolean $isNull = false;
    +           >int $value = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin('>')
    +    assert(code2.toString == expected)
    +  }
    +
    +  test("Block can capture input expr values") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val value = JavaCode.variable("expr1", IntegerType)
    +    val code =
    +      code"""
    +           |boolean $isNull = false;
    +           |int $value = -1;
    +          """.stripMargin
    +    val exprValues = code.exprValues
    +    assert(exprValues.size == 2)
    +    assert(exprValues === Set(value, isNull))
    +  }
    +
    +  test("concatenate blocks") {
    +    val isNull1 = JavaCode.isNullVariable("expr1_isNull")
    +    val value1 = JavaCode.variable("expr1", IntegerType)
    +    val isNull2 = JavaCode.isNullVariable("expr2_isNull")
    +    val value2 = JavaCode.variable("expr2", IntegerType)
    +    val literal = JavaCode.literal("100", IntegerType)
    +
    +    val code =
    +      code"""
    +           |boolean $isNull1 = false;
    +           |int $value1 = -1;""".stripMargin +
    +      code"""
    +           |boolean $isNull2 = true;
    +           |int $value2 = $literal;""".stripMargin
    +
    +    val expected =
    +      """
    +       |boolean expr1_isNull = false;
    +       |int expr1 = -1;
    +       |boolean expr2_isNull = true;
    +       |int expr2 = 100;""".stripMargin.trim
    +
    +    assert(code.toString == expected)
    +
    +    val exprValues = code.exprValues
    +    assert(exprValues.size == 5)
    +    assert(exprValues === Set(isNull1, value1, isNull2, value2, literal))
    +  }
    +
    +  test("Throws exception when interpolating unexcepted object in code block") {
    +    val obj = TestClass(100)
    +    val e = intercept[IllegalArgumentException] {
    +      code"$obj"
    +    }
    +    assert(e.getMessage().contains(s"Can not interpolate ${obj.getClass.getName}"))
    +  }
    +
    +  test("replace expr values in code block") {
    +    val statement = JavaCode.expression("1 + 1", IntegerType)
    --- End diff --
    
    Nit: can we rename this `statement` variable to something like `expr` or `someExpr` or something? It's an expression not a statement.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189264507
  
    --- Diff: sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeBlockSuite.scala ---
    @@ -0,0 +1,130 @@
    +/*
    + * 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.spark.sql.catalyst.expressions.codegen
    +
    +import org.apache.spark.SparkFunSuite
    +import org.apache.spark.sql.catalyst.expressions.codegen.Block._
    +import org.apache.spark.sql.types.{BooleanType, IntegerType}
    +
    +class CodeBlockSuite extends SparkFunSuite {
    +
    +  test("Block can interpolate string and ExprValue inputs") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val code = code"boolean ${isNull} = ${JavaCode.defaultLiteral(BooleanType)};"
    +    assert(code.toString == "boolean expr1_isNull = false;")
    +  }
    +
    +  test("Block.stripMargin") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val value = JavaCode.variable("expr1", IntegerType)
    +    val code1 =
    +      code"""
    +           |boolean $isNull = false;
    +           |int $value = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin
    +    val expected =
    +      s"""
    +        |boolean expr1_isNull = false;
    +        |int expr1 = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin.trim
    +    assert(code1.toString == expected)
    +
    +    val code2 =
    +      code"""
    +           >boolean $isNull = false;
    +           >int $value = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin('>')
    +    assert(code2.toString == expected)
    +  }
    +
    +  test("Block can capture input expr values") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val value = JavaCode.variable("expr1", IntegerType)
    +    val code =
    +      code"""
    +           |boolean $isNull = false;
    +           |int $value = -1;
    +          """.stripMargin
    +    val exprValues = code.exprValues
    +    assert(exprValues.size == 2)
    +    assert(exprValues === Set(value, isNull))
    +  }
    +
    +  test("concatenate blocks") {
    +    val isNull1 = JavaCode.isNullVariable("expr1_isNull")
    +    val value1 = JavaCode.variable("expr1", IntegerType)
    +    val isNull2 = JavaCode.isNullVariable("expr2_isNull")
    +    val value2 = JavaCode.variable("expr2", IntegerType)
    +    val literal = JavaCode.literal("100", IntegerType)
    +
    +    val code =
    +      code"""
    +           |boolean $isNull1 = false;
    +           |int $value1 = -1;""".stripMargin +
    +      code"""
    +           |boolean $isNull2 = true;
    +           |int $value2 = $literal;""".stripMargin
    +
    +    val expected =
    +      """
    +       |boolean expr1_isNull = false;
    +       |int expr1 = -1;
    +       |boolean expr2_isNull = true;
    +       |int expr2 = 100;""".stripMargin.trim
    +
    +    assert(code.toString == expected)
    +
    +    val exprValues = code.exprValues
    +    assert(exprValues.size == 5)
    +    assert(exprValues === Set(isNull1, value1, isNull2, value2, literal))
    +  }
    +
    +  test("Throws exception when interpolating unexcepted object in code block") {
    +    val obj = TestClass(100)
    +    val e = intercept[IllegalArgumentException] {
    +      code"$obj"
    +    }
    +    assert(e.getMessage().contains(s"Can not interpolate ${obj.getClass.getName}"))
    +  }
    +
    +  test("replace expr values in code block") {
    +    val statement = JavaCode.expression("1 + 1", IntegerType)
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val exprInFunc = JavaCode.variable("expr1", IntegerType)
    +
    +    val code =
    +      code"""
    +           |callFunc(int $statement) {
    +           |  boolean $isNull = false;
    +           |  int $exprInFunc = $statement + 1;
    +           |}""".stripMargin
    +
    +    val aliasedParam = JavaCode.variable("aliased", statement.javaType)
    +    val aliasedInputs = code.asInstanceOf[CodeBlock].blockInputs.map {
    +      case _: SimpleExprValue => aliasedParam
    +      case other => other
    +    }
    +    val aliasedCode = CodeBlock(code.asInstanceOf[CodeBlock].codeParts, aliasedInputs).stripMargin
    --- End diff --
    
    Yes, I agreed. In the follow up, we definitely should have a better API for manipulating code. I think here it is used to show what we can do for `CodeBlock` right now.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90241 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90241/testReport)** for PR 21193 at commit [`ee9a4c0`](https://github.com/apache/spark/commit/ee9a4c03a2da8a01f588c1283500f3412e356875).
     * This patch **fails due to an unknown error code, -9**.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90430/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by ueshin <gi...@git.apache.org>.
Github user ueshin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186681857
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    +        ${castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast)}
    --- End diff --
    
    I might miss something, but don't we need to pass `ExprValue` or `Block` and return `Block` from `castCode()` to keep track of code snippets and inputs?
    We can say the same thing anywhere we create a smaller code snippet using `s` interpolation.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90009/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r188956140
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Set(e)
    +      case _ => Set.empty[ExprValue]
    +    }.toSet
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +    buf append StringContext.treatEscapes(strings.next)
    +    while (strings.hasNext) {
    +      buf append inputs.next
    +      buf append StringContext.treatEscapes(strings.next)
    +    }
    +    buf.toString
    +  }
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(Seq(this, c))
    +    case b: Blocks => Blocks(Seq(this) ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +case class Blocks(blocks: Seq[Block]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = blocks.flatMap(_.exprValues).toSet
    --- End diff --
    
    oh, sorry, `blocks ` is a `Seq`, sorry, my bad.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90357 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90357/testReport)** for PR 21193 at commit [`53b329a`](https://github.com/apache/spark/commit/53b329a3b4e72d423cf503af2982d545848bece8).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Thanks for your review @hvanhovell @cloud-fan @kiszk @maropu @mgaido91 @ueshin @rednaxelafx 


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r187034014
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    --- End diff --
    
    ok.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2863/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    I think this can be reviewed for now. Thanks. cc @cloud-fan @hvanhovell @kiszk @maropu 


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189616918
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -167,9 +170,40 @@ object Block {
               case other => throw new IllegalArgumentException(
                 s"Can not interpolate ${other.getClass.getName} into code block.")
             }
    -        CodeBlock(sc.parts, args)
    +
    +        val (codeParts, blockInputs) = foldLiteralArgs(sc.parts, args)
    +        CodeBlock(codeParts, blockInputs)
    +      }
    +    }
    +  }
    +
    +  // Folds eagerly the literal args into the code parts.
    +  private def foldLiteralArgs(parts: Seq[String], args: Seq[Any]): (Seq[String], Seq[Any]) = {
    +    val codeParts = ArrayBuffer.empty[String]
    +    val blockInputs = ArrayBuffer.empty[Any]
    --- End diff --
    
    shall we make the type `JavaCode` instead of `Any`?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90723/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL][WIP] Add API for handling expr...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r185762835
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,102 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), exprValues = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A block of java code which involves some expressions represented by `ExprValue`.
    + */
    +trait Block extends JavaCode {
    +  def exprValues: Seq[Any]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    --- End diff --
    
    chat about adding `checkLengths(args)`?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2832/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by maropu <gi...@git.apache.org>.
Github user maropu commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Thanks for cc. I'll check tonight.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/3294/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by ueshin <gi...@git.apache.org>.
Github user ueshin commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186683015
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeGenerator.scala ---
    @@ -56,19 +57,19 @@ import org.apache.spark.util.{ParentClassLoader, Utils}
      * @param value A term for a (possibly primitive) value of the result of the evaluation. Not
      *              valid if `isNull` is set to `true`.
      */
    -case class ExprCode(var code: String, var isNull: ExprValue, var value: ExprValue)
    +case class ExprCode(var code: Block, var isNull: ExprValue, var value: ExprValue)
     
     object ExprCode {
       def apply(isNull: ExprValue, value: ExprValue): ExprCode = {
    -    ExprCode(code = "", isNull, value)
    +    ExprCode(code = code"", isNull, value)
    --- End diff --
    
    `EmptyBlock`?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by rednaxelafx <gi...@git.apache.org>.
Github user rednaxelafx commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189785968
  
    --- Diff: sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeBlockSuite.scala ---
    @@ -23,12 +23,20 @@ import org.apache.spark.sql.types.{BooleanType, IntegerType}
     
     class CodeBlockSuite extends SparkFunSuite {
     
    -  test("Block can interpolate string and ExprValue inputs") {
    +  test("Block interpolates string and ExprValue inputs") {
         val isNull = JavaCode.isNullVariable("expr1_isNull")
    -    val code = code"boolean ${isNull} = ${JavaCode.defaultLiteral(BooleanType)};"
    +    val stringLiteral = "false"
    +    val code = code"boolean $isNull = $stringLiteral;"
         assert(code.toString == "boolean expr1_isNull = false;")
       }
     
    +  test("Literals are folded into string code parts instead of block inputs") {
    --- End diff --
    
    Great, I like it!


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    @rednaxelafx Thanks for your comments! Yes, #19813 is should be the first use case. However, I'd like to first have follow up for some points we discussed so far, e.g., preventing string interpolation, manipulating code API, etc.. So this API can be more easily to be used.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90059 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90059/testReport)** for PR 21193 at commit [`5fe425c`](https://github.com/apache/spark/commit/5fe425c2d2837f00bdfe9ba5e6f446829fba32c1).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90176 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90176/testReport)** for PR 21193 at commit [`d138ee0`](https://github.com/apache/spark/commit/d138ee05541bc1976442c5f1170ba7a7f3f5114c).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r187058840
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala ---
    @@ -100,17 +101,18 @@ abstract class Expression extends TreeNode[Expression] {
         ctx.subExprEliminationExprs.get(this).map { subExprState =>
           // This expression is repeated which means that the code to evaluate it has already been added
           // as a function before. In that case, we just re-use it.
    -      ExprCode(ctx.registerComment(this.toString), subExprState.isNull, subExprState.value)
    +      ExprCode(code"${ctx.registerComment(this.toString)}", subExprState.isNull,
    --- End diff --
    
    Done.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2851/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90244 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90244/testReport)** for PR 21193 at commit [`ee9a4c0`](https://github.com/apache/spark/commit/ee9a4c03a2da8a01f588c1283500f3412e356875).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/3299/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186250552
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    --- End diff --
    
    Currently we have many usage like"
    ```
      s"""
        | val isNull = false;
        | ...
       """.stripMargin
    ```
    
    To enable this usage with `Block`, so we need to make `Block` with `stripMargin` API. 


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90260 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90260/testReport)** for PR 21193 at commit [`2b30654`](https://github.com/apache/spark/commit/2b30654bc50a39a8af597df68ba288280299defe).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90355 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90355/testReport)** for PR 21193 at commit [`aff411b`](https://github.com/apache/spark/commit/aff411bbf21f484c20588997d98682f2ec77191a).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    retest this please.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186621034
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,19 +114,128 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    --- End diff --
    
    Note that we should not do `distinct` on `blockInputs` because the length of `codeParts` and `blockInputs` must be matched.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r188954468
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Set(e)
    +      case _ => Set.empty[ExprValue]
    +    }.toSet
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +    buf append StringContext.treatEscapes(strings.next)
    +    while (strings.hasNext) {
    +      buf append inputs.next
    +      buf append StringContext.treatEscapes(strings.next)
    +    }
    +    buf.toString
    +  }
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(Seq(this, c))
    +    case b: Blocks => Blocks(Seq(this) ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +case class Blocks(blocks: Seq[Block]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = blocks.flatMap(_.exprValues).toSet
    --- End diff --
    
    It's required. Otherwise a type mismatch compile error.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90726/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189430164
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    --- End diff --
    
    I think this is a good idea. We should not change literal args. Keeping them in block inputs seems meaningless.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90931 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90931/testReport)** for PR 21193 at commit [`96c594a`](https://github.com/apache/spark/commit/96c594a26af966d406f6c6f6786e486c0e04847d).
     * This patch **fails due to an unknown error code, -9**.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[JavaCode]) extends Block `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by mgaido91 <gi...@git.apache.org>.
Github user mgaido91 commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r188950520
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = {
    +    blockInputs.flatMap {
    --- End diff --
    
    what about `foldLeft(Set.empty[ExprValue]) { ... }`?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by hvanhovell <gi...@git.apache.org>.
Github user hvanhovell commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186361480
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +  implicit def blockToString(block: Block): String = block.toString
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    --- End diff --
    
    +100000


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90414 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90414/testReport)** for PR 21193 at commit [`72faac3`](https://github.com/apache/spark/commit/72faac3209beb8bc38938f8788de6338e9b2ffae).
     * This patch **fails Spark unit tests**.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test FAILed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/90414/
    Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by maropu <gi...@git.apache.org>.
Github user maropu commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186247501
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -112,6 +112,112 @@ object JavaCode {
       def isNullExpression(code: String): SimpleExprValue = {
         expression(code, BooleanType)
       }
    +
    +  def block(code: String): Block = {
    +    CodeBlock(codeParts = Seq(code), blockInputs = Seq.empty)
    +  }
    +}
    +
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // This will be called during string interpolation.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c)
    +    case _ => code
    +  }
    +
    +  var _marginChar: Option[Char] = None
    +
    +  def stripMargin(c: Char): this.type = {
    --- End diff --
    
    We need to expose this function? If we could hide this stripping operation inside `Block`, I think it would be nice.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2943/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by cloud-fan <gi...@git.apache.org>.
Github user cloud-fan commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189259323
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,115 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Set[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  def length: Int = toString.length
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Set(e)
    +      case _ => Set.empty[ExprValue]
    +    }.toSet
    +  }
    +
    +  override def code: String = {
    +    val strings = codeParts.iterator
    +    val inputs = blockInputs.iterator
    +    val buf = new StringBuilder(Block.CODE_BLOCK_BUFFER_LENGTH)
    +    buf append StringContext.treatEscapes(strings.next)
    +    while (strings.hasNext) {
    +      buf append inputs.next
    +      buf append StringContext.treatEscapes(strings.next)
    +    }
    +    buf.toString
    +  }
    +
    +  override def + (other: Block): Block = other match {
    +    case c: CodeBlock => Blocks(Seq(this, c))
    +    case b: Blocks => Blocks(Seq(this) ++ b.blocks)
    +    case EmptyBlock => this
    +  }
    +}
    +
    +case class Blocks(blocks: Seq[Block]) extends Block {
    +  override lazy val exprValues: Set[ExprValue] = blocks.flatMap(_.exprValues).toSet
    +  override def code: String = blocks.map(_.toString).mkString("\n")
    --- End diff --
    
    it depends on how we would implement code rewriting later. If we wanna keep `JavaCode` immutable, then `lazy val` is OK here, because once we rewrite the code, we will have a new `Blocks`.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186679287
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,6 +114,113 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    --- End diff --
    
    They are `ExprValues` in the inputs. Inputs may contain other than `ExprValues`, e.g. other blocks, literals...


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90251 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90251/testReport)** for PR 21193 at commit [`5945c15`](https://github.com/apache/spark/commit/5945c156b2df7aa2f61df57d86f07279b6959e2a).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90244 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90244/testReport)** for PR 21193 at commit [`ee9a4c0`](https://github.com/apache/spark/commit/ee9a4c03a2da8a01f588c1283500f3412e356875).
     * This patch passes all tests.
     * This patch merges cleanly.
     * This patch adds no public classes.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90120 has finished](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90120/testReport)** for PR 21193 at commit [`00bef6b`](https://github.com/apache/spark/commit/00bef6bb2559d93e68266d2605ef4403f4d8d2af).
     * This patch **fails Spark unit tests**.
     * This patch merges cleanly.
     * This patch adds the following public classes _(experimental)_:
      * `case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block `


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by rednaxelafx <gi...@git.apache.org>.
Github user rednaxelafx commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r189229566
  
    --- Diff: sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/codegen/CodeBlockSuite.scala ---
    @@ -0,0 +1,130 @@
    +/*
    + * 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.spark.sql.catalyst.expressions.codegen
    +
    +import org.apache.spark.SparkFunSuite
    +import org.apache.spark.sql.catalyst.expressions.codegen.Block._
    +import org.apache.spark.sql.types.{BooleanType, IntegerType}
    +
    +class CodeBlockSuite extends SparkFunSuite {
    +
    +  test("Block can interpolate string and ExprValue inputs") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val code = code"boolean ${isNull} = ${JavaCode.defaultLiteral(BooleanType)};"
    +    assert(code.toString == "boolean expr1_isNull = false;")
    +  }
    +
    +  test("Block.stripMargin") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val value = JavaCode.variable("expr1", IntegerType)
    +    val code1 =
    +      code"""
    +           |boolean $isNull = false;
    +           |int $value = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin
    +    val expected =
    +      s"""
    +        |boolean expr1_isNull = false;
    +        |int expr1 = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin.trim
    +    assert(code1.toString == expected)
    +
    +    val code2 =
    +      code"""
    +           >boolean $isNull = false;
    +           >int $value = ${JavaCode.defaultLiteral(IntegerType)};""".stripMargin('>')
    +    assert(code2.toString == expected)
    +  }
    +
    +  test("Block can capture input expr values") {
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val value = JavaCode.variable("expr1", IntegerType)
    +    val code =
    +      code"""
    +           |boolean $isNull = false;
    +           |int $value = -1;
    +          """.stripMargin
    +    val exprValues = code.exprValues
    +    assert(exprValues.size == 2)
    +    assert(exprValues === Set(value, isNull))
    +  }
    +
    +  test("concatenate blocks") {
    +    val isNull1 = JavaCode.isNullVariable("expr1_isNull")
    +    val value1 = JavaCode.variable("expr1", IntegerType)
    +    val isNull2 = JavaCode.isNullVariable("expr2_isNull")
    +    val value2 = JavaCode.variable("expr2", IntegerType)
    +    val literal = JavaCode.literal("100", IntegerType)
    +
    +    val code =
    +      code"""
    +           |boolean $isNull1 = false;
    +           |int $value1 = -1;""".stripMargin +
    +      code"""
    +           |boolean $isNull2 = true;
    +           |int $value2 = $literal;""".stripMargin
    +
    +    val expected =
    +      """
    +       |boolean expr1_isNull = false;
    +       |int expr1 = -1;
    +       |boolean expr2_isNull = true;
    +       |int expr2 = 100;""".stripMargin.trim
    +
    +    assert(code.toString == expected)
    +
    +    val exprValues = code.exprValues
    +    assert(exprValues.size == 5)
    +    assert(exprValues === Set(isNull1, value1, isNull2, value2, literal))
    +  }
    +
    +  test("Throws exception when interpolating unexcepted object in code block") {
    +    val obj = TestClass(100)
    +    val e = intercept[IllegalArgumentException] {
    +      code"$obj"
    +    }
    +    assert(e.getMessage().contains(s"Can not interpolate ${obj.getClass.getName}"))
    +  }
    +
    +  test("replace expr values in code block") {
    +    val statement = JavaCode.expression("1 + 1", IntegerType)
    +    val isNull = JavaCode.isNullVariable("expr1_isNull")
    +    val exprInFunc = JavaCode.variable("expr1", IntegerType)
    +
    +    val code =
    +      code"""
    +           |callFunc(int $statement) {
    +           |  boolean $isNull = false;
    +           |  int $exprInFunc = $statement + 1;
    +           |}""".stripMargin
    +
    +    val aliasedParam = JavaCode.variable("aliased", statement.javaType)
    +    val aliasedInputs = code.asInstanceOf[CodeBlock].blockInputs.map {
    +      case _: SimpleExprValue => aliasedParam
    +      case other => other
    +    }
    +    val aliasedCode = CodeBlock(code.asInstanceOf[CodeBlock].codeParts, aliasedInputs).stripMargin
    --- End diff --
    
    +1 with @cloud-fan 's comment above. The current demonstrated way of manipulating code is less than ideal. But at least this PR does provide a good carrier for us to build the future code manipulation API so it's good enough for now.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186627026
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    --- End diff --
    
    Btw, I'm working to remove this manual reference. But it might increase code diff a lot. It's better to leave it to follow-up.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186679356
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Expression.scala ---
    @@ -119,7 +121,7 @@ abstract class Expression extends TreeNode[Expression] {
     
       private def reduceCodeSize(ctx: CodegenContext, eval: ExprCode): Unit = {
         // TODO: support whole stage codegen too
    -    if (eval.code.trim.length > 1024 && ctx.INPUT_ROW != null && ctx.currentVars == null) {
    +    if (eval.code.toString.length > 1024 && ctx.INPUT_ROW != null && ctx.currentVars == null) {
    --- End diff --
    
    Sure. Good idea.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186618580
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/codegen/javaCode.scala ---
    @@ -114,19 +114,128 @@ object JavaCode {
       }
     }
     
    +/**
    + * A trait representing a block of java code.
    + */
    +trait Block extends JavaCode {
    +
    +  // The expressions to be evaluated inside this block.
    +  def exprValues: Seq[ExprValue]
    +
    +  // Returns java code string for this code block.
    +  override def toString: String = _marginChar match {
    +    case Some(c) => code.stripMargin(c).trim
    +    case _ => code.trim
    +  }
    +
    +  // The leading prefix that should be stripped from each line.
    +  // By default we strip blanks or control characters followed by '|' from the line.
    +  var _marginChar: Option[Char] = Some('|')
    +
    +  def stripMargin(c: Char): this.type = {
    +    _marginChar = Some(c)
    +    this
    +  }
    +
    +  def stripMargin: this.type = {
    +    _marginChar = Some('|')
    +    this
    +  }
    +
    +  // Concatenates this block with other block.
    +  def + (other: Block): Block
    +}
    +
    +object Block {
    +
    +  val CODE_BLOCK_BUFFER_LENGTH: Int = 512
    +
    +  implicit def blocksToBlock(blocks: Seq[Block]): Block = Blocks(blocks)
    +
    +  implicit class BlockHelper(val sc: StringContext) extends AnyVal {
    +    def code(args: Any*): Block = {
    +      sc.checkLengths(args)
    +      if (sc.parts.length == 0) {
    +        EmptyBlock
    +      } else {
    +        args.foreach {
    +          case _: ExprValue =>
    +          case _: Int | _: Long | _: Float | _: Double | _: String =>
    +          case _: Block =>
    +          case other => throw new IllegalArgumentException(
    +            s"Can not interpolate ${other.getClass.getName} into code block.")
    +        }
    +        CodeBlock(sc.parts, args)
    +      }
    +    }
    +  }
    +}
    +
    +/**
    + * A block of java code. Including a sequence of code parts and some inputs to this block.
    + * The actual java code is generated by embedding the inputs into the code parts.
    + */
    +case class CodeBlock(codeParts: Seq[String], blockInputs: Seq[Any]) extends Block {
    +  override def exprValues: Seq[ExprValue] = {
    +    blockInputs.flatMap {
    +      case b: Block => b.exprValues
    +      case e: ExprValue => Seq(e)
    --- End diff --
    
    It's possible. A distinct helps here?


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark pull request #21193: [SPARK-24121][SQL] Add API for handling expressio...

Posted by hvanhovell <gi...@git.apache.org>.
Github user hvanhovell commented on a diff in the pull request:

    https://github.com/apache/spark/pull/21193#discussion_r186644321
  
    --- Diff: sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala ---
    @@ -623,8 +624,14 @@ case class Cast(child: Expression, dataType: DataType, timeZoneId: Option[String
       override def doGenCode(ctx: CodegenContext, ev: ExprCode): ExprCode = {
         val eval = child.genCode(ctx)
         val nullSafeCast = nullSafeCastFunction(child.dataType, dataType, ctx)
    +
    +    // Below the code comment including `eval.value` and `eval.isNull` is a trick. It makes the two
    +    // expr values are referred by this code block.
         ev.copy(code = eval.code +
    -      castCode(ctx, eval.value, eval.isNull, ev.value, ev.isNull, dataType, nullSafeCast))
    +      code"""
    +        // Cast from ${eval.value}, ${eval.isNull}
    --- End diff --
    
    In this particular case I think we should not use the string interpolator. My preferred end game would be that the `CodeGenerator` functions will just return blocks (or something like that) instead of an opaque strings. That is definitely something we should do in a follow up, can we for now just manually create the block?
    
    That being said, if we are going to pick then I'd strong prefer option 2. I think option 1 is much harder to work with, and is also potentially buggy (what happens if you get the order wrong).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Test PASSed.
    Refer to this link for build results (access rights to CI server needed): 
    https://amplab.cs.berkeley.edu/jenkins//job/testing-k8s-prb-make-spark-distribution/2876/
    Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by viirya <gi...@git.apache.org>.
Github user viirya commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Thanks @maropu @kiszk @mgaido91 
    
    @mgaido91 I overlooked it. Just replied you.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test FAILed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90004 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90004/testReport)** for PR 21193 at commit [`369242a`](https://github.com/apache/spark/commit/369242a017fd503e21e076cf010f3935d162b90b).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by AmplabJenkins <gi...@git.apache.org>.
Github user AmplabJenkins commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    Merged build finished. Test PASSed.


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL][WIP] Add API for handling expression ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90135 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90135/testReport)** for PR 21193 at commit [`00bef6b`](https://github.com/apache/spark/commit/00bef6bb2559d93e68266d2605ef4403f4d8d2af).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org


[GitHub] spark issue #21193: [SPARK-24121][SQL] Add API for handling expression code ...

Posted by SparkQA <gi...@git.apache.org>.
Github user SparkQA commented on the issue:

    https://github.com/apache/spark/pull/21193
  
    **[Test build #90833 has started](https://amplab.cs.berkeley.edu/jenkins/job/SparkPullRequestBuilder/90833/testReport)** for PR 21193 at commit [`2ca9741`](https://github.com/apache/spark/commit/2ca974190527f3ac1ade1feddf9bd2b953fabdd7).


---

---------------------------------------------------------------------
To unsubscribe, e-mail: reviews-unsubscribe@spark.apache.org
For additional commands, e-mail: reviews-help@spark.apache.org