public abstract class BinaryExpression implements Expression {
	private Expression leftExpression;
	private Expression rightExpression;

	public BinaryExpression(Expression leftExpression, Expression rightExpression) {
  	this.leftExpression = leftExpression;
    this.rightExpression = rightExpression;
	}
  public BinaryExpression() {
  }
	

	public Expression getLeftExpression() {
		return leftExpression;
	}

	public Expression getRightExpression() {
		return rightExpression;
	}

	public void setLeftExpression(Expression expression) {
		leftExpression = expression;
	}

	public void setRightExpression(Expression expression) {
		rightExpression = expression;
	}

	public String toString() {
		return "("+getLeftExpression()+" "+getStringExpression()+" "+getRightExpression()+")";
	}

	public abstract String getStringExpression();
	
}
 public class DoubleValue implements Expression, PrimitiveValue {
	private double value;

  public DoubleValue(double value) { this.value = value; }

	public DoubleValue(String value) {
	    if (value.charAt(0) == '+') {
	        value = value.substring(1);
	    }
		this.value = Double.parseDouble(value);
	}
	
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}


	public double getValue() {
		return value;
	}

	public void setValue(double d) {
		value = d;
	}

	public String toRawString(){ return toString(); }
	public String toString() {
		return ""+value;
	}
	
  public long toLong() throws PrimitiveValue.InvalidPrimitive
  	{ throw new PrimitiveValue.InvalidPrimitive(); }
  public double toDouble() { return getValue(); }
  public boolean toBool() throws PrimitiveValue.InvalidPrimitive 
    { throw new PrimitiveValue.InvalidPrimitive(); }
  
  public boolean equals(Object o){
    if(o instanceof DoubleValue){
      return value == ((DoubleValue)o).getValue();
    } else if(o instanceof LongValue) {
      return value == (double)((LongValue)o).getValue();
    } else {
      return false;
    }
  }
  public int hashCode(){
    return new Double(value).hashCode();
  }
  
  public PrimitiveType getType() { return PrimitiveType.DOUBLE; }
} public interface Expression {
	public void accept(ExpressionVisitor expressionVisitor);
}
 public class Function implements Expression {

	private String name;
	private ExpressionList parameters;
	private boolean allColumns = false;
	private boolean distinct = false;
	private boolean isEscaped = false;
	
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	/**
	 * The name of he function, i.e. "MAX"
	 * @return the name of he function
	 */
	public String getName() {
		return name;
	}

	public void setName(String string) {
		name = string;
	}

	/**
	 * true if the parameter to the function is "*"
	 * @return true if the parameter to the function is "*"
	 */
	public boolean isAllColumns() {
		return allColumns;
	}

	public void setAllColumns(boolean b) {
		allColumns = b;
	}

	/**
	 * true if the function is "distinct"
	 * @return true if the function is "distinct"
	 */
	public boolean isDistinct() {
		return distinct;
	}

	public void setDistinct(boolean b) {
		distinct = b;
	}

	/**
	 * The list of parameters of the function (if any, else null)
	 * If the parameter is "*", allColumns is set to true
	 * @return the list of parameters of the function (if any, else null)
	 */
	public ExpressionList getParameters() {
		return parameters;
	}

	public void setParameters(ExpressionList list) {
		parameters = list;
	}

    /**
     * Return true if it's in the form "{fn function_body() }" 
     * @return true if it's java-escaped
     */
    public boolean isEscaped() {
        return isEscaped;
    }
    
    public void setEscaped(boolean isEscaped) {
        this.isEscaped = isEscaped;
    }

    public String toString() {
    	String params = "";
    	
    	if(allColumns) {
    		params = "(*)";
    	}
    	else if(parameters != null) {
			params = parameters.toString();
    		if (isDistinct()) {
    			params = params.replaceFirst("\\(", "(DISTINCT ");
    		} 
    	}
    	
    	String ans = name+""+params+"";
    	
    	if(isEscaped) {
    		ans = "{fn "+ans+"}"; 
    	}
    	
    	return ans;
    }
}
 public class InverseExpression implements Expression {
	private Expression expression;
	
	public InverseExpression() {
	}

	public InverseExpression(Expression expression) {
		setExpression(expression);
	}

	public Expression getExpression() {
		return expression;
	}

	public void setExpression(Expression expression) {
		this.expression = expression;
	}

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String toString() 
	{
		if(
			(expression instanceof BooleanValue)
			|| (expression instanceof AndExpression)
			|| (expression instanceof OrExpression)
			|| (expression instanceof Between)
			|| (expression instanceof EqualsTo)
			|| (expression instanceof ExistsExpression)
			|| (expression instanceof GreaterThan)
			|| (expression instanceof GreaterThanEquals)
			|| (expression instanceof InExpression)
			|| (expression instanceof IsNullExpression)
			|| (expression instanceof LikeExpression)
			|| (expression instanceof Matches)
			|| (expression instanceof MinorThan)
			|| (expression instanceof MinorThanEquals)
			|| (expression instanceof NotEqualsTo)
		){ return "NOT (" + expression.toString() + ")"; }
		else { return "-(" + expression.toString() + ")"; }
	}
}
 public class JdbcParameter implements Expression {
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String toString() {
		return "?";
	}
}
 public class LongValue implements Expression, PrimitiveValue {
	private long value;

  public LongValue(long value) { this.value = value; }

	public LongValue(String value) {
	    if (value.charAt(0) == '+') {
	        value = value.substring(1);
	    }
		this.value = Long.parseLong(value);
	}

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public long getValue() {
		return value;
	}

	public void setValue(long d) {
		value = d;
	}

	public String toRawString(){ return toString(); }
	public String toString() {
		return ""+value;
	}

  public long toLong() { return getValue(); }
  public double toDouble() { return getValue(); }
  public boolean toBool() throws PrimitiveValue.InvalidPrimitive 
    { throw new PrimitiveValue.InvalidPrimitive(); }
  
  public boolean equals(Object o){
    if(o instanceof DoubleValue){
      return (double)value == ((DoubleValue)o).getValue();
    } else if(o instanceof LongValue) {
      return value == ((LongValue)o).getValue();
    } else {
      return false;
    }
  }
  public int hashCode(){
    return new Long(value).hashCode();
  }

  public PrimitiveType getType() { return PrimitiveType.LONG; }
} public class DateValue implements Expression, PrimitiveValue {
	private Date value;
	
	public DateValue(String value) {
		this.value = Date.valueOf(value);
	}

  public static DateValue parseEscaped(String escapedValue) {
    return new DateValue(escapedValue.substring(1, escapedValue.length()-1));
  }
	
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
  
  public int getYear() {
    return value.getYear();
  }
  public int getMonth() {
    return value.getMonth();
  }
  public int getDate() {
    return value.getDate();
  }

	public Date getValue() {
		return value;
	}

	public void setValue(Date d) {
		value = d;
	}
  
  public String toRawString(){ return toString(); }
  public String toString()
  {
    return value.toString();
  }
  
  public long toLong() throws PrimitiveValue.InvalidPrimitive 
    { throw new PrimitiveValue.InvalidPrimitive(); }
  public double toDouble() throws PrimitiveValue.InvalidPrimitive 
    { throw new PrimitiveValue.InvalidPrimitive(); }
  public boolean toBool() throws PrimitiveValue.InvalidPrimitive 
    { throw new PrimitiveValue.InvalidPrimitive(); }
  
  public boolean equals(Object o)
  {
    try { 
      return value.equals(((DateValue)o).value);
    } catch(ClassCastException e){
      return false;
    }
  }
  public int hashCode(){
    return value.hashCode();
  }

  public PrimitiveType getType() { return PrimitiveType.DATE; }
} public class TimeValue implements Expression, PrimitiveValue {
	private Time value;

	public TimeValue(String value) {
		this.value = Time.valueOf(value.substring(1, value.length()-1));
	}
	
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}


	public Time getValue() {
		return value;
	}

	public void setValue(Time d) {
		value = d;
	}

	public String toRawString(){ return value.toString(); }
	public String toString() {
		return "{t '"+value+"'}";
	}

	public long toLong() throws PrimitiveValue.InvalidPrimitive 
		{ throw new PrimitiveValue.InvalidPrimitive(); }
	public double toDouble() throws PrimitiveValue.InvalidPrimitive 
		{ throw new PrimitiveValue.InvalidPrimitive(); }
	public boolean toBool() throws PrimitiveValue.InvalidPrimitive 
		{ throw new PrimitiveValue.InvalidPrimitive(); }
  
  public boolean equals(Object o){
    try { 
      return value.equals(((TimeValue)o).value);
    } catch(ClassCastException e){
      return false;
    }
  }
  public int hashCode(){
    return value.hashCode();
  }

  public PrimitiveType getType() { return PrimitiveType.TIME; }
} public class TimestampValue implements Expression, PrimitiveValue {
	private Timestamp value;

	public TimestampValue(String value) {
		this.value = Timestamp.valueOf(value.substring(1, value.length()-1));
	}
	
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}


	public Timestamp getValue() {
		return value;
	}

	public void setValue(Timestamp d) {
		value = d;
	}

	public String toRawString(){ return value.toString(); }
	public String toString() {
		return "{ts '"+value+"'}";
	}

	public long toLong() throws PrimitiveValue.InvalidPrimitive 
		{ throw new PrimitiveValue.InvalidPrimitive(); }
	public double toDouble() throws PrimitiveValue.InvalidPrimitive 
		{ throw new PrimitiveValue.InvalidPrimitive(); }
	public boolean toBool() throws PrimitiveValue.InvalidPrimitive 
		{ throw new PrimitiveValue.InvalidPrimitive(); }
  
  public boolean equals(Object o){
    try { 
      return value.equals(((TimestampValue)o).value);
    } catch(ClassCastException e){
      return false;
    }
  }
  public int hashCode(){
    return value.hashCode();
  }

  public PrimitiveType getType() { return PrimitiveType.TIMESTAMP; }
}
 public class NullValue implements Expression, PrimitiveValue {
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

  public String toRawString(){ return ""; }
	public String toString() {
		return "NULL";
	}

  public long toLong() throws PrimitiveValue.InvalidPrimitive 
  	{ throw new PrimitiveValue.InvalidPrimitive(); }
  public double toDouble() throws PrimitiveValue.InvalidPrimitive 
  	{ throw new PrimitiveValue.InvalidPrimitive(); }
  public boolean toBool() throws PrimitiveValue.InvalidPrimitive 
    { throw new PrimitiveValue.InvalidPrimitive(); }

  public boolean equals(Object o){
    return false;
  }
  public int hashCode(){
    return 0;
  }

  public PrimitiveType getType() { return null; }
} public class StringValue implements Expression, PrimitiveValue {
	private String value = "";
	
	public StringValue(String value)
	{
		this.value = value;
	}

	public static StringValue parseEscaped(String escapedValue) {
		return new StringValue(escapedValue.substring(1, escapedValue.length() - 1));
	}
	
	public String getValue() {
		return value;
	}

	public String getNotExcapedValue() {
		return value;
	}

	public void setValue(String string) {
		value = string;
	}
	
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String toRawString() {
		return value;
	}

	public String toString() {
		return "'"+value+"'";
	}

  public long toLong() throws PrimitiveValue.InvalidPrimitive 
  	{ throw new PrimitiveValue.InvalidPrimitive(); }
  public double toDouble() throws PrimitiveValue.InvalidPrimitive 
  	{ throw new PrimitiveValue.InvalidPrimitive(); }
  public boolean toBool() throws PrimitiveValue.InvalidPrimitive 
    { throw new PrimitiveValue.InvalidPrimitive(); }
  
  public boolean equals(Object o){
    try { 
      return value.equals(((StringValue)o).value);
    } catch(ClassCastException e){
      return false;
    }
  }
  public int hashCode(){
    return value.hashCode();
  }

  public PrimitiveType getType() { return PrimitiveType.STRING; }
} public class BooleanValue implements PrimitiveValue, Expression {
	private boolean value;

	private BooleanValue(boolean value) { this.value = value; }

	public boolean getValue() { return value; }
  
  public static final BooleanValue 
    TRUE = new BooleanValue(true),
    FALSE = new BooleanValue(false);
  
  public long toLong() { return value ? 1 : 0; }
  public double toDouble() { return value ? 1.0 : 0.0; }
  public boolean toBool() { return value; }

  public String toRawString(){ return toString(); }
	public String toString() {
		return value ? "TRUE" : "FALSE";
	}
  
  public boolean equals(Object o){
    try { 
      return value == (((BooleanValue)o).value);
    } catch(ClassCastException e){
      return false;
    }
  }
  public int hashCode(){
    return value ? 1 : 0;
  }

  public void accept(ExpressionVisitor visitor) { visitor.visit(this); }

  public PrimitiveType getType() { return PrimitiveType.BOOL; }
}
 public class CaseExpression implements Expression {

	private Expression switchExpression;
	
	private List<WhenClause> whenClauses;
	
	private Expression elseExpression;
	
	/* (non-Javadoc)
	 * @see net.sf.jsqlparser.expression.Expression#accept(net.sf.jsqlparser.expression.ExpressionVisitor)
	 */
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	/**
	 * @return Returns the switchExpression.
	 */
	public Expression getSwitchExpression() {
		return switchExpression;
	}
	/**
	 * @param switchExpression The switchExpression to set.
	 */
	public void setSwitchExpression(Expression switchExpression) {
		this.switchExpression = switchExpression;
	}
	
	/**
	 * @return Returns the elseExpression.
	 */
	public Expression getElseExpression() {
		return elseExpression;
	}
	/**
	 * @param elseExpression The elseExpression to set.
	 */
	public void setElseExpression(Expression elseExpression) {
		this.elseExpression = elseExpression;
	}
	/**
	 * @return Returns the whenClauses.
	 */
	public List<WhenClause> getWhenClauses() {
		return whenClauses;
	}
	
	/**
	 * @param whenClauses The whenClauses to set.
	 */
	public void setWhenClauses(List<WhenClause> whenClauses) {
		this.whenClauses = whenClauses;
	}
	
	public String toString() {
		return "CASE "+((switchExpression!=null)?switchExpression+" ":"")+
				PlainSelect.getStringList(whenClauses,false, false)+" "+
				((elseExpression!=null)?"ELSE "+elseExpression+" ":"")+
				"END";
	}
}
 public class WhenClause implements Expression {

	private Expression whenExpression;
	private Expression thenExpression;
	
	/* (non-Javadoc)
	 * @see net.sf.jsqlparser.expression.Expression#accept(net.sf.jsqlparser.expression.ExpressionVisitor)
	 */
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	/**
	 * @return Returns the thenExpression.
	 */
	public Expression getThenExpression() {
		return thenExpression;
	}
	/**
	 * @param thenExpression The thenExpression to set.
	 */
	public void setThenExpression(Expression thenExpression) {
		this.thenExpression = thenExpression;
	}
	/**
	 * @return Returns the whenExpression.
	 */
	public Expression getWhenExpression() {
		return whenExpression;
	}
	/**
	 * @param whenExpression The whenExpression to set.
	 */
	public void setWhenExpression(Expression whenExpression) {
		this.whenExpression = whenExpression;
	}
	
	public String toString() {
		return "WHEN "+whenExpression+" THEN "+thenExpression;
	}
}
 public class AnyComparisonExpression implements Expression {
	private SubSelect subSelect;
	
	public AnyComparisonExpression(SubSelect subSelect) {
		this.subSelect = subSelect;
	}
	
	public SubSelect getSubSelect() {
		return subSelect;
	}

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
}
 public class AllComparisonExpression implements Expression {
	private SubSelect subSelect;
	
	public AllComparisonExpression(SubSelect subSelect) {
		this.subSelect = subSelect;
	}
	
	public SubSelect getSubSelect() {
		return subSelect;
	}
	
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

}
 public class Addition extends BinaryExpression {

  public Addition(){ super(); }
  public Addition(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	public String getStringExpression() {
		return "+";
	}
} public class BitwiseAnd extends BinaryExpression {

  public BitwiseAnd(){ super(); }
  public BitwiseAnd(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	public String getStringExpression() {
		return "&";
	}
} public class BitwiseOr extends BinaryExpression {

  public BitwiseOr(){ super(); }
  public BitwiseOr(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	public String getStringExpression() {
		return "|";
	}
} public class BitwiseXor extends BinaryExpression {

  public BitwiseXor(){ super(); }
  public BitwiseXor(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	public String getStringExpression() {
		return "^";
	}
} public class Concat extends BinaryExpression {

	public Concat(){ super(); }
	public Concat(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	public String getStringExpression() {
		return "||";
	}

} public class Division extends BinaryExpression {

  public Division(){ super(); }
  public Division(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	public String getStringExpression() {
		return "/";
	}

} public class Multiplication extends BinaryExpression {

  public Multiplication(){ super(); }
  public Multiplication(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String getStringExpression() {
		return "*";
	}
} public class Subtraction extends BinaryExpression {

  public Subtraction(){ super(); }
  public Subtraction(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	public String getStringExpression() {
		return "-";
	}

} public class AndExpression extends BinaryExpression {

  public AndExpression(){ super(); }
  public AndExpression(Expression lhs, Expression rhs){ super(lhs, rhs); }
  
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	public String getStringExpression() {
		return "AND";
	}
} public class OrExpression extends BinaryExpression {

  public OrExpression(){ super(); }
  public OrExpression(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String getStringExpression() {
		return "OR";
	}
} public class Between implements Expression {
	private Expression leftExpression;
	private boolean not = false;
	private Expression betweenExpressionStart;
	private Expression betweenExpressionEnd;

	public Expression getBetweenExpressionEnd() {
		return betweenExpressionEnd;
	}

	public Expression getBetweenExpressionStart() {
		return betweenExpressionStart;
	}

	public Expression getLeftExpression() {
		return leftExpression;
	}

	public boolean isNot() {
		return not;
	}

	public void setBetweenExpressionEnd(Expression expression) {
		betweenExpressionEnd = expression;
	}

	public void setBetweenExpressionStart(Expression expression) {
		betweenExpressionStart = expression;
	}

	public void setLeftExpression(Expression expression) {
		leftExpression = expression;
	}

	public void setNot(boolean b) {
		not = b;
	}

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String toString() {
		return leftExpression + " " + (not?"NOT ":"") + "BETWEEN "+
		betweenExpressionStart+" AND "+betweenExpressionEnd;
	}
}
 public class EqualsTo extends BinaryExpression {
  
  public EqualsTo(){ super(); }
  public EqualsTo(Expression lhs, Expression rhs){ super(lhs, rhs); }
  
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	public String getStringExpression() {
		return "=";
	}

} public class ExpressionList implements ItemsList {
	private List<Expression> expressions;

	public ExpressionList() {
	}

	public ExpressionList(List<Expression> expressions) {
		this.expressions = expressions;
	}

	public List<Expression> getExpressions() {
		return expressions;
	}

	public void setExpressions(List<Expression> list) {
		expressions = list;
	}

	public void accept(ItemsListVisitor itemsListVisitor) {
		itemsListVisitor.visit(this);
	}

	public String toString() {
		return PlainSelect.getStringList(expressions, true, true);
	}
}
 public class GreaterThan extends BinaryExpression {

  public GreaterThan(){ super(); }
  public GreaterThan(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String getStringExpression() {
		return ">";
	}
} public class GreaterThanEquals extends BinaryExpression {

  public GreaterThanEquals(){ super(); }
  public GreaterThanEquals(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String getStringExpression() {
		return ">=";
	}
} public class InExpression implements Expression {
	private Expression leftExpression;
	private ItemsList itemsList; 
	private boolean not = false;
	
	public InExpression() {
	}

	public InExpression(Expression leftExpression, ItemsList itemsList) {
		setLeftExpression(leftExpression);
		setItemsList(itemsList);
	}
	
	public ItemsList getItemsList() {
		return itemsList;
	}

	public Expression getLeftExpression() {
		return leftExpression;
	}

	public void setItemsList(ItemsList list) {
		itemsList = list;
	}

	public void setLeftExpression(Expression expression) {
		leftExpression = expression;
	}

	public boolean isNot() {
		return not;
	}

	public void setNot(boolean b) {
		not = b;
	}

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String toString() {
		return leftExpression + " "+((not)?"NOT ":"")+"IN "+ itemsList+"";
	}
}
 public class IsNullExpression implements Expression {
	private Expression leftExpression;
	private boolean not = false;

	public Expression getLeftExpression() {
		return leftExpression;
	}

	public boolean isNot() {
		return not;
	}

	public void setLeftExpression(Expression expression) {
		leftExpression = expression;
	}

	public void setNot(boolean b) {
		not = b;
	}

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}
	
	public String toString() {
        return leftExpression + " IS "+((not)?"NOT ":"")+"NULL";
    }

}
 public interface ItemsList {
	public void accept(ItemsListVisitor itemsListVisitor);
}
 public class LikeExpression extends BinaryExpression {
	private boolean not = false;
	private String escape = null;

	public boolean isNot() {
		return not;
	}

	public void setNot(boolean b) {
		not = b;
	}

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}


	public String getStringExpression() {
		return ((not)?"NOT ":"")+"LIKE";
	}
	

	public String toString() {
	    String retval = super.toString();
	    if (escape != null) {
	        retval += " ESCAPE " + "'" + escape + "'";
	    }
	    
	    return retval;
	}

	public String getEscape() {
        return escape;
    }
    
    public void setEscape(String escape) {
        this.escape = escape;
    }
}
 public class ExistsExpression implements Expression {
	private Expression rightExpression;
	private boolean not = false;

	public Expression getRightExpression() {
		return rightExpression;
	}

	public void setRightExpression(Expression expression) {
		rightExpression = expression;
	}

	public boolean isNot() {
		return not;
	}

	public void setNot(boolean b) {
		not = b;
	}

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String getStringExpression() {
		return ((not)?"NOT ":"")+"EXISTS";
	}

	public String toString() {
		return getStringExpression() + " " + rightExpression.toString();
	}
}
 public class Matches extends BinaryExpression {
	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String getStringExpression() {
		return "@@";
	}
}
 public class MinorThan extends BinaryExpression {

  public MinorThan(){ super(); }
  public MinorThan(Expression lhs, Expression rhs){ super(lhs, rhs); }


	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String getStringExpression() {
		return "<";
	}
} public class MinorThanEquals extends BinaryExpression {

  public MinorThanEquals(){ super(); }
  public MinorThanEquals(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}


	public String getStringExpression() {
		return "<=";
	}
} public class NotEqualsTo extends BinaryExpression {

  public NotEqualsTo(){ super(); }
  public NotEqualsTo(Expression lhs, Expression rhs){ super(lhs, rhs); }

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}


	public String getStringExpression() {
		return "<>";
	}
} public class Column implements Expression {
	private String columnName = "";
	private Table table;
	
	public Column() {
	}

	public Column(Table table, String columnName) {
		this.table = table;
		this.columnName = columnName;
	}
	
	public String getColumnName() {
		return columnName;
	}

	public Table getTable() {
		return table;
	}

	public void setColumnName(String string) {
		columnName = string;
	}

	public void setTable(Table table) {
		this.table = table;
	}
	
	/**
	 * @return the name of the column, prefixed with 'tableName' and '.' 
	 */
	public String getWholeColumnName() {
		
		String columnWholeName = null;
		String tableWholeName = table.getWholeTableName();
		
		if (tableWholeName != null && tableWholeName.length() != 0) {
			columnWholeName = tableWholeName + "." + columnName;
		} else {
			columnWholeName = columnName;
		}
		
		return columnWholeName;

	}
	
	public void accept(ExpressionVisitor expressionVisitor) 
	{
		expressionVisitor.visit(this);
	}

	public String toString() {
		return getWholeColumnName();
	}

	public int hashCode()
	{
		return columnName.hashCode();
	}

	public boolean equals(Object o)
	{
		if(!(o instanceof Column)){ return false; }
		Column other = (Column)o;
		if(!columnName.equalsIgnoreCase(other.columnName)){ return false; }
		if(table == null || other.table == null){ return true; }
		if(table.getName() == null || other.table.getName() == null){ return true; }
		return table.getName().equalsIgnoreCase(other.table.getName());
	}
}
 public class Table implements FromItem {
	private String schemaName;
	private String name;
	private String alias;
	
	public Table() { this(null, null); }

	public Table(String name) { this(null, name); }

	public Table(String schemaName, String name) {
		this.schemaName = schemaName;
		this.name = name;
	}
	
	public String getName() {
		return name;
	}

	public String getSchemaName() {
		return schemaName;
	}

	public void setName(String string) {
		name = string;
	}

	public void setSchemaName(String string) {
		schemaName = string;
	}

	public String getAlias() {
		return alias;
	}

	public void setAlias(String string) {
		alias = string;
	}
	
	public String getWholeTableName() {

		String tableWholeName = null;
		if (name == null) {
			return null;
		}
		if (schemaName != null) {
			tableWholeName = schemaName + "." + name;
		} else {
			tableWholeName = name;
		}
		
		return tableWholeName;

	}

	public void accept(FromItemVisitor fromItemVisitor) {
		fromItemVisitor.visit(this);
	}
	
	public void accept(IntoTableVisitor intoTableVisitor) {
		intoTableVisitor.visit(this);
	}
	
	
	public String toString() {
		return getWholeTableName()+((alias!=null)?" AS "+alias:"");
	}
}
 public interface Statement {
	public void accept(StatementVisitor statementVisitor);
}
 public class ColDataType {

    private String dataType;
    private List<String> argumentsStringList;

    public List<String> getArgumentsStringList() {
        return argumentsStringList;
    }

    public String getDataType() {
        return dataType;
    }

    public void setArgumentsStringList(List<String> list) {
        argumentsStringList = list;
    }

    public void setDataType(String string) {
        dataType = string;
    }

    public String toString() {
        return dataType + (argumentsStringList!=null?" "+PlainSelect.getStringList(argumentsStringList, true, true):"");
    }
} public class ColumnDefinition {
	private String columnName;
	private ColDataType colDataType;
	private List<String> columnSpecStrings;
	
	/**
	 * A list of strings of every word after the datatype of the column.
	 * Example ("NOT", "NULL")
	 *
	 * @return A list of the datatype strings
	 */
	public List<String> getColumnSpecStrings() {
		return columnSpecStrings;
	}

	public void setColumnSpecStrings(List<String> list) {
		columnSpecStrings = list;
	}

	/**
	 * The {@link ColDataType} of this column definition 
	 * 
	 * @return The datatype
	 */
	public ColDataType getColDataType() {
		return colDataType;
	}

	public void setColDataType(ColDataType type) {
		colDataType = type;
	}

	public String getColumnName() {
		return columnName;
	}

	public void setColumnName(String string) {
		columnName = string;
	}
	
	public String toString() {
		return columnName+" "+colDataType+" "+PlainSelect.getStringList(columnSpecStrings, false, false);
	}

}
 public class CreateTable implements Statement {

    private Table table;
    private boolean tableIfNotExists = false;
    private boolean orReplaceTable = false;
    private List<String> tableOptionsStrings;
    private List<ColumnDefinition> columnDefinitions;
    private List<Index> indexes;

    public void accept(StatementVisitor statementVisitor) {
        statementVisitor.visit(this);
    }

    /**
     * The name of the table to be created
     *
     * @return The {@link Table} identifier for the table being created.
     */
    public Table getTable() {
        return table;
    }

    public void setTable(Table table) {
        this.table = table;
    }
    
    /**
     * Table if not exists  
     *
     * @return The table if not exists
     */
    public boolean getTableIfNotExists() {
        return tableIfNotExists;
    }

    public void setTableIfNotExists(boolean tableIfNotExists) {
        this.tableIfNotExists = tableIfNotExists;
    }
    
    /**
     * Replace Table if exists 
     *
     * @return The or replace table 
     */
    public boolean getOrReplaceTable() {
        return orReplaceTable;
    }

    public void setOrReplaceTable(boolean orReplaceTable) {
        this.orReplaceTable = orReplaceTable;
    }

    /**
     * A list of {@link ColumnDefinition}s of this table.
     *
     * @return The column definitions.
     */
    public List<ColumnDefinition> getColumnDefinitions() {
        return columnDefinitions;
    }

    public void setColumnDefinitions(List<ColumnDefinition> list) {
        columnDefinitions = list;
    }

    /**
     * A list of options (as simple strings) of this table definition, as ("TYPE", "=", "MYISAM") 
     *
     * @return The table options as simple strings
     */
    public List<String> getTableOptionsStrings() {
        return tableOptionsStrings;
    }

    public void setTableOptionsStrings(List<String> list) {
        tableOptionsStrings = list;
    }

    /**
     * A list of {@link Index}es (for example "PRIMARY KEY") of this table.<br>
     * Indexes created with column definitions (as in mycol INT PRIMARY KEY) are not inserted into this list.  
     *
     * @return A list of indexes
     */
    public List<Index> getIndexes() {
        return indexes;
    }

    public void setIndexes(List<Index> list) {
        indexes = list;
    }

    public String toString() {
        String sql = "";
        String ifNotExistsStr = this.tableIfNotExists ? "IF NOT EXISTS " : "";
        String orReplaceStr = this.orReplaceTable ? "DROP TABLE " + table + ";\n" : "";
        sql += orReplaceStr;
        sql += "CREATE TABLE " + ifNotExistsStr + table + " (";

        sql += PlainSelect.getStringList(columnDefinitions, true, false);
        if (indexes != null && indexes.size() != 0) {
            sql += ", ";
            sql += PlainSelect.getStringList(indexes);
        }
        sql += ") ";
        sql += PlainSelect.getStringList(tableOptionsStrings, false, false);

        return sql;
    }
} public class Index {

    private String type;
    private List<String> columnsNames;
    private String name;

    /**
     * A list of strings of all the columns regarding this index  
     *
     * @return The String name of all columns indexed by this index.
     */
    public List<String> getColumnsNames() {
        return columnsNames;
    }

    public String getName() {
        return name;
    }

    /**
     * The type of this index: "PRIMARY KEY", "UNIQUE", "INDEX"
     *
     * @return the String type of this index.
     */
    public String getType() {
        return type;
    }

    public void setColumnsNames(List<String> list) {
        columnsNames = list;
    }

    public void setName(String string) {
        name = string;
    }

    public void setType(String string) {
        type = string;
    }

    public String toString() {
        return type + " " + PlainSelect.getStringList(columnsNames, true, true) + (name!=null?" "+name:"");
    }
} public class Delete implements Statement {
	private Table table;
	private Expression where;
	
	public void accept(StatementVisitor statementVisitor) {
		statementVisitor.visit(this);
	}

	public Table getTable() {
		return table;
	}

	public Expression getWhere() {
		return where;
	}

	public void setTable(Table name) {
		table = name;
	}

	public void setWhere(Expression expression) {
		where = expression;
	}

	public String toString() {
		return "DELETE FROM "+table+((where!=null)?" WHERE "+where:"");
	}
}
 public class Drop implements Statement {
	private String type;
	private String name;
	private List parameters;
	
	public void accept(StatementVisitor statementVisitor) {
		statementVisitor.visit(this);
	}

	public String getName() {
		return name;
	}

	public List getParameters() {
		return parameters;
	}

	public String getType() {
		return type;
	}

	public void setName(String string) {
		name = string;
	}

	public void setParameters(List list) {
		parameters = list;
	}

	public void setType(String string) {
		type = string;
	}

	public String toString() {
		String sql = "DROP "+type+" "+name;
		
		if( parameters != null && parameters.size() > 0) {
			sql += " "+PlainSelect.getStringList(parameters);
		}
		
		return sql;
	}
}
 public class Insert implements Statement {
	private Table table;
	private List<Column> columns;
	private ItemsList itemsList;
	private boolean useValues = true;
	private boolean orReplace = false;
	
	public void accept(StatementVisitor statementVisitor) {
		statementVisitor.visit(this);
	}

	public Table getTable() {
		return table;
	}

	public void setTable(Table name) {
		table = name;
	}

	/**
	 * Get the columns (found in "INSERT INTO (col1,col2..) [...]" )
	 * @return a list of {@link net.sf.jsqlparser.schema.Column}
	 */
	public List<Column> getColumns() {
		return columns;
	}

	public void setColumns(List<Column> list) {
		columns = list;
	}

	/**
	 * Get the values (as VALUES (...) or SELECT) 
	 * @return the values of the insert
	 */
	public ItemsList getItemsList() {
		return itemsList;
	}

	public void setItemsList(ItemsList list) {
		itemsList = list;
	}

    public boolean isUseValues() {
        return useValues;
    }
    
    public void setUseValues(boolean useValues) {
        this.useValues = useValues;
    }

    public boolean isOrReplace() { return orReplace; }

    public void setIsOrReplace(boolean orReplace) {
    	this.orReplace = orReplace;
    }
    
	public String toString() {
		String sql = "";

		sql = "INSERT INTO ";
		sql += table+" ";
		sql += ((columns!=null)?PlainSelect.getStringList(columns, true, true)+" ":"");
		
		if(useValues) {
			sql += "VALUES "+itemsList+"";
		} else {
			sql += ""+itemsList+"";
		}
		
		return sql;
	}

}
 public class Replace implements Statement {
	private Table table;
	private List<Column> columns;
	private ItemsList itemsList;
	private List<Expression> expressions;
	private boolean useValues = true;

	public void accept(StatementVisitor statementVisitor) {
		statementVisitor.visit(this);
	}

	public Table getTable() {
		return table;
	}

	public void setTable(Table name) {
		table = name;
	}

	/**
	 * A list of {@link net.sf.jsqlparser.schema.Column}s either from a "REPLACE mytab (col1, col2) [...]" or a "REPLACE mytab SET col1=exp1, col2=exp2". 
	 * @return a list of {@link net.sf.jsqlparser.schema.Column}s
	 */
	public List<Column> getColumns() {
		return columns;
	}


	/**
	 * An {@link ItemsList} (either from a "REPLACE mytab VALUES (exp1,exp2)" or a "REPLACE mytab SELECT * FROM mytab2")  
	 * it is null in case of a "REPLACE mytab SET col1=exp1, col2=exp2"
	 * @return The target relation
	 */
	public ItemsList getItemsList() {
		return itemsList;
	}


	public void setColumns(List<Column> list) {
		columns = list;
	}

	public void setItemsList(ItemsList list) {
		itemsList = list;
	}

	/**
	 * A list of {@link net.sf.jsqlparser.expression.Expression}s (from a "REPLACE mytab SET col1=exp1, col2=exp2"). <br>
	 * it is null in case of a "REPLACE mytab (col1, col2) [...]"  
	 * @return The replacement expressions
	 */
	public List<Expression> getExpressions() {
		return expressions;
	}

	public void setExpressions(List<Expression> list) {
		expressions = list;
	}

	public boolean isUseValues() {
        return useValues;
    }
    
	public void setUseValues(boolean useValues) {
        this.useValues = useValues;
    }
	
	public String toString() {
		String sql = "REPLACE "+table;
		
		if(expressions != null && columns != null ) {
			//the SET col1=exp1, col2=exp2 case
			sql += " SET ";
			//each element from expressions match up with a column from columns.
			for (int i = 0, s = columns.size(); i < s; i++) {
				sql += ""+columns.get(i)+"="+expressions.get(i);
				sql += (i<s-1)?", ":"";
			}
		}
		else if( columns != null ) {
			//the REPLACE mytab (col1, col2) [...] case 
			sql += " "+PlainSelect.getStringList(columns, true, true);
		}
		
		if( itemsList != null ) {
			//REPLACE mytab SELECT * FROM mytab2
			//or VALUES ('as', ?, 565)
			
			if( useValues ) {
				sql += " VALUES";
			}
			
			sql += " "+itemsList;
		}
		
		return sql;
	}

}
 public class AllColumns implements SelectItem {
	public void accept(SelectItemVisitor selectItemVisitor) {
		selectItemVisitor.visit(this);
	}
	
	public String toString() {
		return "*";
	}
}
 public class AllTableColumns implements SelectItem {
	private Table table;
	
	public AllTableColumns() {
	}

	public AllTableColumns(Table tableName) {
		this.table = tableName;
	}

	
	public Table getTable() {
		return table;
	}

	public void setTable(Table table) {
		this.table = table;
	}

	public void accept(SelectItemVisitor selectItemVisitor) {
		selectItemVisitor.visit(this);
	}
	
	public String toString() {
		return table+".*";
	}

}
 public class Distinct {
	private List<SelectExpressionItem> onSelectItems;
	
	/**
	 * A list of {@link SelectItem}s expressions, as in "select DISTINCT ON (a,b,c) a,b FROM..." 
	 * @return a list of {@link SelectItem}s expressions
	 */
	public List<SelectExpressionItem> getOnSelectItems() {
		return onSelectItems;
	}

	public void setOnSelectItems(List<SelectExpressionItem> list) {
		onSelectItems = list;
	}

	public String toString() {
		String sql = "DISTINCT";
		
		if(onSelectItems != null && onSelectItems.size() > 0) {
			sql += " ON ("+PlainSelect.getStringList(onSelectItems)+")";
		}
		
		return sql;
	}
}
 public interface FromItem {
	public void accept(FromItemVisitor fromItemVisitor);
	public String getAlias();
	public void setAlias(String alias);
	
}
 public class Join {
	private boolean outer = false;
	private boolean right = false;
	private boolean left = false;
	private boolean natural = false;
	private boolean full = false;
	private boolean inner = false;
	private boolean simple = false;
	private FromItem rightItem;
	private Expression onExpression;
	private List<Column> usingColumns; 

	/**
	 * Whether is a tab1,tab2 join
	 * @return true if is a "tab1,tab2" join
	 */
	public boolean isSimple() {
		return simple;
	}

	public void setSimple(boolean b) {
		simple = b;
	}
	/**
	 * Whether is a "INNER" join
	 * @return true if is a "INNER" join
	 */
	public boolean isInner() {
		return inner;
	}

	public void setInner(boolean b) {
		inner = b;
	}
	
	/**
	 * Whether is a "OUTER" join
	 * @return true if is a "OUTER" join
	 */
	public boolean isOuter() {
		return outer;
	}

	public void setOuter(boolean b) {
		outer = b;
	}

	/**
	 * Whether is a "LEFT" join
	 * @return true if is a "LEFT" join
	 */
	public boolean isLeft() {
		return left;
	}

	public void setLeft(boolean b) {
		left = b;
	}

	/**
	 * Whether is a "RIGHT" join
	 * @return true if is a "RIGHT" join
	 */
	public boolean isRight() {
		return right;
	}

	public void setRight(boolean b) {
		right = b;
	}

	/**
	 * Whether is a "NATURAL" join
	 * @return true if is a "NATURAL" join
	 */
	public boolean isNatural() {
		return natural;
	}

	public void setNatural(boolean b) {
		natural = b;
	}

	/**
	 * Whether is a "FULL" join
	 * @return true if is a "FULL" join
	 */
	public boolean isFull() {
		return full;
	}

	public void setFull(boolean b) {
		full = b;
	}

	/**
	 * Returns the right item of the join
	 * @return the item to the right of the JOIN
	 */
	public FromItem getRightItem() {
		return rightItem;
	}

	public void setRightItem(FromItem item) {
		rightItem = item;
	}

	/**
	 * Returns the "ON" expression (if any)
	 * @return the Join expression
	 */
	public Expression getOnExpression() {
		return onExpression;
	}

	public void setOnExpression(Expression expression) {
		onExpression = expression;
	}

	/**
	 * Returns the "USING" list of {@link net.sf.jsqlparser.schema.Column}s (if any)
	 * @return the USING columns
	 */
	public List<Column> getUsingColumns() {
		return usingColumns;
	}

	public void setUsingColumns(List<Column> list) {
		usingColumns = list;
	}

	public String toString() {
		if (isSimple())
			return "" + rightItem;
		else
		{
			String type = "";
	
			if (isRight())
				type += "RIGHT ";
			else if (isNatural())
				type += "NATURAL ";
			else if (isFull())
				type += "FULL ";
			else if (isLeft())
				type += "LEFT ";
			
			if (isOuter())
				type += "OUTER ";
			else if (isInner())
				type += "INNER ";

			return type +"JOIN " +
			rightItem+
			((onExpression!=null)?" ON "+onExpression+"":"")+
			PlainSelect.getFormatedList(usingColumns, "USING", true, true);
		}
		
	}
}
 public class SubJoin implements FromItem {
	private FromItem left;
	private Join join;
	private String alias;

	public void accept(FromItemVisitor fromItemVisitor) {
		fromItemVisitor.visit(this);
	}

	public FromItem getLeft() {
		return left;
	}

	public void setLeft(FromItem l) {
		left = l;
	}
	
	public Join getJoin() {
		return join;
	}

	public void setJoin(Join j) {
		join = j;
	}

	public String getAlias() {
		return alias;
	}

	public void setAlias(String string) {
		alias = string;
	}
	
	public String toString () {
		return "("+left+" "+join+")"+((alias!=null)?" AS "+alias:"");
	}
}
 public class Limit {
	private long offset;
	private long rowCount ;
	private boolean rowCountJdbcParameter = false;
	private boolean offsetJdbcParameter = false;
	private boolean limitAll;
	
	public long getOffset() {
		return offset;
	}

	public long getRowCount() {
		return rowCount;
	}

	public void setOffset(long l) {
		offset = l;
	}

	public void setRowCount(long l) {
		rowCount = l;
	}

	public boolean isOffsetJdbcParameter() {
		return offsetJdbcParameter;
	}

	public boolean isRowCountJdbcParameter() {
		return rowCountJdbcParameter;
	}

	public void setOffsetJdbcParameter(boolean b) {
		offsetJdbcParameter = b;
	}

	public void setRowCountJdbcParameter(boolean b) {
		rowCountJdbcParameter = b;
	}


	/**
	 * @return true if the limit is "LIMIT ALL [OFFSET ...])
	 */
	public boolean isLimitAll() {
		return limitAll;
	}

	public void setLimitAll(boolean b) {
		limitAll = b;
	}

	public String toString() {
	    String retVal = "";
	    if (rowCount > 0 || rowCountJdbcParameter ) {
	        retVal += " LIMIT "+(rowCountJdbcParameter?"?":rowCount+"");
	    }
	    if (offset > 0 || offsetJdbcParameter) {
	        retVal += " OFFSET "+(offsetJdbcParameter?"?":offset+"");
	    }
	    return retVal;
	}
}
 public class OrderByElement {
	private Expression expression;
	private boolean asc = true; 
	

	public boolean isAsc() {
		return asc;
	}

	public void setAsc(boolean b) {
		asc = b;
	}


	public void accept(OrderByVisitor orderByVisitor){
		orderByVisitor.visit(this);
	}

	public Expression getExpression() {
		return expression;
	}

	public void setExpression(Expression expression) {
		this.expression = expression;
	}

	public String toString() {
		return ""+expression+((asc)?"":" DESC");
	}
}
 public class PlainSelect implements SelectBody {
	private Distinct distinct = null;
	private List<SelectItem> selectItems;
	private Table into;
	private FromItem fromItem;
	private List<Join> joins;
	private Expression where;
	private List<Column> groupByColumnReferences;
	private List<OrderByElement> orderByElements;
	private Expression having;
	private Limit limit;
	private Top top;
	


	/**
	 * The {@link FromItem} in this query
	 * @return the {@link FromItem}
	 */
	public FromItem getFromItem() {
		return fromItem;
	}

	public Table getInto() {
		return into;
	}

	/**
	 * The {@link SelectItem}s in this query (for example the A,B,C in "SELECT A,B,C")
	 * @return a list of {@link SelectItem}s
	 */
	public List<SelectItem> getSelectItems() {
		return selectItems;
	}

	public Expression getWhere() {
		return where;
	}

	public void setFromItem(FromItem item) {
		fromItem = item;
	}

	public void setInto(Table table) {
		into = table;
	}


	public void setSelectItems(List<SelectItem> list) {
		selectItems = list;
	}

	public void setWhere(Expression where) {
		this.where = where;
	}

	
	/**
	 * The list of {@link Join}s
	 * @return the list of {@link Join}s
	 */
	public List<Join> getJoins() {
		return joins;
	}

	public void setJoins(List<Join> list) {
		joins = list;
	}

	public void accept(SelectVisitor selectVisitor){
		selectVisitor.visit(this);
	}

	public List<OrderByElement> getOrderByElements() {
		return orderByElements;
	}

	public void setOrderByElements(List<OrderByElement> orderByElements) {
		this.orderByElements = orderByElements;
	}

	public Limit getLimit() {
		return limit;
	}

	public void setLimit(Limit limit) {
		this.limit = limit;
	}

	public Top getTop() {
		return top;
	}

	public void setTop(Top top) {
		this.top = top;
	}

	public Distinct getDistinct() {
		return distinct;
	}

	public void setDistinct(Distinct distinct) {
		this.distinct = distinct;
	}

	public Expression getHaving() {
		return having;
	}

	public void setHaving(Expression expression) {
		having = expression;
	}

	/**
	 * A list of {@link Expression}s of the GROUP BY clause.
	 * It is null in case there is no GROUP BY clause
	 * @return a list of {@link Expression}s 
	 */
	public List<Column> getGroupByColumnReferences() {
		return groupByColumnReferences;
	}

	public void setGroupByColumnReferences(List<Column> list) {
		groupByColumnReferences = list;
	}

	public String toString() {
		String sql = "";

		sql = "SELECT ";
		sql += ((distinct != null)?""+distinct+" ":"");
		sql += ((top != null)?""+top+" ":"");
		sql += getStringList(selectItems);
		sql += " FROM " + fromItem;
		if (joins != null) {
			Iterator it = joins.iterator();
			while(it.hasNext()) {
				Join join = (Join)it.next();
				if (join.isSimple()) {
					sql += ", " + join;
				}
				else {
					sql += " " + join;
				}
			}
		}
		//sql += getFormatedList(joins, "", false, false);
		sql += ((where != null) ? " WHERE " + where : "");
		sql += getFormatedList(groupByColumnReferences, "GROUP BY");
		sql += ((having != null) ? " HAVING " + having : "");
		sql += orderByToString(orderByElements);
		sql += ((limit != null) ? limit+"" : "");

		return sql;
	}


	public static String orderByToString(List<OrderByElement> orderByElements) {
		return getFormatedList(orderByElements, "ORDER BY");
	}

	
	public static String getFormatedList(List list, String expression) {
		return getFormatedList(list, expression, true, false);
	}

	
	public static String getFormatedList(List list, String expression, boolean useComma, boolean useBrackets) {
		String sql = getStringList(list, useComma, useBrackets);

		if (sql.length() > 0) {
		    if (expression.length() > 0) {
		        sql = " " + expression + " " + sql;
		    } else { 
		        sql = " " + sql;
		    }
		}

		return sql;
	}

	/**
	 * List the toString out put of the objects in the List comma separated. If
	 * the List is null or empty an empty string is returned.
	 * 
	 * The same as getStringList(list, true, false)
	 * @see #getStringList(List, boolean, boolean)
	 * @param list
	 *            list of objects with toString methods
	 * @return comma separated list of the elements in the list
	 */
	public static String getStringList(List list) {
		return getStringList(list, true, false);
	}

	/**
	 * List the toString out put of the objects in the List that can be comma separated. If
	 * the List is null or empty an empty string is returned.
	 * 
	 * @param list list of objects with toString methods
	 * @param useComma true if the list has to be comma separated
	 * @param useBrackets true if the list has to be enclosed in brackets
	 * @return comma separated list of the elements in the list
	 */
	public static String getStringList(List list, boolean useComma, boolean useBrackets) {
		String ans = "";
		String comma = ",";
		if (!useComma) {
		    comma = "";
		}
		if (list != null) {
		    if (useBrackets) {
		        ans += "(";
		    }
		    
			for (int i = 0; i < list.size(); i++) {
				ans += "" + list.get(i) + ((i < list.size() - 1) ? comma + " " : "");
			}
			
		    if (useBrackets) {
		        ans += ")";
		    }
		}

		return ans;
	}
}
 public class Select implements Statement {
	private SelectBody selectBody;
	private List<WithItem> withItemsList;
	
	public void accept(StatementVisitor statementVisitor) {
		statementVisitor.visit(this);
	}

	public SelectBody getSelectBody() {
		return selectBody;
	}

	public void setSelectBody(SelectBody body) {
		selectBody = body;
	}
	
	public String toString() {
		StringBuffer retval = new StringBuffer();
		if (withItemsList != null && !withItemsList.isEmpty()) {
			retval.append("WITH ");
			for (Iterator<WithItem> iter = withItemsList.iterator(); iter.hasNext();) {
				WithItem withItem = (WithItem)iter.next();
				retval.append(withItem);
				if (iter.hasNext())
					retval.append(",");
				retval.append(" ");
			}
		}
		retval.append(selectBody);
		return retval.toString();
	}

	public List<WithItem> getWithItemsList() {
		return withItemsList;
	}

	public void setWithItemsList(List<WithItem> withItemsList) {
		this.withItemsList = withItemsList;
	}
}
 public interface SelectBody {
	public void accept(SelectVisitor selectVisitor);
}
 public class SelectExpressionItem implements SelectItem {
	private Expression expression;
	private String alias;
	
	public String getAlias() {
		return alias;
	}

	public Expression getExpression() {
		return expression;
	}

	public void setAlias(String string) {
		alias = string;
	}

	public void setExpression(Expression expression) {
		this.expression = expression;
	}

	public void accept(SelectItemVisitor selectItemVisitor) {
		selectItemVisitor.visit(this);
	}
	
	public String toString() {
		return expression+((alias!=null)?" AS "+alias:"");
	}
}
 public interface SelectItem {
	public void accept(SelectItemVisitor selectItemVisitor);
}
 public class SubSelect implements FromItem, Expression, ItemsList {
	private SelectBody selectBody;
	private String alias;

	public void accept(FromItemVisitor fromItemVisitor) {
		fromItemVisitor.visit(this);
	}

	public SelectBody getSelectBody() {
		return selectBody;
	}

	public void setSelectBody(SelectBody body) {
		selectBody = body;
	}

	public void accept(ExpressionVisitor expressionVisitor) {
		expressionVisitor.visit(this);
	}

	public String getAlias() {
		return alias;
	}

	public void setAlias(String string) {
		alias = string;
	}

	public void accept(ItemsListVisitor itemsListVisitor) {
		itemsListVisitor.visit(this);
	}

	public String toString () {
		return "("+selectBody+")"+((alias!=null)?" "+alias:"");
	}
}
 public class Top {
	private long rowCount ;
	private boolean rowCountJdbcParameter = false;

	public long getRowCount() {
		return rowCount;
	}

	
	public void setRowCount(long l) {
		rowCount = l;
	}

	public boolean isRowCountJdbcParameter() {
		return rowCountJdbcParameter;
	}

	public void setRowCountJdbcParameter(boolean b) {
		rowCountJdbcParameter = b;
	}
	
	public String toString() {
		return "TOP "+(rowCountJdbcParameter?"?":rowCount+"");
	}


}
 public class Union implements SelectBody {

	private List<PlainSelect> plainSelects;
	private List<OrderByElement> orderByElements;
	private Limit limit;
	private boolean distinct;
	private boolean all;
	
	
	public void accept(SelectVisitor selectVisitor){
		selectVisitor.visit(this);
	}

	public List<OrderByElement> getOrderByElements() {
		return orderByElements;
	}

	/**
	 * the list of {@link PlainSelect}s in this UNION
	 * @return the list of {@link PlainSelect}s
	 */
	public List<PlainSelect> getPlainSelects() {
		return plainSelects;
	}

	public void setOrderByElements(List<OrderByElement> orderByElements) {
		this.orderByElements = orderByElements;
	}

	public void setPlainSelects(List<PlainSelect> list) {
		plainSelects = list;
	}

	public Limit getLimit() {
		return limit;
	}

	public void setLimit(Limit limit) {
		this.limit = limit;
	}
	
	/**
	 * This is not 100% right; every UNION should have their own All/Distinct clause...
	 * @return true if this union is a UNION ALL
	 */
	public boolean isAll() {
		return all;
	}

	public void setAll(boolean all) {
		this.all = all;
	}

	/**
	 * This is not 100% right; every UNION should have their own All/Distinct clause...
	 * @return true if this union is a UNION DISTINCT
	 */
	public boolean isDistinct() {
		return distinct;
	}

	public void setDistinct(boolean distinct) {
		this.distinct = distinct;
	}
	
	public String toString() {

		String selects = "";
		String allDistinct = "";
		if (isAll()) {
			allDistinct = "ALL ";
		} else if (isDistinct()) {
			allDistinct = "DISTINCT ";
		}
			
		for (int i = 0; i < plainSelects.size(); i++) {
			selects += plainSelects.get(i) + ((i < plainSelects.size() - 1) ? " UNION " + allDistinct : "");
		}

		return selects + 
				((orderByElements!=null)?PlainSelect.orderByToString(orderByElements):"") +
				((limit!=null)?limit+"":"");  
	}
	

}
 public class WithItem {
	private String name;
	private	List<SelectExpressionItem> withItemList;
	private SelectBody selectBody;

	/**
	 * The name of this WITH item (for example, "myWITH" in "WITH myWITH AS (SELECT A,B,C))"
	 * @return the name of this WITH
	 */
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	/**
	 * The {@link SelectBody} of this WITH item is the part after the "AS" keyword
	 * @return {@link SelectBody} of this WITH item
	 */
	public SelectBody getSelectBody() {
		return selectBody;
	}
	public void setSelectBody(SelectBody selectBody) {
		this.selectBody = selectBody;
	}
	
	/**
	 * The {@link SelectItem}s in this WITH (for example the A,B,C in "WITH mywith (A,B,C) AS ...")
	 * @return a list of {@link SelectItem}s
	 */
	public List<SelectExpressionItem> getWithItemList() {
		return withItemList;
	}
	public void setWithItemList(List<SelectExpressionItem> withItemList) {
		this.withItemList = withItemList;
	}
	
	public String toString() {
		return name + ((withItemList != null)?" " + PlainSelect.getStringList(withItemList, true, true):"") + " AS (" + selectBody + ")";
	}
	
	
}
 public class Truncate implements Statement {
	private Table table;

	public void accept(StatementVisitor statementVisitor) {
		statementVisitor.visit(this);
	}

	public Table getTable() {
		return table;
	}

	public void setTable(Table table) {
		this.table = table;
	}

	public String toString() {
		return "TRUNCATE TABLE "+table;
	}
}
 public class Update implements Statement {
	private Table table;
	private Expression where;
	private List<Column> columns;
	private List<Expression> expressions;

	public void accept(StatementVisitor statementVisitor) {
		statementVisitor.visit(this);
	}

	public Table getTable() {
		return table;
	}

	public Expression getWhere() {
		return where;
	}

	public void setTable(Table name) {
		table = name;
	}

	public void setWhere(Expression expression) {
		where = expression;
	}

	/**
	 * The {@link net.sf.jsqlparser.schema.Column}s in this update (as col1 and col2 in UPDATE col1='a', col2='b')
	 * @return a list of {@link net.sf.jsqlparser.schema.Column}s
	 */
	public List<Column> getColumns() {
		return columns;
	}

	/**
	 * The {@link Expression}s in this update (as 'a' and 'b' in UPDATE col1='a', col2='b')
	 * @return a list of {@link Expression}s
	 */
	public List<Expression> getExpressions() {
		return expressions;
	}

	public void setColumns(List<Column> list) {
		columns = list;
	}

	public void setExpressions(List<Expression> list) {
		expressions = list;
	}

}

import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.DoubleValue;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.Function;
import net.sf.jsqlparser.expression.InverseExpression;
import net.sf.jsqlparser.expression.JdbcParameter;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.DateValue;
import net.sf.jsqlparser.expression.TimeValue;
import net.sf.jsqlparser.expression.TimestampValue;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.BooleanValue;
import net.sf.jsqlparser.expression.CaseExpression;
import net.sf.jsqlparser.expression.WhenClause;
import net.sf.jsqlparser.expression.AnyComparisonExpression;
import net.sf.jsqlparser.expression.AllComparisonExpression;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseAnd;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseOr;
import net.sf.jsqlparser.expression.operators.arithmetic.BitwiseXor;
import net.sf.jsqlparser.expression.operators.arithmetic.Concat;
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.Between;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
import net.sf.jsqlparser.expression.operators.relational.Matches;
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.create.table.ColDataType;
import net.sf.jsqlparser.statement.create.table.ColumnDefinition;
import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.create.table.Index;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.drop.Drop;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.replace.Replace;
import net.sf.jsqlparser.statement.select.AllColumns;
import net.sf.jsqlparser.statement.select.AllTableColumns;
import net.sf.jsqlparser.statement.select.Distinct;
import net.sf.jsqlparser.statement.select.FromItem;
import net.sf.jsqlparser.statement.select.Join;
import net.sf.jsqlparser.statement.select.SubJoin;
import net.sf.jsqlparser.statement.select.Limit;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectBody;
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
import net.sf.jsqlparser.statement.select.SelectItem;
import net.sf.jsqlparser.statement.select.SubSelect;
import net.sf.jsqlparser.statement.select.Top;
import net.sf.jsqlparser.statement.select.Union;
import net.sf.jsqlparser.statement.select.WithItem;
import net.sf.jsqlparser.statement.truncate.Truncate;
import net.sf.jsqlparser.statement.update.Update;
  final public SelectItem SelectItem() throws ParseException {
        Function function = null;
        AllColumns allTableColumns = null;
        Column tableColumn = null;
        String alias = null;
        SelectItem selectItem = null;
        SelectExpressionItem selectExpressionItem = null;
        Expression expression = null;
        SubSelect subSelect = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 83:
      jj_consume_token(83);
           selectItem = new AllColumns();
      break;
    default:
      jj_la1[54] = jj_gen;
      if (jj_2_6(2147483647)) {
        selectItem = AllTableColumns();
      } else {
        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
        case K_KEY:
        case K_NOT:
        case K_END:
        case K_NULL:
        case K_CASE:
        case K_BEGIN:
        case K_EXISTS:
        case K_REPLACE:
        case K_CAST:
        case S_DOUBLE:
        case S_INTEGER:
        case S_IDENTIFIER:
        case S_CHAR_LITERAL:
        case S_QUOTED_IDENTIFIER:
        case 80:
        case 84:
        case 96:
        case 97:
        case 100:
        case 102:
        case 103:
        case 104:
          expression = Expression();
                                   selectExpressionItem = new SelectExpressionItem(); selectExpressionItem.setExpression(expression);
          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
          case K_AS:
          case K_KEY:
          case K_END:
          case K_BEGIN:
          case S_IDENTIFIER:
          case S_QUOTED_IDENTIFIER:
            alias = Alias();
                                          selectExpressionItem.setAlias(alias);
            break;
          default:
            jj_la1[53] = jj_gen;
            ;
          }
                                                                                     selectItem = selectExpressionItem;
          break;
        default:
          jj_la1[55] = jj_gen;
          jj_consume_token(-1);
          throw new ParseException();
        }
      }
    }
                {if (true) return selectItem;}
    throw new Error("Missing return statement in function");
  }

  final public AllTableColumns AllTableColumns() throws ParseException {
        Table table = null;
    table = Table();
    jj_consume_token(82);
    jj_consume_token(83);
                {if (true) return new AllTableColumns(table);}
    throw new Error("Missing return statement in function");
  }

  final public String Alias() throws ParseException {
  String retval = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case K_AS:
      jj_consume_token(K_AS);
      break;
    default:
      jj_la1[56] = jj_gen;
      ;
    }
    retval = RelObjectName();
     {if (true) return retval;}
    throw new Error("Missing return statement in function");
  }

  final public void IntoClause() throws ParseException {
    jj_consume_token(K_INTO);
    Table();
    label_11:
    while (true) {
      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
      case 79:
        ;
        break;
      default:
        jj_la1[57] = jj_gen;
        break label_11;
      }
      jj_consume_token(79);
      Table();
    }
  }

  final public FromItem FromItem() throws ParseException {
        FromItem fromItem = null;
        String alias = null;
    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
    case 80:
      jj_consume_token(80);
      if (jj_2_7(2147483647)) {
        fromItem = SubJoin();