]> git.sur5r.net Git - openldap/commitdiff
Sync with HEAD
authorKurt Zeilenga <kurt@openldap.org>
Sat, 17 Jan 2004 19:29:09 +0000 (19:29 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Sat, 17 Jan 2004 19:29:09 +0000 (19:29 +0000)
servers/slapd/back-sql/init.c
servers/slapd/back-sql/rdbms_depend/mysql/slapd.conf
servers/slapd/back-sql/rdbms_depend/mysql/testdb_metadata.sql
servers/slapd/back-sql/rdbms_depend/pgsql/testdb_metadata.sql
servers/slapd/back-sql/schema-map.c
servers/slapd/back-sql/schema-map.h
servers/slapd/back-sql/search.c
servers/slapd/back-sql/sql-wrap.c
servers/slapd/back-sql/util.c

index 686cc2c2d488a48dd765e56c92698dabc8fe81d7..840ef0989adae36be6c9db70786d341cdb4d6f3b 100644 (file)
@@ -58,11 +58,11 @@ sql_back_initialize(
 #if 0 /* needs updating */
 #ifdef LDAP_CONTROL_NOOP
                LDAP_CONTROL_NOOP,
-#endif
+#endif /* LDAP_CONTROL_NOOP */
 #endif
 #ifdef LDAP_CONTROL_VALUESRETURNFILTER
                LDAP_CONTROL_VALUESRETURNFILTER,
-#endif
+#endif /* LDAP_CONTROL_VALUESRETURNFILTER */
                NULL
        };
 
index 3157628b5fb7874eb5d64235d2933b23b0f3d4a9..a780c83954d2dcb7b52786c111193ab01dc329c0 100644 (file)
@@ -29,3 +29,4 @@ dbuser                root
 dbpasswd       
 subtree_cond   "ldap_entries.dn LIKE CONCAT('%',?)"
 insentry_query "INSERT INTO ldap_entries (dn,oc_map_id,parent,keyval) VALUES (?,?,?,?)"
+has_ldapinfo_dn_ru     no
index 13aef2574e97bc32b9455fd48e7b5190a9bb3632..f119abba799339eb6c4bdb184260d6741e5e6958 100644 (file)
@@ -1,5 +1,13 @@
---mappings 
-
+-- mappings 
+
+-- objectClass mappings: these may be viewed as structuralObjectClass, the ones that are used to decide how to build an entry
+--     id              a unique number identifying the objectClass
+--     name            the name of the objectClass; it MUST match the name of an objectClass that is loaded in slapd's schema
+--     keytbl          the name of the table that is referenced for the primary key of an entry
+--     keycol          the name of the column in "keytbl" that contains the primary key of an entry; the pair "keytbl.keycol" uniquely identifies an entry of objectClass "id"
+--     create_proc     a procedure to create the entry
+--     delete_proc     a procedure to delete the entry; it takes "keytbl.keycol" of the row to be deleted
+--     expect_return   a bitmap that marks whether create_proc (1) and delete_proc (2) return a value or not
 insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
 values (1,'inetOrgPerson','persons','id',"insert into persons (name) values ('');\n select last_insert_id();",NULL,0);
 
@@ -9,7 +17,17 @@ values (2,'document','documents','id',NULL,NULL,0);
 insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,delete_proc,expect_return)
 values (3,'organization','institutes','id',NULL,NULL,0);
 
-
+-- attributeType mappings: describe how an attributeType for a certain objectClass maps to the SQL data.
+--     id              a unique number identifying the attribute       
+--     oc_map_id       the value of "ldap_oc_mappings.id" that identifies the objectClass this attributeType is defined for
+--     name            the name of the attributeType; it MUST match the name of an attributeType that is loaded in slapd's schema
+--     sel_expr        the expression that is used to select this attribute (the "select <sel_expr> from ..." portion)
+--     from_tbls       the expression that defines the table(s) this attribute is taken from (the "select ... from <from_tbls> where ..." portion)
+--     join_where      the expression that defines the condition to select this attribute (the "select ... where <join_where> ..." portion)
+--     add_proc        a procedure to insert the attribute; it takes the value of the attribute that is added, and the "keytbl.keycol" of the entry it is associated to
+--     delete_proc     a procedure to delete the attribute; it takes the value of the attribute that is added, and the "keytbl.keycol" of the entry it is associated to
+--     param_order     a mask that marks if the "keytbl.keycol" value comes before or after the value in add_proc (1) and delete_proc (2)
+--     expect_return   a mask that marks whether add_proc (1) and delete_proc(2) are expected to return a value or not
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
 values (1,1,'cn','persons.name','persons',NULL,NULL,NULL,3,0);
 
@@ -26,10 +44,10 @@ values (4,2,'description','documents.abstract','documents',NULL,NULL,NULL,3,0);
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
 values (5,2,'documentTitle','documents.title','documents',NULL,NULL,NULL,3,0);
 
--- insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
--- values (6,2,'documentAuthor','persons.name','persons,documents,authors_docs',
---         'persons.id=authors_docs.pers_id AND documents.id=authors_docs.doc_id',
---     NULL,NULL,3,0);
+insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
+values (6,2,'documentAuthor','documentAuthor.dn','ldap_entries AS documentAuthor,documents,authors_docs,persons',
+       'documentAuthor.keyval=persons.id AND documentAuthor.oc_map_id=1 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
+       NULL,NULL,3,0);
 
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
 values (7,3,'o','institutes.name','institutes',NULL,NULL,NULL,3,0);
@@ -39,13 +57,12 @@ values (8,1,'documentDN','ldap_entries.dn','ldap_entries,documents,authors_docs,
         'ldap_entries.keyval=documents.id AND ldap_entries.oc_map_id=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
        NULL,NULL,3,0);
 
-insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return)
-values (9,2,'documentAuthor','ldap_entries.dn','ldap_entries,documents,authors_docs,persons',
-        'ldap_entries.keyval=persons.id AND ldap_entries.oc_map_id=1 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',
-       NULL,NULL,3,0);
-       
--- entries
-       
+-- entries mapping: each entry must appear in this table, with a unique DN rooted at the database naming context
+--     id              a unique number > 0 identifying the entry
+--     dn              the DN of the entry, in "pretty" form
+--     oc_map_id       the "ldap_oc_mappings.id" of the main objectClass of this entry (view it as the structuralObjectClass)
+--     parent          the "ldap_entries.id" of the parent of this objectClass; 0 if it is the "suffix" of the database
+--     keyval          the value of the "keytbl.keycol" defined for this objectClass
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval)
 values (1,'o=sql,c=RU',3,0,1);
 
@@ -64,11 +81,15 @@ values (5,'documentTitle=book1,o=sql,c=RU',2,1,1);
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval)
 values (6,'documentTitle=book2,o=sql,c=RU',2,1,2);
        
-       
--- referrals
 
+-- objectClass mapping: entries that have multiple objectClass instances are listed here with the objectClass name (view them as auxiliary objectClass)
+--     entry_id        the "ldap_entries.id" of the entry this objectClass value must be added
+--     oc_name         the name of the objectClass; it MUST match the name of an objectClass that is loaded in slapd's schema
 insert into ldap_entry_objclasses (entry_id,oc_name)
 values (4,'referral');
 
+-- referrals mapping: entries that should be treated as referrals are stored here
+--     entry_id        the "ldap_entries.id" of the entry that should be treated as a referral
+--     url             the URI of the referral
 insert into ldap_referrals (entry_id,url)
 values (4,'http://localhost');
index d42175906e4ef352e8628c128a2151b328751adc..ab9ab045a439d56c314cc0986adf519a97303b31 100644 (file)
@@ -1,12 +1,30 @@
---mappings 
-
+-- mappings 
+
+-- objectClass mappings: these may be viewed as structuralObjectClass, the ones that are used to decide how to build an entry
+--     id              a unique number identifying the objectClass
+--     name            the name of the objectClass; it MUST match the name of an objectClass that is loaded in slapd's schema
+--     keytbl          the name of the table that is referenced for the primary key of an entry
+--     keycol          the name of the column in "keytbl" that contains the primary key of an entry; the pair "keytbl.keycol" uniquely identifies an entry of objectClass "id"
+--     create_proc     a procedure to create the entry
+--     delete_proc     a procedure to delete the entry; it takes "keytbl.keycol" of the row to be deleted
+--     expect_return   a bitmap that marks whether create_proc (1) and delete_proc (2) return a value or not
 insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) values (1,'inetOrgPerson','persons','id','select create_person()','select delete_person(?)',0);
 
 insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) values (2,'document','documents','id',NULL,NULL,0);
 
 insert into ldap_oc_mappings (id,name,keytbl,keycol,create_proc,delete_proc,expect_return) values (3,'organization','institutes','id',NULL,NULL,0);
 
-
+-- attributeType mappings: describe how an attributeType for a certain objectClass maps to the SQL data.
+--     id              a unique number identifying the attribute       
+--     oc_map_id       the value of "ldap_oc_mappings.id" that identifies the objectClass this attributeType is defined for
+--     name            the name of the attributeType; it MUST match the name of an attributeType that is loaded in slapd's schema
+--     sel_expr        the expression that is used to select this attribute (the "select <sel_expr> from ..." portion)
+--     from_tbls       the expression that defines the table(s) this attribute is taken from (the "select ... from <from_tbls> where ..." portion)
+--     join_where      the expression that defines the condition to select this attribute (the "select ... where <join_where> ..." portion)
+--     add_proc        a procedure to insert the attribute; it takes the value of the attribute that is added, and the "keytbl.keycol" of the entry it is associated to
+--     delete_proc     a procedure to delete the attribute; it takes the value of the attribute that is added, and the "keytbl.keycol" of the entry it is associated to
+--     param_order     a mask that marks if the "keytbl.keycol" value comes before or after the value in add_proc (1) and delete_proc (2)
+--     expect_return   a mask that marks whether add_proc (1) and delete_proc(2) are expected to return a value or not
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (1,1,'cn','text(persons.name||'' ''||persons.surname)','persons',NULL,'select update_person_cn(?,?)',NULL,3,0);
 
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (2,1,'telephoneNumber','phones.phone','persons,phones','phones.pers_id=persons.id','select add_phone(?,?)','select delete_phone(?,?)',3,0);
@@ -24,8 +42,13 @@ insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,
 
 insert into ldap_attr_mappings (id,oc_map_id,name,sel_expr,from_tbls,join_where,add_proc,delete_proc,param_order,expect_return) values (8,1,'documentIdentifier','documentIdentifier.dn','ldap_entries AS documentIdentifier,documents,authors_docs,persons','documentIdentifier.keyval=documents.id AND documentIdentifier.oc_map_id=2 AND authors_docs.doc_id=documents.id AND authors_docs.pers_id=persons.id',NULL,NULL,3,0);
 
--- entries
-       
+
+-- entries mapping: each entry must appear in this table, with a unique DN rooted at the database naming context
+--     id              a unique number > 0 identifying the entry
+--     dn              the DN of the entry, in "pretty" form
+--     oc_map_id       the "ldap_oc_mappings.id" of the main objectClass of this entry (view it as the structuralObjectClass)
+--     parent          the "ldap_entries.id" of the parent of this objectClass; 0 if it is the "suffix" of the database
+--     keyval          the value of the "keytbl.keycol" defined for this objectClass
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (1,'o=sql,c=RU',3,0,1);
 
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (2,'cn=Mitya Kovalev,o=sql,c=RU',1,1,1);
@@ -39,14 +62,18 @@ insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (5,'documentTitl
 insert into ldap_entries (id,dn,oc_map_id,parent,keyval) values (6,'documentTitle=book2,o=sql,c=RU',2,1,2);
        
        
--- referrals
-
+-- objectClass mapping: entries that have multiple objectClass instances are listed here with the objectClass name (view them as auxiliary objectClass)
+--     entry_id        the "ldap_entries.id" of the entry this objectClass value must be added
+--     oc_name         the name of the objectClass; it MUST match the name of an objectClass that is loaded in slapd's schema
 insert into ldap_entry_objclasses (entry_id,oc_name) values (4,'referral');
 
+-- referrals mapping: entries that should be treated as referrals are stored here
+--     entry_id        the "ldap_entries.id" of the entry that should be treated as a referral
+--     url             the URI of the referral
 insert into ldap_referrals (entry_id,url) values (4,'ldap://localhost/');
 
 -- procedures
-
+-- these procedures are specific for this RDBMS and are used in mapping objectClass and attributeType creation/modify/deletion
 create function create_person () returns int
 as '
        select setval (''persons_id_seq'', (select max(id) from persons));
index f73114b3ed3005492486655de18bd383ab153c2e..3f75bb84ad5f4a8fccd3ed26822a4a80ada6a80a 100644 (file)
@@ -567,43 +567,71 @@ backsql_ad2at( backsql_oc_map_rec* objclass, AttributeDescription *ad )
        return res;
 }
 
-#if 0
+/* attributeType inheritance */
+struct supad2at_t {
+       backsql_at_map_rec      **ret;
+       AttributeDescription    *ad;
+       unsigned                n;
+};
+
+#define SUPAD2AT_STOP  (-1)
+
+static int
+supad2at_f( void *v_at, void *v_arg )
+{
+       backsql_at_map_rec      *at = (backsql_at_map_rec *)v_at;
+       struct supad2at_t       *va = (struct supad2at_t *)v_arg;
+
+       if ( is_at_subtype( at->bam_ad->ad_type, va->ad->ad_type ) ) {
+               backsql_at_map_rec      **ret;
+
+               ret = ch_realloc( va->ret, sizeof( backsql_at_map_rec *) * ( va->n + 2 ) );
+               if ( ret == NULL ) {
+                       ch_free( va->ret );
+                       return SUPAD2AT_STOP;
+               }
+
+               ret[ va->n ] = at;
+               va->n++;
+               ret[ va->n ] = NULL;
+               va->ret = ret;
+       }
+
+       return 0;
+}
+
 /*
- * Deprecated
+ * stores in *pret a NULL terminated array of pointers
+ * to backsql_at_map_rec whose attributeType is supad->ad_type 
+ * or derived from it
  */
-backsql_at_map_rec *
-backsql_name2at( backsql_oc_map_rec* objclass, struct berval *attr )
+int
+backsql_supad2at( backsql_oc_map_rec *objclass, AttributeDescription *supad,
+               backsql_at_map_rec ***pret )
 {
-       backsql_at_map_rec      tmp, *res;
-       const char              *text = NULL;
-#ifdef BACKSQL_TRACE
-       Debug( LDAP_DEBUG_TRACE, "==>backsql_name2at(): "
-               "searching for attribute '%s' for objectclass '%s'\n",
-               attr, BACKSQL_OC_NAME( objclass ), 0 );
-#endif /* BACKSQL_TRACE */
+       struct supad2at_t       va;
+       int                     rc;
 
-       if ( slap_bv2ad( attr, &tmp.bam_ad, &text ) != LDAP_SUCCESS ) {
-               return NULL;
-       }
+       assert( objclass );
+       assert( supad );
+       assert( pret );
 
-       res = (backsql_at_map_rec *)avl_find( objclass->bom_attrs, &tmp,
-                       backsql_cmp_attr );
+       *pret = NULL;
 
-#ifdef BACKSQL_TRACE
-       if ( res != NULL ) {
-               Debug( LDAP_DEBUG_TRACE, "<==backsql_name2at(): "
-                       "found name='%s', sel_expr='%s'\n",
-                       res->bam_name, res->bam_sel_expr.bv_val, 0 );
-       } else {
-               Debug( LDAP_DEBUG_TRACE, "<==backsql_name2at(): "
-                       "not found\n", 0, 0, 0 );
+       va.ret = NULL;
+       va.ad = supad;
+       va.n = 0;
+       
+       rc = avl_apply( objclass->bom_attrs, supad2at_f, &va,
+                       SUPAD2AT_STOP, AVL_INORDER );
+       if ( rc == SUPAD2AT_STOP ) {
+               return -1;
        }
-#endif /* BACKSQL_TRACE */
 
-       return res;
+       *pret = va.ret;
+
+       return 0;
 }
-#endif
 
 static void
 backsql_free_attr( void *v_at )
index f9add2d7c891fcfc2c867bf7079fcd1c3366542a..cf7d388a3a00269b7af1f20cf7902ff9ba9454d3 100644 (file)
@@ -100,6 +100,8 @@ backsql_at_map_rec *backsql_name2at( backsql_oc_map_rec *objclass,
                struct berval *at_name );
 backsql_at_map_rec *backsql_ad2at( backsql_oc_map_rec *objclass,
                AttributeDescription *ad );
+int backsql_supad2at( backsql_oc_map_rec *objclass,
+               AttributeDescription *supad, backsql_at_map_rec ***pret );
 int backsql_destroy_schema_map( backsql_info *si );
 
 #endif /* __BACKSQL_SCHEMA_MAP_H__ */
index 7266bd3dfbb61fb37fabd800a7758a94d149216f..fc89418bf7bd03ae1b67dcca5cae6eebbb04c6d5 100644 (file)
@@ -215,10 +215,10 @@ backsql_process_filter_list( backsql_srch_info *bsi, Filter *f, int op )
 }
 
 static int
-backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
+backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f,
+       backsql_at_map_rec *at )
 {
        int                     i;
-       backsql_at_map_rec      *at;
        backsql_info            *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;
        int                     casefold = 0;
 
@@ -234,10 +234,6 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
                casefold = 1;
        }
 
-       at = backsql_ad2at( bsi->bsi_oc, f->f_sub_desc );
-
-       assert( at );
-
        /*
         * When dealing with case-sensitive strings 
         * we may omit normalization; however, normalized
@@ -247,8 +243,9 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
        backsql_strfcat( &bsi->bsi_flt_where, "c", '(' /* ) */  );
 
        /* TimesTen */
-       Debug( LDAP_DEBUG_TRACE, "expr: '%s' '%s'\n", at->bam_sel_expr.bv_val,
-               at->bam_sel_expr_u.bv_val ? at->bam_sel_expr_u.bv_val : "<NULL>", 0 );
+       Debug( LDAP_DEBUG_TRACE, "expr: '%s%s%s'\n", at->bam_sel_expr.bv_val,
+               at->bam_sel_expr_u.bv_val ? "' '" : "",
+               at->bam_sel_expr_u.bv_val ? at->bam_sel_expr_u.bv_val : "" );
        if ( casefold && bi->upper_func.bv_val ) {
                /*
                 * If a pre-upper-cased version of the column exists, use it
@@ -294,9 +291,9 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
 
 #ifdef BACKSQL_TRACE
                        Debug( LDAP_DEBUG_TRACE, 
-                               "==>backsql_process_sub_filter(): "
-                               "sub_any='%s'\n", f->f_sub_any[ i ].bv_val,
-                               0, 0 );
+                               "==>backsql_process_sub_filter(%s): "
+                               "sub_any='%s'\n", at->bam_ad->ad_cname.bv_val,
+                               f->f_sub_any[ i ].bv_val, 0 );
 #endif /* BACKSQL_TRACE */
 
                        start = bsi->bsi_flt_where.bb_val.bv_len;
@@ -333,14 +330,18 @@ backsql_process_sub_filter( backsql_srch_info *bsi, Filter *f )
 static int
 backsql_process_filter( backsql_srch_info *bsi, Filter *f )
 {
-       backsql_at_map_rec      *at;
+       backsql_at_map_rec      **vat = NULL;
        AttributeDescription    *ad = NULL;
+       unsigned                i;
        int                     done = 0;
        int                     rc = 0;
 
        Debug( LDAP_DEBUG_TRACE, "==>backsql_process_filter()\n", 0, 0, 0 );
-       if ( f == NULL || f->f_choice == SLAPD_FILTER_COMPUTED ) {
-               return 0;
+       if ( f->f_choice == SLAPD_FILTER_COMPUTED ) {
+               Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): "
+                       "invalid filter\n", 0, 0, 0 );
+               rc = -1;
+               goto done;
        }
 
        switch( f->f_choice ) {
@@ -379,10 +380,11 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
        }
 
        if ( rc == -1 ) {
-               goto impossible;
+               goto done;
        }
  
        if ( done ) {
+               rc = 1;
                goto done;
        }
 
@@ -402,13 +404,20 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
                        ObjectClass     *oc = oc_bvfind( &f->f_av_value );
 
                        if ( oc == NULL ) {
+                               Debug( LDAP_DEBUG_TRACE,
+                                               "backsql_process_filter(): "
+                                               "unknown objectClass \"%s\" "
+                                               "in filter\n",
+                                               f->f_av_value.bv_val, 0, 0 );
                                bsi->bsi_status = LDAP_OTHER;
-                               goto impossible;
+                               rc = -1;
+                               goto done;
                        }
 
                        /*
-                        * objectClass inheritance:
-                        * - a search for "person" will also return "inetOrgPerson"
+                        * "structural" objectClass inheritance:
+                        * - a search for "person" will also return 
+                        *   "inetOrgPerson"
                         * - a search for "top" will return everything
                         */
                        if ( is_object_subclass( oc, bsi->bsi_oc->bom_oc ) ) {
@@ -423,11 +432,18 @@ filter_oc_success:;
                        backsql_strfcat( &bsi->bsi_flt_where, "l",
                                        (ber_len_t)sizeof( "1=1" ) - 1, "1=1" );
                        bsi->bsi_status = LDAP_SUCCESS;
+                       rc = 1;
                        goto done;
                        
                default:
+                       Debug( LDAP_DEBUG_TRACE,
+                                       "backsql_process_filter(): "
+                                       "illegal/unhandled filter "
+                                       "on objectClass attribute",
+                                       0, 0, 0 );
                        bsi->bsi_status = LDAP_OTHER;
-                       goto impossible;
+                       rc = -1;
+                       goto done;
                }
 
        } else if ( ad == slap_schema.si_ad_hasSubordinates || ad == NULL ) {
@@ -462,44 +478,76 @@ filter_oc_success:;
                         */
                        backsql_attrlist_add( bsi, NULL );
                }
+               rc = 1;
                goto done;
        }
 
-       /* look for attribute (also if objectClass but not structural one) */
-       at = backsql_ad2at( bsi->bsi_oc, ad );
+       /*
+        * attribute inheritance:
+        */
+       if ( backsql_supad2at( bsi->bsi_oc, ad, &vat ) ) {
+               bsi->bsi_status = LDAP_OTHER;
+               rc = -1;
+               goto done;
+       }
 
-       if ( at == NULL ) {
-               Debug( LDAP_DEBUG_TRACE, "backsql_process_filter(): "
-                       "attribute '%s' is not defined for objectclass '%s'\n",
-                       ad->ad_cname.bv_val, BACKSQL_OC_NAME( bsi->bsi_oc ), 0 );
+       if ( vat == NULL ) {
+               /* search anyway; other parts of the filter
+                * may succeeed */
                backsql_strfcat( &bsi->bsi_flt_where, "l",
-                               (ber_len_t)sizeof( "1=0" ) - 1, "1=0" );
-               bsi->bsi_status = LDAP_UNDEFINED_TYPE;
-               goto impossible;
+                               (ber_len_t)sizeof( "1=1" ) - 1, "1=1" );
+               bsi->bsi_status = LDAP_SUCCESS;
+               rc = 1;
+               goto done;
        }
 
-       backsql_strfcat( &bsi->bsi_flt_where, "c", '(' );
+       /* if required, open extra level of parens */
+       done = 0;
+       if ( vat[0]->bam_next || vat[1] ) {
+               backsql_strfcat( &bsi->bsi_flt_where, "c", '(' );
+               done = 1;
+       }
+
+       i = 0;
 next:;
-       if ( backsql_process_filter_attr( bsi, f, at ) == -1 ) {
+       /* apply attr */
+       if ( backsql_process_filter_attr( bsi, f, vat[i] ) == -1 ) {
                return -1;
        }
 
-       if ( at->bam_next ) {
+       /* if more definitions of the same attr, apply */
+       if ( vat[i]->bam_next ) {
+               backsql_strfcat( &bsi->bsi_flt_where, "l",
+                       sizeof( " OR " ) - 1, " OR " );
+               vat[i] = vat[i]->bam_next;
+               goto next;
+       }
+
+       /* if more descendants of the same attr, apply */
+       i++;
+       if ( vat[i] ) {
                backsql_strfcat( &bsi->bsi_flt_where, "l",
-                               sizeof( " OR " ) - 1, " OR " );
-               at = at->bam_next;
+                       sizeof( " OR " ) - 1, " OR " );
                goto next;
        }
-       backsql_strfcat( &bsi->bsi_flt_where, "c", ')' );
+
+       /* if needed, close extra level of parens */
+       if ( done ) {
+               backsql_strfcat( &bsi->bsi_flt_where, "c", ')' );
+       }
+
+       rc = 1;
 
 done:;
-       Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter()\n", 0, 0, 0 );
-       return 1;
+       if ( vat ) {
+               ch_free( vat );
+       }
 
-impossible:;
-       Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter() returns -1\n",
-                       0, 0, 0 );
-       return -1;
+       Debug( LDAP_DEBUG_TRACE,
+                       "<==backsql_process_filter() %s\n",
+                       rc == 1 ? "succeeded" : "failed", 0, 0);
+
+       return rc;
 }
 
 static int
@@ -587,7 +635,7 @@ equality_match:;
 
                } else {
                        backsql_strfcat( &bsi->bsi_flt_where, "cblbl",
-                                       '(',
+                                       '(', /* ) */
                                        &at->bam_sel_expr,
                                        (ber_len_t)sizeof( "='" ) - 1, "='",
                                        filter_value,
@@ -618,7 +666,7 @@ equality_match:;
 
                        if ( at->bam_sel_expr_u.bv_val ) {
                                backsql_strfcat( &bsi->bsi_flt_where, "cbbc",
-                                               '(',
+                                               '(', /* ) */
                                                &at->bam_sel_expr_u, 
                                                &ordering,
                                                '\'' );
@@ -664,7 +712,7 @@ equality_match:;
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
-               backsql_process_sub_filter( bsi, f );
+               backsql_process_sub_filter( bsi, f, at );
                break;
 
        case LDAP_FILTER_APPROX:
@@ -1376,16 +1424,15 @@ backsql_search( Operation *op, SlapReply *rs )
 #if 0  /* noop is masked SLAP_CTRL_UPDATE */
                        if ( op->o_noop ) {
                                sres = 0;
-                       } else {
+                       } else
 #endif
+                       {
                                rs->sr_attrs = op->oq_search.rs_attrs;
                                rs->sr_entry = entry;
                                sres = send_search_entry( op, rs );
                                rs->sr_entry = NULL;
                                rs->sr_attrs = NULL;
-#if 0
                        }
-#endif
 
                        switch ( sres ) {
                        case 0:
index 414aeafc54e47ea95c1abfc6593afd196c8ed46a..07ec0e5b77740f06439a3470d92742564a6bdc17 100644 (file)
@@ -126,31 +126,6 @@ backsql_Prepare( SQLHDBC dbh, SQLHSTMT *sth, char *query, int timeout )
        return SQLPrepare( *sth, query, SQL_NTS );
 }
 
-#if 0
-/*
- * Turned into macros --- see sql-wrap.h
- */
-RETCODE
-backsql_BindParamStr( SQLHSTMT sth, int par_ind, char *str, int maxlen )
-{
-       RETCODE         rc;
-
-       rc = SQLBindParameter( sth, (SQLUSMALLINT)par_ind, SQL_PARAM_INPUT,
-                       SQL_C_CHAR, SQL_VARCHAR,
-                       (SQLUINTEGER)maxlen, 0, (SQLPOINTER)str,
-                       (SQLUINTEGER)maxlen, NULL );
-       return rc;
-}
-
-RETCODE
-backsql_BindParamID( SQLHSTMT sth, int par_ind, unsigned long *id )
-{
-       return SQLBindParameter( sth, (SQLUSMALLINT)par_ind,
-                       SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER,
-                       0, 0, (SQLPOINTER)id, 0, (SQLINTEGER*)NULL );
-}
-#endif
-
 RETCODE
 backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row )
 {
index cebd7a006f9a14e1fe70e6427ed7f3d7ee44bdc6..02bd21d6392cb6a236208c3ad1f174965f10d30b 100644 (file)
@@ -321,7 +321,7 @@ backsql_get_table_spec( char **p )
 
 #if 0
        backsql_strcat( &res, " AS ", s, NULL );
-       /* oracle doesn't understand AS :( */
+       /* oracle doesn't understand AS :( and other RDBMSes don't need it */
 #endif
 
        /* table alias */