xpath BUGFIX proper not-found support in unions
diff --git a/src/xpath.c b/src/xpath.c
index da27681..bc5f695 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -899,18 +899,21 @@
 set_init(struct lyxp_set *new, const struct lyxp_set *set)
 {
     memset(new, 0, sizeof *new);
-    if (set) {
-        new->non_child_axis = set->non_child_axis;
-        new->ctx = set->ctx;
-        new->cur_node = set->cur_node;
-        new->root_type = set->root_type;
-        new->context_op = set->context_op;
-        new->tree = set->tree;
-        new->cur_mod = set->cur_mod;
-        new->format = set->format;
-        new->prefix_data = set->prefix_data;
-        new->vars = set->vars;
+    if (!set) {
+        return;
     }
+
+    new->non_child_axis = set->non_child_axis;
+    new->not_found = set->not_found;
+    new->ctx = set->ctx;
+    new->cur_node = set->cur_node;
+    new->root_type = set->root_type;
+    new->context_op = set->context_op;
+    new->tree = set->tree;
+    new->cur_mod = set->cur_mod;
+    new->format = set->format;
+    new->prefix_data = set->prefix_data;
+    new->vars = set->vars;
 }
 
 /**
@@ -7522,7 +7525,11 @@
             *tok_idx = orig_exp;
 
             rc = eval_expr_select(exp, tok_idx, 0, &set2, options);
-            if (rc != LY_SUCCESS) {
+            if (!rc && set2.not_found) {
+                set->not_found = 1;
+                break;
+            }
+            if (rc) {
                 lyxp_set_free_content(&set2);
                 return rc;
             }
@@ -7571,6 +7578,9 @@
             *tok_idx = orig_exp;
 
             rc = eval_expr_select(exp, tok_idx, 0, set, options);
+            if (!rc && set->not_found) {
+                break;
+            }
             LY_CHECK_RET(rc);
 
             set->val.scnodes[i].in_ctx = pred_in_ctx;
@@ -7590,7 +7600,7 @@
         set_fill_set(&set2, set);
 
         rc = eval_expr_select(exp, tok_idx, 0, &set2, options);
-        if (rc != LY_SUCCESS) {
+        if (rc) {
             lyxp_set_free_content(&set2);
             return rc;
         }
@@ -8205,8 +8215,7 @@
 
                 if (options & LYXP_SCNODE_ERROR) {
                     /* error */
-                    rc = LY_ENOTFOUND;
-                    goto cleanup;
+                    set->not_found = 1;
                 }
 
                 /* skip the predicates and the rest of this path to not generate invalid warnings */
@@ -8248,10 +8257,8 @@
         /* restore options */
         options &= ~LYXP_SKIP_EXPR;
     }
-    if (!(options & LYXP_SKIP_EXPR)) {
-        lydict_remove(set->ctx, ncname_dict);
-        ly_path_predicates_free(set->ctx, predicates);
-    }
+    lydict_remove(set->ctx, ncname_dict);
+    ly_path_predicates_free(set->ctx, predicates);
     return rc;
 }
 
@@ -8423,8 +8430,9 @@
             rc = eval_name_test_with_predicate(exp, tok_idx, axis, all_desc, set, options);
             if (rc == LY_ENOT) {
                 assert(options & LYXP_SCNODE_ALL);
-                /* skip the rest of this path */
                 rc = LY_SUCCESS;
+
+                /* skip the rest of this path */
                 scnode_skip_path = 1;
                 options |= LYXP_SKIP_EXPR;
             }
@@ -8673,8 +8681,9 @@
 
             rc = eval_expr_select(exp, tok_idx, 0, args[0], options);
             LY_CHECK_GOTO(rc, cleanup);
+            set->not_found = args[0]->not_found;
         } else {
-            rc = eval_expr_select(exp, tok_idx, 0, set, options | LYXP_SKIP_EXPR);
+            rc = eval_expr_select(exp, tok_idx, 0, set, options);
             LY_CHECK_GOTO(rc, cleanup);
         }
     }
@@ -8696,8 +8705,11 @@
 
             rc = eval_expr_select(exp, tok_idx, 0, args[arg_count - 1], options);
             LY_CHECK_GOTO(rc, cleanup);
+            if (args[arg_count - 1]->not_found) {
+                set->not_found = 1;
+            }
         } else {
-            rc = eval_expr_select(exp, tok_idx, 0, set, options | LYXP_SKIP_EXPR);
+            rc = eval_expr_select(exp, tok_idx, 0, set, options);
             LY_CHECK_GOTO(rc, cleanup);
         }
     }
@@ -8990,8 +9002,9 @@
 eval_union_expr(const struct lyxp_expr *exp, uint32_t *tok_idx, uint32_t repeat, struct lyxp_set *set, uint32_t options)
 {
     LY_ERR rc = LY_SUCCESS;
-    struct lyxp_set orig_set, set2;
     uint32_t i;
+    struct lyxp_set orig_set, set2;
+    ly_bool found = 0;
 
     assert(repeat);
 
@@ -9002,6 +9015,11 @@
 
     rc = eval_expr_select(exp, tok_idx, LYXP_EXPR_UNION, set, options);
     LY_CHECK_GOTO(rc, cleanup);
+    if (set->not_found) {
+        set->not_found = 0;
+    } else {
+        found = 1;
+    }
 
     /* ('|' PathExpr)* */
     for (i = 0; i < repeat; ++i) {
@@ -9019,6 +9037,9 @@
         set_fill_set(&set2, &orig_set);
         rc = eval_expr_select(exp, tok_idx, LYXP_EXPR_UNION, &set2, options);
         LY_CHECK_GOTO(rc, cleanup);
+        if (!set2.not_found) {
+            found = 1;
+        }
 
         /* eval */
         if (options & LYXP_SCNODE_ALL) {
@@ -9032,6 +9053,9 @@
 cleanup:
     lyxp_set_free_content(&orig_set);
     lyxp_set_free_content(&set2);
+    if (!found) {
+        set->not_found = 1;
+    }
     return rc;
 }
 
@@ -9099,7 +9123,7 @@
 eval_multiplicative_expr(const struct lyxp_expr *exp, uint32_t *tok_idx, uint32_t repeat, struct lyxp_set *set,
         uint32_t options)
 {
-    LY_ERR rc;
+    LY_ERR rc = LY_SUCCESS;
     uint32_t i, this_op;
     struct lyxp_set orig_set, set2;
 
@@ -9131,6 +9155,9 @@
         set_fill_set(&set2, &orig_set);
         rc = eval_expr_select(exp, tok_idx, LYXP_EXPR_MULTIPLICATIVE, &set2, options);
         LY_CHECK_GOTO(rc, cleanup);
+        if (set2.not_found) {
+            set->not_found = 1;
+        }
 
         /* eval */
         if (options & LYXP_SCNODE_ALL) {
@@ -9166,7 +9193,7 @@
 static LY_ERR
 eval_additive_expr(const struct lyxp_expr *exp, uint32_t *tok_idx, uint32_t repeat, struct lyxp_set *set, uint32_t options)
 {
-    LY_ERR rc;
+    LY_ERR rc = LY_SUCCESS;
     uint32_t i, this_op;
     struct lyxp_set orig_set, set2;
 
@@ -9198,6 +9225,9 @@
         set_fill_set(&set2, &orig_set);
         rc = eval_expr_select(exp, tok_idx, LYXP_EXPR_ADDITIVE, &set2, options);
         LY_CHECK_GOTO(rc, cleanup);
+        if (set2.not_found) {
+            set->not_found = 1;
+        }
 
         /* eval */
         if (options & LYXP_SCNODE_ALL) {
@@ -9235,7 +9265,7 @@
 static LY_ERR
 eval_relational_expr(const struct lyxp_expr *exp, uint32_t *tok_idx, uint32_t repeat, struct lyxp_set *set, uint32_t options)
 {
-    LY_ERR rc;
+    LY_ERR rc = LY_SUCCESS;
     uint32_t i, this_op;
     struct lyxp_set orig_set, set2;
 
@@ -9267,6 +9297,9 @@
         set_fill_set(&set2, &orig_set);
         rc = eval_expr_select(exp, tok_idx, LYXP_EXPR_RELATIONAL, &set2, options);
         LY_CHECK_GOTO(rc, cleanup);
+        if (set2.not_found) {
+            set->not_found = 1;
+        }
 
         /* eval */
         if (options & LYXP_SCNODE_ALL) {
@@ -9304,7 +9337,7 @@
 static LY_ERR
 eval_equality_expr(const struct lyxp_expr *exp, uint32_t *tok_idx, uint32_t repeat, struct lyxp_set *set, uint32_t options)
 {
-    LY_ERR rc;
+    LY_ERR rc = LY_SUCCESS;
     uint32_t i, this_op;
     struct lyxp_set orig_set, set2;
 
@@ -9336,6 +9369,9 @@
         set_fill_set(&set2, &orig_set);
         rc = eval_expr_select(exp, tok_idx, LYXP_EXPR_EQUALITY, &set2, options);
         LY_CHECK_GOTO(rc, cleanup);
+        if (set2.not_found) {
+            set->not_found = 1;
+        }
 
         /* eval */
         if (options & LYXP_SCNODE_ALL) {
@@ -9374,7 +9410,7 @@
 static LY_ERR
 eval_and_expr(const struct lyxp_expr *exp, uint32_t *tok_idx, uint32_t repeat, struct lyxp_set *set, uint32_t options)
 {
-    LY_ERR rc;
+    LY_ERR rc = LY_SUCCESS;
     struct lyxp_set orig_set, set2;
     uint32_t i;
 
@@ -9414,6 +9450,9 @@
         set_fill_set(&set2, &orig_set);
         rc = eval_expr_select(exp, tok_idx, LYXP_EXPR_AND, &set2, options);
         LY_CHECK_GOTO(rc, cleanup);
+        if (set2.not_found) {
+            set->not_found = 1;
+        }
 
         /* eval - just get boolean value actually */
         if (set->type == LYXP_SET_SCNODE_SET) {
@@ -9446,7 +9485,7 @@
 static LY_ERR
 eval_or_expr(const struct lyxp_expr *exp, uint32_t *tok_idx, uint32_t repeat, struct lyxp_set *set, uint32_t options)
 {
-    LY_ERR rc;
+    LY_ERR rc = LY_SUCCESS;
     struct lyxp_set orig_set, set2;
     uint32_t i;
 
@@ -9488,6 +9527,9 @@
          * but it does not matter */
         rc = eval_expr_select(exp, tok_idx, LYXP_EXPR_OR, &set2, options);
         LY_CHECK_GOTO(rc, cleanup);
+        if (set2.not_found) {
+            set->not_found = 1;
+        }
 
         /* eval - just get boolean value actually */
         if (set->type == LYXP_SET_SCNODE_SET) {
@@ -9674,7 +9716,10 @@
 
     /* evaluate */
     rc = eval_expr_select(exp, &tok_idx, 0, set, options);
-    if (rc != LY_SUCCESS) {
+    if (!rc && set->not_found) {
+        rc = LY_ENOTFOUND;
+    }
+    if (rc) {
         lyxp_set_free_content(set);
     }
 
@@ -9915,7 +9960,7 @@
         LY_VALUE_FORMAT format, void *prefix_data, const struct lysc_node *cur_scnode,
         const struct lysc_node *ctx_scnode, struct lyxp_set *set, uint32_t options)
 {
-    LY_ERR ret;
+    LY_ERR rc;
     uint32_t tok_idx = 0;
 
     LY_CHECK_ARG_RET(ctx, ctx, exp, set, LY_EINVAL);
@@ -9943,10 +9988,13 @@
     LOG_LOCSET(set->cur_scnode, NULL, NULL, NULL);
 
     /* evaluate */
-    ret = eval_expr_select(exp, &tok_idx, 0, set, options);
+    rc = eval_expr_select(exp, &tok_idx, 0, set, options);
+    if (!rc && set->not_found) {
+        rc = LY_ENOTFOUND;
+    }
 
     LOG_LOCBACK(set->cur_scnode ? 1 : 0, 0, 0, 0);
-    return ret;
+    return rc;
 }
 
 LIBYANG_API_DEF const char *