From: <one...@us...> - 2002-11-19 15:28:12
|
Update of /cvsroot/hibernate/Hibernate/cirrus/hibernate/query In directory sc8-pr-cvs1:/tmp/cvs-serv373/hibernate/query Modified Files: ClauseParser.java FromParser.java GroupByParser.java OrderByParser.java ParserHelper.java QueryTranslator.java SelectParser.java WhereParser.java Added Files: PreprocessingParser.java Log Message: allow not between, not in in query language allow subqueries beginning with a from clause in query language --- NEW FILE: PreprocessingParser.java --- //$Id: PreprocessingParser.java,v 1.1 2002/11/19 15:28:07 oneovthafew Exp $ package cirrus.hibernate.query; import java.util.HashSet; import java.util.Map; import java.util.Set; import cirrus.hibernate.QueryException; /** * */ public class PreprocessingParser implements Parser { private static final Set operators; static { operators = new HashSet(); operators.add("<="); operators.add(">="); operators.add("=>"); operators.add("=<"); operators.add("!="); operators.add("<>"); operators.add("!#"); operators.add("!<"); operators.add("!>"); operators.add("is not"); operators.add("not like"); operators.add("not in"); operators.add("not between"); operators.add("not exists"); } private Map replacements; private boolean quoted; private StringBuffer quotedString; private ClauseParser parser = new ClauseParser(); private String lastToken; public PreprocessingParser(Map replacements) { this.replacements=replacements; } /** * @see cirrus.hibernate.query.Parser#token(String, QueryTranslator) */ public void token(String token, QueryTranslator q) throws QueryException { //handle quoted strings if (quoted) { quotedString.append(token); } if ( "'".equals(token) ) { if (quoted) { token = quotedString.toString(); } else { quotedString = new StringBuffer(20).append(token); } quoted = !quoted; } if (quoted) return; //ignore whitespace if ( ParserHelper.isWhitespace(token) ) return; //do replacements String substoken = (String) replacements.get(token); token = (substoken==null) ? token : substoken; //handle <=, >=, !=, is not, not between, not in if (lastToken==null) { lastToken=token; } else { String doubleToken = (token.length()>1) ? lastToken + ' ' + token : lastToken + token; if ( operators.contains(doubleToken) ) { parser.token(doubleToken, q); lastToken=null; } else { parser.token(lastToken, q); lastToken=token; } } } /** * @see cirrus.hibernate.query.Parser#start(QueryTranslator) */ public void start(QueryTranslator q) throws QueryException { quoted = false; parser.start(q); } /** * @see cirrus.hibernate.query.Parser#end(QueryTranslator) */ public void end(QueryTranslator q) throws QueryException { if (lastToken!=null) parser.token(lastToken, q); parser.end(q); } } Index: ClauseParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/query/ClauseParser.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** ClauseParser.java 25 Oct 2002 13:03:13 -0000 1.15 --- ClauseParser.java 19 Nov 2002 15:28:06 -0000 1.16 *************** *** 16,20 **** private List selectTokens; private boolean cacheSelectTokens = false; - private boolean quoted=false; private boolean byExpected = false; private boolean enableSubselect = false; --- 16,19 ---- *************** *** 23,87 **** String lcToken = token.toLowerCase(); ! if ( ! byExpected && ! !lcToken.equals("by") && ! !ParserHelper.isWhitespace(lcToken) ! ) throw new QueryException("BY expected after GROUP or ORDER: " + token); ! if ( lcToken.equals("'") ) { ! quoted=!quoted; } ! if (quoted) { ! child.token(token, q); } else { ! if ( !enableSubselect && lcToken.equals("select") ) { ! selectTokens = new ArrayList(); ! cacheSelectTokens = true; ! } ! else if ( !enableSubselect && lcToken.equals("from") ) { ! child = new FromParser(); ! child.start(q); ! cacheSelectTokens = false; ! } ! else if ( !enableSubselect && lcToken.equals("where") ) { ! enableSubselect = true; ! endChild(q); ! child = new WhereParser(); ! child.start(q); ! } ! else if ( lcToken.equals("order") ) { ! endChild(q); ! child = new OrderByParser(); ! byExpected = true; ! } ! else if ( lcToken.equals("having") ) { ! endChild(q); ! enableSubselect = true; ! child = new HavingParser(); ! child.start(q); ! } ! else if ( lcToken.equals("group") ) { ! endChild(q); ! child = new GroupByParser(); ! byExpected = true; ! } ! else if ( lcToken.equals("by") ) { ! if ( !byExpected ) throw new QueryException("GROUP or ORDER expected before BY"); ! child.start(q); ! byExpected = false; } else { ! if (cacheSelectTokens) { ! selectTokens.add(token); } else { ! if (child==null) { ! if ( !ParserHelper.isWhitespace(token) ) ! throw new QueryException("query must begin with SELECT or FROM: " + token); ! } ! else { ! child.token(token, q); ! } } } --- 22,75 ---- String lcToken = token.toLowerCase(); ! if ( byExpected && !lcToken.equals("by") ) ! throw new QueryException("BY expected after GROUP or ORDER: " + token); ! ! if ( !enableSubselect && lcToken.equals("select") ) { ! selectTokens = new ArrayList(); ! cacheSelectTokens = true; } ! else if ( !enableSubselect && lcToken.equals("from") ) { ! child = new FromParser(); ! child.start(q); ! cacheSelectTokens = false; ! } ! else if ( !enableSubselect && lcToken.equals("where") ) { ! enableSubselect = true; ! endChild(q); ! child = new WhereParser(); ! child.start(q); ! } ! else if ( lcToken.equals("order") ) { ! endChild(q); ! child = new OrderByParser(); ! byExpected = true; ! } ! else if ( lcToken.equals("having") ) { ! endChild(q); ! enableSubselect = true; ! child = new HavingParser(); ! child.start(q); ! } ! else if ( lcToken.equals("group") ) { ! endChild(q); ! child = new GroupByParser(); ! byExpected = true; ! } ! else if ( lcToken.equals("by") ) { ! if ( !byExpected ) throw new QueryException("GROUP or ORDER expected before BY"); ! child.start(q); ! byExpected = false; } else { ! if (cacheSelectTokens) { ! selectTokens.add(token); } else { ! if (child==null) { ! throw new QueryException("query must begin with SELECT or FROM: " + token); } else { ! child.token(token, q); } } *************** *** 113,117 **** child.end(q); } - quoted=false; byExpected=false; enableSubselect = false; --- 101,104 ---- Index: FromParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/query/FromParser.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** FromParser.java 1 Aug 2002 13:13:36 -0000 1.9 --- FromParser.java 19 Nov 2002 15:28:06 -0000 1.10 *************** *** 18,22 **** public void token(String token, QueryTranslator q) throws QueryException { ! if ( ParserHelper.isWhitespace(token) ) return; //ignore whitespace String lcToken = token.toLowerCase(); if ( lcToken.equals("class") ) { --- 18,22 ---- public void token(String token, QueryTranslator q) throws QueryException { ! String lcToken = token.toLowerCase(); if ( lcToken.equals("class") ) { Index: GroupByParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/query/GroupByParser.java,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** GroupByParser.java 1 Aug 2002 13:13:36 -0000 1.6 --- GroupByParser.java 19 Nov 2002 15:28:07 -0000 1.7 *************** *** 23,27 **** public void token(String token, QueryTranslator q) throws QueryException { ! if ( ParserHelper.isWhitespace(token) ) return; //ignore whitespace if ( q.isName( StringHelper.root(token) ) ) { ParserHelper.parse(pathExpressionParser, token, ParserHelper.PATH_SEPERATORS, q); --- 23,27 ---- public void token(String token, QueryTranslator q) throws QueryException { ! if ( q.isName( StringHelper.root(token) ) ) { ParserHelper.parse(pathExpressionParser, token, ParserHelper.PATH_SEPERATORS, q); Index: OrderByParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/query/OrderByParser.java,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** OrderByParser.java 1 Aug 2002 13:13:36 -0000 1.11 --- OrderByParser.java 19 Nov 2002 15:28:07 -0000 1.12 *************** *** 22,26 **** public void token(String token, QueryTranslator q) throws QueryException { ! if ( ParserHelper.isWhitespace(token) ) return; //ignore whitespace if ( q.isName( StringHelper.root(token) ) ) { ParserHelper.parse(pathExpressionParser, token, ParserHelper.PATH_SEPERATORS, q); --- 22,26 ---- public void token(String token, QueryTranslator q) throws QueryException { ! if ( q.isName( StringHelper.root(token) ) ) { ParserHelper.parse(pathExpressionParser, token, ParserHelper.PATH_SEPERATORS, q); Index: ParserHelper.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/query/ParserHelper.java,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** ParserHelper.java 17 Sep 2002 13:53:12 -0000 1.9 --- ParserHelper.java 19 Nov 2002 15:28:07 -0000 1.10 *************** *** 2,6 **** package cirrus.hibernate.query; - import java.util.Map; import java.util.StringTokenizer; --- 2,5 ---- *************** *** 30,54 **** while ( tokens.hasMoreElements() ) p.token( tokens.nextToken(), q ); p.end(q); - } - - - public static void parse(Parser p, String text, String seperators, QueryTranslator q, Map replacements) throws QueryException { - - if ( replacements.size() == 0 ) { - parse(p, text, seperators, q); - } - else { - boolean quoted = false; - StringTokenizer tokens = new StringTokenizer(text, seperators, true); - p.start(q); - while ( tokens.hasMoreElements() ) { - String token = tokens.nextToken(); - if ( token.equals("'") ) quoted = !quoted; - String substoken = (String) replacements.get(token); - p.token( (quoted || substoken==null) ? token : substoken, q ); - } - p.end(q); - } - } --- 29,32 ---- Index: QueryTranslator.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/query/QueryTranslator.java,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** QueryTranslator.java 14 Nov 2002 11:28:55 -0000 1.43 --- QueryTranslator.java 19 Nov 2002 15:28:07 -0000 1.44 *************** *** 45,49 **** private static final HashSet dontSpace = new HashSet(); static { ! dontSpace.add("'"); dontSpace.add("."); dontSpace.add("<"); --- 45,49 ---- private static final HashSet dontSpace = new HashSet(); static { ! //dontSpace.add("'"); dontSpace.add("."); dontSpace.add("<"); *************** *** 133,137 **** log.trace("compiling query"); try { ! ParserHelper.parse( new ClauseParser(), queryString, ParserHelper.HQL_SEPERATORS, this, replacements ); sql = renderSQL(); } --- 133,137 ---- log.trace("compiling query"); try { ! ParserHelper.parse( new PreprocessingParser(replacements), queryString, ParserHelper.HQL_SEPERATORS, this ); sql = renderSQL(); } *************** *** 600,608 **** private void appendTokens(StringBuffer buf, Iterator iter) { boolean lastSpaceable=true; - boolean quoted=false; while ( iter.hasNext() ) { String token = (String) iter.next(); ! if ( token.equals("'") ) quoted=!quoted; ! boolean spaceable = !quoted && !dontSpace.contains(token); if (spaceable && lastSpaceable) buf.append(' '); lastSpaceable = spaceable; --- 600,606 ---- private void appendTokens(StringBuffer buf, Iterator iter) { boolean lastSpaceable=true; while ( iter.hasNext() ) { String token = (String) iter.next(); ! boolean spaceable = !dontSpace.contains(token); if (spaceable && lastSpaceable) buf.append(' '); lastSpaceable = spaceable; Index: SelectParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/query/SelectParser.java,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** SelectParser.java 26 Oct 2002 16:23:02 -0000 1.33 --- SelectParser.java 19 Nov 2002 15:28:07 -0000 1.34 *************** *** 35,39 **** public void token(String token, QueryTranslator q) throws QueryException { - if ( ParserHelper.isWhitespace(token) ) return; //ignore whitespace String lctoken = token.toLowerCase(); --- 35,38 ---- Index: WhereParser.java =================================================================== RCS file: /cvsroot/hibernate/Hibernate/cirrus/hibernate/query/WhereParser.java,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** WhereParser.java 14 Nov 2002 11:28:55 -0000 1.37 --- WhereParser.java 19 Nov 2002 15:28:07 -0000 1.38 *************** *** 39,54 **** private static final Set expressionOpeners = new HashSet(); //tokens that open a sub expression private static final Set booleanOperators = new HashSet(); //tokens that would indicate a sub expression is a boolean expression - private static final Set functions = new HashSet(); static { expressionTerminators.add("and"); expressionTerminators.add("or"); - //expressionTerminators.add(","); //TODO: is this needed???? expressionTerminators.add(")"); expressionOpeners.add("and"); expressionOpeners.add("or"); - //expressionOpeners.add(","); //TODO: is this needed???? expressionOpeners.add("("); booleanOperators.add("<"); --- 39,53 ---- private static final Set expressionOpeners = new HashSet(); //tokens that open a sub expression private static final Set booleanOperators = new HashSet(); //tokens that would indicate a sub expression is a boolean expression static { expressionTerminators.add("and"); expressionTerminators.add("or"); expressionTerminators.add(")"); + //expressionTerminators.add(","); // deliberately excluded expressionOpeners.add("and"); expressionOpeners.add("or"); expressionOpeners.add("("); + //expressionOpeners.add(","); // deliberately excluded booleanOperators.add("<"); *************** *** 64,73 **** booleanOperators.add("exists"); booleanOperators.add("between"); - functions.add("in"); - functions.add("exists"); - functions.add("any"); - functions.add("some"); - functions.add("all"); } // Handles things like: --- 63,81 ---- booleanOperators.add("exists"); booleanOperators.add("between"); + booleanOperators.add("<="); + booleanOperators.add(">="); + booleanOperators.add("=>"); + booleanOperators.add("=<"); + booleanOperators.add("!="); + booleanOperators.add("<>"); + booleanOperators.add("!#"); + booleanOperators.add("!<"); + booleanOperators.add("!>"); + booleanOperators.add("is not"); + booleanOperators.add("not like"); + booleanOperators.add("not in"); + booleanOperators.add("not between"); + booleanOperators.add("not exists"); } // Handles things like: *************** *** 92,97 **** private boolean quoted = false; //Inside a quoted string private boolean betweenSpecialCase = false; //Inside a BETWEEN ... AND ... expression - private boolean isSpecialCase = false; //Inside an IS NULL or IS NOT NULL expression - //private boolean functionSpecialCase = false; //Inside an IN (...,...) expression TODO: is this special case needed now????? private int bracketsSinceFunction = 0; //How deep inside in IN are we? --- 100,103 ---- *************** *** 112,127 **** String lcToken = token.toLowerCase(); - //Cope with quoted strings - - if ( token.equals("'") ) { - quoted=!quoted; - appendToken(q, token); - return; - } - else if (quoted) { - appendToken(q, token); - return; - } - //Cope with [,] --- 118,121 ---- *************** *** 185,189 **** //Cope with a subselect ! if ( lcToken.equals("select") ) { inSubselect=true; subselect = new StringBuffer(20); --- 179,183 ---- //Cope with a subselect ! if ( !inSubselect && ( lcToken.equals("select") || lcToken.equals("from") ) ) { inSubselect=true; subselect = new StringBuffer(20); *************** *** 207,220 **** if (inSubselect) { if ( token.equals("(") ) bracketsSinceSelect++; ! subselect.append(token); return; } - //Cope with whitespace - - if ( ParserHelper.isWhitespace(token) ) { - return; //ignore whitespace - } - //Cope with special cases of AND, NOT, () --- 201,208 ---- if (inSubselect) { if ( token.equals("(") ) bracketsSinceSelect++; ! subselect.append(token).append(' '); return; } //Cope with special cases of AND, NOT, () *************** *** 223,227 **** //Close extra brackets we opened ! if ( /*!functionSpecialCase &&*/ !betweenSpecialCase && expressionTerminators.contains(lcToken) ) { closeExpression(q, lcToken); } --- 211,215 ---- //Close extra brackets we opened ! if ( !betweenSpecialCase && expressionTerminators.contains(lcToken) ) { closeExpression(q, lcToken); } *************** *** 240,247 **** //Open any extra brackets we might need. ! if ( /*!functionSpecialCase &&*/ !betweenSpecialCase && expressionOpeners.contains(lcToken) ) { openExpression(q, lcToken); } ! else if ( !isSpecialCase && lcToken.equals("not") ) { startNot(q); } --- 228,235 ---- //Open any extra brackets we might need. ! if ( !betweenSpecialCase && expressionOpeners.contains(lcToken) ) { openExpression(q, lcToken); } ! else if ( lcToken.equals("not") ) { startNot(q); } *************** *** 322,326 **** q.addIdentifierSpace( pathExpressionParser.getCollectionTable() ); closeExpression(q, ""); - //if (functionSpecialCase && bracketsSinceFunction==0) functionSpecialCase=false; } else { --- 310,313 ---- *************** *** 376,405 **** private void specialCasesBefore(String lcToken) { ! if ( lcToken.equals("between") ) { betweenSpecialCase = true; } - else if ( lcToken.equals("is") ) { - isSpecialCase = true; - } - /*else if ( functions.contains(lcToken) ) { - functionSpecialCase = true; - } - else if ( functionSpecialCase && lcToken.equals("(") ) { - bracketsSinceFunction++; - }*/ } private void specialCasesAfter(String lcToken) { ! if ( lcToken.equals("and") ) { betweenSpecialCase = false; } - else if ( lcToken.equals("null") ) { - isSpecialCase = false; - } - /*else if ( functionSpecialCase && lcToken.equals(")") ) { - if ( --bracketsSinceFunction == 0 ) { - functionSpecialCase = false; - } - }*/ } --- 363,375 ---- private void specialCasesBefore(String lcToken) { ! if ( lcToken.equals("between") || lcToken.equals("not between") ) { betweenSpecialCase = true; } } private void specialCasesAfter(String lcToken) { ! if ( betweenSpecialCase && lcToken.equals("and") ) { betweenSpecialCase = false; } } |