|
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;
}
}
|