JsqlParser how to rewrite a expression - expression

I have a sql where cluase:
a > 1 and b < 1 and c = 3
In this case I want to remove the a>1, how could I rewrite it to
1 = 1 and b < 1 and c =3
I have try the ExpressionVisitor, but couldn't rewrite the Expression

You can simply replace the where part of a SQL by using something like:
((PlainSelect)selectBody).setWhere(CCJSqlParserUtil.parseCondExpression("mycol = 10"));
but if you want to use the where expression itself and want to find in it the expression a > 1, then you have to use something like
Select stmt = (Select) CCJSqlParserUtil.parse("select * from a where a > 1 and b < 1 and c = 3");
System.out.println("before " + stmt.toString());
((PlainSelect) stmt.getSelectBody()).getWhere().accept(new ExpressionVisitorAdapter() {
#Override
public void visitBinaryExpression(BinaryExpression expr) {
if ("a > 1".equals(expr.getLeftExpression().toString())) {
try {
expr.setLeftExpression(CCJSqlParserUtil.parseCondExpression("1=1"));
} catch (JSQLParserException ex) {
Logger.getLogger(SimpleSqlParser39ReplaceExpressionInWhere.class.getName()).log(Level.SEVERE, null, ex);
}
}
super.visitBinaryExpression(expr);
}
});
System.out.println("after " + stmt.toString());
This is not a complete solution since you have to check the right expression as well. Since you are indeed not able to modify the binary expression a > 1 itself you have to look for the enclosing expression and replace it there. So that's the main idea.
By the way this is the output of this little snippet:
before SELECT * FROM a WHERE a > 1 AND b < 1 AND c = 3
after SELECT * FROM a WHERE 1 = 1 AND b < 1 AND c = 3

Related

How to loop through a folder with conditional statement in Stata?

I have a folder with a bunch of csv files and I want to loop through each file, check if a list of variables in each of the files = 0, then save the csv file as a .dta if they do not equal 0.
I'm having trouble finding online help to do this but here's what I've tried so far:
foreach file in `files' {
import delimited using `file', clear
if a & b & c & d != 0
save "Desktop\myfolder\`file'.dta"
}
when I try this though Stata tells me "{ required r(100)".
Any help appreciated. Thanks.
Stealing some code from the estimable #Wouter Wakker, let's first suppose that the criterion is that a non-zero value is found somewhere in a b c d
foreach file in `files' {
import delimited using `file', clear
local OK = 0
quietly foreach v in a b c d {
count if `v' != 0
if r(N) > 0 local OK = 1
}
if `OK' save "Desktop/myfolder/`file'.dta"
}
Whatever your precise criterion, I think you need to loop over a b c d and (say) count or summarize according to what you want or do not want.
From help ifcmd:
Syntax
if exp { or if exp single_command
multiple_commands
}
So you can do either
foreach file in `files' {
import delimited using `file', clear
if a & b & c & d != 0 save "Desktop\myfolder\`file'.dta"
}
or
foreach file in `files' {
import delimited using `file', clear
if a & b & c & d != 0 {
save "Desktop\myfolder\`file'.dta"
}
}
However, I don't think your if condition does what you think it does. What you're looking for would rather be:
if a != 0 & b != 0 & c != 0 & d != 0

Shortcut assignment in go excluding empty/nil value

This can be done in python / javascript:
# Python:
a = ""
b = "test"
c = a or b # test
// javascript
a = "";
b = "test";
c = a || b; // test
Can the same be accomplished in go without doing some conditional block? The only way I'm able to do this so far is with conditional blocks...
a := ""
b := "test"
var c
if a {
c = a
} else {
c = b
}
I think this is answer is going to be "no, this cannot be done", but I figured I would ask just in case I'm wrong. The example here is simplified. The variables a and b could have been defined long ago...
From golang FAQ, There is no ternary testing operation in Go. You may use the following to achieve the same result:
if expr {
n = trueVal
} else {
n = falseVal
}

PigLatin - Local Mode - ERROR 1066: Unable to open iterator for alias B

I am experimenting with Pig UDFs. I am able to get simple UDF like Upper Case working for me. so I was trying to write my own UDF. I want to process each line of an input file which contains 3 integers. If the 3 integers satisfy the criteria for sides of a right angle triangle, then the hypotenuse is returned else null is returned.
But I am getting following error - ERROR 1066: Unable to open iterator for alias B
Here is the Pig Script Code -
-- rat.pig - A Pig script to test right angle triangle
REGISTER /Users/admin/Programming/PigUDF/bin/myudfs/myudfs.jar;
A = LOAD '/Users/admin/Programming/pigdata/triangle.csv' AS (sides: tuple(side_0:int, side_1:int, side_2:int));
B = FILTER A BY (myudfs.RAT(A.sides)!= 0);
DUMP B;
The UDF is like
package myudfs;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
public class RAT extends EvalFunc<Integer>{
public Integer exec(Tuple input) throws IOException {
if (input == null || input.size() == 0) {
return null;
}
try {
int num_0 = (Integer)input.get(0);
int num_1 = (Integer)input.get(1);
int num_2 = (Integer)input.get(2);
if ((num_0 * num_0) + (num_1 * num_1) == num_2 * num_2)
return Integer.valueOf(num_2);
else if ((num_0 * num_0) + (num_2 * num_2) == num_1 * num_1)
return Integer.valueOf(num_1);
else if ((num_1 * num_1) + (num_2 * num_2) == num_0 * num_0)
return Integer.valueOf(num_0);
else {
return null;
}
} catch (Exception e) {
throw new IOException(" Caught exception processing input row", e);
}
}
}
I was wondering what I am doing wrong here. Any pointer is appreciated. Thanks.
Sumod,
There are couple of changes that you need to do.
Your LOAD statement doesn't seem to generate a proper Tuple. And the function also needs to be changed slightly.
Please see the code modifications I have done. Any questions please let me know.
REGISTER PIGTrnFilter.jar;
A = LOAD '/home/hadoop/lab/examples/PigTrnTest.txt' AS (side_0:int, side_1:int, side_2:int);
B = FILTER A BY (inverika.training.examples.RAT(TOTUPLE(A.side_0, A.side_1, A.side_2)) != 0);
DUMP B;
The Filter functions is below.
package inverika.training.examples;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
public class RAT extends EvalFunc<Integer>{
public Integer exec(Tuple TT) throws IOException {
if (TT == null || TT.size() == 0) {
return null;
}
try {
Object tupleObject = TT.get(0);
Tuple input = (Tuple) tupleObject;
Object object0 = input.get(0);
Object object1 = input.get(1);
Object object2 = input.get(2);
int num_0 = (Integer) object0;
int num_1 = (Integer) object1;
int num_2 = (Integer) object2;
if ((num_0 * num_0) + (num_1 * num_1) == num_2 * num_2)
return Integer.valueOf(num_2);
else if ((num_0 * num_0) + (num_2 * num_2) == num_1 * num_1)
return Integer.valueOf(num_1);
else if ((num_1 * num_1) + (num_2 * num_2) == num_0 * num_0)
return Integer.valueOf(num_0);
else {
return new Integer(0);
}
} catch (Exception e) {
throw new IOException(" Caught exception processing input row", e);
}
}
}
Please note that I have used a Tab separated data rather than a csv. if have a csv then you need to use PigStorage function to load.
1 2 3
2 5 2
2 2 2
1 3 7
7 2 10
3 4 5
I have made minor modifications which I guess you can follow. Look at the relation schema to understand the changes I made. You can actually use a FilerFunc which returns Boolean than an EvalFunc. Hope this helps you.

removing nesting of if statements

I have a piece of code, which I am not sure how to refactor.. It is not very readable and I would like to make it readable. Here is a the problem
There are two columns in database which can be either NULL, 0 or have a value each. On the web page there is a checkbox - enable and text box - value for each of those two columns.
x = checkbox1
z = textbox1
y = checkbox2
w = textbox2
The logic is if both the checkboxes are not selected, then both the values should be 0. If either one is selected and other is not, then others value should be NULL. and for the one that is selected, if the textbox is empty its value should be NULL else should be the value in the textbox
if{x}
{
if(z)
{
a = NULL;
}
else
{
a = z;
}
if(y)
{
if(w)
{
b=w;
}
else
{
b = NULL;
}
}
else
{
b = null
}
}
else
{
if(y)
{
a = NULL;
if(w)
{
b=w;
}
else
{
b = NULL;
}
}
else
{
a = 0;
b = 0;
}
}
Trust me this is a valid scenario. Let me know if this makes sense or I should give more information
Using some logical ands and nots, we get something more readable.
We can save a little by defaulting to NULL (thus not needing to set the other to NULL). We can also save by putting the code for checking if a textbox is set or using null into a little function.
In pseudo code:
a = NULL
b = NULL
if (not checkbox1) and (not checkbox2):
a = 0
b = 0
if (checkbox1):
a = valueornull(textbox1)
if (checkbox2):
b = valueornull(textbox2)
function valueornull(textbox):
if textbox value:
return value
else:
return null
I think it would help to use more descriptive names that the single letters here, but assuming this is C code, it looks a lot neater with inline if statements:
if(x)
{
a = z ? NULL : z;
b = (y && w) ? w : NULL;
}
else
{
a = y ? NULL : 0;
b = (y && w) ? w : 0;
}

Simple ranking algorithm in Groovy

I have a short groovy algorithm for assigning rankings to food based on their rating. This can be run in the groovy console. The code works perfectly, but I'm wondering if there is a more Groovy or functional way of writing the code. Thinking it would be nice to get rid of the previousItem and rank local variables if possible.
def food = [
[name:'Chocolate Brownie',rating:5.5, rank:null],
[name:'Fudge', rating:2.1, rank:null],
[name:'Pizza',rating:3.4, rank:null],
[name:'Icecream', rating:2.1, rank:null],
[name:'Cabbage', rating:1.4, rank:null]]
food.sort { -it.rating }
def previousItem = food[0]
def rank = 1
previousItem.rank = rank
food.each { item ->
if (item.rating == previousItem.rating) {
item.rank = previousItem.rank
} else {
item.rank = rank
}
previousItem = item
rank++
}
assert food[0].rank == 1
assert food[1].rank == 2
assert food[2].rank == 3
assert food[3].rank == 3 // Note same rating = same rank
assert food[4].rank == 5 // Note, 4 skipped as we have two at rank 3
Suggestions?
This is my solution:
def rank = 1
def groupedByRating = food.groupBy { -it.rating }
groupedByRating.sort().each { rating, items ->
items.each { it.rank = rank }
rank += items.size()
}
I didn't try it, but maybe this could work.
food.eachWithIndex { item, i ->
if( i>0 && food[i-1].rating == item.rating )
item.rank = food[i-1].rank
else
item.rank = i + 1
}
Here's another alternative that doesn't use "local defs" with the groovy inject method:
food.sort { -it.rating }.inject([index: 0]) { map, current ->
current.rank = (current.rating == map.lastRating ? map.lastRank : map.index + 1)
[ lastRating: current.rating, lastRank: current.rank, index: map.index + 1 ]
}

Resources