build pending updates in the 'updates' array to match all AST-level updates described in the context NULL values are allowed in SET clauses but not in MERGE clauses
| 121 | // AST-level updates described in the context |
| 122 | // NULL values are allowed in SET clauses but not in MERGE clauses |
| 123 | void EvalEntityUpdates |
| 124 | ( |
| 125 | GraphContext *gc, |
| 126 | dict *node_updates, |
| 127 | dict *edge_updates, |
| 128 | const Record r, |
| 129 | const EntityUpdateEvalCtx *ctx, |
| 130 | bool allow_null |
| 131 | ) { |
| 132 | Schema *s = NULL; |
| 133 | |
| 134 | //-------------------------------------------------------------------------- |
| 135 | // validate entity type |
| 136 | //-------------------------------------------------------------------------- |
| 137 | |
| 138 | // get the type of the entity to update |
| 139 | // if the expected entity was not found, make no updates but do not error |
| 140 | RecordEntryType t = Record_GetType(r, ctx->record_idx); |
| 141 | if(unlikely(t == REC_TYPE_UNKNOWN)) { |
| 142 | return; |
| 143 | } |
| 144 | |
| 145 | // make sure we're updating either a node or an edge |
| 146 | if(unlikely(t != REC_TYPE_NODE && t != REC_TYPE_EDGE)) { |
| 147 | ErrorCtx_RaiseRuntimeException( |
| 148 | "Update error: alias '%s' did not resolve to a graph entity", |
| 149 | ctx->alias); |
| 150 | } |
| 151 | |
| 152 | // label(s) update can only be performed on nodes |
| 153 | if(unlikely((ctx->add_labels != NULL || ctx->remove_labels != NULL) && |
| 154 | t != REC_TYPE_NODE)) { |
| 155 | ErrorCtx_RaiseRuntimeException( |
| 156 | "Type mismatch: expected Node but was Relationship"); |
| 157 | } |
| 158 | |
| 159 | GraphEntity *entity = Record_GetGraphEntity(r, ctx->record_idx); |
| 160 | |
| 161 | // if the entity is marked as deleted, make no updates but do not error |
| 162 | if(unlikely(Graph_EntityIsDeleted(entity))) { |
| 163 | return; |
| 164 | } |
| 165 | |
| 166 | dict *updates; |
| 167 | GraphEntityType entity_type; |
| 168 | if(t == REC_TYPE_NODE) { |
| 169 | updates = node_updates; |
| 170 | entity_type = GETYPE_NODE; |
| 171 | } else { |
| 172 | updates = edge_updates; |
| 173 | entity_type = GETYPE_EDGE; |
| 174 | } |
| 175 | |
| 176 | PendingUpdateCtx *update; |
| 177 | dictEntry *entry = HashTableFind(updates, (void *)ENTITY_GET_ID(entity)); |
| 178 | if(entry == NULL) { |
| 179 | // create a new update context |
| 180 | update = rm_malloc(sizeof(PendingUpdateCtx)); |
no test coverage detected