lelit/pglast

Using visitors you cannot replace elements from a list of values.

gcbirzan opened this issue · 5 comments

Trying to replace them results in an error. Example:

import pglast.ast
from pglast import parse_sql
from pglast.visitors import Visitor


class TestVisitor(Visitor):
    def visit_A_Const(self, ancestors, node):
        return pglast.ast.A_Const(val=pglast.ast.Integer(0))

q = "INSERT INTO foo VALUES (42)"

TestVisitor()(parse_sql(q))

Exception:

Traceback (most recent call last):
  File "scratch_171.py", line 12, in <module>
    TestVisitor()(parse_sql(q))
  File "pglast/visitors.py", line 253, in __call__
    ancestors, node = generator.send(Continue if result is None else result)
  File "pglast/visitors.py", line 322, in iterate
    setattr(parent, ancestors.member, new_node)
TypeError: attribute name must be string, not 'int'

The other sequence I tried with was ARRAY[], where the node in the iterate call is the array, which is a sequence. But, in this case, the node ends up being the actual value, the sequence is a level above, in ancestors.node. I haven't looked enough at the code to be able to suggest a fix, sorry.

lelit commented

Thanks for the report.
The replace functionality is surely the less tested one, will try to write more tests on it.
I'll be able to study the case this evening.

lelit commented

This seems fixed, can you please give it a try?

lelit commented

I just released 3.14 addressing this.

Sorry, I was travelling last week, I didn't get a chance to take a look. It does fix my issue, thank you!

lelit commented

Great, thanks for the feedback!