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

Resolution using Table Context #2004

Merged
merged 17 commits into from
Apr 22, 2021
Merged

Resolution using Table Context #2004

merged 17 commits into from
Apr 22, 2021

Conversation

rishi-aga
Copy link
Collaborator

One of the PR that Resolves #1829

Description

Expression resolution using TableContext.

License

I confirm that this contribution is made under an Apache 2.0 license and that I have the authority necessary to make this contribution on behalf of its copyright owner.

Comment on lines +82 to +85
String value = matcher.group(1);
if (!value.startsWith("$$") && !value.startsWith("sql ")) {
references.add(value);
}
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added this temporarily until ColumnVisitor is removed for test cases to work for SQL helper.


private final Handlebars handlebars = new Handlebars()
.with(EscapingStrategy.NOOP)
.registerHelper("sql", new Helper<Object>() {
Copy link
Member

Choose a reason for hiding this comment

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

Does this Helper return Object or String?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Object

}
}

private static void parseArguments(String argsString, Map<String, Object> pinnedArgs)
Copy link
Member

Choose a reason for hiding this comment

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

This code is common with RSQLFilterDialect. Maybe we should migrate it to another shared utility class?

String invokedColumnExpr = table.getColumnMap().get(invokedColumnName).getExpression();

Map<String, Object> currentColumnArgs = (Map<String, Object>)
((Map<String, Object>) currentTableCtx.get(COL_PREFIX))
Copy link
Member

Choose a reason for hiding this comment

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

Double cast doesn't feel necessary here.

Table table = metaDataStore.getTable(queryable.getName(), queryable.getVersion());

// Add the default argument values stored in metadata store.
if (table != null) {
Copy link
Member

Choose a reason for hiding this comment

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

Do we ever expect table to be null?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It can be null when it runs for Nested Queries.


joinQueryable.getJoins().forEach((name, join) -> {
SQLTable joinTable = metaDataStore.getTable(join.getJoinTableType());
newCtx.addJoin(name, joinTable);
Copy link
Member

Choose a reason for hiding this comment

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

Instead of storing the joins in the context, we can fetch them directly from the joinTable.

return resolveHandlebars(invokedTableCtx, invokedColumnName, invokedColumnExpr, pinnedArgs);
}

public void addJoin(String joinName, Queryable joinQueryable) {
Copy link
Member

Choose a reason for hiding this comment

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

We can remove this function if we leverage the joins stored in the associated Queryable.

@@ -87,7 +87,8 @@ public SQLMetricProjection(Metric metric,
@Override
public String toSQL(Queryable source, SQLReferenceTable lookupTable) {
if (expression.matches(".*\\{\\{.*\\}\\}.*")) {
return lookupTable.getResolvedReference(source, getName());
//TODO: Add query context to Table Context before calling get
Copy link
Member

Choose a reason for hiding this comment

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

What does this mean?

Copy link
Collaborator Author

@rishi-aga rishi-aga Apr 19, 2021

Choose a reason for hiding this comment

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

Thinking to change this method to public String toSQL(Queryable source, SQLReferenceTable lookupTable, Map<String, Object> queryContext) { and then pass user provided queryContext also for resolving definitions.

import javax.persistence.Id;
import javax.sql.DataSource;

public class TableContextTest {
Copy link
Member

Choose a reason for hiding this comment

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

Not sure if we want to do this as part of this PR or another - but we also need to test

  • Join template substitution
  • FromQuery template substitution.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I will submit PRs for these against this PR.

Copy link
Member

Choose a reason for hiding this comment

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

We also need to test nested queries. I don't see any tests for those.


// default value of 'format' argument is used for 'conversion_rate' column
assertEquals("TO_CHAR(SUM(`com_yahoo_elide_datastores_aggregation_metadata_RevenueFact`.`revenue`) * "
+ "TO_CHAR(`com_yahoo_elide_datastores_aggregation_metadata_RevenueFact_rate`.`conversion_rate`, 999D00), "
Copy link
Member

Choose a reason for hiding this comment

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

I don't understand how the conversion rate format here is different than the test below.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

definition of revenue column uses {{rate.conversionRate}} and revenueUsingSqlHelper uses {{sql from='rate' column='conversionRate'}}
For first scenario, its using default value of 'format' argument defined for conversionRate field in rate table.
In the case of SQL helper, its using default value of 'format' argument defined for revenueUsingSqlHelper field

@rishi-aga rishi-aga force-pushed the populateTableContext branch 3 times, most recently from 520a255 to f3ac673 Compare April 19, 2021 19:35

if (!isEmpty(argsString)) {

Matcher matcher = FILTER_ARGUMENTS_PATTERN.matcher(argsString);
Copy link
Member

Choose a reason for hiding this comment

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

We should move the FILTER_ARGUMENTS_PATTERN to this file. Does this function make sense in TypeHelper?

@@ -80,6 +84,13 @@ public Object get(Object key) {
newCtx.put(column.getName(), column.getExpression());
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this (copy of queryable columns into the context) should happen in the constructor of the TableContext? Or maybe they shoudln't be stored in the map at all (and just referenced directly from the queryable like the joins)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Removed them from the Map.

@@ -92,7 +103,7 @@ public Object get(Object key) {
verifyKeyExists(key, super.keySet());

Object value = super.get(key);
if (key.toString().startsWith("$$")) {
if (value instanceof Map) {
Copy link
Member

Choose a reason for hiding this comment

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

Instead of checking types here, I wonder if we just look to see if the key is one of the queryable columns - then call resolveHandlebars on the value. Otherwise, just return what is in the map.

import javax.persistence.Id;
import javax.sql.DataSource;

public class TableContextTest {
Copy link
Member

Choose a reason for hiding this comment

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

We also need to test nested queries. I don't see any tests for those.

aklish
aklish previously approved these changes Apr 22, 2021
moizarafat
moizarafat previously approved these changes Apr 22, 2021
@rishi-aga rishi-aga merged commit 89e96b0 into master Apr 22, 2021
@rishi-aga rishi-aga deleted the populateTableContext branch April 22, 2021 21:56
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.

3 participants