libidav/davqlparser.c

changeset 102
e9ae1318a559
parent 99
579238097973
child 103
b29692d5f7a7
equal deleted inserted replaced
101:95a215337b53 102:e9ae1318a559
87 case DAVQL_LIKE: return "LIKE"; case DAVQL_UNLIKE: return "UNLIKE"; 87 case DAVQL_LIKE: return "LIKE"; case DAVQL_UNLIKE: return "UNLIKE";
88 default: return "unknown"; 88 default: return "unknown";
89 } 89 }
90 } 90 }
91 91
92 static void dav_debug_ql_fnames_print(DavQLStatement *stmt) {
93 printf("Field names: ");
94 UCX_FOREACH(field, stmt->fields) {
95 DavQLField *f = field->data;
96 printf("%.*s, ", sfmtarg(f->name));
97 }
98 printf("\b\b \b\b\n");
99 }
100
92 static void dav_debug_ql_stmt_print(DavQLStatement *stmt) { 101 static void dav_debug_ql_stmt_print(DavQLStatement *stmt) {
93 // Basic information 102 // Basic information
94 size_t fieldcount = ucx_list_size(stmt->fields); 103 size_t fieldcount = ucx_list_size(stmt->fields);
95 int specialfield = 0; 104 int specialfield = 0;
96 if (stmt->fields) { 105 if (stmt->fields) {
103 } 112 }
104 } 113 }
105 if (specialfield) { 114 if (specialfield) {
106 fieldcount--; 115 fieldcount--;
107 } 116 }
108 printf("Statement: %.*s\nType: %s\nField count: %zu %s\nPath: %.*s\n" 117 printf("Statement: %.*s\nType: %s\nField count: %zu %s\n",
109 "Has where clause: %s\n",
110 sfmtarg(stmt->srctext), 118 sfmtarg(stmt->srctext),
111 _map_querytype(stmt->type), 119 _map_querytype(stmt->type),
112 fieldcount, 120 fieldcount,
113 _map_specialfield(specialfield), 121 _map_specialfield(specialfield));
122
123 dav_debug_ql_fnames_print(stmt);
124 printf("Path: %.*s\nHas where clause: %s\n",
114 sfmtarg(stmt->path), 125 sfmtarg(stmt->path),
115 stmt->where ? "yes" : "no"); 126 stmt->where ? "yes" : "no");
116 127
117 // WITH attributes 128 // WITH attributes
118 if (stmt->depth == DAV_DEPTH_INFINITY) { 129 if (stmt->depth == DAV_DEPTH_INFINITY) {
169 } 180 }
170 181
171 #define DQLD_CMD_Q 0 182 #define DQLD_CMD_Q 0
172 #define DQLD_CMD_PS 1 183 #define DQLD_CMD_PS 1
173 #define DQLD_CMD_PE 2 184 #define DQLD_CMD_PE 2
185 #define DQLD_CMD_PF 3
174 #define DQLD_CMD_F 10 186 #define DQLD_CMD_F 10
175 #define DQLD_CMD_W 11 187 #define DQLD_CMD_W 11
176 #define DQLD_CMD_O 12 188 #define DQLD_CMD_O 12
177 #define DQLD_CMD_L 21 189 #define DQLD_CMD_L 21
178 #define DQLD_CMD_R 22 190 #define DQLD_CMD_R 22
195 return DQLD_CMD_Q; 207 return DQLD_CMD_Q;
196 } else if (!strcmp(buffer, "ps\n")) { 208 } else if (!strcmp(buffer, "ps\n")) {
197 return DQLD_CMD_PS; 209 return DQLD_CMD_PS;
198 } else if (!strcmp(buffer, "pe\n")) { 210 } else if (!strcmp(buffer, "pe\n")) {
199 return DQLD_CMD_PE; 211 return DQLD_CMD_PE;
212 } else if (!strcmp(buffer, "pf\n")) {
213 return DQLD_CMD_PF;
200 } else if (!strcmp(buffer, "l\n")) { 214 } else if (!strcmp(buffer, "l\n")) {
201 return DQLD_CMD_L; 215 return DQLD_CMD_L;
202 } else if (!strcmp(buffer, "r\n")) { 216 } else if (!strcmp(buffer, "r\n")) {
203 return DQLD_CMD_R; 217 return DQLD_CMD_R;
204 } else if (!strcmp(buffer, "h\n")) { 218 } else if (!strcmp(buffer, "h\n")) {
239 int cmd = dav_debug_ql_command(); 253 int cmd = dav_debug_ql_command();
240 switch (cmd) { 254 switch (cmd) {
241 case DQLD_CMD_Q: return; 255 case DQLD_CMD_Q: return;
242 case DQLD_CMD_PS: dav_debug_ql_stmt_print(stmt); break; 256 case DQLD_CMD_PS: dav_debug_ql_stmt_print(stmt); break;
243 case DQLD_CMD_PE: dav_debug_ql_expr_print(examineexpr); break; 257 case DQLD_CMD_PE: dav_debug_ql_expr_print(examineexpr); break;
258 case DQLD_CMD_PF: dav_debug_ql_fnames_print(stmt); break;
244 case DQLD_CMD_F: 259 case DQLD_CMD_F:
245 if (examineclause != DQLD_CMD_F) { 260 if (examineclause != DQLD_CMD_F) {
246 examineclause = DQLD_CMD_F; 261 examineclause = DQLD_CMD_F;
247 examineelem = stmt->fields; 262 examineelem = stmt->fields;
248 examineexpr = stmt->fields ? 263 examineexpr = stmt->fields ?
311 printf( 326 printf(
312 "\nCommands:\n" 327 "\nCommands:\n"
313 "ps: print statement information\n" 328 "ps: print statement information\n"
314 "o: examine order by clause\n" 329 "o: examine order by clause\n"
315 "f: examine field list\n" 330 "f: examine field list\n"
331 "pf: print field names\n"
316 "w: examine where clause\n" 332 "w: examine where clause\n"
317 "n: examine next expression " 333 "n: examine next expression "
318 "(in order by clause or field list)\n" 334 "(in order by clause or field list)\n"
319 "p: examine previous expression " 335 "p: examine previous expression "
320 "(in order by clause or field list)\n" 336 "(in order by clause or field list)\n"
534 } 550 }
535 551
536 #define _step_fieldlist_ 10 // field list 552 #define _step_fieldlist_ 10 // field list
537 #define _step_FROM_ 20 // FROM clause 553 #define _step_FROM_ 20 // FROM clause
538 #define _step_WITH_ 30 // WITH clause 554 #define _step_WITH_ 30 // WITH clause
555 #define _step_WITHopt_ 530 // expecting more WITH details or end
539 #define _step_WHERE_ 40 // WHERE clause 556 #define _step_WHERE_ 40 // WHERE clause
540 #define _step_ORDER_BYopt_ 552 // expecting more ORDER BY details or end
541 #define _step_ORDER_BY_ 50 // ORDER BY clause 557 #define _step_ORDER_BY_ 50 // ORDER BY clause
558 #define _step_ORDER_BYopt_ 550 // expecting more ORDER BY details or end
542 #define _step_end_ 500 // expect end 559 #define _step_end_ 500 // expect end
543 560
544 struct fieldlist_parser_state { 561 struct fieldlist_parser_state {
545 UcxList *expr_firsttoken; 562 UcxList *expr_firsttoken;
546 DavQLField *currentfield; 563 DavQLField *currentfield;
723 struct with_parser_state { 740 struct with_parser_state {
724 /* 741 /*
725 * 0: key 742 * 0: key
726 * 1: = 743 * 1: =
727 * 2: value 744 * 2: value
728 * 3: comma or new clause 745 * 3: comma or new clause or end
729 */ 746 */
730 int step; 747 int step;
731 /* 748 /*
732 * 1: depth 749 * 1: depth
733 */ 750 */
800 dav_free_expression(depthexpr); 817 dav_free_expression(depthexpr);
801 } 818 }
802 break; 819 break;
803 } 820 }
804 state->step = 3; 821 state->step = 3;
805 return _step_WITH_; // continue parsing WITH clause 822 return _step_WITHopt_; // continue parsing WITH clause
806 case 3: 823 case 3:
807 // a with clause may be continued with a comma 824 // a with clause may be continued with a comma
808 // or another clause may follow 825 // or another clause may follow
809 if (!sstrcmp(tokendata, S(","))) { 826 if (!sstrcmp(tokendata, S(","))) {
810 state->step = 0; // reset clause parser 827 state->step = 0; // reset clause parser
904 dav_free_expression(crit->column); 921 dav_free_expression(crit->column);
905 } 922 }
906 free(crit); 923 free(crit);
907 } 924 }
908 925
926 /**
927 * Semantic analysis of a get statement.
928 * @param stmt the statement to analyze.
929 */
930 static void dav_analyze_get_statement(DavQLStatement *stmt) {
931 // TODO: make it so
932 }
933
934
935 /**
936 * Parser of a get statement.
937 * @param stmt the statement object that shall contain the syntax tree
938 * @param tokens the token list
939 */
909 static void dav_parse_get_statement(DavQLStatement *stmt, UcxList *tokens) { 940 static void dav_parse_get_statement(DavQLStatement *stmt, UcxList *tokens) {
910 stmt->type = DAVQL_GET; 941 stmt->type = DAVQL_GET;
911 942
912 int step = _step_fieldlist_; 943 int step = _step_fieldlist_;
913 944
935 case _step_FROM_: { 966 case _step_FROM_: {
936 step = dav_parse_from(stmt, token); 967 step = dav_parse_from(stmt, token);
937 break; 968 break;
938 } 969 }
939 // with clause 970 // with clause
940 case _step_WITH_: { 971 case _step_WITH_:
972 case _step_WITHopt_: {
941 step = dav_parse_with_clause(stmt, token, &state_with); 973 step = dav_parse_with_clause(stmt, token, &state_with);
942 break; 974 break;
943 } 975 }
944 // where clause 976 // where clause
945 case _step_WHERE_: 977 case _step_WHERE_:
960 if (stmt->errorcode) { 992 if (stmt->errorcode) {
961 break; 993 break;
962 } 994 }
963 } 995 }
964 996
965 if (!stmt->errorcode && step < _step_end_) { 997 if (!stmt->errorcode) {
966 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_END; 998 if (step < _step_end_) {
967 stmt->errormessage = strdup(_unexpected_end_msg); 999 stmt->errorcode = DAVQL_ERROR_UNEXPECTED_END;
1000 stmt->errormessage = strdup(_unexpected_end_msg);
1001 } else {
1002 dav_analyze_get_statement(stmt);
1003 }
968 } 1004 }
969 } 1005 }
970 1006
971 static void dav_parse_set_statement(DavQLStatement *stmt, UcxList *tokens) { 1007 static void dav_parse_set_statement(DavQLStatement *stmt, UcxList *tokens) {
972 stmt->type = DAVQL_SET; 1008 stmt->type = DAVQL_SET;

mercurial