- RSET rset_l;
- RSET rset_r;
-
- rset_l = rpn_search_structure (zh, zs->u.complex->s1,
- attributeSet, stream, rset_nmem,
- sort_sequence,
- num_bases, basenames);
- if (rset_l == NULL)
- return NULL;
- rset_r = rpn_search_structure (zh, zs->u.complex->s2,
- attributeSet, stream, rset_nmem,
- sort_sequence,
- num_bases, basenames);
- if (rset_r == NULL)
- {
- rset_delete (rset_l);
- return NULL;
- }
-
- switch (zop->which)
- {
- case Z_Operator_and:
- r = rsbool_create_and(rset_nmem,key_it_ctrl, rset_l,rset_r );
- break;
- case Z_Operator_or:
- r = rsbool_create_or(rset_nmem,key_it_ctrl, rset_l,rset_r );
- break;
- case Z_Operator_and_not:
- r = rsbool_create_not(rset_nmem,key_it_ctrl, rset_l,rset_r );
- break;
- case Z_Operator_prox:
- if (zop->u.prox->which != Z_ProximityOperator_known)
- {
- zh->errCode = 132;
- return NULL;
- }
- if (*zop->u.prox->u.known != Z_ProxUnit_word)
- {
- char *val = (char *) nmem_malloc (stream, 16);
- zh->errCode = 132;
- zh->errString = val;
- sprintf (val, "%d", *zop->u.prox->u.known);
- return NULL;
- }
- else
- {
- /* new / old prox */
- RSET twosets[2];
-
- twosets[0] = rset_l;
- twosets[1] = rset_r;
- r=rsprox_create(rset_nmem,key_it_ctrl,
- 2, twosets,
- *zop->u.prox->ordered,
- (!zop->u.prox->exclusion ?
- 0 : *zop->u.prox->exclusion),
- *zop->u.prox->relationType,
- *zop->u.prox->distance );
- }
- break;
- default:
- zh->errCode = 110;
- return NULL;
- }
+ RSET *result_sets_l = 0;
+ int num_result_sets_l = 0;
+ RSET *result_sets_r = 0;
+ int num_result_sets_r = 0;
+
+ res = rpn_search_structure(zh, zs->u.complex->s1,
+ attributeSet, stream, rset_nmem,
+ sort_sequence,
+ num_bases, basenames,
+ &result_sets_l, &num_result_sets_l,
+ zop, kc);
+ if (res != ZEBRA_OK)
+ {
+ int i;
+ for (i = 0; i<num_result_sets_l; i++)
+ rset_delete(result_sets_l[i]);
+ return res;
+ }
+ res = rpn_search_structure(zh, zs->u.complex->s2,
+ attributeSet, stream, rset_nmem,
+ sort_sequence,
+ num_bases, basenames,
+ &result_sets_r, &num_result_sets_r,
+ zop, kc);
+ if (res != ZEBRA_OK)
+ {
+ int i;
+ for (i = 0; i<num_result_sets_l; i++)
+ rset_delete(result_sets_l[i]);
+ for (i = 0; i<num_result_sets_r; i++)
+ rset_delete(result_sets_r[i]);
+ return res;
+ }
+
+ /* make a new list of result for all children */
+ *num_result_sets = num_result_sets_l + num_result_sets_r;
+ *result_sets = nmem_malloc(stream, *num_result_sets *
+ sizeof(**result_sets));
+ memcpy(*result_sets, result_sets_l,
+ num_result_sets_l * sizeof(**result_sets));
+ memcpy(*result_sets + num_result_sets_l, result_sets_r,
+ num_result_sets_r * sizeof(**result_sets));
+
+ if (!parent_op || parent_op->which != zop->which
+ || (zop->which != Z_Operator_and &&
+ zop->which != Z_Operator_or))
+ {
+ /* parent node different from this one (or non-present) */
+ /* we must combine result sets now */
+ RSET rset;
+ switch (zop->which)
+ {
+ case Z_Operator_and:
+ rset = rsmulti_and_create(rset_nmem, kc,
+ kc->scope,
+ *num_result_sets, *result_sets);
+ break;
+ case Z_Operator_or:
+ rset = rsmulti_or_create(rset_nmem, kc,
+ kc->scope, 0, /* termid */
+ *num_result_sets, *result_sets);
+ break;
+ case Z_Operator_and_not:
+ rset = rsbool_create_not(rset_nmem, kc,
+ kc->scope,
+ (*result_sets)[0],
+ (*result_sets)[1]);
+ break;
+ case Z_Operator_prox:
+ if (zop->u.prox->which != Z_ProximityOperator_known)
+ {
+ zebra_setError(zh,
+ YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
+ 0);
+ return ZEBRA_FAIL;
+ }
+ if (*zop->u.prox->u.known != Z_ProxUnit_word)
+ {
+ zebra_setError_zint(zh,
+ YAZ_BIB1_UNSUPP_PROX_UNIT_CODE,
+ *zop->u.prox->u.known);
+ return ZEBRA_FAIL;
+ }
+ else
+ {
+ rset = rsprox_create(rset_nmem, kc,
+ kc->scope,
+ *num_result_sets, *result_sets,
+ *zop->u.prox->ordered,
+ (!zop->u.prox->exclusion ?
+ 0 : *zop->u.prox->exclusion),
+ *zop->u.prox->relationType,
+ *zop->u.prox->distance );
+ }
+ break;
+ default:
+ zebra_setError(zh, YAZ_BIB1_OPERATOR_UNSUPP, 0);
+ return ZEBRA_FAIL;
+ }
+ *num_result_sets = 1;
+ *result_sets = nmem_malloc(stream, *num_result_sets *
+ sizeof(**result_sets));
+ (*result_sets)[0] = rset;
+ }