]> git.sur5r.net Git - openldap/commitdiff
use syntax and matching rules knowledge when preparing SQL filters (to reduce pseudo...
authorPierangelo Masarati <ando@openldap.org>
Wed, 16 Apr 2003 10:22:33 +0000 (10:22 +0000)
committerPierangelo Masarati <ando@openldap.org>
Wed, 16 Apr 2003 10:22:33 +0000 (10:22 +0000)
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/entry-id.c
servers/slapd/back-sql/init.c
servers/slapd/back-sql/search.c
servers/slapd/schema_init.c
servers/slapd/slap.h

index 2fb550867065986bdd19c4b9b6e66a4f4216fc0b..63004112aaf9b59e12393e3080c352d6073208ed 100644 (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;
index deb7c6a05121d3a7a5632fc853aa27b6f1802fdb..81729c8f309a183ea0f055bc2739f79b53a7e947 100644 (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;
index dd0e8320d95917a51b9d5b5989de01d47b0bb3d4..712ac7aef65658cdda027063dcc4fe8aeefa34e9 100644 (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;
index 77f6e895371ddc0dc174cb58c855ecda56c3b4cb..f1cc0ada09a14f7a0729b4962b110d9a295c7603 100644 (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 );
 }
index 243bcea6cb0769ae9eeb1a63371a5a02ef2d28e7..e023f39dc2353f5f1ce2eb9ccfc952b0c671df44 100644 (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 );
 
index e72b55bb90590178e9aeb74786d1e97b1babf9a6..a6a3f4b5a9f89166944192961489f671ddbb790e 100644 (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