public class JsonLoaderImpl extends Object implements JsonLoader, ErrorFactory
ResultSetLoader abstraction. Uses the listener-based
JsonStructureParser to walk the JSON tree in a "streaming"
fashion, calling events which this class turns into vector write
operations. Listeners handle options such as all text mode
vs. type-specific parsing. Think of this implementation as a
listener-based recursive-descent parser.
The JSON loader mechanism runs two state machines intertwined:
JsonStructureParser.When a field first contains null or an empty list, "null deferral" logic adds a special state that "waits" for an actual data type to present itself. This allows the parser to handle a series of nulls, empty arrays, or arrays of nulls (when using lists) at the start of the file. If no type ever appears, the loader forces the field to "text mode", hoping that the field is scalar.
To slightly help the null case, if the projection list shows that a column must be an array or a map, then that information is used to guess the type of a null column.
The code includes a prototype mechanism to provide type hints for columns. At present, it is just used to handle nulls that are never "resolved" by the end of a batch. Would be much better to use the hints (or a full schema) to avoid the huge mass of code needed to handle nulls.
JsonReader class used in Drill versions 1.17
and before. Compared with the previous version, this implementation:
UserException objects, complete with context
information, rather than as generic Java exception as in the prior version.JsonOptions class.readBatch() until it returns
false. Errors are reported out-of-band via an exception.ResultSetLoader rather than
the JSON loader. This class always creates a vector writer, but the result set
loader will return a dummy (no-op) writer for non-projected columns.SELECT COUNT(*) queries.| Modifier and Type | Class and Description |
|---|---|
static class |
JsonLoaderImpl.JsonLoaderBuilder |
JSON_LITERAL_MODE, JSON_MODE, JSON_TEXT_MODE, JSON_TYPED_MODE| Modifier | Constructor and Description |
|---|---|
protected |
JsonLoaderImpl(JsonLoaderImpl.JsonLoaderBuilder builder) |
| Modifier and Type | Method and Description |
|---|---|
void |
addNullMarker(org.apache.drill.exec.store.easy.json.loader.JsonLoaderImpl.NullTypeMarker marker) |
UserException |
buildError(ColumnMetadata schema,
UserException.Builder builder) |
protected UserException |
buildError(UserException.Builder builder) |
void |
close()
Releases resources held by this class including the input stream.
|
UserException |
dataConversionError(ColumnMetadata schema,
String tokenType,
String value) |
protected void |
endBatch()
Finish reading a batch of data.
|
FieldFactory |
fieldFactory() |
RuntimeException |
ioException(IOException e)
I/O error reported from the Jackson JSON parser.
|
RuntimeException |
messageParseError(MessageParser.MessageContextException e)
Parser is configured to find a message tag within the JSON
and a syntax occurred when following the data path.
|
UserException |
nullDisallowedError(ColumnMetadata schema) |
JsonLoaderOptions |
options() |
RuntimeException |
parseError(String msg,
com.fasterxml.jackson.core.JsonParseException e)
The Jackson JSON parser failed to start on the input file.
|
JsonStructureParser |
parser() |
boolean |
readBatch()
Read one record of data.
|
void |
removeNullMarker(org.apache.drill.exec.store.easy.json.loader.JsonLoaderImpl.NullTypeMarker marker) |
RuntimeException |
structureError(String msg)
General structure-level error: something very unusual occurred
in the JSON that passed Jackson, but failed in the structure
parser.
|
RuntimeException |
syntaxError(com.fasterxml.jackson.core.JsonParseException e)
The Jackson parser reported a syntax error.
|
RuntimeException |
syntaxError(com.fasterxml.jackson.core.JsonToken token)
Received an unexpected token.
|
UserException |
typeConversionError(ColumnMetadata schema,
String tokenType) |
UserException |
typeConversionError(ColumnMetadata schema,
ValueDef valueDef) |
RuntimeException |
typeError(UnsupportedConversionError e)
The Jackson parser reported an error when trying to convert
a value to a specific type.
|
RuntimeException |
unrecoverableError()
Error recovery is on, the structure parser tried to recover, but
encountered too many other errors and gave up.
|
UserException |
unsupportedJsonTypeException(String key,
ValueDef.JsonType jsonType) |
UserException |
unsupportedType(ColumnMetadata schema) |
protected JsonLoaderImpl(JsonLoaderImpl.JsonLoaderBuilder builder)
public JsonLoaderOptions options()
public JsonStructureParser parser()
public FieldFactory fieldFactory()
public boolean readBatch()
JsonLoaderreadBatch in interface JsonLoadertrue if a record was loaded, false if EOF.public void addNullMarker(org.apache.drill.exec.store.easy.json.loader.JsonLoaderImpl.NullTypeMarker marker)
public void removeNullMarker(org.apache.drill.exec.store.easy.json.loader.JsonLoaderImpl.NullTypeMarker marker)
protected void endBatch()
This choices is not perfect. Switching to text mode means results will vary from run to run depending on the order that we see empty and non-empty values for this column. Plus, since the system is distributed, the decision made here may conflict with that made in some other fragment.
The only real solution is for the user to provide a schema.
Bottom line: the user is responsible for not giving Drill ambiguous data that would require Drill to predict the future.
public void close()
JsonLoaderclose in interface JsonLoaderpublic RuntimeException parseError(String msg, com.fasterxml.jackson.core.JsonParseException e)
ErrorFactoryparseError in interface ErrorFactorypublic RuntimeException ioException(IOException e)
ErrorFactoryioException in interface ErrorFactorypublic RuntimeException structureError(String msg)
ErrorFactorystructureError in interface ErrorFactorypublic RuntimeException syntaxError(com.fasterxml.jackson.core.JsonParseException e)
ErrorFactorysyntaxError in interface ErrorFactorypublic RuntimeException typeError(UnsupportedConversionError e)
ErrorFactorytypeError in interface ErrorFactorypublic RuntimeException syntaxError(com.fasterxml.jackson.core.JsonToken token)
ErrorFactorysyntaxError in interface ErrorFactorypublic RuntimeException unrecoverableError()
ErrorFactoryunrecoverableError in interface ErrorFactorypublic UserException typeConversionError(ColumnMetadata schema, ValueDef valueDef)
public UserException typeConversionError(ColumnMetadata schema, String tokenType)
public UserException dataConversionError(ColumnMetadata schema, String tokenType, String value)
public UserException nullDisallowedError(ColumnMetadata schema)
public UserException unsupportedType(ColumnMetadata schema)
public UserException unsupportedJsonTypeException(String key, ValueDef.JsonType jsonType)
public RuntimeException messageParseError(MessageParser.MessageContextException e)
ErrorFactorymessageParseError in interface ErrorFactorypublic UserException buildError(ColumnMetadata schema, UserException.Builder builder)
protected UserException buildError(UserException.Builder builder)
Copyright © 2021 The Apache Software Foundation. All rights reserved.