use syntax and matching rules knowledge when preparing SQL filters (to reduce pseudo-normalization efforts and search candidate number)

This commit is contained in:
Pierangelo Masarati 2003-04-16 10:22:33 +00:00
parent fc7e29e0c5
commit d9d5912383
6 changed files with 92 additions and 32 deletions

View file

@ -101,6 +101,9 @@ typedef struct {
char *insentry_query,*delentry_query;
char *id_query;
char *has_children_query;
MatchingRule *bi_caseIgnoreMatch;
struct berval upper_func;
struct berval upper_func_open;
struct berval upper_func_close;

View file

@ -413,8 +413,6 @@ backsql_id2entry( backsql_srch_info *bsi, Entry *e, backsql_entryID *eid )
size_t textlen = sizeof( textbuf );
struct berval bv[ 2 ];
struct berval soc;
AttributeDescription *ad_soc
= slap_schema.si_ad_structuralObjectClass;
int rc;
bv[ 0 ] = bsi->oc->oc->soc_cname;

View file

@ -215,7 +215,10 @@ backsql_db_open(
ber_str2bv( /* (? */ ")", 0, 1, &si->upper_func_close );
}
}
/* normalize filter values only if necessary */
si->bi_caseIgnoreMatch = mr_find( "caseIgnoreMatch" );
if ( si->dbuser == NULL ) {
Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
"user name not specified "
@ -385,11 +388,14 @@ backsql_db_open(
backsql_strcat( &bb, backsql_id_query,
"dn_ru=?", NULL );
} else {
#if 0
if ( BACKSQL_USE_REVERSE_DN( si ) ) {
#endif
backsql_strfcat( &bb, "sbl",
backsql_id_query,
&si->upper_func,
(ber_len_t)sizeof( "(dn)=?" ) - 1, "(dn)=?" );
#if 0
} else {
backsql_strfcat( &bb, "sblbcb",
backsql_id_query,
@ -399,6 +405,7 @@ backsql_db_open(
'?',
&si->upper_func_close );
}
#endif
}
}
si->id_query = bb.bb_val.bv_val;

View file

@ -205,11 +205,17 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
int i;
backsql_at_map_rec *at;
backsql_info *bi = (backsql_info *)bsi->op->o_bd->be_private;
int casefold = 0;
if ( !f ) {
return 0;
}
if ( SLAP_MR_ASSOCIATED( f->f_sub_desc->ad_type->sat_substr,
bi->bi_caseIgnoreMatch ) ) {
casefold = 1;
}
at = backsql_ad2at( bsi->oc, f->f_sub_desc );
assert( at );
@ -225,7 +231,7 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
/* TimesTen */
Debug( LDAP_DEBUG_TRACE, "expr: '%s' '%s'\n", at->sel_expr.bv_val,
at->sel_expr_u.bv_val ? at->sel_expr_u.bv_val : "<NULL>", 0 );
if ( bi->upper_func.bv_val ) {
if ( casefold && bi->upper_func.bv_val ) {
/*
* If a pre-upper-cased version of the column exists, use it
*/
@ -257,7 +263,7 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
start = bsi->flt_where.bb_val.bv_len;
backsql_strfcat( &bsi->flt_where, "b",
&f->f_sub_initial );
if ( bi->upper_func.bv_val ) {
if ( casefold && bi->upper_func.bv_val ) {
ldap_pvt_str2upper( &bsi->flt_where.bb_val.bv_val[ start ] );
}
}
@ -280,7 +286,7 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
"bc",
&f->f_sub_any[ i ],
'%' );
if ( bi->upper_func.bv_val ) {
if ( casefold && bi->upper_func.bv_val ) {
/*
* Note: toupper('%') = '%'
*/
@ -294,7 +300,7 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
start = bsi->flt_where.bb_val.bv_len;
backsql_strfcat( &bsi->flt_where, "b",
&f->f_sub_final );
if ( bi->upper_func.bv_val ) {
if ( casefold && bi->upper_func.bv_val ) {
ldap_pvt_str2upper( &bsi->flt_where.bb_val.bv_val[ start ] );
}
}
@ -316,9 +322,11 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
BER_BVNULL, NULL, NULL, NULL };
AttributeDescription *ad = NULL;
int done = 0;
/* TimesTen */
int casefold = 0;
int rc = 0;
struct berval *filter_value = NULL;
MatchingRule *matching_rule = NULL;
struct berval ordering = BER_BVC("<=");
Debug( LDAP_DEBUG_TRACE, "==>backsql_process_filter()\n", 0, 0, 0 );
if ( f == NULL || f->f_choice == SLAPD_FILTER_COMPUTED ) {
@ -457,21 +465,29 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
switch ( f->f_choice ) {
case LDAP_FILTER_EQUALITY:
filter_value = &f->f_av_value;
matching_rule = ad->ad_type->sat_equality;
goto equality_match;
/* fail over next case */
/* fail over into next case */
case LDAP_FILTER_EXT:
filter_value = &f->f_mra->ma_value;
matching_rule = f->f_mr_rule;
equality_match:;
if ( SLAP_MR_ASSOCIATED( matching_rule,
bi->bi_caseIgnoreMatch ) ) {
casefold = 1;
}
/*
* maybe we should check type of at->sel_expr here somehow,
* to know whether upper_func is applicable, but for now
* upper_func stuff is made for Oracle, where UPPER is
* safely applicable to NUMBER etc.
*/
if ( bi->upper_func.bv_val ) {
if ( casefold && bi->upper_func.bv_val ) {
size_t start;
if ( at->sel_expr_u.bv_val ) {
@ -511,27 +527,58 @@ equality_match:;
break;
case LDAP_FILTER_GE:
/*
* FIXME: should we uppercase the operands?
*/
backsql_strfcat( &bsi->flt_where, "cblbc",
'(' /* ) */ ,
&at->sel_expr,
(ber_len_t)sizeof( ">=" ) - 1, ">=",
&f->f_av_value,
/* ( */ ')' );
break;
ordering.bv_val = ">=";
/* fall thru to next case */
case LDAP_FILTER_LE:
if ( SLAP_MR_ASSOCIATED( ad->ad_type->sat_ordering,
bi->bi_caseIgnoreMatch ) ) {
casefold = 1;
}
/*
* FIXME: should we uppercase the operands?
*/
backsql_strfcat( &bsi->flt_where, "cblbc",
'(' /* ) */ ,
&at->sel_expr,
(ber_len_t)sizeof( "<=" ) - 1, "<=",
&f->f_av_value,
/* ( */ ')' );
if ( casefold && bi->upper_func.bv_val ) {
size_t start;
if ( at->sel_expr_u.bv_val ) {
backsql_strfcat( &bsi->flt_where, "cbbc",
'(',
&at->sel_expr_u,
&ordering,
'\'' );
} else {
backsql_strfcat( &bsi->flt_where, "cbcbcbc",
'(' /* ) */ ,
&bi->upper_func,
'(' /* ) */ ,
&at->sel_expr,
/* ( */ ')',
&ordering,
'\'' );
}
start = bsi->flt_where.bb_val.bv_len;
backsql_strfcat( &bsi->flt_where, "bl",
filter_value,
(ber_len_t)sizeof( /* (' */ "')" ) - 1,
/* (' */ "')" );
ldap_pvt_str2upper( &bsi->flt_where.bb_val.bv_val[ start ] );
} else {
backsql_strfcat( &bsi->flt_where, "cbbcbl",
'(' /* ) */ ,
&at->sel_expr,
&ordering,
'\'',
&f->f_av_value,
(ber_len_t)sizeof( /* (' */ "')" ) - 1,
/* ( */ "')" );
}
break;
case LDAP_FILTER_PRESENT:
@ -800,6 +847,10 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
BACKSQL_ROW_NTS row;
int i;
int j;
int n_candidates = bsi->n_candidates;
bsi->status = LDAP_SUCCESS;
Debug( LDAP_DEBUG_TRACE, "==>backsql_oc_get_candidates(): oc='%s'\n",
BACKSQL_OC_NAME( oc ), 0, 0 );
@ -982,7 +1033,8 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
backsql_FreeRow( &row );
SQLFreeStmt( sth, SQL_DROP );
Debug( LDAP_DEBUG_TRACE, "<==backsql_oc_get_candidates()\n", 0, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "<==backsql_oc_get_candidates(): %d\n",
n_candidates - bsi->n_candidates, 0, 0 );
return ( bsi->n_candidates == -1 ? BACKSQL_STOP : BACKSQL_CONTINUE );
}

View file

@ -30,9 +30,6 @@
#define SLAP_NVALUES 1
#define MR_ASSOCIATED(mr,amr) (((mr) == (amr)) || \
((mr)->smr_associated == (amr)))
/* not yet implemented */
#define objectIdentifierNormalize NULL
#define integerOrderingMatch NULL
@ -1005,7 +1002,7 @@ UTF8StringNormalize(
return LDAP_SUCCESS;
}
flags = MR_ASSOCIATED( mr, slap_schema.si_mr_caseExactMatch )
flags = SLAP_MR_ASSOCIATED( mr, slap_schema.si_mr_caseExactMatch )
? LDAP_UTF8_NOCASEFOLD : LDAP_UTF8_CASEFOLD;
flags |= ( ( use & SLAP_MR_EQUALITY_APPROX ) == SLAP_MR_EQUALITY_APPROX )
? LDAP_UTF8_APPROX : 0;
@ -1694,7 +1691,7 @@ IA5StringNormalize(
void *ctx )
{
char *p, *q;
int casefold = MR_ASSOCIATED( mr, slap_schema.si_mr_caseExactIA5Match );
int casefold = SLAP_MR_ASSOCIATED( mr, slap_schema.si_mr_caseExactIA5Match );
assert( val->bv_len );

View file

@ -495,6 +495,9 @@ typedef struct slap_matching_rule {
*/
struct slap_matching_rule *smr_associated;
#define SLAP_MR_ASSOCIATED(mr,amr) (((mr) == (amr)) || \
((mr)->smr_associated == (amr)))
LDAP_SLIST_ENTRY(slap_matching_rule)smr_next;
#define smr_oid smr_mrule.mr_oid