Anika Kelhanka created SPARK-59629:
--------------------------------------

             Summary: CSV Reader, mapping columnNameOfCorruptRecord does not 
honor spark.sql.caseSensitive=false
                 Key: SPARK-59629
                 URL: https://issues.apache.org/jira/browse/SPARK-59629
             Project: Spark
          Issue Type: Bug
          Components: Bug
    Affects Versions: 4.1.2, 3.5.3
            Reporter: Anika Kelhanka


The Spark CSV reader resolves \{{columnNameOfCorruptRecord}} against the
user-supplied schema using exact string equality, and 
\{{spark.sql.caseSensitive}}
is not honoured. When the schema declares the corrupt-record field in a
different case to the option value, the reader does not fail — it silently
returns \{{NULL}} in that column and discards the malformed record.

XML was made to honour \{{spark.sql.caseSensitive}} in 4.0.0 (SPARK-45844), and
SPARK-46954 extracted the lookup into
{\{StructType.getFieldIndexCaseInsensitive}}. The CSV corrupt-record path still
uses the case-sensitive \{{getFieldIndex}}.

Within the CSV reader, header-to-schema matching already honours
{\{spark.sql.caseSensitive}} (SPARK-23786); the corrupt-record name does not.



h2. Reproducer

{code:scala}
spark.conf.set("spark.sql.caseSensitive", "false")   // the default

// id,name
// 1,Alice
// invalid,Bob

val schema = new StructType()
  .add("id", IntegerType)
  .add("name", StringType)
  .add("_CORRUPT_RECORD", StringType)   // option default is "_corrupt_record"

spark.read.option("header", "true").option("mode", "PERMISSIVE")
  .schema(schema).csv(path).show(false)
{code}

*Expected* — and what you get if the field is spelled \{{_corrupt_record}}:

{noformat}
|1   |Alice|NULL       |
|NULL|Bob  |invalid,Bob|
{noformat}

*Actual*:

{noformat}
|1   |Alice|NULL|
|NULL|Bob  |NULL|
{noformat}

The bad row is still detected, but \{{invalid,Bob}} is discarded. The only 
signal
is a WARN from \{{CSVHeaderChecker}} about the column count. Reproduced on 3.5.3
and 4.1.2.

h2. Suggested fix

Match \{{columnNameOfCorruptRecord}} case-insensitively. Or, if case-sensitive
matching must be preserved for any reason, then
{\{verifyColumnNameOfCorruptRecord}} should throw an \{{AnalysisException}} 
when a
field matches case-insensitively but not exactly. Failing at analysis time is
strictly better than silently returning NULL.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to