49 #define DEBUG DEBUG_NONE
53 static char error_message[DB_ERROR_BUF_SIZE];
54 static int error_line;
55 static const char *error_function;
56 #define RETURN(value) \
58 if(error_message[0] == '\0') { \
59 strncpy(error_message, lexer->input, sizeof(error_message) - 1); \
60 error_line = __LINE__; \
61 error_function = __func__; \
65 #define RESET_ERROR() \
67 error_message[0] = '\0'; \
69 error_function = NULL; \
72 #define RETURN(value) return (value)
75 #define PARSER(name) \
77 parse_##name(lexer_t *lexer)
78 #define PARSER_ARG(name, arg) \
80 parse_##name(lexer_t *lexer, arg)
81 #define PARSER_TOKEN(name) \
83 parse_##name(lexer_t *lexer)
85 !AQL_ERROR(parse_##name(lexer))
86 #define PARSE_TOKEN(name) \
89 #define NEXT lexer_next(lexer)
90 #define REWIND lexer_rewind(lexer); RESET_ERROR()
91 #define TOKEN *lexer->token
92 #define VALUE *lexer->value
94 #define CONSUME(token) \
97 if(TOKEN != (token)) { \
98 RETURN(SYNTAX_ERROR); \
103 static aql_adt_t *adt;
107 static lvm_instance_t p;
108 static unsigned char vmcode[DB_VM_BYTECODE_SIZE];
142 PARSER_TOKEN(aggregator)
161 aql_aggregator_t
function;
163 token = PARSE_TOKEN(aggregator);
167 function = AQL_COUNT;
176 function = AQL_MEDIAN;
185 RETURN(SYNTAX_ERROR);
188 AQL_SET_FLAG(adt, AQL_FLAG_AGGREGATE);
190 PRINTF(
"aggregator: %d\n", TOKEN);
196 AQL_ADD_AGGREGATE(adt,
function, VALUE);
197 PRINTF(
"aggregated attribute: %s\n", VALUE);
199 CONSUME(RIGHT_PAREN);
200 goto check_more_attributes;
209 AQL_ADD_ATTRIBUTE(adt, VALUE, DOMAIN_UNSPECIFIED, 0);
211 check_more_attributes:
214 if(!PARSE(attributes)) {
215 RETURN(SYNTAX_ERROR);
229 AQL_ADD_RELATION(adt, VALUE);
232 if(!PARSE(relations)) {
233 RETURN(SYNTAX_ERROR);
248 AQL_ADD_VALUE(adt, DOMAIN_STRING, VALUE);
251 AQL_ADD_VALUE(adt, DOMAIN_INT, VALUE);
254 RETURN(SYNTAX_ERROR);
259 return PARSE(values);
272 lvm_register_variable(VALUE, LVM_LONG);
273 lvm_set_variable(&p, VALUE);
274 AQL_ADD_PROCESSING_ATTRIBUTE(adt, VALUE);
281 lvm_set_long(&p, *(
long *)lexer->value);
284 RETURN(SYNTAX_ERROR);
296 saved_end = lvm_get_end(&p);
299 if(TOKEN == LEFT_PAREN) {
301 RETURN(SYNTAX_ERROR);
303 CONSUME(RIGHT_PAREN);
306 if(!PARSE(operand)) {
307 RETURN(SYNTAX_ERROR);
312 token = PARSE_TOKEN(op);
314 saved_end = lvm_get_end(&p);
317 }
else if (token == RIGHT_PAREN) {
321 if(!PARSE(operand) && !PARSE(expr)) {
322 RETURN(SYNTAX_ERROR);
325 saved_end = lvm_shift_for_operator(&p, saved_end);
341 RETURN(SYNTAX_ERROR);
344 lvm_set_end(&p, saved_end);
356 saved_end = lvm_jump_to_operand(&p);
359 RETURN(SYNTAX_ERROR);
362 saved_end = lvm_set_end(&p, saved_end);
364 token = PARSE_TOKEN(cmp);
366 RETURN(SYNTAX_ERROR);
389 RETURN(SYNTAX_ERROR);
392 lvm_set_relation(&p, rel);
393 lvm_set_end(&p, saved_end);
396 RETURN(SYNTAX_ERROR);
405 operator_t connective;
408 if(!PARSE(comparison)) {
409 RETURN(SYNTAX_ERROR);
417 if(TOKEN != AND && TOKEN != OR) {
422 connective = TOKEN == AND ? LVM_AND : LVM_OR;
424 saved_end = lvm_shift_for_operator(&p, saved_end);
425 lvm_set_relation(&p, connective);
426 lvm_set_end(&p, saved_end);
429 if(TOKEN == LEFT_PAREN) {
432 RETURN(SYNTAX_ERROR);
434 CONSUME(RIGHT_PAREN);
437 r = PARSE(comparison);
451 AQL_SET_TYPE(adt, AQL_TYPE_JOIN);
455 PRINTF(
"Left relation: %s\n", VALUE);
456 AQL_ADD_RELATION(adt, VALUE);
461 PRINTF(
"Right relation: %s\n", VALUE);
462 AQL_ADD_RELATION(adt, VALUE);
467 PRINTF(
"Join on attribute %s\n", VALUE);
468 AQL_ADD_ATTRIBUTE(adt, VALUE, DOMAIN_UNSPECIFIED, 0);
473 if(!PARSE(attributes)) {
474 RETURN(SYNTAX_ERROR);
484 AQL_SET_TYPE(adt, AQL_TYPE_SELECT);
487 if(!PARSE(attributes)) {
488 RETURN(SYNTAX_ERROR);
492 if(!PARSE(relations)) {
493 RETURN(SYNTAX_ERROR);
498 lvm_reset(&p, vmcode,
sizeof(vmcode));
501 RETURN(SYNTAX_ERROR);
504 AQL_SET_CONDITION(adt, &p);
517 AQL_SET_TYPE(adt, AQL_TYPE_INSERT);
522 RETURN(SYNTAX_ERROR);
525 CONSUME(RIGHT_PAREN);
528 if(!PARSE(relations)) {
529 RETURN(SYNTAX_ERROR);
535 PARSER(remove_attribute)
537 AQL_SET_TYPE(adt, AQL_TYPE_REMOVE_ATTRIBUTE);
540 AQL_ADD_RELATION(adt, VALUE);
545 PRINTF(
"Removing the index for the attribute %s\n", VALUE);
546 AQL_ADD_ATTRIBUTE(adt, VALUE, DOMAIN_UNSPECIFIED, 0);
551 #if DB_FEATURE_REMOVE
554 AQL_SET_TYPE(adt, AQL_TYPE_REMOVE_TUPLES);
557 AQL_SET_FLAG(adt, AQL_FLAG_ASSIGN);
558 AQL_ADD_RELATION(adt, REMOVE_RELATION);
561 AQL_ADD_RELATION(adt, VALUE);
565 lvm_reset(&p, vmcode,
sizeof(vmcode));
566 AQL_SET_CONDITION(adt, &p);
575 AQL_SET_TYPE(adt, AQL_TYPE_REMOVE_INDEX);
578 AQL_ADD_RELATION(adt, VALUE);
583 PRINTF(
"remove index: %s\n", VALUE);
584 AQL_ADD_ATTRIBUTE(adt, VALUE, DOMAIN_UNSPECIFIED, 0);
589 PARSER(remove_relation)
591 AQL_SET_TYPE(adt, AQL_TYPE_REMOVE_RELATION);
594 PRINTF(
"remove relation: %s\n", VALUE);
595 AQL_ADD_RELATION(adt, VALUE);
607 r = PARSE(remove_attribute);
609 #if DB_FEATURE_REMOVE
611 r = PARSE(remove_from);
615 r = PARSE(remove_index);
618 r = PARSE(remove_relation);
621 RETURN(SYNTAX_ERROR);
625 RETURN(SYNTAX_ERROR);
633 PARSER_TOKEN(index_type)
643 type = INDEX_MAXHEAP;
646 type = INDEX_MEMHASH;
652 AQL_SET_INDEX_TYPE(adt, type);
658 AQL_SET_TYPE(adt, AQL_TYPE_CREATE_INDEX);
661 AQL_ADD_RELATION(adt, VALUE);
666 PRINTF(
"Creating an index for the attribute %s\n", VALUE);
667 AQL_ADD_ATTRIBUTE(adt, VALUE, DOMAIN_UNSPECIFIED, 0);
671 if(PARSE_TOKEN(index_type) == NONE) {
672 RETURN(SYNTAX_ERROR);
678 PARSER(create_relation)
682 AQL_SET_TYPE(adt, AQL_TYPE_CREATE_RELATION);
683 AQL_ADD_RELATION(adt, VALUE);
688 PARSER_ARG(domain,
char *name)
691 unsigned element_size;
696 domain = DOMAIN_STRING;
700 CONSUME(INTEGER_VALUE);
701 element_size = *(
long *)lexer->value;
702 CONSUME(RIGHT_PAREN);
706 domain = DOMAIN_LONG;
717 AQL_ADD_ATTRIBUTE(adt, name, domain, element_size);
722 PARSER(create_attributes)
725 char name[ATTRIBUTE_NAME_LENGTH];
727 AQL_SET_TYPE(adt, AQL_TYPE_CREATE_ATTRIBUTE);
731 strncpy(name, VALUE,
sizeof(name) - 1);
732 name[
sizeof(name) - 1] =
'\0';
736 r = parse_domain(lexer, name);
744 AQL_ADD_RELATION(adt, VALUE);
756 r = PARSE(create_attributes);
759 r = PARSE(create_index);
762 r = PARSE(create_relation);
765 RETURN(SYNTAX_ERROR);
769 RETURN(SYNTAX_ERROR);
778 aql_parse(aql_adt_t *external_adt,
char *input_string)
781 token_t token = NONE;
787 PRINTF(
"Parsing \"%s\"\n", input_string);
791 AQL_SET_CONDITION(adt,
NULL);
793 lexer_start(&lex, input_string, &token, &value);
795 result = lexer_next(&lex);
796 if(!AQL_ERROR(result)) {
799 PRINTF(
"Assign the result to relation %s\n", *lex.value);
800 AQL_ADD_RELATION(adt, *lex.value);
801 AQL_SET_FLAG(adt, AQL_FLAG_ASSIGN);
802 if(AQL_ERROR(lexer_next(&lex))) {
803 result = SYNTAX_ERROR;
806 if(*lex.token != ASSIGN) {
807 result = SYNTAX_ERROR;
810 if(AQL_ERROR(lexer_next(&lex))) {
811 result = SYNTAX_ERROR;
816 result = parse_select(&lex);
819 result = parse_join(&lex);
822 result = SYNTAX_ERROR;
826 result = parse_join(&lex);
829 result = parse_create(&lex);
832 result = parse_remove(&lex);
835 result = parse_insert(&lex);
838 result = parse_select(&lex);
846 result = SYNTAX_ERROR;
850 if(AQL_ERROR(result)) {
851 PRINTF(
"Error in function %s, line %d: input \"%s\"\n",
852 error_function, error_line, error_message);
Definitions and declarations for AQL, the Antelope Query Language.
#define NULL
The null pointer.
Definitions and declarations for the Propositional Logic Engine.
Database configuration options.
Definitions for attributes.
A set of debugging macros.