| 147 | } |
| 148 | |
| 149 | bool AST_ReadOnly |
| 150 | ( |
| 151 | const cypher_astnode_t *root |
| 152 | ) { |
| 153 | // check for empty query |
| 154 | if(root == NULL) return true; |
| 155 | |
| 156 | cypher_astnode_type_t type = cypher_astnode_type(root); |
| 157 | if(type == CYPHER_AST_CREATE || |
| 158 | type == CYPHER_AST_MERGE || |
| 159 | type == CYPHER_AST_DELETE || |
| 160 | type == CYPHER_AST_SET || |
| 161 | type == CYPHER_AST_REMOVE || |
| 162 | type == CYPHER_AST_CREATE_NODE_PROPS_INDEX || |
| 163 | type == CYPHER_AST_CREATE_PATTERN_PROPS_INDEX || |
| 164 | type == CYPHER_AST_DROP_PROPS_INDEX) { |
| 165 | return false; |
| 166 | } |
| 167 | |
| 168 | // in case of procedure call which modifies the graph/indices |
| 169 | if(type == CYPHER_AST_CALL) { |
| 170 | const char *proc_name = cypher_ast_proc_name_get_value( |
| 171 | cypher_ast_call_get_proc_name(root)); |
| 172 | |
| 173 | ProcedureCtx *proc = Proc_Get(proc_name); |
| 174 | bool read_only = Procedure_IsReadOnly(proc); |
| 175 | Proc_Free(proc); |
| 176 | |
| 177 | if(!read_only) return false; |
| 178 | } |
| 179 | |
| 180 | uint num_children = cypher_astnode_nchildren(root); |
| 181 | for(uint i = 0; i < num_children; i ++) { |
| 182 | const cypher_astnode_t *child = cypher_astnode_get_child(root, i); |
| 183 | if(!AST_ReadOnly(child)) return false; |
| 184 | } |
| 185 | |
| 186 | return true; |
| 187 | } |
| 188 | |
| 189 | // returns true if the given ast-node will result in an eager operation |
| 190 | static bool _clause_is_eager |
no test coverage detected