浏览代码

Ticket #48109 - substring index with nssubstrbegin: 1 is not being used with filters like (attr=x*)

Description: subString index width was not properly passed to the
syntax plugin in the substr search.  This patch fixes a couple of
issues.
1. Pass substrlen array to syntax plugin by stashing it in pblock
   with SLAPI_SYNTAX_SUBSTRLENS.
2. Advertised format "nsSubStr{Begin,Middle,End}: width" was not
   supported.  It is again supported.
3. If both "nsSubStr{Begin,Middle,End}: width" and "nsMatchingRule:
   nsSubStr{Begin,Middle,End}=width" are specified, the former is
   honored, the latter is used if the former directive does not exist.

https://fedorahosted.org/389/ticket/48109

Reviewed by [email protected] (Thank you, Rich!!)
Noriko Hosoi 10 年之前
父节点
当前提交
ae69e4aa1d

+ 4 - 1
ldap/servers/slapd/back-ldbm/filterindex.c

@@ -936,6 +936,7 @@ substring_candidates(
     Slapi_Attr   sattr;
     back_txn     txn = {NULL};
     int          pr_idx = -1;
+    struct attrinfo *ai = NULL;
 
     LDAPDebug( LDAP_DEBUG_TRACE, "=> sub_candidates\n", 0, 0, 0 );
 
@@ -950,7 +951,9 @@ substring_candidates(
      * assertion values
      */
     slapi_attr_init(&sattr, type);
-    slapi_attr_assertion2keys_sub_sv( &sattr, initial, any, final, &ivals );
+    ainfo_get(be, type, &ai);
+    slapi_pblock_set(pb, SLAPI_SYNTAX_SUBSTRLENS, ai->ai_substr_lens );
+    slapi_attr_assertion2keys_sub_sv_pb( pb, &sattr, initial, any, final, &ivals );
     attr_done(&sattr);
     slapi_pblock_get(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx);
     if ( ivals == NULL || *ivals == NULL ) {

+ 56 - 14
ldap/servers/slapd/back-ldbm/ldbm_attr.c

@@ -677,6 +677,7 @@ attr_index_config(
 	Slapi_Attr *attr;
 	int mr_count = 0;
 	char myreturntext[SLAPI_DSE_RETURNTEXT_SIZE];
+	int substrval = 0;
 
 	/* Get the cn */
 	if (0 == slapi_entry_attr_find(e, "cn", &attr)) {
@@ -762,6 +763,31 @@ attr_index_config(
 	 * ordering matching rule compatible with the attribute syntax, and there is
 	 * a compare function.  If not, we assume it is a RULE index definition.
 	 */
+	/*
+	 * nsSubStrBegin: 2
+	 * nsSubStrMiddle: 2
+	 * nsSubStrEnd: 2
+	 */ 
+	substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTRBEGIN);
+	if (substrval) {
+		substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN);
+		substrlens[INDEX_SUBSTRBEGIN] = substrval;
+	}
+	substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTRMIDDLE);
+	if (substrval) {
+		if (!substrlens) {
+			substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN);
+		}
+		substrlens[INDEX_SUBSTRMIDDLE] = substrval;
+	}
+	substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTREND);
+	if (substrval) {
+		if (!substrlens) {
+			substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN);
+		}
+		substrlens[INDEX_SUBSTREND] = substrval;
+	}
+	a->ai_substr_lens = substrlens;
 
 	if(0 == slapi_entry_attr_find(e, "nsMatchingRule", &attr)){
 		char** official_rules;
@@ -778,21 +804,35 @@ attr_index_config(
 			Slapi_PBlock* pb = NULL;
 			int do_continue = 0; /* can we skip the RULE parsing stuff? */
 			attrValue = slapi_value_get_berval(sval);
-
-			if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTRBEGIN)) {
-				_set_attr_substrlen(INDEX_SUBSTRBEGIN, attrValue->bv_val, &substrlens);
-				do_continue = 1; /* done with j - next j */
-			} else if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTRMIDDLE)) {
-				_set_attr_substrlen(INDEX_SUBSTRMIDDLE, attrValue->bv_val,	&substrlens);
-				do_continue = 1; /* done with j - next j */
-			} else if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTREND)) {
-				_set_attr_substrlen(INDEX_SUBSTREND, attrValue->bv_val, &substrlens);
-				do_continue = 1; /* done with j - next j */
+			/*
+			 * In case nsSubstr{Begin,Middle,End}: num is not set, but set by this format:
+			 *   nsMatchingRule: nsSubstrBegin=2
+			 *   nsMatchingRule: nsSubstrMiddle=2
+			 *   nsMatchingRule: nsSubstrEnd=2
+			 */ 
+			if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTRBEGIN]) {
+				if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTRBEGIN)) {
+					_set_attr_substrlen(INDEX_SUBSTRBEGIN, attrValue->bv_val, &substrlens);
+					do_continue = 1; /* done with j - next j */
+				}
+			}
+			if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTRMIDDLE]) {
+				if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTRMIDDLE)) {
+					_set_attr_substrlen(INDEX_SUBSTRMIDDLE, attrValue->bv_val, &substrlens);
+					do_continue = 1; /* done with j - next j */
+				}
+			}
+			if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTREND]) {
+				if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTREND)) {
+					_set_attr_substrlen(INDEX_SUBSTREND, attrValue->bv_val, &substrlens);
+					do_continue = 1; /* done with j - next j */
+				}
+			}
 			/* check if this is a simple ordering specification
 			   for an attribute that has no ordering matching rule */
-			} else if (slapi_matchingrule_is_ordering(attrValue->bv_val, attrsyntax_oid) &&
-					   slapi_matchingrule_can_use_compare_fn(attrValue->bv_val) &&
-					   !a->ai_sattr.a_mr_ord_plugin) { /* no ordering for this attribute */
+			if (slapi_matchingrule_is_ordering(attrValue->bv_val, attrsyntax_oid) &&
+			    slapi_matchingrule_can_use_compare_fn(attrValue->bv_val) &&
+			    !a->ai_sattr.a_mr_ord_plugin) { /* no ordering for this attribute */
 				need_compare_fn = 1; /* get compare func for this attr */
 				do_continue = 1; /* done with j - next j */
 			}
@@ -844,7 +884,9 @@ attr_index_config(
 			slapi_pblock_destroy (pb);
 		}
 		official_rules[k] = NULL;
-		a->ai_substr_lens = substrlens;
+		if (substrlens) {
+			a->ai_substr_lens = substrlens;
+		}
 		if (k > 0) {
 			a->ai_index_rules = official_rules;
 			a->ai_indexmask |= INDEX_RULES;

+ 19 - 3
ldap/servers/slapd/plugin_syntax.c

@@ -907,6 +907,19 @@ slapi_attr_assertion2keys_sub_sv(
     char		*final,
     Slapi_Value	***ivals
 )
+{
+	return slapi_attr_assertion2keys_sub_sv_pb(NULL, sattr, initial, any, final, ivals);
+}
+
+int
+slapi_attr_assertion2keys_sub_sv_pb(
+    Slapi_PBlock *pb,
+    const Slapi_Attr *sattr,
+    char		*initial,
+    char		**any,
+    char		*final,
+    Slapi_Value	***ivals
+)
 {
 	int			rc;
 	Slapi_PBlock		pipb;
@@ -927,13 +940,16 @@ slapi_attr_assertion2keys_sub_sv(
 		pi = sattr->a_plugin;
 		a2k_fn = sattr->a_plugin->plg_syntax_assertion2keys_sub;
 	}
-	pblock_init( &pipb );
-	slapi_pblock_set( &pipb, SLAPI_PLUGIN, pi );
+	if (NULL == pb) {
+		pblock_init( &pipb );
+		pb = &pipb;
+	}
+	slapi_pblock_set( pb, SLAPI_PLUGIN, pi );
 
 	rc = -1;	/* means no assertion2keys function */
 	*ivals = NULL;
 	if ( a2k_fn != NULL ) {
-		rc = (*a2k_fn)( &pipb, initial, any, final, ivals );
+		rc = (*a2k_fn)( pb, initial, any, final, ivals );
 	}
 
 	LDAPDebug( LDAP_DEBUG_FILTER,

+ 2 - 0
ldap/servers/slapd/slapi-plugin.h

@@ -5849,6 +5849,8 @@ int slapi_call_syntax_assertion2keys_ava_sv( void *vpi, Slapi_Value *val,
 	Slapi_Value ***ivals, int ftype );
 int slapi_call_syntax_assertion2keys_sub_sv( void *vpi, char *initial,
 	char **any, char *final, Slapi_Value ***ivals );
+int slapi_call_syntax_assertion2keys_sub_sv_pb( Slapi_PBlock *pb, void *vpi,
+	char *initial, char **any, char *final, Slapi_Value ***ivals );
 
 int slapi_attr_values2keys_sv( const Slapi_Attr *sattr, Slapi_Value **vals,
 	Slapi_Value ***ivals, int ftype );