src/utils/raSqlQuery/raSqlQuery.c 1.7
1.7 2009/11/20 06:00:29 kent
Adding 'or' and 'and'
Index: src/utils/raSqlQuery/raSqlQuery.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/utils/raSqlQuery/raSqlQuery.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -b -B -U 4 -r1.6 -r1.7
--- src/utils/raSqlQuery/raSqlQuery.c 20 Nov 2009 04:57:14 -0000 1.6
+++ src/utils/raSqlQuery/raSqlQuery.c 20 Nov 2009 06:00:29 -0000 1.7
@@ -75,8 +75,10 @@
rqlParseEq, /* An equals comparison */
rqlParseNe, /* A not equals comparison */
rqlParseStringToBoolean,
+ rqlParseIntToBoolean,
+ rqlParseDoubleToBoolean,
rqlParseStringToInt,
rqlParseStringToDouble,
rqlParseBooleanToInt,
rqlParseBooleanToDouble,
@@ -113,8 +115,12 @@
return "rqlParseOr";
case rqlParseStringToBoolean:
return "rqlParseStringToBoolean";
+ case rqlParseIntToBoolean:
+ return "rqlParseIntToBoolean";
+ case rqlParseDoubleToBoolean:
+ return "rqlParseDoubleToBoolean";
case rqlParseStringToInt:
return "rqlParseStringToInt";
case rqlParseStringToDouble:
return "rqlParseStringToDouble";
@@ -307,8 +313,12 @@
switch (oldType)
{
case rqlTypeString:
return rqlParseStringToBoolean;
+ case rqlTypeInt:
+ return rqlParseIntToBoolean;
+ case rqlTypeDouble:
+ return rqlParseDoubleToBoolean;
default:
internalErr();
return rqlParseUnknown;
}
@@ -482,12 +492,72 @@
}
return p;
}
+struct rqlParse *rqlParseAndLoop(struct tokenizer *tkz)
+/* Parse out and or or. */
+{
+struct rqlParse *l = rqlParseCoerce(rqlParseCmp(tkz), rqlTypeBoolean);
+struct rqlParse *parent = NULL;
+struct rqlParse *p = l;
+for (;;)
+ {
+ char *tok = tokenizerNext(tkz);
+ if (tok == NULL || !sameString(tok, "and"))
+ {
+ tokenizerReuse(tkz);
+ return p;
+ }
+ else
+ {
+ if (parent == NULL)
+ {
+ AllocVar(parent);
+ parent->op = rqlParseAnd;
+ parent->type = rqlTypeBoolean;
+ parent->children = p;
+ p = parent;
+ }
+ struct rqlParse *r = rqlParseCoerce(rqlParseCmp(tkz), rqlTypeBoolean);
+ slAddTail(&parent->children, r);
+ }
+ }
+}
+
+struct rqlParse *rqlParseOrLoop(struct tokenizer *tkz)
+/* Parse out and or or. */
+{
+struct rqlParse *l = rqlParseCoerce(rqlParseAndLoop(tkz), rqlTypeBoolean);
+struct rqlParse *parent = NULL;
+struct rqlParse *p = l;
+for (;;)
+ {
+ char *tok = tokenizerNext(tkz);
+ if (tok == NULL || !sameString(tok, "or"))
+ {
+ tokenizerReuse(tkz);
+ return p;
+ }
+ else
+ {
+ if (parent == NULL)
+ {
+ AllocVar(parent);
+ parent->op = rqlParseOr;
+ parent->type = rqlTypeBoolean;
+ parent->children = p;
+ p = parent;
+ }
+ struct rqlParse *r = rqlParseCoerce(rqlParseAndLoop(tkz), rqlTypeBoolean);
+ slAddTail(&parent->children, r);
+ }
+ }
+}
+
struct rqlParse *rqlParseClause(struct tokenizer *tkz)
/* Parse out a clause, usually a where clause. */
{
-return rqlParseCmp(tkz);
+return rqlParseOrLoop(tkz);
}
char *rqlParseFieldSpec(struct tokenizer *tkz, struct dyString *buf)
/* Return a field spec, which may contain * and ?. Put results in buf, and
@@ -740,14 +810,58 @@
case rqlParseLike:
res = rqlEvalLike(p,ra);
break;
+ /* Logical ops. */
+ case rqlParseAnd:
+ {
+ res.type = rqlTypeBoolean;
+ res.val.b = TRUE;
+ struct rqlParse *c;
+ for (c = p->children; c != NULL; c= c->next)
+ {
+ struct rqlEval e = rqlEvalOnRecord(c, ra);
+ if (!e.val.b)
+ {
+ res.val.b = FALSE;
+ break;
+ }
+ }
+ break;
+ }
+ case rqlParseOr:
+ {
+ res.type = rqlTypeBoolean;
+ res.val.b = FALSE;
+ struct rqlParse *c;
+ for (c = p->children; c != NULL; c= c->next)
+ {
+ struct rqlEval e = rqlEvalOnRecord(c, ra);
+ if (e.val.b)
+ {
+ res.val.b = TRUE;
+ break;
+ }
+ }
+ break;
+ }
+
/* Type casts. */
case rqlParseStringToBoolean:
res = rqlEvalOnRecord(p->children, ra);
res.type = rqlTypeBoolean;
res.val.b = (res.val.s[0] != 0);
break;
+ case rqlParseIntToBoolean:
+ res = rqlEvalOnRecord(p->children, ra);
+ res.type = rqlTypeBoolean;
+ res.val.b = (res.val.i != 0);
+ break;
+ case rqlParseDoubleToBoolean:
+ res = rqlEvalOnRecord(p->children, ra);
+ res.type = rqlTypeBoolean;
+ res.val.b = (res.val.x != 0.0);
+ break;
case rqlParseStringToInt:
res = rqlEvalOnRecord(p->children, ra);
res.type = rqlTypeInt;
res.val.i = atoi(res.val.s);