public void testIfNode_true() throws Exception {
    SelectClauseNode select = new SelectClauseNode("select");
    select.appendNode(OtherNode.of(" * "));
    FromClauseNode from = new FromClauseNode("from");
    from.appendNode(WhitespaceNode.of(" "));
    from.appendNode(new WordNode("aaa"));
    from.appendNode(WhitespaceNode.of(" "));
    WhereClauseNode where = new WhereClauseNode("where");
    where.appendNode(WhitespaceNode.of(" "));
    IfNode ifNode = new IfNode(location, "true", "/*if true*/");
    ifNode.appendNode(new WordNode("bbb"));
    ifNode.appendNode(OtherNode.of(" = "));
    ifNode.appendNode(new WordNode("ccc"));
    IfBlockNode ifBlockNode = new IfBlockNode();
    ifBlockNode.setIfNode(ifNode);
    ifBlockNode.setEndNode(new EndNode("/*end*/"));
    where.appendNode(ifBlockNode);

    SelectStatementNode statement = new SelectStatementNode();
    statement.setSelectClauseNode(select);
    statement.setFromClauseNode(from);
    statement.setWhereClauseNode(where);
    AnonymousNode root = new AnonymousNode();
    root.appendNode(statement);

    ExpressionEvaluator evaluator = new ExpressionEvaluator();
    NodePreparedSqlBuilder builder =
        new NodePreparedSqlBuilder(
            config, SqlKind.SELECT, "dummyPath", evaluator, SqlLogType.FORMATTED);
    PreparedSql sql = builder.build(statement, Function.identity());
    assertEquals("select * from aaa where bbb = ccc", sql.getRawSql());
  }
  public void testBindVariableNode() throws Exception {
    SelectClauseNode select = new SelectClauseNode("select");
    select.appendNode(OtherNode.of(" * "));
    FromClauseNode from = new FromClauseNode("from");
    from.appendNode(WhitespaceNode.of(" "));
    from.appendNode(new WordNode("aaa"));
    from.appendNode(WhitespaceNode.of(" "));
    WhereClauseNode where = new WhereClauseNode("where");
    where.appendNode(WhitespaceNode.of(" "));
    where.appendNode(new WordNode("bbb"));
    where.appendNode(OtherNode.of(" = "));
    BindVariableNode variable1 = new BindVariableNode(location, "name", "/*#name*/");
    variable1.setWordNode(new WordNode("'hoge'"));
    where.appendNode(variable1);
    where.appendNode(WhitespaceNode.of(" "));
    where.appendNode(new LogicalOperatorNode("and"));
    where.appendNode(WhitespaceNode.of(" "));
    where.appendNode(new WordNode("ccc"));
    where.appendNode(OtherNode.of(" = "));
    BindVariableNode variable2 = new BindVariableNode(location, "salary", "/*#salary*/");
    variable2.setWordNode(new WordNode("100"));
    where.appendNode(variable2);

    SelectStatementNode statement = new SelectStatementNode();
    statement.setSelectClauseNode(select);
    statement.setFromClauseNode(from);
    statement.setWhereClauseNode(where);
    AnonymousNode root = new AnonymousNode();
    root.appendNode(statement);

    ExpressionEvaluator evaluator = new ExpressionEvaluator();
    evaluator.add("name", new Value(String.class, "hoge"));
    evaluator.add("salary", new Value(BigDecimal.class, new BigDecimal(100)));
    NodePreparedSqlBuilder builder =
        new NodePreparedSqlBuilder(
            config, SqlKind.SELECT, "dummyPath", evaluator, SqlLogType.FORMATTED);
    PreparedSql sql = builder.build(root, Function.identity());
    assertEquals("select * from aaa where bbb = ? and ccc = ?", sql.getRawSql());
    assertEquals(2, sql.getParameters().size());
    assertEquals("hoge", sql.getParameters().get(0).getWrapper().get());
    assertEquals(new BigDecimal(100), sql.getParameters().get(1).getWrapper().get());
  }
  protected SqlNode appendTopNode(SelectStatementNode node) {
    SelectClauseNode select = new SelectClauseNode(node.getSelectClauseNode().getWordNode());
    select.appendNode(new FragmentNode(" top (" + limit + ")"));
    for (SqlNode child : node.getSelectClauseNode().getChildren()) {
      select.appendNode(child);
    }

    SelectStatementNode result = new SelectStatementNode();
    result.setSelectClauseNode(select);
    result.setFromClauseNode(node.getFromClauseNode());
    result.setWhereClauseNode(node.getWhereClauseNode());
    result.setGroupByClauseNode(node.getGroupByClauseNode());
    result.setHavingClauseNode(node.getHavingClauseNode());
    result.setOrderByClauseNode(node.getOrderByClauseNode());
    result.setForUpdateClauseNode(node.getForUpdateClauseNode());
    result.setOptionClauseNode(node.getOptionClauseNode());
    return result;
  }
  @Override
  public SqlNode visitSelectStatementNode(SelectStatementNode node, Void p) {
    if (processed) {
      return node;
    }
    processed = true;

    OrderByClauseNode originalOrderBy = node.getOrderByClauseNode();
    OrderByClauseNode orderBy = node.getOrderByClauseNode();
    if (originalOrderBy != null) {
      orderBy = new OrderByClauseNode(originalOrderBy.getWordNode());
      for (SqlNode child : originalOrderBy.getChildren()) {
        orderBy.addNode(child);
      }
    } else {
      orderBy = new OrderByClauseNode("");
    }
    orderBy.addNode(new FragmentNode(" limit "));
    if (limit >= 0) {
      orderBy.addNode(new FragmentNode(String.valueOf(limit)));
    } else {
      orderBy.addNode(new FragmentNode("0"));
    }
    if (offset >= 0) {
      orderBy.addNode(new FragmentNode(" offset "));
      orderBy.addNode(new FragmentNode(String.valueOf(offset)));
    }
    ForUpdateClauseNode forUpdate = node.getForUpdateClauseNode();
    if (forUpdate != null) {
      orderBy.addNode(new FragmentNode(" "));
    }

    SelectStatementNode result = new SelectStatementNode();
    result.setSelectClauseNode(node.getSelectClauseNode());
    result.setFromClauseNode(node.getFromClauseNode());
    result.setWhereClauseNode(node.getWhereClauseNode());
    result.setGroupByClauseNode(node.getGroupByClauseNode());
    result.setHavingClauseNode(node.getHavingClauseNode());
    result.setOrderByClauseNode(orderBy);
    result.setForUpdateClauseNode(forUpdate);
    return result;
  }