Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,10 @@ class UnivocityParser(
// their positions in the data schema.
private val parsedSchema = if (options.columnPruning) requiredSchema else dataSchema

val tokenizer = {
val tokenizer: CsvParser = {
val parserSetting = options.asParserSettings
// When to-be-parsed schema is shorter than the to-be-read data schema, we let Univocity CSV
// parser select a sequence of fields for reading by their positions.
// if (options.columnPruning && requiredSchema.length < dataSchema.length) {
if (parsedSchema.length < dataSchema.length) {
parserSetting.selectIndexes(tokenIndexArr: _*)
}
Expand Down Expand Up @@ -203,7 +202,11 @@ class UnivocityParser(
}
}

private val doParse = if (options.columnPruning && requiredSchema.isEmpty) {
/**
* Parses a single CSV string and turns it into either one resulting row or no row (if the
* the record is malformed).
*/
val parse: String => Option[InternalRow] = if (options.columnPruning && requiredSchema.isEmpty) {
Comment thread
HyukjinKwon marked this conversation as resolved.
Outdated
// If `columnPruning` enabled and partition attributes scanned only,
// `schema` gets empty.
(_: String) => Some(InternalRow.empty)
Expand All @@ -212,12 +215,6 @@ class UnivocityParser(
(input: String) => convert(tokenizer.parseLine(input))
}

/**
* Parses a single CSV string and turns it into either one resulting row or no row (if the
* the record is malformed).
*/
def parse(input: String): Option[InternalRow] = doParse(input)

private val getToken = if (options.columnPruning) {
(tokens: Array[String], index: Int) => tokens(index)
} else {
Expand All @@ -232,18 +229,13 @@ class UnivocityParser(
new RuntimeException("Malformed CSV record"))
}

var checkedTokens = tokens
var badRecordException: Option[Throwable] = None
Comment thread
HyukjinKwon marked this conversation as resolved.
Outdated

if (tokens.length != parsedSchema.length) {
// If the number of tokens doesn't match the schema, we should treat it as a malformed record.
// However, we still have chance to parse some of the tokens, by adding extra null tokens in
// the tail if the number is smaller, or by dropping extra tokens if the number is larger.
checkedTokens = if (parsedSchema.length > tokens.length) {
tokens ++ new Array[String](parsedSchema.length - tokens.length)
} else {
tokens.take(parsedSchema.length)
}
// However, we still have chance to parse some of the tokens. It continues to parses the
// tokens normally and sets null when `ArrayIndexOutOfBoundsException` occurs for missing
// tokens.
badRecordException = Some(new RuntimeException("Malformed CSV record"))
}
// When the length of the returned tokens is identical to the length of the parsed schema,
Expand All @@ -255,15 +247,14 @@ class UnivocityParser(
var skipRow = false
while (i < requiredSchema.length) {
try {
if (!skipRow) {
if (skipRow) {
row.setNullAt(i)
} else {
row(i) = valueConverters(i).apply(getToken(tokens, i))
if (csvFilters.skipRow(row, i)) {
skipRow = true
}
}
if (skipRow) {
row.setNullAt(i)
}
} catch {
case NonFatal(e) =>
badRecordException = badRecordException.orElse(Some(e))
Expand Down