betodealmeida commented on code in PR #32175:
URL: https://github.com/apache/superset/pull/32175#discussion_r1951578488


##########
superset/jinja_context.py:
##########
@@ -596,12 +596,24 @@ def process_template(self, sql: str, **kwargs: Any) -> 
str:
         >>> sql = "SELECT '{{ datetime(2017, 1, 1).isoformat() }}'"
         >>> process_template(sql)
         "SELECT '2017-01-01T00:00:00'"
+        This function will attempt to resolve nested Jinja expressions
+        up to 4 iterations.
         """
-        template = self.env.from_string(sql)
+        # Initialize the rendered SQL with the original SQL string.
+        rendered_sql = sql
         kwargs.update(self._context)
-
         context = validate_template_context(self.engine, kwargs)
-        return template.render(context)
+
+        # Render recursively up to 4 levels.
+        for _i in range(4):

Review Comment:
   I gave this more thought, and I think re-rendering the template might be 
problematic, since the template could end with template markers after being 
rendered, eg:
   
   ```python
   Template("{{ foo }}").render(context={"foo": "{{"})
   ```
   
   I think what we want to do is modify the `metric_macro` function to check if 
it has additional calls to `metric()` after being rendered, and if so, keep 
rendering the template.
   
   
https://github.com/apache/superset/blob/319a860f2375438448457892b3a841c83889fb1d/superset/jinja_context.py#L891
   
   We can parse the template and check for the occurrence of `metric()` by 
analyzing the AST:
   
   ```python
   from jinja2 import Environment, nodes
   from jinja2.nodes import Call, Node
   
   
   def has_metric_macro(template_string: str) -> bool:
       env = Environment()
       ast = env.parse(template_string)
   
       def visit_node(node: Node) -> bool:
           return (
               isinstance(node, Call)
               and isinstance(node.node, nodes.Name)
               and node.node.name == "metric"
           ) or any(visit_node(child) for child in node.iter_child_nodes())
   
       return visit_node(ast)
   ```
   
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to