void andOrList(SqlWriter writer, SqlKind sepKind) { SqlBinaryOperator sepOp = sepKind == SqlKind.AND ? SqlStdOperatorTable.AND : SqlStdOperatorTable.OR; for (int i = 0; i < list.size(); i++) { SqlNode node = list.get(i); writer.sep(sepKind.name(), false); // The precedence pulling on the LHS of a node is the // right-precedence of the separator operator, except at the start // of the list; similarly for the RHS of a node. If the operator // has left precedence 4 and right precedence 5, the precedences // in a 3-node list will look as follows: // 0 <- node1 -> 4 5 <- node2 -> 4 5 <- node3 -> 0 int lprec = (i == 0) ? 0 : sepOp.getRightPrec(); int rprec = (i == (list.size() - 1)) ? 0 : sepOp.getLeftPrec(); node.unparse(writer, lprec, rprec); } }
public boolean equalsDeep(SqlNode node, boolean fail) { if (!(node instanceof SqlNodeList)) { assert !fail : this + "!=" + node; return false; } SqlNodeList that = (SqlNodeList) node; if (this.size() != that.size()) { assert !fail : this + "!=" + node; return false; } for (int i = 0; i < list.size(); i++) { SqlNode thisChild = list.get(i); final SqlNode thatChild = that.list.get(i); if (!thisChild.equalsDeep(thatChild, fail)) { return false; } } return true; }
public int size() { return list.size(); }
public SqlNode set(int n, SqlNode node) { return list.set(n, node); }
public SqlNode get(int n) { return list.get(n); }
public void add(SqlNode node) { list.add(node); }
// implement Iterable<SqlNode> public Iterator<SqlNode> iterator() { return list.iterator(); }
public SqlNode[] toArray() { return list.toArray(new SqlNode[list.size()]); }
public int reduceExpr(int opOrdinal, List<Object> list) { final SqlParserUtil.ToTreeListItem betweenNode = (SqlParserUtil.ToTreeListItem) list.get(opOrdinal); SqlOperator op = betweenNode.getOperator(); assert op == this; // Break the expression up into expressions. For example, a simple // expression breaks down as follows: // // opOrdinal endExp1 // | | // a + b BETWEEN c + d AND e + f // |_____| |_____| |_____| // exp0 exp1 exp2 // Create the expression between 'BETWEEN' and 'AND'. final SqlParserPos pos = ((SqlNode) list.get(opOrdinal + 1)).getParserPosition(); SqlNode exp1 = SqlParserUtil.toTreeEx(list, opOrdinal + 1, 0, SqlKind.AND); if ((opOrdinal + 2) >= list.size()) { SqlParserPos lastPos = ((SqlNode) list.get(list.size() - 1)).getParserPosition(); final int line = lastPos.getEndLineNum(); final int col = lastPos.getEndColumnNum() + 1; SqlParserPos errPos = new SqlParserPos(line, col, line, col); throw SqlUtil.newContextException( errPos, EigenbaseResource.instance().BetweenWithoutAnd.ex()); } final Object o = list.get(opOrdinal + 2); if (!(o instanceof SqlParserUtil.ToTreeListItem)) { SqlParserPos errPos = ((SqlNode) o).getParserPosition(); throw SqlUtil.newContextException( errPos, EigenbaseResource.instance().BetweenWithoutAnd.ex()); } if (((SqlParserUtil.ToTreeListItem) o).getOperator().getKind() != SqlKind.AND) { SqlParserPos errPos = ((SqlParserUtil.ToTreeListItem) o).getPos(); throw SqlUtil.newContextException( errPos, EigenbaseResource.instance().BetweenWithoutAnd.ex()); } // Create the expression after 'AND', but stopping if we encounter an // operator of lower precedence. // // For example, // a BETWEEN b AND c + d OR e // becomes // (a BETWEEN b AND c + d) OR e // because OR has lower precedence than BETWEEN. SqlNode exp2 = SqlParserUtil.toTreeEx(list, opOrdinal + 3, getRightPrec(), SqlKind.OTHER); // Create the call. SqlNode exp0 = (SqlNode) list.get(opOrdinal - 1); SqlCall newExp = createCall( betweenNode.getPos(), exp0, exp1, exp2, SqlLiteral.createSymbol(flag, SqlParserPos.ZERO)); // Replace all of the matched nodes with the single reduced node. SqlParserUtil.replaceSublist(list, opOrdinal - 1, opOrdinal + 4, newExp); // Return the ordinal of the new current node. return opOrdinal - 1; }