src/utils/raSqlQuery/rqlEval.c 1.3

1.3 2009/12/02 19:11:55 kent
Librarifying RQL parser and interpreter.
Index: src/utils/raSqlQuery/rqlEval.c
===================================================================
RCS file: src/utils/raSqlQuery/rqlEval.c
diff -N src/utils/raSqlQuery/rqlEval.c
--- src/utils/raSqlQuery/rqlEval.c	22 Nov 2009 02:11:09 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,288 +0,0 @@
-/* rqlEval - evaluate tree returned by rqlParse. */
-#include "common.h"
-#include "linefile.h"
-#include "hash.h"
-#include "dystring.h"
-#include "tokenizer.h"
-#include "sqlNum.h"
-#include "raRecord.h"
-#include "rql.h"
-
-static char const rcsid[] = "$Id$";
-
-struct rqlEval rqlEvalCoerceToBoolean(struct rqlEval r)
-/* Return TRUE if it's a nonempty string or a non-zero number. */
-{
-switch (r.type)
-    {
-    case rqlTypeBoolean:
-	break;	/* It's already done. */
-    case rqlTypeString:
-        r.val.b = (r.val.s != NULL && r.val.s[0] != 0);
-	break;
-    case rqlTypeInt:
-        r.val.b = (r.val.i != 0);
-	break;
-    case rqlTypeDouble:
-        r.val.b = (r.val.x != 0.0);
-	break;
-    default:
-	internalErr();
-	r.val.b = FALSE;
-	break;
-    }
-r.type = rqlTypeBoolean;
-return r;
-}
-
-static struct rqlEval rqlEvalEq(struct rqlParse *p, struct raRecord *ra)
-/* Return true if two children are equal regardless of children type
- * (which are just gauranteed to be the same). */
-{
-struct rqlParse *lp = p->children;
-struct rqlParse *rp = lp->next;
-struct rqlEval lv = rqlEvalOnRecord(lp, ra);
-struct rqlEval rv = rqlEvalOnRecord(rp, ra);
-struct rqlEval res;
-res.type = rqlTypeBoolean;
-assert(lv.type == rv.type);
-switch (lv.type)
-    {
-    case rqlTypeBoolean:
-        res.val.b = (lv.val.b == rv.val.b);
-	break;
-    case rqlTypeString:
-	res.val.b = sameString(lv.val.s, rv.val.s);
-	break;
-    case rqlTypeInt:
-	res.val.b = (lv.val.i == rv.val.i);
-	break;
-    case rqlTypeDouble:
-	res.val.b = (lv.val.x == rv.val.x);
-	break;
-    default:
-	internalErr();
-	res.val.b = FALSE;
-	break;
-    }
-return res;
-}
-
-static struct rqlEval rqlEvalLt(struct rqlParse *p, struct raRecord *ra)
-/* Return true if r < l . */
-{
-struct rqlParse *lp = p->children;
-struct rqlParse *rp = lp->next;
-struct rqlEval lv = rqlEvalOnRecord(lp, ra);
-struct rqlEval rv = rqlEvalOnRecord(rp, ra);
-struct rqlEval res;
-res.type = rqlTypeBoolean;
-switch (lv.type)
-    {
-    case rqlTypeBoolean:
-        res.val.b = (lv.val.b < rv.val.b);
-	break;
-    case rqlTypeString:
-	res.val.b = strcmp(lv.val.s, rv.val.s) < 0;
-	break;
-    case rqlTypeInt:
-	res.val.b = (lv.val.i < rv.val.i);
-	break;
-    case rqlTypeDouble:
-	res.val.b = (lv.val.x < rv.val.x);
-	break;
-    default:
-	internalErr();
-	res.val.b = FALSE;
-	break;
-    }
-return res;
-}
-
-static struct rqlEval rqlEvalGt(struct rqlParse *p, struct raRecord *ra)
-/* Return true if r > l . */
-{
-struct rqlParse *lp = p->children;
-struct rqlParse *rp = lp->next;
-struct rqlEval lv = rqlEvalOnRecord(lp, ra);
-struct rqlEval rv = rqlEvalOnRecord(rp, ra);
-struct rqlEval res;
-res.type = rqlTypeBoolean;
-switch (lv.type)
-    {
-    case rqlTypeBoolean:
-        res.val.b = (lv.val.b > rv.val.b);
-	break;
-    case rqlTypeString:
-	res.val.b = strcmp(lv.val.s, rv.val.s) > 0;
-	break;
-    case rqlTypeInt:
-	res.val.b = (lv.val.i > rv.val.i);
-	break;
-    case rqlTypeDouble:
-	res.val.b = (lv.val.x > rv.val.x);
-	break;
-    default:
-	internalErr();
-	res.val.b = FALSE;
-	break;
-    }
-return res;
-}
-
-static struct rqlEval rqlEvalLike(struct rqlParse *p, struct raRecord *ra)
-/* Return true if r like l . */
-{
-struct rqlParse *lp = p->children;
-struct rqlParse *rp = lp->next;
-struct rqlEval lv = rqlEvalOnRecord(lp, ra);
-struct rqlEval rv = rqlEvalOnRecord(rp, ra);
-struct rqlEval res;
-res.type = rqlTypeBoolean;
-assert(rv.type == rqlTypeString);
-assert(rv.type == lv.type);
-res.val.b = sqlMatchLike(rv.val.s, lv.val.s);
-return res;
-}
-
-struct rqlEval rqlEvalOnRecord(struct rqlParse *p, struct raRecord *ra)
-/* Evaluate self on ra. */
-{
-struct rqlEval res;
-switch (p->op)
-    {
-    case rqlOpLiteral:
-	res.val = p->val;
-	res.type = p->type;
-	break;
-    case rqlOpSymbol:
-	res.type = rqlTypeString;
-	struct raField *f = raRecordField(ra, p->val.s);
-	if (f == NULL)
-	    res.val.s = "";
-	else
-	    res.val.s = f->val;
-	break;
-    case rqlOpEq:
-	res = rqlEvalEq(p, ra);
-	break;
-    case rqlOpNe:
-	res = rqlEvalEq(p, ra);
-	res.val.b = !res.val.b;
-	break;
-
-    /* Inequalities. */
-    case rqlOpLt:
-        res = rqlEvalLt(p, ra);
-	break;
-    case rqlOpGt:
-        res = rqlEvalGt(p, ra);
-	break;
-    case rqlOpLe:
-        res = rqlEvalGt(p, ra);
-	res.val.b = !res.val.b;
-	break;
-    case rqlOpGe:
-        res = rqlEvalLt(p, ra);
-	res.val.b = !res.val.b;
-	break;
-    case rqlOpLike:
-        res = rqlEvalLike(p,ra);
-	break;
-
-    /* Logical ops. */
-    case rqlOpAnd:
-	{
-        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 rqlOpOr:
-	{
-        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;
-	}
-
-    case rqlOpNot:
-        res = rqlEvalOnRecord(p->children, ra);
-	res.val.b = !res.val.b;
-	break;
-
-    /* Type casts. */
-    case rqlOpStringToBoolean:
-	res = rqlEvalOnRecord(p->children, ra);
-	res.type = rqlTypeBoolean;
-	res.val.b = (res.val.s[0] != 0);
-	break;
-    case rqlOpIntToBoolean:
-        res = rqlEvalOnRecord(p->children, ra);
-	res.type = rqlTypeBoolean;
-	res.val.b = (res.val.i != 0);
-	break;
-    case rqlOpDoubleToBoolean:
-        res = rqlEvalOnRecord(p->children, ra);
-	res.type = rqlTypeBoolean;
-	res.val.b = (res.val.x != 0.0);
-	break;
-    case rqlOpStringToInt:
-	res = rqlEvalOnRecord(p->children, ra);
-	res.type = rqlTypeInt;
-	res.val.i = atoi(res.val.s);
-	break;
-    case rqlOpStringToDouble:
-	res = rqlEvalOnRecord(p->children, ra);
-	res.type = rqlTypeDouble;
-	res.val.x = atof(res.val.s);
-	break;
-    case rqlOpBooleanToInt:
-	res = rqlEvalOnRecord(p->children, ra);
-	res.type = rqlTypeInt;
-	res.val.i = res.val.b;
-	break;
-    case rqlOpBooleanToDouble:
-	res = rqlEvalOnRecord(p->children, ra);
-	res.type = rqlTypeDouble;
-	res.val.x = res.val.b;
-	break;
-    case rqlOpIntToDouble:
-	res = rqlEvalOnRecord(p->children, ra);
-	res.type = rqlTypeDouble;
-	res.val.x = res.val.b;
-	break;
-
-    case rqlOpUnaryMinusDouble:
-        res = rqlEvalOnRecord(p->children, ra);
-	res.type = rqlTypeDouble;
-	res.val.x = -res.val.x;
-	break;
-
-    default:
-        errAbort("Unknown op %s\n", rqlOpToString(p->op));
-	res.type = rqlTypeInt;	// Keep compiler from complaining.
-	res.val.i = 0;	// Keep compiler from complaining.
-	break;
-    }
-return res;
-}
-