Here is what I can find about defining / adding a new syntax.
Peter Marschall wrote on Sat, 5 Jul 2003
Defining a new syntax means defining a new form of data structure that the server must know about. This is not possible using only configration options. You need to code it into the server. Of course the same holds for matching rules.
Howard Chu wrote on 2002-10-25
if you had originally configured with --enable-modules, You need to create a dynamic module that calls register_syntax() with your new syntax definition, and then use moduleload in slapd.conf to load your module.
My question is:
1. is there a module that introduces a new syntax, from which I could observe how that is done?
2. Is there any document on what-to-be-aware-of if you design a new syntax?
3. Do I need to design a new syntax at all? My requirement is the following:
I need a new syntax for ranged-values. Examples are:
- netWeight: 12~13kg - ISOSensitivity: 800~1600 - heightAdjustableRange: 1.2m~1.5m
The spec of ranged-value is a numeric, optionally followed by a measurement unit, followed by a tild as seperator†, followed by another measurement.
The syntax needs its own comparison rules, so that you can filter a range, and get entries who offer values ranging in that range.
† quote from http://en.wikipedia.org/wiki/~ In some languages (though not English), a tilde-like wavy dash may be used as punctuation (instead of an unspaced hyphen or en-dash) between two numbers, to indicate a range rather than subtraction or a hyphenated number (such as a part number or model number).
Zhang Weiwu wrote:
Do I need to design a new syntax at all? My requirement is the following:
I need a new syntax for ranged-values. Examples are:
- netWeight: 12~13kg
- ISOSensitivity: 800~1600
- heightAdjustableRange: 1.2m~1.5m
The spec of ranged-value is a numeric, optionally followed by a measurement unit, followed by a tild as seperator†, followed by another measurement.
The syntax needs its own comparison rules, so that you can filter a range, and get entries who offer values ranging in that range.
Not exactly what you're after but have a look at slapo-constraint. Maybe you can find some suitable regex patterns for your use-case.
Hmm, it would be handy to have min/max constraints for attribute types for which an ORDERING matching rule is defined. So maybe extending slapo-constraint would be the most flexible way of implementing ranges.
Ciao, Michael.
On Mon, 5 Aug 2013, Michael Ströder wrote:
Zhang Weiwu wrote:
Do I need to design a new syntax at all? My requirement is the following:
I need a new syntax for ranged-values. Examples are:
- netWeight: 12~13kg
- ISOSensitivity: 800~1600
- heightAdjustableRange: 1.2m~1.5m
The spec of ranged-value is a numeric, optionally followed by a measurement unit, followed by a tild as seperator†, followed by another measurement.
The syntax needs its own comparison rules, so that you can filter a range, and get entries who offer values ranging in that range.
Not exactly what you're after but have a look at slapo-constraint. Maybe you can find some suitable regex patterns for your use-case.
Hmm, it would be handy to have min/max constraints for attribute types for which an ORDERING matching rule is defined. So maybe extending slapo-constraint would be the most flexible way of implementing ranges.
Thanks for the comment, but the problem your solution to solve is not the one I face. I guess I wasn't clear enough.
I do not intend to constrain the value of attributes, but to store the constraint into the value.
Perhaps it is best explained with examples. Say I want to find out all desks that can adjust to exactly 1.4m, there are 3 entris:
dn: model=BigDesk,dc=wood,dc=com model: BigDesk heightAdjustableRange: 1.6m~2m
dn: model=MediumDesk,dc=wood,dc=com model: MediumDesk heightAdjustableRange: 1.3m~1.8m
dn: model=SmallDesk,dc=wood,dc=com model: SmallDesk heightAdjustableRange: 1.1m~1.5m
And I do an inquiry, expect to get only MediumDesk and SmallDesk.
To reprise, there is no constraint to the value, but there are constraints in the value.
There are 2 ways to solve it, I am unsure which is better. The first is to design a new SYNTAX, apparently requiring coding a matching model.
The other method is to use multi-value INTEGER syntax:
dn: model=BigDesk,dc=wood,dc=com model: BigDesk possibleHeightInCM: 160 possibleHeightInCM: 200
dn: model=MediumDesk,dc=wood,dc=com model: MediumDesk possibleHeightInCM: 130 possibleHeightInCM: 180
dn: model=SmallDesk,dc=wood,dc=com model: SmallDesk possibleHeightInCM: 110 possibleHeightInCM: 150
And I can find my choice of desk by using:
(&(possibleHeightInCM>=140)(possibleHeightInCM<=140))
Which should result the SmallDesk and MediumDesk.
Zhang Weiwu writes:
- is there a module that introduces a new syntax, from which I could
observe how that is done?
- Is there any document on what-to-be-aware-of if you design a new syntax?
servers/slapd/schema_init.c documents how to write syntaxes and matching rules, and defines most built-ins. If it's unclear, please tell how to improve the doc. servers/slapd/overlays/accesslog.c defines its own syntax. contrib/slapd-modules/passwd/radius.c is a small module you can see for general module setup.
Do I need to design a new syntax at all? My requirement is the following:
I need a new syntax for ranged-values. Examples are:
- netWeight: 12~13kg
- ISOSensitivity: 800~1600
- heightAdjustableRange: 1.2m~1.5m
The spec of ranged-value is a numeric, optionally followed by a measurement unit, followed by a tild as seperator+, followed by another measurement.
LDAP syntaxes often use '$' or '#' as separators, but it's up to you. See e.g. RFC 4517 3.3.28 Postal Address, 3.3.21 Name and Optional UID.
The syntax needs its own comparison rules, so that you can filter a range, and get entries who offer values ranging in that range.
Then you need a syntax and matching rule(s) for it.
I wrote:
Zhang Weiwu writes:
The syntax needs its own comparison rules, so that you can filter a range, and get entries who offer values ranging in that range.
Then you need a syntax and matching rule(s) for it.
On second thought, a single LDAP attribute won't do for you if you want to be able to index the attribute for range match. An attribute can have equality, substring and ordering matching rules. Range match is neither. A filter can use extensible match, (attr:fooRangeMatch:=20~40) could e.g. mean the attr value fully covers range 20~40, but you cannot index for that.
When we needed to index IP subnet ranges, we defined two single-valued attributes with max and min value stored as single decimal integers. Integers support ORDERING indexin, so clients could then filter for (&(min<=IPNUM)(max>=IPNUM)). This would not work if we needed multiple ranges in a single entry.
I had not thought of the constraint overlay which Michael mentions, maybe that'll work too. I suppose it depends on how much work you are willing to do on the client side. You could define a normalized range format which is easy to match and which the the client rather than the server is responsible for maintaining. Indexing would still not work.
Hallvard Breien Furuseth wrote:
When we needed to index IP subnet ranges, we defined two single-valued attributes with max and min value stored as single decimal integers.
Interesting. The Integer value in your case covers the whole address (32 bits for IPv4 and 128 bits for IPv6)?
What does the whole schema look like?
I'd be interested to work out an I-D together for storing IP subnet and host network configuration.
Ciao, Michael.
Michael Ströder writes:
Hallvard Breien Furuseth wrote:
When we needed to index IP subnet ranges, we defined two single-valued attributes with max and min value stored as single decimal integers.
Interesting. The Integer value in your case covers the whole address (32 bits for IPv4 and 128 bits for IPv6)?
No, I should have said IPv4. Our IPv6 subnets will hopefully have just a few simple formats so a client which wants to find the subnet of an address can just generate one or two possibilities and look it up with equality match.
What does the whole schema look like?
attributeTypes: ( 1.3.6.1.4.1.2428.10000.971.35854.11.1.40 NAME 'uioIpAddressRangeStart' DESC 'Lowest IP address in an address range, stored as an integer' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributeTypes: ( 1.3.6.1.4.1.2428.10000.971.35854.11.1.41 NAME 'uioIpAddressRangeEnd' DESC 'Highest IP address in an address range, stored as an integer' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) objectClasses: ( 1.3.6.1.4.1.2428.10000.971.35854.2.106 NAME 'uioIpNetwork' DESC 'Information about IP networks' AUXILIARY MAY ( uioIpAddressRangeStart $ uioIpAddressRangeEnd ) )
openldap-technical@openldap.org