diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/json/JacksonParser.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/json/JacksonParser.scala index 13129d44fe0c..19e2c4228236 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/json/JacksonParser.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/json/JacksonParser.scala @@ -292,13 +292,8 @@ class JacksonParser( case _: StringType => (parser: JsonParser) => { // This must be enabled if we will retrieve the bytes directly from the raw content: - val includeSourceInLocation = JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION - val originalMask = if (includeSourceInLocation.enabledIn(parser.getFeatureMask)) { - 1 - } else { - 0 - } - parser.overrideStdFeatures(includeSourceInLocation.getMask, includeSourceInLocation.getMask) + val oldFeature = parser.getFeatureMask + parser.setFeatureMask(oldFeature | JsonParser.Feature.INCLUDE_SOURCE_IN_LOCATION.getMask) val result = parseJsonToken[UTF8String](parser, dataType) { case VALUE_STRING => UTF8String.fromString(parser.getText) @@ -344,7 +339,7 @@ class JacksonParser( } } // Reset back to the original configuration: - parser.overrideStdFeatures(includeSourceInLocation.getMask, originalMask) + parser.setFeatureMask(oldFeature) result } diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/json/JacksonParserSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/json/JacksonParserSuite.scala index 587e22e787b8..89cdd38a3e7b 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/json/JacksonParserSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/json/JacksonParserSuite.scala @@ -24,6 +24,19 @@ import org.apache.spark.sql.types.StructType import org.apache.spark.unsafe.types.UTF8String class JacksonParserSuite extends SparkFunSuite { + test("feature mask should remain unchanged") { + val options = new JSONOptions(Map.empty[String, String], "GMT", "") + val parser = new JacksonParser(StructType.fromDDL("a string"), options, false, Nil) + val input = """{"a": {"b": 1}}""".getBytes + // The creating function is usually called inside `parser.parse`, but we need the JSON parser + // here for testing purpose. + val jsonParser = options.buildJsonFactory().createParser(input) + val oldFeature = jsonParser.getFeatureMask + val result = parser.parse[Array[Byte]](input, (_, _) => jsonParser, UTF8String.fromBytes) + assert(result === Seq(InternalRow(UTF8String.fromString("""{"b": 1}""")))) + assert(jsonParser.getFeatureMask == oldFeature) + } + test("skipping rows using pushdown filters") { def check( input: String = """{"i":1, "s": "a"}""",