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

Proper way to create a duplicate Expression object #897

Closed
sivaraam opened this issue Nov 18, 2019 · 9 comments
Closed

Proper way to create a duplicate Expression object #897

sivaraam opened this issue Nov 18, 2019 · 9 comments

Comments

@sivaraam
Copy link
Contributor

I recently faced a situation where I needed to set the same criteria expression in all the SELECTs in a UNION query. Though the criteria is same, I would want distinct objects that represent the same criteria i.e., changing the criteria in one of the SELECT queries should not affect the criteria in the other SELECT queries. Let me demonstrate what I was trying to achieve:

		Select selectStatement = (Select) CCJSqlParserUtil.parse(
                "SELECT id FROM table1 UNION SELECT id FROM table2"
        );
        Expression criteriaExpr = CCJSqlParserUtil.parseCondExpression("NAME LIKE '%M%'");

        selectStatement.getSelectBody().accept(new SelectVisitorAdapter() {
            @Override
            public void visit(PlainSelect plainSelect) {
                plainSelect.setWhere(criteriaExpr);
            }

            @Override
            public void visit(SetOperationList setOpList) {
                setOpList.getSelects().forEach(
                        selectBody -> selectBody.accept(this)
                );
            }
        });

The program properly sets the criteria for both the queries. But as it uses the same criteriaExpr object for both the queries in the UNION, changing the criteria in one of the queries also changes the criteria in the other query. This is an issue in my case.

One way to overcome this is by moving the creation of the criteriaExpr into the visit(PlainSelect plainSelect) method. But it has the limitation that there is no direct way to communicate to the caller, the case in which the criteria could not be parsed (i.e., when an JSQLParserException occurs) as the signature of the visit method cannot be changed.

Coming to the question, is there a way to create a clone of the creteriaExpr without having to parse the expression again so that a unique object can be assigned to all the queries in the UNION?

@wumpz
Copy link
Member

wumpz commented Nov 18, 2019

Not yet. The proper way would-be to parse the string again.

@sivaraam
Copy link
Contributor Author

sivaraam commented Nov 19, 2019

Ok. Thanks. Looks I would have to work around with communicating the parse exception, for now 🙂

@wumpz
Copy link
Member

wumpz commented Nov 19, 2019

The the true right way would be to implement a CopyVisitor for this. Besides, before I started maintaining the project the logic to traverse the object tree was externalized within the Visitor interfaces or classes. Til now I could not decide where to put it best (extern or class intern).

@wumpz
Copy link
Member

wumpz commented Dec 1, 2019

With my proposal #901 this would be more simple.

@wumpz
Copy link
Member

wumpz commented Feb 2, 2020

Do you have some comments regarding #901?

@sivaraam
Copy link
Contributor Author

sivaraam commented Feb 3, 2020

For the record, I've replied in #901 with my opinion.

@sivaraam
Copy link
Contributor Author

sivaraam commented Feb 3, 2020

Also, sorry that I didn't add my comments earlier! Forgot about the suggested API change. My bad 🤦‍♂.

Feel free to ping me the next time if you feel that I could provide some useful input.

@wumpz
Copy link
Member

wumpz commented Feb 4, 2020

Never mind. Could I close this issue.

@sivaraam
Copy link
Contributor Author

sivaraam commented Feb 4, 2020

Sure.

@sivaraam sivaraam closed this as completed Feb 4, 2020
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

No branches or pull requests

2 participants