[master] e984abc Add level limits to query language

Martin Blix Grydeland martin at varnish-cache.org
Tue Oct 1 14:48:19 CEST 2013


commit e984abcfc4e924efef002d2922a6eaadfc8504f6
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Mon Sep 30 14:33:53 2013 +0200

    Add level limits to query language

diff --git a/bin/varnishtest/tests/l00001.vtc b/bin/varnishtest/tests/l00001.vtc
index 6dc2b7d..1da61df 100644
--- a/bin/varnishtest/tests/l00001.vtc
+++ b/bin/varnishtest/tests/l00001.vtc
@@ -193,3 +193,21 @@ logexpect l1 -d 1 -g vxid -q "RespStatus" {
 	  expect * =	ReqEnd
 	  expect * =	End
 } -run
+
+# Test level limits equal
+logexpect l1 -d 1 -g vxid -q "{1}Begin ~ req" {
+	  expect 0 *	Begin	req
+	  expect * =	End
+} -run
+
+# Test level limits less than or equal
+logexpect l1 -d 1 -g vxid -q "{2-}Begin ~ req" {
+	  expect 0 *	Begin	req
+	  expect * =	End
+} -run
+
+# Test level limits greater than or equal
+logexpect l1 -d 1 -g vxid -q "{0+}Begin ~ req" {
+	  expect 0 *	Begin	req
+	  expect * =	End
+} -run
diff --git a/lib/libvarnishapi/vsl_query.c b/lib/libvarnishapi/vsl_query.c
index 7098c4d..7f1b66b 100644
--- a/lib/libvarnishapi/vsl_query.c
+++ b/lib/libvarnishapi/vsl_query.c
@@ -208,6 +208,22 @@ vslq_test(const struct vex *vex, struct VSL_transaction * const ptrans[])
 	AN(vex->lhs->tags);
 
 	for (t = ptrans[0]; t != NULL; t = *++ptrans) {
+		if (vex->lhs->level >= 0) {
+			if (vex->lhs->level_pm < 0) {
+				/* OK if less than or equal */
+				if (t->level > vex->lhs->level)
+					continue;
+			} else if (vex->lhs->level_pm > 0) {
+				/* OK if greater than or equal */
+				if (t->level < vex->lhs->level)
+					continue;
+			} else {
+				/* OK if equal */
+				if (t->level != vex->lhs->level)
+					continue;
+			}
+		}
+
 		AZ(VSL_ResetCursor(t->c));
 		while (1) {
 			i = VSL_Next(t->c);
diff --git a/lib/libvarnishapi/vxp.h b/lib/libvarnishapi/vxp.h
index c0b979f..20df7ed 100644
--- a/lib/libvarnishapi/vxp.h
+++ b/lib/libvarnishapi/vxp.h
@@ -36,7 +36,7 @@
 #include "vxp_tokens.h"
 
 #define isword(c)  (isalpha(c) || isdigit(c) || (c) == '_' || (c) == '-' || \
-	    (c) == '.' || (c) == '*')
+	    (c) == '+' || (c) == '.' || (c) == '*')
 
 #define PF(t)	(int)((t)->e - (t)->b), (t)->b
 
@@ -86,8 +86,8 @@ struct vex_lhs {
 	char			*prefix;
 	int			prefixlen;
 	int			field;
-	int			level_min;
-	int			level_max;
+	int			level;
+	int			level_pm;
 };
 
 enum vex_rhs_e {
diff --git a/lib/libvarnishapi/vxp_parse.c b/lib/libvarnishapi/vxp_parse.c
index bdf64c5..83dbd52 100644
--- a/lib/libvarnishapi/vxp_parse.c
+++ b/lib/libvarnishapi/vxp_parse.c
@@ -60,6 +60,40 @@ vxp_expr_lhs(struct vxp *vxp, struct vex_lhs **plhs)
 	ALLOC_OBJ(*plhs, VEX_LHS_MAGIC);
 	AN(*plhs);
 	(*plhs)->tags = vbit_init(SLT__MAX);
+	(*plhs)->level = -1;
+
+	if (vxp->t->tok == '{') {
+		/* Transaction level limits */
+		vxp_NextToken(vxp);
+		if (vxp->t->tok != VAL) {
+			VSB_printf(vxp->sb, "Expected integer got '%.*s' ",
+			    PF(vxp->t));
+			vxp_ErrWhere(vxp, vxp->t, -1);
+			return;
+		}
+		(*plhs)->level = (int)strtol(vxp->t->dec, &p, 0);
+		if ((*plhs)->level < 0) {
+			VSB_printf(vxp->sb, "Expected positive integer ");
+			vxp_ErrWhere(vxp, vxp->t, -1);
+			return;
+		}
+		if (*p == '-') {
+			(*plhs)->level_pm = -1;
+			p++;
+		} else if (*p == '+') {
+			(*plhs)->level_pm = 1;
+			p++;
+		}
+		if (*p) {
+			VSB_printf(vxp->sb, "Syntax error in level limit ");
+			vxp_ErrWhere(vxp, vxp->t, -1);
+			return;
+		}
+		vxp_NextToken(vxp);
+		ExpectErr(vxp, '}');
+		vxp_NextToken(vxp);
+	}
+
 	while (1) {
 		/* The tags this expression applies to */
 		if (vxp->t->tok != VAL) {
@@ -127,8 +161,6 @@ vxp_expr_lhs(struct vxp *vxp, struct vex_lhs **plhs)
 		ExpectErr(vxp, ']');
 		vxp_NextToken(vxp);
 	}
-
-	/* XXX: LHS Level {} */
 }
 
 static void
@@ -539,14 +571,19 @@ vex_print(const struct vex *vex, int indent)
 	if (vex->lhs != NULL) {
 		CHECK_OBJ_NOTNULL(vex->lhs, VEX_LHS_MAGIC);
 		AN(vex->lhs->tags);
-		fprintf(stderr, " lhs=(");
+		fprintf(stderr, " lhs=");
+		if (vex->lhs->level >= 0)
+			fprintf(stderr, "{%d%s}", vex->lhs->level,
+			    vex->lhs->level_pm < 0 ? "-" :
+			    vex->lhs->level_pm > 0 ? "+" : "");
+		fprintf(stderr, "(");
 		vex_print_tags(vex->lhs->tags);
 		fprintf(stderr, ")");
 		if (vex->lhs->prefix) {
 			assert(vex->lhs->prefixlen == strlen(vex->lhs->prefix));
 			fprintf(stderr, ":%s", vex->lhs->prefix);
 		}
-		if (vex->lhs->field >= 0)
+		if (vex->lhs->field > 0)
 			fprintf(stderr, "[%d]", vex->lhs->field);
 	}
 	if (vex->rhs != NULL) {



More information about the varnish-commit mailing list