honor attributeType inheritance as well

This commit is contained in:
Pierangelo Masarati 2004-01-17 16:27:11 +00:00
parent d65f402058
commit c4a8f58a0d
3 changed files with 140 additions and 47 deletions

View 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

View 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__ */

View 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 );
/*
* attribute inheritance:
*/
if ( backsql_supad2at( bsi->bsi_oc, ad, &vat ) ) {
bsi->bsi_status = LDAP_OTHER;
rc = -1;
goto done;
}
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 );
#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 " );
at = at->bam_next;
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 " );
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: