]> git.sur5r.net Git - openldap/commitdiff
honor attributeType inheritance as well
authorPierangelo Masarati <ando@openldap.org>
Sat, 17 Jan 2004 16:27:11 +0000 (16:27 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 17 Jan 2004 16:27:11 +0000 (16:27 +0000)
servers/slapd/back-sql/schema-map.c
servers/slapd/back-sql/schema-map.h
servers/slapd/back-sql/search.c

index f73114b3ed3005492486655de18bd383ab153c2e..106d73e4ffd8be4d744e4fa9ae0228042e095775 100644 (file)
@@ -567,6 +567,73 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad )
        return res;
 }
 
+/* attributeType inheritance */
+struct supad2at_t {
+       backsql_at_map_rec      **ret;
+       AttributeDescription    *ad;
+       unsigned                n;
+};
+
+#define SUPAD2AT_STOP  (-1)
+
+static int
+supad2at_f( void *v_at, void *v_arg )
+{
+       backsql_at_map_rec      *at = (backsql_at_map_rec *)v_at;
+       struct supad2at_t       *va = (struct supad2at_t *)v_arg;
+
+       if ( is_at_subtype( at->bam_ad->ad_type, va->ad->ad_type ) ) {
+               backsql_at_map_rec      **ret;
+
+               ret = ch_realloc( va->ret, sizeof( backsql_at_map_rec *) * ( va->n + 2 ) );
+               if ( ret == NULL ) {
+                       ch_free( va->ret );
+                       return SUPAD2AT_STOP;
+               }
+
+               ret[ va->n ] = at;
+               va->n++;
+               ret[ va->n ] = NULL;
+               va->ret = ret;
+       }
+
+       return 0;
+}
+
+/*
+ * stores in *pret a NULL terminated array of pointers
+ * to backsql_at_map_rec whose attributeType is supad->ad_type 
+ * or derived from it
+ */
+int
+backsql_supad2at( backsql_oc_map_rec *objclass, AttributeDescription *supad,
+               backsql_at_map_rec ***pret )
+{
+       struct supad2at_t       va;
+       int                     rc;
+
+       assert( objclass );
+       assert( supad );
+       assert( pret );
+
+       *pret = NULL;
+
+       va.ret = NULL;
+       va.ad = supad;
+       va.n = 0;
+       
+       rc = avl_apply( objclass->bom_attrs, supad2at_f, &va,
+                       SUPAD2AT_STOP, AVL_INORDER );
+       if ( rc == SUPAD2AT_STOP ) {
+               return -1;
+       }
+
+       *pret = va.ret;
+
+       return 0;
+}
+
+
 #if 0
 /*
  * Deprecated
index f9add2d7c891fcfc2c867bf7079fcd1c3366542a..cf7d388a3a00269b7af1f20cf7902ff9ba9454d3 100644 (file)
@@ -100,6 +100,8 @@ backsql_at_map_rec *backsql_name2at( backsql_oc_map_rec *objclass,
                struct berval *at_name );
 backsql_at_map_rec *backsql_ad2at( backsql_oc_map_rec *objclass,
                AttributeDescription *ad );
+int backsql_supad2at( backsql_oc_map_rec *objclass,
+               AttributeDescription *supad, backsql_at_map_rec ***pret );
 int backsql_destroy_schema_map( backsql_info *si );
 
 #endif /* __BACKSQL_SCHEMA_MAP_H__ */
index 56538aa4a1858f4285aec174f0b89bf5cb66a25d..342b79becf4d9a75af1bb0a7e1de90ddf4d43d32 100644 (file)
@@ -215,10 +215,10 @@ backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op )
 }
 
 static int
-backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
+backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f,
+       backsql_at_map_rec *at )
 {
        int                     i;
-       backsql_at_map_rec      *at;
        backsql_info            *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;
        int                     casefold = 0;
 
@@ -234,10 +234,6 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
                casefold = 1;
        }
 
-       at = backsql_ad2at( bsi->bsi_oc, f->f_sub_desc );
-
-       assert( at );
-
        /*
         * When dealing with case-sensitive strings 
         * we may omit normalization; however, normalized
@@ -247,8 +243,9 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
        backsql_strfcat( &bsi->bsi_flt_where, "c", '(' /* ) */  );
 
        /* TimesTen */
-       Debug( LDAP_DEBUG_TRACE, "expr: '%s' '%s'\n", at->bam_sel_expr.bv_val,
-               at->bam_sel_expr_u.bv_val ? at->bam_sel_expr_u.bv_val : "<NULL>", 0 );
+       Debug( LDAP_DEBUG_TRACE, "expr: '%s%s%s'\n", at->bam_sel_expr.bv_val,
+               at->bam_sel_expr_u.bv_val ? "' '" : "",
+               at->bam_sel_expr_u.bv_val ? at->bam_sel_expr_u.bv_val : "" );
        if ( casefold && bi->upper_func.bv_val ) {
                /*
                 * If a pre-upper-cased version of the column exists, use it
@@ -294,9 +291,9 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
 
 #ifdef BACKSQL_TRACE
                        Debug( LDAP_DEBUG_TRACE, 
-                               "==>backsql_process_sub_filter(): "
-                               "sub_any='%s'\n", f->f_sub_any[ i ].bv_val,
-                               0, 0 );
+                               "==>backsql_process_sub_filter(%s): "
+                               "sub_any='%s'\n", at->bam_ad->ad_cname.bv_val,
+                               f->f_sub_any[ i ].bv_val, 0 );
 #endif /* BACKSQL_TRACE */
 
                        start = bsi->bsi_flt_where.bb_val.bv_len;
@@ -333,8 +330,9 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
 static int
 backsql_process_filter( backsql_srch_info *bsi, Filter *f )
 {
-       backsql_at_map_rec      *at;
+       backsql_at_map_rec      **vat = NULL;
        AttributeDescription    *ad = NULL;
+       unsigned                i;
        int                     done = 0;
        int                     rc = 0;
 
@@ -342,7 +340,8 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
        if ( f->f_choice == SLAPD_FILTER_COMPUTED ) {
                Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): "
                        "invalid filter\n", 0, 0, 0 );
-               goto impossible;
+               rc = -1;
+               goto done;
        }
 
        switch( f->f_choice ) {
@@ -381,10 +380,11 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
        }
 
        if ( rc == -1 ) {
-               goto impossible;
+               goto done;
        }
  
        if ( done ) {
+               rc = 1;
                goto done;
        }
 
@@ -410,12 +410,14 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                                                "in filter\n",
                                                f->f_av_value.bv_val, 0, 0 );
                                bsi->bsi_status = LDAP_OTHER;
-                               goto impossible;
+                               rc = -1;
+                               goto done;
                        }
 
                        /*
-                        * objectClass inheritance:
-                        * - a search for "person" will also return "inetOrgPerson"
+                        * "structural" objectClass inheritance:
+                        * - a search for "person" will also return 
+                        *   "inetOrgPerson"
                         * - a search for "top" will return everything
                         */
                        if ( is_object_subclass( oc, bsi->bsi_oc->bom_oc ) ) {
@@ -430,6 +432,7 @@ filter_oc_success:;
                        backsql_strfcat( &bsi->bsi_flt_where, "l",
                                        (ber_len_t)sizeof( "1=1" ) - 1, "1=1" );
                        bsi->bsi_status = LDAP_SUCCESS;
+                       rc = 1;
                        goto done;
                        
                default:
@@ -439,7 +442,8 @@ filter_oc_success:;
                                        "on objectClass attribute",
                                        0, 0, 0 );
                        bsi->bsi_status = LDAP_OTHER;
-                       goto impossible;
+                       rc = -1;
+                       goto done;
                }
 
        } else if ( ad == slap_schema.si_ad_hasSubordinates || ad == NULL ) {
@@ -474,60 +478,80 @@ filter_oc_success:;
                         */
                        backsql_attrlist_add( bsi, NULL );
                }
+               rc = 1;
                goto done;
        }
 
-       /* look for attribute (also if objectClass but not structural one) */
-       at = backsql_ad2at( bsi->bsi_oc, ad );
-
-       if ( at == NULL ) {
-               Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): "
-                       "attribute '%s' is not defined for objectclass '%s'\n",
-                       ad->ad_cname.bv_val, BACKSQL_OC_NAME( bsi->bsi_oc ), 0 );
+       /*
+        * attribute inheritance:
+        */
+       if ( backsql_supad2at( bsi->bsi_oc, ad, &vat ) ) {
+               bsi->bsi_status = LDAP_OTHER;
+               rc = -1;
+               goto done;
+       }
 
-#if 0
-               backsql_strfcat( &bsi->bsi_flt_where, "l",
-                               (ber_len_t)sizeof( "1=0" ) - 1, "1=0" );
-               bsi->bsi_status = LDAP_UNDEFINED_TYPE;
-               goto impossible;
-#else
-               /* search anyway; other parts of the filter may succeeed */
+       if ( vat == NULL ) {
+               /* search anyway; other parts of the filter
+                * may succeeed */
                backsql_strfcat( &bsi->bsi_flt_where, "l",
                                (ber_len_t)sizeof( "1=1" ) - 1, "1=1" );
                bsi->bsi_status = LDAP_SUCCESS;
+               rc = 1;
                goto done;
-#endif
        }
 
-       /* apply extra level of parens only if required */
+       /* if required, open extra level of parens */
        done = 0;
-       if ( at->bam_next ) {
+       if ( vat[0]->bam_next || vat[1] ) {
                backsql_strfcat( &bsi->bsi_flt_where, "c", '(' );
                done = 1;
        }
+
+       i = 0;
 next:;
-       if ( backsql_process_filter_attr( bsi, f, at ) == -1 ) {
+       /* apply attr */
+       if ( backsql_process_filter_attr( bsi, f, vat[i] ) == -1 ) {
                return -1;
        }
 
-       if ( at->bam_next ) {
+       /* if more definitions of the same attr, apply */
+       if ( vat[i]->bam_next ) {
+               backsql_strfcat( &bsi->bsi_flt_where, "l",
+                       sizeof( " OR " ) - 1, " OR " );
+               vat[i] = vat[i]->bam_next;
+               goto next;
+       }
+
+       /* if more descendants of the same attr, apply */
+       i++;
+       if ( vat[i] ) {
                backsql_strfcat( &bsi->bsi_flt_where, "l",
-                               sizeof( " OR " ) - 1, " OR " );
-               at = at->bam_next;
+                       sizeof( " OR " ) - 1, " OR " );
                goto next;
        }
+
+       /* if needed, close extra level of parens */
        if ( done ) {
                backsql_strfcat( &bsi->bsi_flt_where, "c", ')' );
        }
 
-done:;
-       Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter()\n", 0, 0, 0 );
-       return 1;
+       rc = 1;
 
-impossible:;
-       Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter() returns -1\n",
-                       0, 0, 0 );
-       return -1;
+done:;
+       if ( vat ) {
+               ch_free( vat );
+       }
+       if ( rc == 1 ) {
+               Debug( LDAP_DEBUG_TRACE,
+                               "<==backsql_process_filter() succeeded\n",
+                               0, 0, 0 );
+       } else {
+               Debug( LDAP_DEBUG_TRACE,
+                               "<==backsql_process_filter() failed\n",
+                               0, 0, 0 );
+       }
+       return rc;
 }
 
 static int
@@ -692,7 +716,7 @@ equality_match:;
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
-               backsql_process_sub_filter( bsi, f );
+               backsql_process_sub_filter( bsi, f, at );
                break;
 
        case LDAP_FILTER_APPROX: