We need to make the value comparison and index key generation functions matching rule aware. Most places in the server just assume the attribute should just use whatever is provided by the syntax via the syntax plugin, without taking into consideration the EQUALITY, ORDERING, and SUBSTR matching rules defined for the attribute in the schema. The current matching rule plugin API is really only useful for extensible match filters. We need to replace the current server API with one that is matching rule aware.
Functions that deal directly or indirectly with syntax plugins:
Used to get the syntax plugin for valuetree_add_valuearray() and valuetree_add_value()
Used to get the compare function (via plugin_call_syntax_get_compare_fn) for duplicate comparison
The syntax plugin is passed to valuetree_add_valuearray() and valuetree_add_value() - valuetree_add_value() just calls valuetree_add_valuearray() - valuetree_add_valuearray() uses the plugin to call slapi_call_syntax_values2keys_sv() to get the EQUALITY keys for duplicate checking - so we could just pass in the equality matching rule syntax plugin instead, or better yet, find the right plugin to call based on the given attribute name (first parameter to valuetree_add_valuearray() is const char *type), or if it is too expensive to look up the right plugin to use every time from the attribute type name, have a new function that takes a Slapi_Attr * instead, and store the plugin in the Slapi_Attr.
The compare function is used only for equality - replace with plugin_call_syntax_filter_ava()
Used to get the oid of the syntax of the given attribute - this function is primarily used to determine if the given attribute has DN syntax.
Used to call slapi_call_syntax_values2keys_sv() to get the equality keys
Used to call slapi_call_syntax_assertion2keys_ava_sv() - looks like only used for EQUALITY or APPROX but not sure
Used to call slapi_call_syntax_assertion2keys_ava() - range implies ORDERING here
Used to call slapi_call_syntax_assertion2keys_sub_sv - SUBSTR
Used to call slapi_call_syntax_values2keys to get the EQUALITY keys, and to call plugin_call_syntax_get_compare_fn() to get the compare function. The compare_fn here must be able to collate - not just used for equality - that implies ORDERING if available, otherwise fallback to syntax compare function
The struct attrinfo has a member ai_plugin which holds the syntax plugin - we will probably need to add separate plugins for the eq, ord, and sub matching rules - also used to get the compare function if needed (user specified an ordering matching rule in the index config, or the attribute schema def has ORDERING)
Used to call plugin_call_syntax_get_compare_fn to get the compare function for sort ordering for each attribute -
The vlvIndex structure has a member called vlv_syntax_plugin which is an array of syntax plugins, one for each attribute type in the spec
Used to get the dn syntax plugin for syntax validation
Used for syntax validation
Used to get the equality keys - vpi is passed in as an argument to valuetree_add_valuearray - see above valuetree_add_valuearray() about how we could find the matching rule plugin instead
Used to get the equality keys - vpi is the struct slapi_attr a_plugin field which is just the base syntax plugin - could store the eq matching rule plugin in struct slapi_attr
Used to get the equality keys - vpi is from the call to slapi_attr_type2plugin - lookup eq mr plugin from ava type - or possibly store correct plugin to use in struct slapi_filter
Used to get the equality keys - vpi is from vlv_syntax_plugin which is from slapi_attr_type2plugin from vlvIndex_init (see above) - the function does ordering using slapi_berval_cmp, which assumes the keys returned are normalized, but not necessarily ordered (e.g. could use syntax keys if no ordering matching rule was specified) - could change vlvIndex_init to lookup ORDERING plugin, error and/or fallback to syntax plugin
Used to generate equality, approx, substr index keys - vpi is from the struct attrinfo ai_plugin field - change struct attrinfo to add eq, ord, and sub mr syntax plugins
Used to generate the vlv key to look for - vpi is from vlv_syntax_plugin[0] from vlvIndex_Init
See above
Used to generate keys based on type of comparison - vpi is from call to slapi_attr_type2plugin in same function - probably need to extend slapi_attr_type2plugin to return mr plugin based on type needed
Used to generate equality keys for ordering - vpi is from call to slapi_attr_type2plugin in same function - should use ordering plugin if available, or equality, or regular syntax plugin fallback
Used to get substring keys - vpi is from call to slapi_attr_type2plugin in same function
`a.asi_plugin = plugin_syntax_find( attr_syntax );
Used in schema verification, to see if specified syntax is supported
Used with schema_syntax_enum_callback to list all officially supported ldapSyntaxes
Lists plugins in nsslapd-plugin attribute
`syntaxoid = plugin_syntax2oid(asip->asi_plugin);
lookup parent syntax for attribute superior
used to call slapi_matchingrule_is_ordering()
for duplicate value checking
For key ordering - implies ORDERING
used for qsort for values - implies ORDERING
The server code is mostly hardwired to expect that the equality, ordering, substring, and the corresponding index key generation are handled by the syntax plugin for the attribute. The matching rule plugins are only used with extensible filters, not with regular filters.
I think what we need are parallel functions for each function in plugin_syntax.c that takes a Slapi_Attr as an argument instead of the plugin. Some of them already work that way e.g. plugin_call_syntax_filter_ava(), but some do not e.g. slapi_call_syntax_values2keys(). So for the latter, we would need a function slapi_call_syntax_values2keys_attr() or something like that which takes as the first argument a Slapi_Attr *attr instead of void *plugin.
The Slapi_Attr would be extended to have a field not only for the syntax plugin but also for the equality, ordering, and substring plugin. The current behavior would be preserved by having the functions that use these new fields fall back to the syntax plugin if no eq, ord, or sub plugin was specified for the attribute.
struct asyntaxinfo would be extended the same way - fields for asi_eq_plugin, asi_ord_plugin, and asi_sub_plugin would be added. These would be set when the attribute definitions are read in, much the same way as the asi_plugin field is set based on the syntax oid now.
The tricky part would be changing the way we use functions like valuetree_add_valuearray() and valuetree_add_value() that take the plugin as a value. These functions always want to use the EQ matching and key generation. We would need to make sure we either pass in the eq plugin, or use a different API that takes the attribute name and dynamically looks up which plugin to use based on the usage. There may be other places in the code that look up the plugin first, without any knowledge of what usage the plugin will have, so those places will probably need to be changed to just pass in the attribute name/slapi_attr and usage rather than the plugin.
The new eq, ord, and sub plugins will just be plain old syntax plugins. I had considered having them be matching rule plugins, but the matching rule plugin API is really designed for the extensible matching filters and i18n collation. It would be difficult to make it fit in with the way the syntax plugins are used. Using the syntax plugin API, for example, an eq syntax plugin will not provide functions for slapi_call_syntax_assertion2keys_sub(), only for slapi_call_syntax_assertion2keys_ava(). Conversely, a sub syntax plugin will not provide slapi_call_syntax_assertion2keys_ava(), only slapi_call_syntax_assertion2keys_sub(), etc. That way, we don’t need another plugin type, we shouldn’t need to extend the current syntax plugin API, and it should be easy for the existing syntax plugin code to register these new “matching rule” syntax plugins using their OID and name.