implemented order by parser

Fri, 29 May 2015 10:15:12 +0200

author
Mike Becker <universe@uap-core.de>
date
Fri, 29 May 2015 10:15:12 +0200
changeset 120
246c50447ebf
parent 119
451607eeff05
child 121
eea36bf5ffe2

implemented order by parser

libidav/davqlparser.c file | annotate | diff | comparison | revisions
libidav/davqlparser.h file | annotate | diff | comparison | revisions
--- a/libidav/davqlparser.c	Fri May 29 09:48:10 2015 +0200
+++ b/libidav/davqlparser.c	Fri May 29 10:15:12 2015 +0200
@@ -390,6 +390,7 @@
 #define _error_invalid_logical_op "invalid logical operator "  _error_context
 #define _error_invalid_fmtspec "invalid format specifier " _error_context
 #define _error_invalid_string "string expected " _error_context
+#define _error_invalid_order_criterion "invalid order criterion " _error_context
 
 #define token_sstr(token) (((DavQLToken*)(token)->data)->value)
 
@@ -1317,11 +1318,72 @@
     return total_consumed;
 }
 
+static int dav_parse_order_crit(DavQLStatement *stmt, UcxList *token,
+    DavQLOrderCriterion *crit) {
+    
+    // RULE:    (Identifier | Number), [" asc"|" desc"];
+    DavQLExpression expr;
+    memset(&expr, 0, sizeof(DavQLExpression));
+    int consumed = dav_parse_expression(stmt, token, &expr);
+    if (stmt->errorcode || !consumed) {
+        return 0;
+    }
+    
+    if (expr.type != DAVQL_IDENTIFIER && expr.type != DAVQL_NUMBER) {
+        dav_error_in_context(DAVQL_ERROR_INVALID_ORDER_CRITERION,
+            _error_invalid_order_criterion, stmt, token);
+        return 0;
+    }
+    
+    crit->column = malloc(sizeof(DavQLExpression));
+    memcpy(crit->column, &expr, sizeof(DavQLExpression));
+    
+    token = ucx_list_get(token, consumed);
+    if (token_is(token, DAVQL_TOKEN_KEYWORD) && (
+            tokenvalue_is(token, "asc") || tokenvalue_is(token, "desc"))) {
+        
+        crit->descending = tokenvalue_is(token, "desc");
+        
+        return consumed+1;
+    } else {
+        crit->descending = 0;
+        return consumed;
+    }
+}
+
 static int dav_parse_orderby_clause(DavQLStatement *stmt, UcxList *token) {
     
+    int total_consumed = 0, consumed;
+    
+    DavQLOrderCriterion crit;
+    
     // RULE:    OrderByCriterion, {",", OrderByCriterion};
-    // OrderByCriterion = (Identifier | Number), [" asc"|" desc"];
-    return 0;
+    do {
+        consumed = dav_parse_order_crit(stmt, token, &crit);
+        if (stmt->errorcode) {
+            return 0;
+        }
+        if (!consumed) {
+            dav_error_in_context(DAVQL_ERROR_MISSING_EXPR, _error_missing_expr,
+                stmt, token);
+            return 0;
+        }
+        token = ucx_list_get(token, consumed);
+        total_consumed += consumed;
+        
+        DavQLOrderCriterion *criterion = malloc(sizeof(DavQLOrderCriterion));
+        memcpy(criterion, &crit, sizeof(DavQLOrderCriterion));
+        stmt->orderby = ucx_list_append(stmt->orderby, criterion);
+        
+        if (token_is(token, DAVQL_TOKEN_COMMA)) {
+            total_consumed++;
+            token = token->next;
+        } else {
+            consumed = 0;
+        }
+    } while (consumed);
+    
+    return total_consumed;
 }
 
 /**
--- a/libidav/davqlparser.h	Fri May 29 09:48:10 2015 +0200
+++ b/libidav/davqlparser.h	Fri May 29 10:15:12 2015 +0200
@@ -314,6 +314,9 @@
 /** A string has been expected. */
 #define DAVQL_ERROR_INVALID_STRING 25
 
+/** The order criterion is invalid (must be an identifier or field index). */
+#define DAVQL_ERROR_INVALID_ORDER_CRITERION 26
+
 /** The depth is invalid. */
 #define DAVQL_ERROR_INVALID_DEPTH 101
 

mercurial