| 3322 | } |
| 3323 | |
| 3324 | static const char *project_item(binding_t *b, cbm_return_item_t *item, char *func_buf, |
| 3325 | size_t buf_sz) { |
| 3326 | if (item->kase) { |
| 3327 | return eval_case_expr(item->kase, b); |
| 3328 | } |
| 3329 | if (item->args) { |
| 3330 | return eval_multiarg_func(b, item, func_buf, buf_sz); |
| 3331 | } |
| 3332 | /* Entity-introspection functions operate on the bound node/edge itself, |
| 3333 | * not on a scalar property value. */ |
| 3334 | if (item->func) { |
| 3335 | if (strcmp(item->func, "labels") == 0) { |
| 3336 | cbm_node_t *n = binding_get(b, item->variable); |
| 3337 | if (n && n->label) { |
| 3338 | snprintf(func_buf, buf_sz, "[\"%s\"]", n->label); |
| 3339 | return func_buf; |
| 3340 | } |
| 3341 | return "[]"; |
| 3342 | } |
| 3343 | if (strcmp(item->func, "type") == 0) { |
| 3344 | cbm_edge_t *e = binding_get_edge(b, item->variable); |
| 3345 | return (e && e->type) ? e->type : ""; |
| 3346 | } |
| 3347 | if (strcmp(item->func, "id") == 0) { |
| 3348 | cbm_node_t *n = binding_get(b, item->variable); |
| 3349 | if (n) { |
| 3350 | snprintf(func_buf, buf_sz, "%lld", (long long)n->id); |
| 3351 | return func_buf; |
| 3352 | } |
| 3353 | cbm_edge_t *e = binding_get_edge(b, item->variable); |
| 3354 | if (e) { |
| 3355 | snprintf(func_buf, buf_sz, "%lld", (long long)e->id); |
| 3356 | return func_buf; |
| 3357 | } |
| 3358 | return ""; |
| 3359 | } |
| 3360 | if (strcmp(item->func, "keys") == 0) { |
| 3361 | cbm_node_t *n = binding_get(b, item->variable); |
| 3362 | return n ? node_keys_list(n, func_buf, buf_sz) : "[]"; |
| 3363 | } |
| 3364 | if (strcmp(item->func, "properties") == 0) { |
| 3365 | cbm_node_t *n = binding_get(b, item->variable); |
| 3366 | if (n) { |
| 3367 | return n->properties_json ? n->properties_json : "{}"; |
| 3368 | } |
| 3369 | cbm_edge_t *e = binding_get_edge(b, item->variable); |
| 3370 | if (e) { |
| 3371 | return e->properties_json ? e->properties_json : "{}"; |
| 3372 | } |
| 3373 | return "{}"; |
| 3374 | } |
| 3375 | } |
| 3376 | const char *raw = binding_get_virtual(b, item->variable, item->property); |
| 3377 | if (is_scalar_value_func(item->func)) { |
| 3378 | return apply_string_func(item->func, raw, func_buf, buf_sz); |
| 3379 | } |
| 3380 | /* Copy into the caller's per-column buffer. `raw` may point to node_prop's |
| 3381 | * rotating scratch buffer, which the next column's projection would overwrite |
no test coverage detected