- debug("in parse_query()");
-
- CQLNode term = parse_term(qualifier, relation);
- while (lexer.ttype == lexer.TT_WORD) {
- String op = lexer.sval.toLowerCase();
- debug("checking op '" + op + "'");
- if (lexer.sval.equals("and")) {
- match(lexer.TT_WORD);
- CQLNode term2 = parse_term(qualifier, relation);
- term = new CQLAndNode(term, term2);
- } else if (lexer.sval.equals("or")) {
- match(lexer.TT_WORD);
- CQLNode term2 = parse_term(qualifier, relation);
- term = new CQLOrNode(term, term2);
- } else if (lexer.sval.equals("not")) {
- match(lexer.TT_WORD);
- CQLNode term2 = parse_term(qualifier, relation);
- term = new CQLNotNode(term, term2);
- } else if (lexer.sval.equals("prox")) {
- // ### Handle "prox"
+ debug("top-level prefix mapping");
+
+ if (lexer.ttype == '>') {
+ return parsePrefix(index, relation, true);
+ }
+
+ CQLNode node = parseQuery(index, relation);
+ if ((compat == V1POINT2 || compat == V1POINT1SORT) &&
+ lexer.ttype == lexer.TT_SORTBY) {
+ match(lexer.ttype);
+ debug("sortspec");
+
+ CQLSortNode sortnode = new CQLSortNode(node);
+ while (lexer.ttype != lexer.TT_EOF) {
+ String sortindex = matchSymbol("sort index");
+ ModifierSet ms = gatherModifiers(sortindex);
+ sortnode.addSortIndex(ms);
+ }
+
+ if (sortnode.keys.size() == 0) {
+ throw new CQLParseException("no sort keys");
+ }
+
+ node = sortnode;
+ }
+
+ return node;
+ }
+
+ private CQLNode parseQuery(String index, CQLRelation relation)
+ throws CQLParseException, IOException {
+ debug("in parseQuery()");
+
+ CQLNode term = parseTerm(index, relation);
+ while (lexer.ttype != lexer.TT_EOF &&
+ lexer.ttype != ')' &&
+ lexer.ttype != lexer.TT_SORTBY) {
+ if (lexer.ttype == lexer.TT_AND ||
+ lexer.ttype == lexer.TT_OR ||
+ lexer.ttype == lexer.TT_NOT ||
+ lexer.ttype == lexer.TT_PROX) {
+ int type = lexer.ttype;
+ String val = lexer.sval;
+ match(type);
+ ModifierSet ms = gatherModifiers(val);
+ CQLNode term2 = parseTerm(index, relation);
+ term = ((type == lexer.TT_AND) ? new CQLAndNode(term, term2, ms) :
+ (type == lexer.TT_OR) ? new CQLOrNode (term, term2, ms) :
+ (type == lexer.TT_NOT) ? new CQLNotNode(term, term2, ms) :
+ new CQLProxNode(term, term2, ms));