libidav/davqlparser.c

changeset 98
237844f263b4
parent 97
f82cb65a78ec
child 99
579238097973
equal deleted inserted replaced
97:f82cb65a78ec 98:237844f263b4
47 } 47 }
48 } 48 }
49 49
50 static const char* _map_exprtype(davqlexprtype_t type) { 50 static const char* _map_exprtype(davqlexprtype_t type) {
51 switch(type) { 51 switch(type) {
52 case DAVQL_UNDEFINED_TYP: return "undefined";
52 case DAVQL_NUMBER: return "NUMBER"; 53 case DAVQL_NUMBER: return "NUMBER";
53 case DAVQL_STRING: return "STRING"; 54 case DAVQL_STRING: return "STRING";
54 case DAVQL_TIMESTAMP: return "TIMESTAMP"; 55 case DAVQL_TIMESTAMP: return "TIMESTAMP";
55 case DAVQL_IDENTIFIER: return "IDENTIFIER"; 56 case DAVQL_IDENTIFIER: return "IDENTIFIER";
56 case DAVQL_UNARY: return "UNARY"; 57 case DAVQL_UNARY: return "UNARY";
90 91
91 static void dav_debug_ql_stmt_print(DavQLStatement *stmt) { 92 static void dav_debug_ql_stmt_print(DavQLStatement *stmt) {
92 // Basic information 93 // Basic information
93 size_t fieldcount = ucx_list_size(stmt->fields); 94 size_t fieldcount = ucx_list_size(stmt->fields);
94 int specialfield = 0; 95 int specialfield = 0;
95 UCX_FOREACH(elm, stmt->fields) { 96 if (stmt->fields) {
96 DavQLExpression* expr = (DavQLExpression*)elm->data; 97 DavQLField* firstfield = (DavQLField*)stmt->fields->data;
97 if (expr->type == DAVQL_IDENTIFIER && expr->srctext.length == 1) { 98 if (firstfield->expr->type == DAVQL_IDENTIFIER) {
98 if (expr->srctext.ptr[0] == '*') { 99 switch (firstfield->expr->srctext.ptr[0]) {
99 specialfield = 1; 100 case '*': specialfield = 1; break;
100 } else if (expr->srctext.ptr[0] == '-') { 101 case '-': specialfield = 2; break;
101 specialfield = 2;
102 } 102 }
103 } 103 }
104 } 104 }
105 if (specialfield) { 105 if (specialfield) {
106 fieldcount--; 106 fieldcount--;
111 _map_querytype(stmt->type), 111 _map_querytype(stmt->type),
112 fieldcount, 112 fieldcount,
113 _map_specialfield(specialfield), 113 _map_specialfield(specialfield),
114 sfmtarg(stmt->path), 114 sfmtarg(stmt->path),
115 stmt->where ? "yes" : "no"); 115 stmt->where ? "yes" : "no");
116 if (stmt->type == DAVQL_SET) {
117 printf("Value list size matches: %s",
118 ucx_list_size(stmt->fields) == ucx_list_size(stmt->setvalues)
119 ? "yes" : "no");
120 }
121 116
122 // WITH attributes 117 // WITH attributes
123 if (stmt->depth == DAV_DEPTH_INFINITY) { 118 if (stmt->depth == DAV_DEPTH_INFINITY) {
124 printf("Depth: infinity\n"); 119 printf("Depth: infinity\n");
125 } else if (stmt->depth == DAV_DEPTH_PLACEHOLDER) { 120 } else if (stmt->depth == DAV_DEPTH_PLACEHOLDER) {
159 154
160 static void dav_debug_ql_expr_print(DavQLExpression *expr) { 155 static void dav_debug_ql_expr_print(DavQLExpression *expr) {
161 if (dav_debug_ql_expr_selected(expr)) { 156 if (dav_debug_ql_expr_selected(expr)) {
162 sstr_t empty = ST("(empty)"); 157 sstr_t empty = ST("(empty)");
163 printf( 158 printf(
164 "Text: %.*s\nType: %s\nOperator: %s\n" 159 "Text: %.*s\nType: %s\nOperator: %s\n",
165 "Left hand: %.*s\nRight hand: %.*s\n",
166 sfmtarg(expr->srctext), 160 sfmtarg(expr->srctext),
167 _map_exprtype(expr->type), 161 _map_exprtype(expr->type),
168 _map_operator(expr->op), 162 _map_operator(expr->op));
169 sfmtarg(expr->left?expr->left->srctext:empty), 163 if (expr->left || expr->right) {
170 sfmtarg(expr->right?expr->right->srctext:empty)); 164 printf("Left hand: %.*s\nRight hand: %.*s\n",
165 sfmtarg(expr->left?expr->left->srctext:empty),
166 sfmtarg(expr->right?expr->right->srctext:empty));
167 }
171 } 168 }
172 } 169 }
173 170
174 #define DQLD_CMD_Q 0 171 #define DQLD_CMD_Q 0
175 #define DQLD_CMD_PS 1 172 #define DQLD_CMD_PS 1
176 #define DQLD_CMD_PE 2 173 #define DQLD_CMD_PE 2
177 #define DQLD_CMD_P 10 174 #define DQLD_CMD_F 10
175 #define DQLD_CMD_W 11
176 #define DQLD_CMD_O 12
178 #define DQLD_CMD_L 21 177 #define DQLD_CMD_L 21
179 #define DQLD_CMD_R 22 178 #define DQLD_CMD_R 22
179 #define DQLD_CMD_N 23
180 #define DQLD_CMD_P 24
180 #define DQLD_CMD_H 100 181 #define DQLD_CMD_H 100
181 182
182 static int dav_debug_ql_command() { 183 static int dav_debug_ql_command() {
183 printf("> "); 184 printf("> ");
184 185
185 char buffer[16]; 186 char buffer[8];
186 fgets(buffer, 16, stdin); 187 fgets(buffer, 8, stdin);
188 // discard remaining chars
189 if (!strchr(buffer, '\n')) {
190 int chr;
191 while ((chr = fgetc(stdin) != '\n') && chr != EOF);
192 }
193
187 if (!strcmp(buffer, "q\n")) { 194 if (!strcmp(buffer, "q\n")) {
188 return DQLD_CMD_Q; 195 return DQLD_CMD_Q;
189 } else if (!strcmp(buffer, "ps\n")) { 196 } else if (!strcmp(buffer, "ps\n")) {
190 return DQLD_CMD_PS; 197 return DQLD_CMD_PS;
191 } else if (!strcmp(buffer, "pe\n")) { 198 } else if (!strcmp(buffer, "pe\n")) {
194 return DQLD_CMD_L; 201 return DQLD_CMD_L;
195 } else if (!strcmp(buffer, "r\n")) { 202 } else if (!strcmp(buffer, "r\n")) {
196 return DQLD_CMD_R; 203 return DQLD_CMD_R;
197 } else if (!strcmp(buffer, "h\n")) { 204 } else if (!strcmp(buffer, "h\n")) {
198 return DQLD_CMD_H; 205 return DQLD_CMD_H;
206 } else if (!strcmp(buffer, "f\n")) {
207 return DQLD_CMD_F;
208 } else if (!strcmp(buffer, "w\n")) {
209 return DQLD_CMD_W;
210 } else if (!strcmp(buffer, "o\n")) {
211 return DQLD_CMD_O;
212 } else if (!strcmp(buffer, "n\n")) {
213 return DQLD_CMD_N;
214 } else if (!strcmp(buffer, "p\n")) {
215 return DQLD_CMD_P;
199 } else { 216 } else {
200 return -1; 217 return -1;
201 } 218 }
202 } 219 }
203 220
213 if (stmt->errorcode) { 230 if (stmt->errorcode) {
214 return; 231 return;
215 } 232 }
216 233
217 DavQLExpression *examineexpr = NULL; 234 DavQLExpression *examineexpr = NULL;
235 UcxList *examineelem = NULL;
236 int examineclause = 0;
218 237
219 while(1) { 238 while(1) {
220 int cmd = dav_debug_ql_command(); 239 int cmd = dav_debug_ql_command();
221 switch (cmd) { 240 switch (cmd) {
222 case DQLD_CMD_Q: return; 241 case DQLD_CMD_Q: return;
223 case DQLD_CMD_PS: dav_debug_ql_stmt_print(stmt); break; 242 case DQLD_CMD_PS: dav_debug_ql_stmt_print(stmt); break;
224 case DQLD_CMD_PE: dav_debug_ql_expr_print(examineexpr); break; 243 case DQLD_CMD_PE: dav_debug_ql_expr_print(examineexpr); break;
244 case DQLD_CMD_F:
245 if (examineclause != DQLD_CMD_F) {
246 examineclause = DQLD_CMD_F;
247 examineelem = stmt->fields;
248 examineexpr = stmt->fields ?
249 ((DavQLField*)stmt->fields->data)->expr : NULL;
250 dav_debug_ql_expr_print(examineexpr);
251 }
252 break;
253 case DQLD_CMD_W:
254 examineclause = 0; examineelem = NULL;
255 examineexpr = stmt->where;
256 dav_debug_ql_expr_print(examineexpr);
257 break;
258 case DQLD_CMD_O:
259 if (examineclause != DQLD_CMD_O) {
260 examineclause = DQLD_CMD_O;
261 examineelem = stmt->orderby;
262 examineexpr = stmt->orderby ?
263 ((DavQLOrderCriterion*)stmt->orderby->data)->column : NULL;
264 dav_debug_ql_expr_print(examineexpr);
265 }
266 break;
267 case DQLD_CMD_N:
268 case DQLD_CMD_P:
269 if (examineelem) {
270 UcxList *newelem = (cmd == DQLD_CMD_N ?
271 examineelem->next : examineelem->prev);
272 if (newelem) {
273 examineelem = newelem;
274 if (examineclause == DQLD_CMD_O) {
275 examineexpr = ((DavQLOrderCriterion*)
276 examineelem->data)->column;
277 } else if (examineclause == DQLD_CMD_F) {
278 examineexpr = ((DavQLField*)examineelem->data)->expr;
279 } else {
280 printf("Examining unknown clause type.");
281 }
282 dav_debug_ql_expr_print(examineexpr);
283 } else {
284 printf("Reached end of list.\n");
285 }
286 } else {
287 printf("Currently not examining an expression list.\n");
288 }
289 break;
225 case DQLD_CMD_L: 290 case DQLD_CMD_L:
226 if (dav_debug_ql_expr_selected(examineexpr)) { 291 if (dav_debug_ql_expr_selected(examineexpr)) {
227 if (examineexpr->left) { 292 if (examineexpr->left) {
228 examineexpr = examineexpr->left; 293 examineexpr = examineexpr->left;
229 dav_debug_ql_expr_print(examineexpr); 294 dav_debug_ql_expr_print(examineexpr);
244 break; 309 break;
245 case DQLD_CMD_H: 310 case DQLD_CMD_H:
246 printf( 311 printf(
247 "\nCommands:\n" 312 "\nCommands:\n"
248 "ps: print statement information\n" 313 "ps: print statement information\n"
314 "o: examine order by clause\n"
315 "f: examine field list\n"
316 "w: examine where clause\n"
317 "n: examine next expression "
318 "(in order by clause or field list)\n"
319 "p: examine previous expression "
320 "(in order by clause or field list)\n"
249 "q: quit\n\n" 321 "q: quit\n\n"
250 "\nExpression examination:\n" 322 "\nExpression examination:\n"
251 "pe: print expression information\n" 323 "pe: print expression information\n"
252 "l: enter left subtree\n" 324 "l: enter left subtree\n"
253 "r: enter right subtree\n"); 325 "r: enter right subtree\n");
431 } 503 }
432 } 504 }
433 505
434 // process tokens 506 // process tokens
435 for (size_t i = 0 ; i < n ; i++) { 507 for (size_t i = 0 ; i < n ; i++) {
508 sstr_t tokendata = *token_sstr(token);
436 509
437 // TODO: make it so 510 // TODO: make it so
511 printf("Processing %.*s...\n", sfmtarg(tokendata));
438 512
439 // go to next token (if this is not the last token) 513 // go to next token (if this is not the last token)
440 if (i < n-1) { 514 if (i < n-1) {
441 token = token->next; 515 token = token->next;
442 } 516 }
465 #define _step_WITH_ 30 // WITH clause 539 #define _step_WITH_ 30 // WITH clause
466 #define _step_WHERE_ 40 // WHERE clause 540 #define _step_WHERE_ 40 // WHERE clause
467 #define _step_ORDER_BYopt_ 552 // expecting more ORDER BY details or end 541 #define _step_ORDER_BYopt_ 552 // expecting more ORDER BY details or end
468 #define _step_ORDER_BY_ 50 // ORDER BY clause 542 #define _step_ORDER_BY_ 50 // ORDER BY clause
469 #define _step_end_ 500 // expect end 543 #define _step_end_ 500 // expect end
544
545 struct fieldlist_parser_state {
546 UcxList *expr_firsttoken;
547 size_t expr_len;
548 /*
549 * 0: begin of field list - may encounter "*" or "-" special fields
550 * 1: collect expression token
551 * switch to step 2 on keyword "as"
552 * expect "," only if expr_len is 1 (add expr to list and continue)
553 * 2: expect one token (identifier) and a "," - continue with step 1
554 */
555 int step;
556 };
557
558 static int dav_parse_fieldlist(DavQLStatement *stmt, UcxList *token,
559 struct fieldlist_parser_state *state) {
560 sstr_t tokendata = *token_sstr(token);
561
562 switch (state->step) {
563 case 0:
564 // did not encounter special field, fall through to step 1
565 case 1:
566 break;
567 }
568
569 _Bool fromkeyword = !sstrcasecmp(tokendata, S("from"));
570 if (fromkeyword || !sstrcmp(tokendata, S(","))) {
571 if (state->expr_firsttoken) {
572 DavQLField *field = malloc(sizeof(DavQLField));
573 field->expr = dav_parse_expression(
574 stmt, state->expr_firsttoken, state->expr_len);
575 field->name = field->expr->srctext;
576 stmt->fields = ucx_list_append(stmt->fields, field);
577 state->expr_firsttoken = NULL;
578 state->expr_len = 0;
579
580 if (fromkeyword) {
581 return _step_FROM_;
582 }
583 } else {
584 dav_error_in_context(DAVQL_ERROR_UNEXPECTED_TOKEN,
585 _unexpected_token, stmt, token);
586 }
587 } else {
588 // collect tokens for field expression
589 if (state->expr_firsttoken) {
590 state->expr_len++;
591 } else {
592 state->expr_firsttoken = token;
593 state->expr_len = 1;
594 }
595 }
596
597 return _step_fieldlist_;
598 }
599
600 static void dav_free_field(DavQLField *field) {
601 dav_free_expression(field->expr);
602 free(field);
603 }
470 604
471 static int dav_parse_from(DavQLStatement *stmt, UcxList *token) { 605 static int dav_parse_from(DavQLStatement *stmt, UcxList *token) {
472 sstr_t tokendata = *token_sstr(token); 606 sstr_t tokendata = *token_sstr(token);
473 607
474 if (!sstrcasecmp(tokendata, S("with"))) { 608 if (!sstrcasecmp(tokendata, S("with"))) {
691 825
692 struct with_parser_state state_with; 826 struct with_parser_state state_with;
693 memset(&state_with, 0, sizeof(struct with_parser_state)); 827 memset(&state_with, 0, sizeof(struct with_parser_state));
694 struct orderby_parser_state state_orderby; 828 struct orderby_parser_state state_orderby;
695 memset(&state_orderby, 0, sizeof(struct orderby_parser_state)); 829 memset(&state_orderby, 0, sizeof(struct orderby_parser_state));
696 830 struct fieldlist_parser_state state_fieldlist;
697 // Variables for token sublists for expressions 831 memset(&state_fieldlist, 0, sizeof(struct fieldlist_parser_state));
698 // TODO: this is deprecated and won't work with function calls
699 UcxList *exprstart = NULL;
700 size_t exprlen = 0;
701 832
702 // Process tokens 833 // Process tokens
703 UCX_FOREACH(token, tokens) { 834 UCX_FOREACH(token, tokens) {
704 sstr_t tokendata = *token_sstr(token);
705
706 switch (step) { 835 switch (step) {
707 // too much input data 836 // too much input data
708 case _step_end_: 837 case _step_end_:
709 dav_error_in_context(DAVQL_ERROR_UNEXPECTED_TOKEN, 838 dav_error_in_context(DAVQL_ERROR_UNEXPECTED_TOKEN,
710 _unexpected_token, stmt, token); 839 _unexpected_token, stmt, token);
711 break; 840 break;
712 // field list 841 // field list
713 case _step_fieldlist_: { 842 case _step_fieldlist_: {
714 _Bool fromkeyword = !sstrcasecmp(tokendata, S("from")); 843 step = dav_parse_fieldlist(stmt, token, &state_fieldlist);
715 if (fromkeyword || !sstrcmp(tokendata, S(","))) {
716 if (exprstart) {
717 stmt->fields = ucx_list_append(stmt->fields,
718 dav_parse_expression(stmt, exprstart, exprlen));
719 exprstart = NULL;
720 exprlen = 0;
721
722 if (fromkeyword) {
723 step = _step_FROM_;
724 }
725 } else {
726 dav_error_in_context(DAVQL_ERROR_UNEXPECTED_TOKEN,
727 _unexpected_token, stmt, token);
728 }
729 } else {
730 // collect tokens for field expression
731 if (exprstart) {
732 exprlen++;
733 } else {
734 exprstart = token;
735 exprlen = 1;
736 }
737 }
738 break; 844 break;
739 } 845 }
740 // from clause 846 // from clause
741 case _step_FROM_: { 847 case _step_FROM_: {
742 step = dav_parse_from(stmt, token); 848 step = dav_parse_from(stmt, token);
826 return stmt; 932 return stmt;
827 } 933 }
828 934
829 void dav_free_statement(DavQLStatement *stmt) { 935 void dav_free_statement(DavQLStatement *stmt) {
830 UCX_FOREACH(expr, stmt->fields) { 936 UCX_FOREACH(expr, stmt->fields) {
831 dav_free_expression(expr->data); 937 dav_free_field(expr->data);
832 } 938 }
833 ucx_list_free(stmt->fields); 939 ucx_list_free(stmt->fields);
834 UCX_FOREACH(expr, stmt->setvalues) {
835 dav_free_expression(expr->data);
836 }
837 ucx_list_free(stmt->setvalues);
838 940
839 if (stmt->where) { 941 if (stmt->where) {
840 dav_free_expression(stmt->where); 942 dav_free_expression(stmt->where);
841 } 943 }
842 if (stmt->errormessage) { 944 if (stmt->errormessage) {

mercurial