add jdbc mapping for postgres json#11913
Conversation
findepi
left a comment
There was a problem hiding this comment.
Thanks for the PR!
i have a couple of initial comments.
presto-postgresql/src/main/java/com/facebook/presto/plugin/postgresql/PostgreSqlClient.java
Outdated
Show resolved
Hide resolved
presto-base-jdbc/src/main/java/com/facebook/presto/plugin/jdbc/JdbcTypeHandle.java
Show resolved
Hide resolved
presto-postgresql/src/main/java/com/facebook/presto/plugin/postgresql/PostgreSqlClient.java
Outdated
Show resolved
Hide resolved
|
|
||
| public static ReadMapping jsonReadMapping() | ||
| { | ||
| return sliceReadMapping(JSON, (resultSet, columnIndex) -> utf8Slice(resultSet.getString(columnIndex))); |
There was a problem hiding this comment.
Looking at impl of = for JSON type (com.facebook.presto.operator.scalar.JsonOperators#equals), the value should be normalized. At least i would naively expect that {'a': 1, 'b': 2} = {'b': 2, 'a': 1}.
You probably need to do something like cast(some_varchar as json) is doing -- see com.facebook.presto.operator.scalar.JsonOperators#castFromVarchar. Probably the impl of the cast should be moved to utility method (somewhere) and reused.
@electrum json is not part of SPI. How do you think this should be addressed?
There was a problem hiding this comment.
We should be able to do this with TypeManager from ConnectorContext by resolving the CAST operator. This will require a small change to resolveOperator() (or adding a new method ... need to get input from @martint and others on this):
@Override
public MethodHandle resolveOperator(OperatorType operatorType, List<? extends Type> argumentTypes)
{
requireNonNull(functionRegistry, "functionRegistry is null");
Signature signature;
if (operatorType == OperatorType.CAST) {
checkArgument(argumentTypes.size() == 2, "CAST requires exactly two arguments");
signature = functionRegistry.getCoercion(argumentTypes.get(0), argumentTypes.get(1));
}
else {
signature = functionRegistry.resolveOperator(operatorType, argumentTypes);
}
return functionRegistry.getScalarFunctionImplementation(signature).getMethodHandle();
}
...ostgresql/src/test/java/com/facebook/presto/plugin/postgresql/TestPostgreSqlTypeMapping.java
Show resolved
Hide resolved
| case "jsonb": | ||
| case "json": | ||
| return Optional.of(jsonReadMapping()); | ||
| } |
There was a problem hiding this comment.
Will predicate-pushdown work correctly with json? We definitely need some tests for that.
There was a problem hiding this comment.
Can you please elaborate about this and add some references to similar tests ?
| /** | ||
| * The stack representation for JSON objects must have the keys in natural sorted order. | ||
| */ | ||
| public class JsonType |
There was a problem hiding this comment.
Is this a copy of com.facebook.presto.type.JsonType?
There was a problem hiding this comment.
yes. I copied it to spi to be aligned with other types
There was a problem hiding this comment.
@findepi
Somehow I need to merge them in away that json column will be of type com.facebook.presto.spi.type.JsonType
There was a problem hiding this comment.
done by extending com.facebook.presto.type.JsonType from com.facebook.presto.spi.type.JsonType and setting it's static JSON attribute to be com.facebook.presto.spi.type.JsonType.JSON
1289bcf to
3786c36
Compare
There was a problem hiding this comment.
We don't need the type instance to be in the SPI. Instead, compare like this:
type.getTypeSignature().getBase().equals(StandardTypes.JSON)There was a problem hiding this comment.
@electrum with JsonType not being in SPI, how can a connector know this is the correct runtime representation of the JsonType?
We certainly don't need to move JsonType to SPI, but we probably need to have some SPI factory method (or other SPI-level contract) for this.
There was a problem hiding this comment.
My first thought was to resolve the CAST operator using TypeManager. However, cast from varchar to json is actually different from the type constructor. Maybe we should add a method to lookup the type constructor?
@martint thoughts?
There was a problem hiding this comment.
Sill question -- why is the cast from varchar different from type constructor? Is't not intuitive.
There was a problem hiding this comment.
Casting a varchar to JSON results in a JSON string. The type constructor takes a JSON literal and is equivalent to json_parse(). I agree it's confusing, but my memory is that it works like that so that it's consistent when done recursively. For example, casting varchar and array(varchar) work the same way.
See here for a bit more detail: https://prestodb.io/docs/current/functions/json.html#json_parse
There was a problem hiding this comment.
I just put up a PR to allow resolving the type constructor: #12007
There was a problem hiding this comment.
@electrum Can you explain how can I use it from PostgreSqlClient ?
Currently I am using a copied version of jsonParse jsonParse(utf8Slice(resultSet.getString(columnIndex)))), since it's not exposed in the spi. Same for JsonType that is needed by com.facebook.presto.plugin.jdbc.ReadMapping
b9e746b to
61a22b7
Compare
61a22b7 to
09913cc
Compare
There was a problem hiding this comment.
@findepi
Any idea how can I use com.facebook.presto.operator.scalar.JsonFunctions#jsonParse from here without the need to duplicate code ?
Same for com.facebook.presto.type.JsonType that is needed by ReadMapping
794b218 to
3345ded
Compare
3345ded to
3decb18
Compare
3decb18 to
dae7d0e
Compare
…ative json/jsonb and presto native json
dae7d0e to
6a88688
Compare
relates to issue #11821
With this PR postgres native json & jsonb types are mapped to presto json type