av9ash/GitBugs huggingface dataset:
Bug: Cannot alter table with locale tr
Status: Open | Priority: Major | Resolution: 
Created: 26/Aug/22 01:37
Affects Version/s: 3.4.0

How to reproduce this issue:
{code:scala}
  test("Test update stats with locale tr") {
    withSQLConf(SQLConf.CASE_SENSITIVE.key -> "true",
      SQLConf.AUTO_SIZE_UPDATE_ENABLED.key -> "true") {
      withLocale("tr") {
        val tabName = "tAb_I"
        withTable(tabName) {
          sql(s"CREATE TABLE $tabName(col_I int)")
          sql(s"INSERT OVERWRITE TABLE $tabName SELECT 1")
        }
      }
    }
  }
{code}

Error:
{noformat}
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: [tab_ı]: is not a valid table name
	at org.apache.hadoop.hive.ql.metadata.Table.checkValidity(Table.java:192)
	at org.apache.hadoop.hive.ql.metadata.Hive.alterTable(Hive.java:623)
	at org.apache.hadoop.hive.ql.metadata.Hive.alterTable(Hive.java:612)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
{noformat}
Bug: Incorrect value in the error message of NUMERIC_VALUE_OUT_OF_RANGE
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 24/Aug/22 19:36
Affects Version/s: 3.4.0

The example below demonstrates the issue:
{code:sql}
spark-sql> select cast(interval '10.123' second as decimal(1, 0));
[NUMERIC_VALUE_OUT_OF_RANGE] 0.000010 cannot be represented as Decimal(1, 0). If necessary set "spark.sql.ansi.enabled" to "false" to bypass this error.
{code}

The value 0.000010 is not related to 10.123.
Bug:  Send TaskEnd event when task failed with NotSerializableException or TaskOutputFileAlreadyExistException to release executors for dynamic allocation 
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 16/Aug/22 02:13
Affects Version/s: 3.3.0

We found if task failed with NotSerializableException or TaskOutputFileAlreadyExistException, wont send TaskEnd event, and this will cause dynamic allocation not release executor normally.
Bug: Delay onDisconnected to enable Driver receives ExecutorExitCode
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 03/Aug/22 01:19
Affects Version/s: 3.4.0

There are two methods to detect executor loss. First, when RPC fails, the function {{onDisconnected}} will be triggered. Second, when executor exits with ExecutorExitCode, the exit code will be passed from ExecutorRunner to Driver. These two methods may categorize same cases into different conclusions. We hope to categorize the ExecutorLossReason by ExecutorExitCode. This PR aims to make sure Driver receives ExecutorExitCode before onDisconnected is called.
Bug: Sorting of at least Decimal(20, 2) fails for some values near the max.
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 15/Aug/22 20:02
Affects Version/s: 3.2.0

I have been doing some testing with Decimal values for the RAPIDS Accelerator for Apache Spark. I have been trying to add in new corner cases and when I tried to enable the maximum supported value for a sort I started to get failures.  On closer inspection it looks like the CPU is sorting things incorrectly.  Specifically anything that is "999999999999999999.50" or above is placed as a chunk in the wrong location in the outputs.

 In local mode with 12 tasks.
{code:java}
spark.read.parquet("input.parquet").orderBy(col("a")).collect.foreach(System.err.println) {code}
 

Here you will notice that the last entry printed is {{[999999999999999999.49]}}, and {{[999999999999999999.99]}} is near the top near {{[-999999999999999999.99]}}
Bug: Use error class NUMERIC_VALUE_OUT_OF_RANGE for overflow in decimal conversion
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 23/Aug/22 01:20
Affects Version/s: 3.4.0

Use error class NUMERIC_VALUE_OUT_OF_RANGE for overflow in decimal conversion, instead of the confusing error class `CANNOT_CHANGE_DECIMAL_PRECISION`.

Also, use `decimal.toPlainString` instead of `decimal.toDebugString` in the error message.
Bug: Run / Scala 2.13 build with SBT GA failed
Status: In Progress | Priority: Major | Resolution: 
Created: 22/Aug/22 12:00
Affects Version/s: 3.4.0

 
{code:java}
[error] /home/runner/work/spark/spark/sql/hive-thriftserver/src/main/java/org/apache/hive/service/auth/HttpAuthUtils.java:36:1:  error: package org.apache.http.protocol does not exist
1011[error] import org.apache.http.protocol.BasicHttpContext;
1012[error]                                ^
1013[error] /home/runner/work/spark/spark/sql/hive-thriftserver/src/main/java/org/apache/hive/service/auth/HttpAuthUtils.java:156:1:  error: cannot find symbol
1014[error]     private final HttpContext httpContext;
1015[error]                   ^  symbol:   class HttpContext
1016[error]   location: class HttpKerberosClientAction
1017[error] 3 errors {code}
 
 * [https://github.com/apache/spark/runs/7947684467?check_suite_focus=true]
 * [https://github.com/apache/spark/runs/7947300886?check_suite_focus=true]
 * [https://github.com/apache/spark/runs/7946453241?check_suite_focus=true]
 * [https://github.com/apache/spark/runs/7946444061?check_suite_focus=true]

 

But local run

 
{code:java}
./dev/change-scala-version.sh 2.13
./build/sbt -Pyarn -Pmesos -Pkubernetes -Pvolcano -Phive -Phive-thriftserver -Phadoop-cloud -Pkinesis-asl -Pdocker-integration-tests -Pkubernetes-integration-tests -Pspark-ganglia-lgpl -Pscala-2.13 compile Test/compile
 {code}
can pass. Maybe cache file corrupt ？
Bug: Error while creating dataset in Java spark-3.x using Encoders bean with Dense Vector. (Issue arises when updating spark from 2.4 to 3.x)
Status: Open | Priority: Major | Resolution: 
Created: 15/Aug/22 00:28
Affects Version/s: 3.1.2

Encountered a compatibility issue while upgrading spark from 2.4 to 3.x (also scala is upgraded from 2.11 to 2.12). 

This java code below used to work with spark 2.4 but when migrated to 3.x it gives the error (mentioned below) I have done my own research but couldn't find a solution or any related information.
 

 
{code:java|title=Code.java|borderStyle=solid}
public void test() {

final SparkSession spark = SparkSession.builder()
.appName("Test")
.getOrCreate();

DenseClass denseFactor1 = new DenseClass( new DenseVector( new double[]{0.13, 0.24}));

DenseClass denseFactor2 = new DenseClass( new DenseVector( new double[]{0.24, 0.32}));

final List<DenseClass> inputsNew = Arrays.asList(denseFactor1, denseFactor2);

final Dataset<DenseClass> denseVectorDf = spark.createDataset(inputsNew, Encoders.bean(DenseClass.class));

denseVectorDf.printSchema();
}


public static class DenseClass implements Serializable

{ private org.apache.spark.ml.linalg.DenseVector denseVector; }{code}
The error occurs while creating the dataset *denseVectorDf* .

Error
 
{noformat}
}}
{{org.apache.spark.sql.AnalysisException: Cannot up cast `denseVector` from struct<> to struct<type:tinyint,size:int,indices:array<int>,values:array<double>>.
The type path of the target object is:
 - field (class: "org.apache.spark.ml.linalg.DenseVector", name: "denseVector")
You can either add an explicit cast to the input data or choose a higher precision type of the field in the target object}}

{{{noformat}
I have tried to use _double_ instead of dense vector and it works just fine, but fails on using the dense vector with encoders bean.

 

StackOverflow link for the issue: [https://stackoverflow.com/questions/73313660/error-while-creating-dataset-in-java-spark-3-x-using-encoders-bean-with-dense-ve]
Bug: Dynamically merge File Splits
Status: In Progress | Priority: Major | Resolution: 
Created: 19/Aug/22 11:38
Affects Version/s: 3.4.0

We currently use maxPartitionBytes and minPartitionNum to split files and use openCostInBytes to merge file splits. But these are static configurations, and the same configuration does not work in all scenarios.

This PR attempts to dynamically merge file splits, taking into the concurrency while processing more data in one task.
Bug: Enhance EliminateSorts to support removing sorts via LocalLimit
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 12/Aug/22 02:27
Affects Version/s: 3.4.0

It seems we can remove Sort operator:
{code:scala}
    val projectPlan = testRelation.select($"a", $"b")
    val unnecessaryOrderByPlan = projectPlan.orderBy($"a".asc)
    val localLimitPlan = LocalLimit(Literal(2), unnecessaryOrderByPlan)
    val projectPlanB = testRelationB.select($"d")
    val joinPlan = localLimitPlan.join(projectPlanB, RightOuter).select($"a", $"d")
{code}
Bug: Output SparkThrowable to SQL golden files in JSON format
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 09/Aug/22 13:12
Affects Version/s: 3.4.0

Output content of SparkThrowable in the JSON format instead of plain text.

For instance, replace:

{code}
[INVALID_ARRAY_INDEX_IN_ELEMENT_AT] The index 5 is out of bounds. The array has 3 elements. Use `try_element_at` to tolerate accessing element at invalid index and return NULL instead. If necessary set "spark.sql.ansi.enabled" to "false" to bypass this error.
== SQL(line 1, position 8) ==
select element_at(array(1, 2, 3), 5)
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{code}

by

{code}
{"errorClass":"INVALID_ARRAY_INDEX_IN_ELEMENT_AT","messageParameters":["5","3","\"spark.sql.ansi.enabled\""],"queryContext":[{"objectType":"","objectName":"","startIndex":7,"stopIndex":35,"fragment":"element_at(array(1, 2, 3), 5"}]}
{code}
Bug: Task failure handlers should always run if the task failed
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 16/Aug/22 14:14
Affects Version/s: 3.3.0

Today, if a task body succeeds, but a task completion listener fails, task failure listeners are not called -- even tho the task has indeed failed at that point.

If a completion listener fails, and failure listeners were not previously invoked, we should invoke them before running the remaining completion listeners.

Such a change would increase the utility of task listeners, especially ones intended to assist with task cleanup. 

To give one arbitrary example, code like this appears at several places in the code (taken from {{executeTask}} method of FileFormatWriter.scala):
{code:java}
    try {
      Utils.tryWithSafeFinallyAndFailureCallbacks(block = {
        // Execute the task to write rows out and commit the task.
        dataWriter.writeWithIterator(iterator)
        dataWriter.commit()
      })(catchBlock = {
        // If there is an error, abort the task
        dataWriter.abort()
        logError(s"Job $jobId aborted.")
      }, finallyBlock = {
        dataWriter.close()
      })
    } catch {
      case e: FetchFailedException =>
        throw e
      case f: FileAlreadyExistsException if SQLConf.get.fastFailFileFormatOutput =>
        // If any output file to write already exists, it does not make sense to re-run this task.
        // We throw the exception and let Executor throw ExceptionFailure to abort the job.
        throw new TaskOutputFileAlreadyExistException(f)
      case t: Throwable =>
        throw QueryExecutionErrors.taskFailedWhileWritingRowsError(t)
    }{code}
If failure listeners were reliably called, the above idiom could potentially be factored out as two failure listeners plus a completion listener, and reused rather than duplicated.
Bug: Incorrect fragment of query context
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 18/Aug/22 07:37
Affects Version/s: 3.4.0

The query context contains just a part of fragment. The code below demonstrates the issue:

{code:scala}
    withSQLConf(SQLConf.ANSI_ENABLED.key -> "true") {
      val e = intercept[SparkArithmeticException] {
        sql("select 1 / 0").collect()
      }
      println("'" + e.getQueryContext()(0).fragment() + "'")
    }

'1 / '
{code}
Bug: Upgrade rocksdbjni to 7.4.5
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 04/Aug/22 04:39
Affects Version/s: 3.4.0

[https://github.com/facebook/rocksdb/releases/tag/v7.4.5]

 
{code:java}
Fix a bug starting in 7.4.0 in which some fsync operations might be skipped in a DB after any DropColumnFamily on that DB, until it is re-opened. This can lead to data loss on power loss. (For custom FileSystem implementations, this could lead to FSDirectory::Fsync or FSDirectory::Close after the first FSDirectory::Close; Also, valgrind could report call to close() with fd=-1.) {code}
 

Fixed a bug that caused data loss
Bug: Combines limits after projection
Status: In Progress | Priority: Major | Resolution: 
Created: 18/Aug/22 09:03
Affects Version/s: 3.2.2

`Dataset.show` will add extra `Limit` and `Projection` on top of the given logical plan. If the `Dataset` is already a limit job, this will introduce an extra shuffle phase. So we should combine the limit after projection. 

For example:
```scala
spark.sql("select * from spark.store_sales limit 10").show()
```

Before:
```
== Physical Plan ==
AdaptiveSparkPlan (12)
+- == Final Plan ==
   * Project (7)
   +- * GlobalLimit (6)
      +- ShuffleQueryStage (5), Statistics(sizeInBytes=185.6 KiB, rowCount=990)
         +- Exchange (4)
            +- * LocalLimit (3)
               +- * ColumnarToRow (2)
                  +- Scan parquet spark_catalog.spark.store_sales (1)
+- == Initial Plan ==
   Project (11)
   +- GlobalLimit (10)
      +- Exchange (9)
         +- LocalLimit (8)
            +- Scan parquet spark_catalog.spark.store_sales (1)
```

After:
```
== Physical Plan ==
CollectLimit (4)
+- * Project (3)
   +- * ColumnarToRow (2)
      +- Scan parquet spark_catalog.spark.store_sales (1)
```
Bug: Add DELTA_LENGTH_BYTE_ARRAY as a recognized standalone encoding in VectorizedColumnReader
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 17/Aug/22 17:13
Affects Version/s: 3.3.0

Even though https://issues.apache.org/jira/browse/SPARK-36879 added implementations for DELTA_BINARY_PACKED, DELTA_BYTE_ARRAY, and DELTA_LENGTH_BYTE_ARRAY encodings, only DELTA_BINARY_PACKED and DELTA_BYTE_ARRAY were added as top-level standalone column encodings, with DELTA_LENGTH_BYTE_ARRAY only being used in its capacity as a subcomponent of DELTA_BYTE_ARRAY (for the non-shared string/binary suffixes).

Even though there apparently aren't many writers of the standalone DELTA_LENGTH_BYTE_ARRAY encoding, it's part of the core Parquet spec: [https://parquet.apache.org/docs/file-format/data-pages/encodings/#delta-length-byte-array-delta_length_byte_array]–6 and could be more efficient for types of binary/string data that don't take good advantage of sharing common prefixes for incremental encoding.

The problem can be reproduced by trying to load one of the [https://github.com/apache/parquet-testing] files (delta_length_byte_array.parquet).
Bug: New SQL function: get()
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 16/Aug/22 23:20
Affects Version/s: 3.4.0

Currently, when accessing array element with invalid index under ANSI SQL mode, the error is like:
{quote}[INVALID_ARRAY_INDEX] The index -1 is out of bounds. The array has 3 elements. Use `try_element_at` and increase the array index by 1(the starting array index is 1 for `try_element_at`) to tolerate accessing element at invalid index and return NULL instead. If necessary set "spark.sql.ansi.enabled" to "false" to bypass this error.
{quote}
The provided solution is complicated. I suggest introducing a new method get() which always returns null on an invalid array index. This is from [https://docs.snowflake.com/en/sql-reference/functions/get.html.]

Since Spark's map access always returns null, let's don't support map type in the get method for now.
Bug: Add separate infra image for lint job
Status: In Progress | Priority: Major | Resolution: 
Created: 17/Aug/22 13:56
Affects Version/s: 3.4.0

To aovid the issue like [#37243 (comment)|https://github.com/apache/spark/pull/37243#issuecomment-1191422150] , we had some initial discussion, we'd better move infra image into lint image to make lint deps static and upgrade manually.
Bug: InMemoryFIleIndex caches filelists, how to solve the problem that multiple sparksessions run for a long time and filelists is out of sync
Status: Open | Priority: Major | Resolution: 
Created: 17/Aug/22 07:37
Affects Version/s: 3.4.0

For example, two Sparksessions A and B, query table T1 in A, write data to table T1 in B, and fail to query the data written by B in A. There are currently two approaches: 

1. Close SparkSession A and restart it 

2. Invoke Refresh table Command. 

These two practices are not feasible for business users who do not know when to operate. Frequent refresh affects the interaction performance. 

 

Ideally, it would support a centralized caching scheme such as RedIS, providing an extended interface that allows you to customize the Cache
Bug: ANSI mode: always return null on invalid access to map column
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 13/Aug/22 01:20
Affects Version/s: 3.4.0

Since https://github.com/apache/spark/pull/30386, Spark always throws an error on invalid access to a map column. There is no such syntax in the ANSI SQL standard since there is no Map type in it. There is a similar type `multiset` which returns null on non-existing element access.
Also, I investigated PostgreSQL/Snowflake/Biguqery and all of them returns null return on map(json) key not exists.
I suggest loosen the the syntax here. When users get the error, most of them will just use `try_element_at()` to get the same syntax or just turn off the ANSI SQL mode.
Bug: JDBC connection to Hive Metastore fails without first calling any .jdbc call
Status: Open | Priority: Major | Resolution: 
Created: 16/Aug/22 22:58
Affects Version/s: 3.3.0

Tested on pyspark==3.3.0. When talking to hive metastore with MySQL backend, I installed MySQL driver with spark.jars.packages, alongside with other necessary settings:

ss = SparkSession.builder.master('local[*]')\
    .config("spark.jars.packages", "org.apache.hadoop:hadoop-aws:3.3.3," +
        "org.apache.hadoop:hadoop-common:3.3.3,mysql:mysql-connector-java:8.0.30") \   .config("spark.executor.memory", "10g") \
    .config("spark.driver.memory", "10g") \
    .config("spark.memory.offHeap.enabled","true") \
    .config("spark.memory.offHeap.size","32g")  \
    .config("spark.hadoop.javax.jdo.option.ConnectionURL", "jdbc:mysql://localhost:3306/hive") \
    .config("spark.hadoop.javax.jdo.option.ConnectionUserName", "yyyy") \
    .config("spark.hadoop.javax.jdo.option.ConnectionPassword", "xxxx") \
    .config("spark.hadoop.javax.jdo.option.ConnectionDriverName", "com.mysql.cj.jdbc.Driver") \
    .config("spark.sql.hive.metastore.sharedPrefixes", "com.mysql") \
    .config("spark.sql.warehouse.dir", "s3://xxxx-yyyy/") \
    .enableHiveSupport() \
    .appName("hms_test").config(conf=conf).getOrCreate()

Now, if I just do: ss.sql("SHOW DATABASES;").show() I get a lot of errors, saying:

Unable to open a test connection to the given database. JDBC url = jdbc:mysql://localhost:3306/hive, username = yyyy. Terminating connection pool (set lazyInit to true if you expect to start your database after your app). Original Exception: ------
java.sql.SQLException: No suitable driver found for jdbc:mysql://localhost:3306/hive
    at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:702)
    at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:189)
    at com.jolbox.bonecp.BoneCP.obtainRawInternalConnection(BoneCP.java:361)
    at com.jolbox.bonecp.BoneCP.<init>(BoneCP.java:416)
...

However, if I do any "jdbc" read, even if the call ends up in an error, then the call to Hive Metastore seem to succeed without any issue:

try:
    _ = ss.read.format("jdbc") \
        .option("url", "jdbc:mysql://localhost:3306/hive") \
        .option("query", "SHOW TABLES;") \
        .option("driver", "com.mysql.cj.jdbc.Driver").load()
except:
    pass

ss.sql("SHOW DATABASES;").show() # this now works fine.
Bug: Add table name to Spark plan node in SparkUI
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 13/Aug/22 04:03
Affects Version/s: 3.4.0

[SPARK-39902|https://issues.apache.org/jira/browse/SPARK-39902] introduced `Scan#name()` API to expose the name of the TableScan in the `BatchScan` node in SparkUI.
However, a better suggestion was to use the `Table#name()`. Furthermore, we can also extract other useful information `Table` thus revert [SPARK-39902|https://issues.apache.org/jira/browse/SPARK-39902] and use `Table` to fetch relevant information.
Bug: is rocksdbjni required if not using streaming?
Status: Resolved | Priority: Major | Resolution: Duplicate
Created: 16/Aug/22 01:55
Affects Version/s: 3.3.0

my docker file is very big with pyspark

can i remove dis file below if i don't use 'spark streaming'?

35M     /usr/local/lib/python3.10/site-packages/pyspark/jars/rocksdbjni-6.20.3.jar
Bug: is breeze required if not using ML?
Status: Resolved | Priority: Major | Resolution: Duplicate
Created: 16/Aug/22 01:58
Affects Version/s: 3.3.0

my docker file is very big with pyspark

can i remove dis files below if i don't use 'ML'?

14M     /usr/local/lib/python3.10/site-packages/pyspark/jars/breeze_2.12-1.2.jar

5.9M    /usr/local/lib/python3.10/site-packages/pyspark/jars/spark-mllib_2.12-3.3.0.jar
Bug: NULL check in ArrayIntersect adds extraneous null from first param
Status: Resolved | Priority: Major | Resolution: Fixed
Created: 04/Aug/22 04:57
Affects Version/s: 3.3.0

This is very likely a regression from SPARK-36829.

When using {{array_intersect(a, b)}}, if the first parameter contains a {{NULL}} value and the second one does not, an extraneous {{NULL}} is present in the output. This also leads to {{array_intersect(a, b) != array_intersect(b, a)}} which is incorrect as set intersection should be commutative.

Example using PySpark:

{code:python}
>>> a = [1, 2, 3]
>>> b = [3, None, 5]
>>> df = spark.sparkContext.parallelize(data).toDF(["a","b"])
>>> df.show()
+---------+------------+
|        a|           b|
+---------+------------+
|[1, 2, 3]|[3, null, 5]|
+---------+------------+

>>> df.selectExpr("array_intersect(a,b)").show()
+---------------------+
|array_intersect(a, b)|
+---------------------+
|                  [3]|
+---------------------+

>>> df.selectExpr("array_intersect(b,a)").show()
+---------------------+
|array_intersect(b, a)|
+---------------------+
|            [3, null]|
+---------------------+
{code}

Note that in the first case, {{a}} does not contain a {{NULL}}, and the final output is correct: {{[3]}}. In the second case, since {{b}} does contain {{NULL}} and is now the first parameter.

The same behavior occurs in Scala when writing to Parquet:


{code:scala}
scala> val a = Array[java.lang.Integer](1, 2, null, 4)
a: Array[Integer] = Array(1, 2, null, 4)

scala> val b = Array[java.lang.Integer](4, 5, 6, 7)
b: Array[Integer] = Array(4, 5, 6, 7)

scala> val df = Seq((a, b)).toDF("a","b")
df: org.apache.spark.sql.DataFrame = [a: array<int>, b: array<int>]

scala> df.write.parquet("/tmp/simple.parquet")

scala> val df = spark.read.parquet("/tmp/simple.parquet")
df: org.apache.spark.sql.DataFrame = [a: array<int>, b: array<int>]

scala> df.show()
+---------------+------------+
|              a|           b|
+---------------+------------+
|[1, 2, null, 4]|[4, 5, 6, 7]|
+---------------+------------+


scala> df.selectExpr("array_intersect(a,b)").show()
+---------------------+
|array_intersect(a, b)|
+---------------------+
|            [null, 4]|
+---------------------+


scala> df.selectExpr("array_intersect(b,a)").show()
+---------------------+
|array_intersect(b, a)|
+---------------------+
|                  [4]|
+---------------------+
{code}