| 743 | } |
| 744 | |
| 745 | void AR_EXP_CollectAttributes(AR_ExpNode *root, rax *attributes) { |
| 746 | if(AR_EXP_IsOperation(root)) { |
| 747 | if(strcmp(AR_EXP_GetFuncName(root), "property") == 0) { |
| 748 | AR_ExpNode *arg = root->op.children[1]; |
| 749 | ASSERT(AR_EXP_IsConstant(arg)); |
| 750 | ASSERT(SI_TYPE(arg->operand.constant) == T_STRING); |
| 751 | |
| 752 | const char *attr = arg->operand.constant.stringval; |
| 753 | raxInsert(attributes, (unsigned char *)attr, strlen(attr), NULL, NULL); |
| 754 | } |
| 755 | |
| 756 | // continue scanning expression |
| 757 | for(int i = 0; i < root->op.child_count; i ++) { |
| 758 | AR_EXP_CollectAttributes(root->op.children[i], attributes); |
| 759 | } |
| 760 | } |
| 761 | } |
| 762 | |
| 763 | bool AR_EXP_ContainsAggregation(AR_ExpNode *root) { |
| 764 | if(AGGREGATION_NODE(root)) return true; |
no test coverage detected