⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.java

📁 Java写的含有一个jdbc驱动的小型数据库数据库引擎
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
			    e = ec;

			    break;
			}
		    }
		}

		token = tTokenizer.getString();

		if (token.equals("DESC")) {
		    e.setDescending();

		    token = tTokenizer.getString();
		} else if (token.equals("ASC")) {
		    token = tTokenizer.getString();
		}

		vcolumn.addElement(e);

		len++;
	    } while (token.equals(","));

	    select.iOrderLen = len;
	}

	len = vcolumn.size();
	select.eColumn = new Expression[len];

	vcolumn.copyInto(select.eColumn);

	if (token.equals("UNION")) {
	    token = tTokenizer.getString();

	    if (token.equals("ALL")) {
		select.iUnionType = Select.UNIONALL;
	    } else {
		select.iUnionType = Select.UNION;

		tTokenizer.back();
	    }

	    tTokenizer.getThis("SELECT");

	    select.sUnion = parseSelect();
	} else if (token.equals("INTERSECT")) {
	    tTokenizer.getThis("SELECT");

	    select.iUnionType = Select.INTERSECT;
	    select.sUnion = parseSelect();
	} else if (token.equals("EXCEPT") || token.equals("MINUS")) {
	    tTokenizer.getThis("SELECT");

	    select.iUnionType = Select.EXCEPT;
	    select.sUnion = parseSelect();
	} else {
	    tTokenizer.back();
	}

	return select;
    }

    /**
     * Method declaration
     *
     *
     * @param outerjoin
     *
     * @return
     *
     * @throws SQLException
     */
    private TableFilter parseTableFilter(boolean outerjoin)
	    throws SQLException {
	String token = tTokenizer.getString();
	Table  t = null;

	if (token.equals("(")) {
	    tTokenizer.getThis("SELECT");

	    Select s = parseSelect();
	    Result r = s.getResult(0);

	    // it's not a problem that this table has not a unique name
	    t = new Table(dDatabase, false, "SYSTEM_SUBQUERY", false);

	    tTokenizer.getThis(")");
	    t.addColumns(r);
	    t.createPrimaryKey();

	    // subquery creation can't fail because of violation of primary key
	    t.insert(r, cChannel);
	} else {
	    cChannel.check(token, Access.SELECT);

	    t = dDatabase.getTable(token, cChannel);
	}

	String sAlias = null;

	token = tTokenizer.getString();

	if (token.equals("AS")) {
	    sAlias = tTokenizer.getName();
	} else if (tTokenizer.wasName()) {
	    sAlias = token;
	} else {
	    tTokenizer.back();
	}

	return new TableFilter(t, sAlias, outerjoin);
    }

    /**
     * Method declaration
     *
     *
     * @param e1
     * @param e2
     *
     * @return
     */
    private Expression addCondition(Expression e1, Expression e2) {
	if (e1 == null) {
	    return e2;
	} else if (e2 == null) {
	    return e1;
	} else {
	    return new Expression(Expression.AND, e1, e2);
	}
    }

    /**
     * Method declaration
     *
     *
     * @param type
     *
     * @return
     *
     * @throws SQLException
     */
    private Object getValue(int type) throws SQLException {
	Expression r = parseExpression();

	r.resolve(null);

	return r.getValue(type);
    }

    /**
     * Method declaration
     *
     *
     * @return
     *
     * @throws SQLException
     */
    private Expression parseExpression() throws SQLException {
	read();

	// todo: really this should be in readTerm
	// but then grouping is much more complex
	if (iToken == Expression.MIN || iToken == Expression.MAX
		|| iToken == Expression.COUNT || iToken == Expression.SUM
		|| iToken == Expression.AVG) {
	    int type = iToken;

	    read();

	    Expression r = new Expression(type, readOr(), null);

	    tTokenizer.back();

	    return r;
	}

	Expression r = readOr();

	tTokenizer.back();

	return r;
    }

    /**
     * Method declaration
     *
     *
     * @return
     *
     * @throws SQLException
     */
    private Expression readOr() throws SQLException {
	Expression r = readAnd();

	while (iToken == Expression.OR) {
	    int	       type = iToken;
	    Expression a = r;

	    read();

	    r = new Expression(type, a, readAnd());
	}

	return r;
    }

    /**
     * Method declaration
     *
     *
     * @return
     *
     * @throws SQLException
     */
    private Expression readAnd() throws SQLException {
	Expression r = readCondition();

	while (iToken == Expression.AND) {
	    int	       type = iToken;
	    Expression a = r;

	    read();

	    r = new Expression(type, a, readCondition());
	}

	return r;
    }

    /**
     * Method declaration
     *
     *
     * @return
     *
     * @throws SQLException
     */
    private Expression readCondition() throws SQLException {
	if (iToken == Expression.NOT) {
	    int type = iToken;

	    read();

	    return new Expression(type, readCondition(), null);
	} else if (iToken == Expression.EXISTS) {
	    int type = iToken;

	    read();
	    readThis(Expression.OPEN);
	    Trace.check(iToken == Expression.SELECT, Trace.UNEXPECTED_TOKEN);

	    Expression s = new Expression(parseSelect());

	    read();
	    readThis(Expression.CLOSE);

	    return new Expression(type, s, null);
	} else {
	    Expression a = readConcat();
	    boolean    not = false;

	    if (iToken == Expression.NOT) {
		not = true;

		read();
	    }

	    if (iToken == Expression.LIKE) {
		read();

		Expression b = readConcat();
		char       escape = 0;

		if (sToken.equals("ESCAPE")) {
		    read();

		    Expression c = readTerm();

		    Trace.check(c.getType() == Expression.VALUE,
				Trace.INVALID_ESCAPE);

		    String s = (String) c.getValue(Column.VARCHAR);

		    if (s == null || s.length() < 1) {
			throw Trace.error(Trace.INVALID_ESCAPE, s);
		    }

		    escape = s.charAt(0);
		}

		a = new Expression(Expression.LIKE, a, b);

		a.setLikeEscape(escape);
	    } else if (iToken == Expression.BETWEEN) {
		read();

		Expression l = new Expression(Expression.BIGGER_EQUAL, a,
					      readConcat());

		readThis(Expression.AND);

		Expression h = new Expression(Expression.SMALLER_EQUAL, a,
					      readConcat());

		a = new Expression(Expression.AND, l, h);
	    } else if (iToken == Expression.IN) {
		int type = iToken;

		read();
		readThis(Expression.OPEN);

		Expression b = null;

		if (iToken == Expression.SELECT) {
		    b = new Expression(parseSelect());

		    read();
		} else {
		    tTokenizer.back();

		    Vector v = new Vector();

		    while (true) {
			v.addElement(getValue(Column.VARCHAR));
			read();

			if (iToken != Expression.COMMA) {
			    break;
			}
		    }

		    b = new Expression(v);
		}

		readThis(Expression.CLOSE);

		a = new Expression(type, a, b);
	    } else {
		Trace.check(!not, Trace.UNEXPECTED_TOKEN);

		if (Expression.isCompare(iToken)) {
		    int type = iToken;

		    read();

		    return new Expression(type, a, readConcat());
		}

		return a;
	    }

	    if (not) {
		a = new Expression(Expression.NOT, a, null);
	    }

	    return a;
	}
    }

    /**
     * Method declaration
     *
     *
     * @param type
     *
     * @throws SQLException
     */
    private void readThis(int type) throws SQLException {
	Trace.check(iToken == type, Trace.UNEXPECTED_TOKEN);
	read();
    }

    /**
     * Method declaration
     *
     *
     * @return
     *
     * @throws SQLException
     */
    private Expression readConcat() throws SQLException {
	Expression r = readSum();

	while (iToken == Expression.STRINGCONCAT) {
	    int	       type = Expression.CONCAT;
	    Expression a = r;

	    read();

	    r = new Expression(type, a, readSum());
	}

	return r;
    }

    /**
     * Method declaration
     *
     *
     * @return
     *
     * @throws SQLException
     */
    private Expression readSum() throws SQLException {
	Expression r = readFactor();

	while (true) {
	    int type;

	    if (iToken == Expression.PLUS) {
		type = Expression.ADD;
	    } else if (iToken == Expression.NEGATE) {
		type = Expression.SUBTRACT;
	    } else {
		break;
	    }

	    Expression a = r;

	    read();

	    r = new Expression(type, a, readFactor());
	}

	return r;
    }

    /**
     * Method declaration
     *
     *
     * @return
     *
     * @throws SQLException
     */
    private Expression readFactor() throws SQLException {
	Expression r = readTerm();

	while (iToken == Expression.MULTIPLY || iToken == Expression.DIVIDE) {
	    int	       type = iToken;
	    Expression a = r;

	    read();

	    r = new Expression(type, a, readTerm());
	}

	return r;
    }

    /**
     * Method declaration
     *
     *
     * @return
     *
     * @throws SQLException
     */
    private Expression readTerm() throws SQLException {
	Expression r = null;

	if (iToken == Expression.COLUMN) {
	    String name = sToken;

	    r = new Expression(sTable, sToken);

	    read();

	    if (iToken == Expression.OPEN) {
		Function f = new Function(dDatabase.getAlias(name), cChannel);
		int      len = f.getArgCount();
		int      i = 0;

		read();

		if (iToken != Expression.CLOSE) {
		    while (true) {
			f.setArgument(i++, readOr());

			if (iToken != Expression.COMMA) {
			    break;
			}

			read();
		    }
		}

		readThis(Expression.CLOSE);

		r = new Expression(f);
	    }
	} else if (iToken == Expression.NEGATE) {
	    int type = iToken;

	    read();

	    r = new Expression(type, readTerm(), null);
	} else if (iToken == Expression.PLUS) {
	    read();

	    r = readTerm();
	} else if (iToken == Expression.OPEN) {
	    read();

	    r = readOr();

	    if (iToken != Expression.CLOSE) {
		throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken);
	    }

	    read();
	} else if (iToken == Expression.VALUE) {
	    r = new Expression(iType, oData);

	    read();
	} else if (iToken == Expression.SELECT) {
	    r = new Expression(parseSelect());

	    read();
	} else if (iToken == Expression.MULTIPLY) {
	    r = new Expression(sTable, null);

	    read();
	} else if (iToken == Expression.IFNULL
		   || iToken == Expression.CONCAT) {
	    int type = iToken;

	    read();
	    readThis(Expression.OPEN);

	    r = readOr();

	    readThis(Expression.COMMA);

	    r = new Expression(type, r, readOr());

	    readThis(Expression.CLOSE);
	} else if (iToken == Expression.CASEWHEN) {
	    int type = iToken;

	    read();
	    readThis(Expression.OPEN);

	    r = readOr();

	    readThis(Expression.COMMA);

	    Expression thenelse = readOr();

	    readThis(Expression.COMMA);

	    // thenelse part is never evaluated; only init
	    thenelse = new Expression(type, thenelse, readOr());
	    r = new Expression(type, r, thenelse);

	    readThis(Expression.CLOSE);
	} else if (iToken == Expression.CONVERT) {
	    int type = iToken;

	    read();
	    readThis(Expression.OPEN);

	    r = readOr();

	    readThis(Expression.COMMA);

	    int t = Column.getTypeNr(sToken);

	    r = new Expression(type, r, null);

	    r.setDataType(t);
	    read();
	    readThis(Expression.CLOSE);
	} else if (iToken == Expression.CAST) {
	    read();
	    readThis(Expression.OPEN);

	    r = readOr();

	    Trace.check(sToken.equals("AS"), Trace.UNEXPECTED_TOKEN, sToken);
	    read();

	    int t = Column.getTypeNr(sToken);

	    r = new Expression(Expression.CONVERT, r, null);

	    r.setDataType(t);
	    read();
	    readThis(Expression.CLOSE);
	} else {
	    throw Trace.error(Trace.UNEXPECTED_TOKEN, sToken);
	}

	return r;
    }

    /**
     * Method declaration
     *
     *
     * @throws SQLException
     */
    private void read() throws SQLException {
	sToken = tTokenizer.getString();

	if (tTokenizer.wasValue()) {
	    iToken = Expression.VALUE;
	    oData = tTokenizer.getAsValue();
	    iType = tTokenizer.getType();
	} else if (tTokenizer.wasName()) {
	    iToken = Expression.COLUMN;
	    sTable = null;
	} else if (tTokenizer.wasLongName()) {
	    sTable = tTokenizer.getLongNameFirst();
	    sToken = tTokenizer.getLongNameLast();

	    if (sToken.equals("*")) {
		iToken = Expression.MULTIPLY;
	    } else {
		iToken = Expression.COLUMN;
	    }
	} else if (sToken.equals("")) {
	    iToken = Expression.END;
	} else if (sToken.equals("AND")) {
	    iToken = Expression.AND;
	} else if (sToken.equals("OR")) {
	    iToken = Expression.OR;
	} else if (sToken.equals("NOT")) {
	    iToken = Expression.NOT;
	} else if (sToken.equals("IN")) {
	    iToken = Expression.IN;
	} else if (sToken.equals("EXISTS")) {
	    iToken = Expression.EXISTS;
	} else if (sToken.equals("BETWEEN")) {
	    iToken = Expression.BETWEEN;
	} else if (sToken.equals("+")) {
	    iToken = Expression.PLUS;
	} else if (sToken.equals("-")) {
	    iToken = Expression.NEGATE;
	} else if (sToken.equals("*")) {
	    iToken = Expression.MULTIPLY;
	    sTable = null;    // in case of ASTERIX
	} else if (sToken.equals("/")) {
	    iToken = Expression.DIVIDE;
	} else if (sToken.equals("||")) {
	    iToken = Expression.STRINGCONCAT;
	} else if (sToken.equals("(")) {
	    iToken = Expression.OPEN;
	} else if (sToken.equals(")")) {
	    iToken = Expression.CLOSE;
	} else if (sToken.equals("SELECT")) {
	    iToken = Expression.SELECT;
	} else if (sToken.equals("<")) {
	    iToken = Expression.SMALLER;
	} else if (sToken.equals("<=")) {
	    iToken = Expression.SMALLER_EQUAL;
	} else if (sToken.equals(">=")) {
	    iToken = Expression.BIGGER_EQUAL;
	} else if (sToken.equals(">")) {
	    iToken = Expression.BIGGER;
	} else if (sToken.equals("=")) {
	    iToken = Expression.EQUAL;
	} else if (sToken.equals("IS")) {
	    sToken = tTokenizer.getString();

	    if (sToken.equals("NOT")) {
		iToken = Expression.NOT_EQUAL;
	    } else {
		iToken = Expression.EQUAL;

		tTokenizer.back();
	    }
	} else if (sToken.equals("<>") || sToken.equals("!=")) {
	    iToken = Expression.NOT_EQUAL;
	} else if (sToken.equals("LIKE")) {
	    iToken = Expression.LIKE;
	} else if (sToken.equals("COUNT")) {
	    iToken = Expression.COUNT;
	} else if (sToken.equals("SUM")) {
	    iToken = Expression.SUM;
	} else if (sToken.equals("MIN")) {
	    iToken = Expression.MIN;
	} else if (sToken.equals("MAX")) {
	    iToken = Expression.MAX;
	} else if (sToken.equals("AVG")) {
	    iToken = Expression.AVG;
	} else if (sToken.equals("IFNULL")) {
	    iToken = Expression.IFNULL;
	} else if (sToken.equals("CONVERT")) {
	    iToken = Expression.CONVERT;
	} else if (sToken.equals("CAST")) {
	    iToken = Expression.CAST;
	} else if (sToken.equals("CASEWHEN")) {
	    iToken = Expression.CASEWHEN;
	} else if (sToken.equals(",")) {
	    iToken = Expression.COMMA;
	} else {
	    iToken = Expression.END;
	}
    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -