Skip to content

add jdbc mapping for postgres json#11913

Closed
guyco33 wants to merge 3 commits intoprestodb:masterfrom
guyco33:add_support_for_postgres_json
Closed

add jdbc mapping for postgres json#11913
guyco33 wants to merge 3 commits intoprestodb:masterfrom
guyco33:add_support_for_postgres_json

Conversation

@guyco33
Copy link
Contributor

@guyco33 guyco33 commented Nov 13, 2018

relates to issue #11821

With this PR postgres native json & jsonb types are mapped to presto json type

Copy link
Contributor

@findepi findepi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

i have a couple of initial comments.


public static ReadMapping jsonReadMapping()
{
return sliceReadMapping(JSON, (resultSet, columnIndex) -> utf8Slice(resultSet.getString(columnIndex)));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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();
}

case "jsonb":
case "json":
return Optional.of(jsonReadMapping());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will predicate-pushdown work correctly with json? We definitely need some tests for that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a copy of com.facebook.presto.type.JsonType?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. I copied it to spi to be aligned with other types

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@findepi
Somehow I need to merge them in away that json column will be of type com.facebook.presto.spi.type.JsonType

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

@guyco33 guyco33 force-pushed the add_support_for_postgres_json branch from 1289bcf to 3786c36 Compare November 14, 2018 13:00
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need the type instance to be in the SPI. Instead, compare like this:

type.getTypeSignature().getBase().equals(StandardTypes.JSON)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sill question -- why is the cast from varchar different from type constructor? Is't not intuitive.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just put up a PR to allow resolving the type constructor: #12007

Copy link
Contributor Author

@guyco33 guyco33 Dec 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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

@guyco33 guyco33 force-pushed the add_support_for_postgres_json branch 2 times, most recently from b9e746b to 61a22b7 Compare November 24, 2018 20:26
@guyco33 guyco33 force-pushed the add_support_for_postgres_json branch from 61a22b7 to 09913cc Compare November 29, 2018 18:11
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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

@guyco33 guyco33 force-pushed the add_support_for_postgres_json branch 3 times, most recently from 794b218 to 3345ded Compare December 20, 2018 12:26
@guyco33 guyco33 force-pushed the add_support_for_postgres_json branch from 3345ded to 3decb18 Compare January 3, 2019 09:34
@guyco33 guyco33 force-pushed the add_support_for_postgres_json branch from 3decb18 to dae7d0e Compare January 17, 2019 12:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants