Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support translation of JsonPathType to ConnectorExpression #20218

Merged
merged 3 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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 @@ -21,6 +21,7 @@
import io.trino.Session;
import io.trino.connector.system.GlobalSystemConnector;
import io.trino.metadata.ResolvedFunction;
import io.trino.operator.scalar.JsonPath;
import io.trino.plugin.base.expression.ConnectorExpressions;
import io.trino.security.AllowAllAccessControl;
import io.trino.spi.connector.CatalogSchemaName;
Expand Down Expand Up @@ -63,6 +64,7 @@
import io.trino.sql.tree.SubscriptExpression;
import io.trino.sql.tree.SymbolReference;
import io.trino.type.JoniRegexp;
import io.trino.type.JsonPathType;
import io.trino.type.LikePattern;
import io.trino.type.Re2JRegexp;
import io.trino.type.Re2JRegexpType;
Expand Down Expand Up @@ -333,7 +335,8 @@ private Optional<Expression> translateCall(String functionName, ResolvedFunction
return Optional.empty();
}
Expression expression = translated.get();
if ((formalType == JONI_REGEXP || formalType instanceof Re2JRegexpType) && argumentType instanceof VarcharType) {
if ((formalType == JONI_REGEXP || formalType instanceof Re2JRegexpType || formalType instanceof JsonPathType)
&& argumentType instanceof VarcharType) {
// These types are not used in connector expressions, so require special handling when translating back to expressions.
expression = new Cast(expression, toSqlType(formalType));
}
Expand Down Expand Up @@ -814,6 +817,10 @@ private ConnectorExpression constantFor(Expression node)
Slice pattern = Slices.utf8Slice(((Re2JRegexp) value).pattern());
return new Constant(pattern, createVarcharType(countCodePoints(pattern)));
}
if (type instanceof JsonPathType) {
Slice pattern = Slices.utf8Slice(((JsonPath) value).pattern());
return new Constant(pattern, createVarcharType(countCodePoints(pattern)));
}
return new Constant(value, type);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
import static io.trino.sql.planner.TypeAnalyzer.createTestingTypeAnalyzer;
import static io.trino.testing.TransactionBuilder.transaction;
import static io.trino.type.JoniRegexpType.JONI_REGEXP;
import static io.trino.type.JsonPathType.JSON_PATH;
import static io.trino.type.LikeFunctions.likePattern;
import static io.trino.type.LikePatternType.LIKE_PATTERN;
import static java.nio.charset.StandardCharsets.UTF_8;
Expand Down Expand Up @@ -455,6 +456,24 @@ public void testTranslateRegularExpression()
});
}

@Test
void testTranslateJsonPath()
{
// JSON path type is considered implementation detail of the engine and is not exposed to connectors
// within ConnectorExpression. Instead, it is replaced with a varchar pattern.
assertTranslationRoundTrips(
BuiltinFunctionCallBuilder.resolve(PLANNER_CONTEXT.getMetadata())
.setName("json_extract_scalar")
.addArgument(VARCHAR_TYPE, new SymbolReference("varchar_symbol_1"))
.addArgument(JSON_PATH, new Cast(new StringLiteral("$.path"), toSqlType(JSON_PATH)))
.build(),
new Call(
VARCHAR_TYPE,
new FunctionName("json_extract_scalar"),
List.of(new Variable("varchar_symbol_1", VARCHAR_TYPE),
new Constant(utf8Slice("$.path"), createVarcharType(6)))));
}

@Test
public void testTranslateIn()
{
Expand Down
Loading