📄 search.c
字号:
Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter() %s\n", rc == 1 ? "succeeded" : "failed", 0, 0); return rc;}static intbacksql_process_filter_eq( backsql_srch_info *bsi, backsql_at_map_rec *at, int casefold, struct berval *filter_value ){ /* * 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 ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { ber_len_t start; backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "cbl", '(', /* ) */ &at->bam_sel_expr_u, (ber_len_t)STRLENOF( "='" ), "='" ); start = bsi->bsi_flt_where.bb_val.bv_len; backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "bl", filter_value, (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } else { backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "cblbl", '(', /* ) */ &at->bam_sel_expr, (ber_len_t)STRLENOF( "='" ), "='", filter_value, (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); } return 1;} static intbacksql_process_filter_like( backsql_srch_info *bsi, backsql_at_map_rec *at, int casefold, struct berval *filter_value ){ /* * 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 ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { ber_len_t start; backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "cbl", '(', /* ) */ &at->bam_sel_expr_u, (ber_len_t)STRLENOF( " LIKE '%" ), " LIKE '%" ); start = bsi->bsi_flt_where.bb_val.bv_len; backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "bl", filter_value, (ber_len_t)STRLENOF( /* (' */ "%')" ), /* (' */ "%')" ); ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } else { backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "cblbl", '(', /* ) */ &at->bam_sel_expr, (ber_len_t)STRLENOF( " LIKE '%" ), " LIKE '%", filter_value, (ber_len_t)STRLENOF( /* (' */ "%')" ), /* (' */ "%')" ); } return 1;}static intbacksql_process_filter_attr( backsql_srch_info *bsi, Filter *f, backsql_at_map_rec *at ){ backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private; int casefold = 0; struct berval *filter_value = NULL; MatchingRule *matching_rule = NULL; struct berval ordering = BER_BVC("<="); Debug( LDAP_DEBUG_TRACE, "==>backsql_process_filter_attr(%s)\n", at->bam_ad->ad_cname.bv_val, 0, 0 ); /* * need to add this attribute to list of attrs to load, * so that we can do test_filter() later */ backsql_attrlist_add( bsi, at->bam_ad ); backsql_merge_from_tbls( bsi, &at->bam_from_tbls ); if ( !BER_BVISNULL( &at->bam_join_where ) && strstr( bsi->bsi_join_where.bb_val.bv_val, at->bam_join_where.bv_val ) == NULL ) { backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "lb", (ber_len_t)STRLENOF( " AND " ), " AND ", &at->bam_join_where ); } switch ( f->f_choice ) { case LDAP_FILTER_EQUALITY: filter_value = &f->f_av_value; matching_rule = at->bam_ad->ad_type->sat_equality; goto equality_match; /* fail over into next case */ case LDAP_FILTER_EXT: filter_value = &f->f_mra->ma_value; matching_rule = f->f_mr_rule;equality_match:; /* always uppercase strings by now */#ifdef BACKSQL_UPPERCASE_FILTER if ( SLAP_MR_ASSOCIATED( matching_rule, bi->sql_caseIgnoreMatch ) )#endif /* BACKSQL_UPPERCASE_FILTER */ { casefold = 1; } /* FIXME: directoryString filtering should use a similar * approach to deal with non-prettified values like * " A non prettified value ", by using a LIKE * filter with all whitespaces collapsed to a single '%' */ if ( SLAP_MR_ASSOCIATED( matching_rule, bi->sql_telephoneNumberMatch ) ) { struct berval bv; ber_len_t i; /* * to check for matching telephone numbers * with intermized chars, e.g. val='1234' * use * * val LIKE '%1%2%3%4%' */ bv.bv_len = 2 * filter_value->bv_len - 1; bv.bv_val = ch_malloc( bv.bv_len + 1 ); bv.bv_val[ 0 ] = filter_value->bv_val[ 0 ]; for ( i = 1; i < filter_value->bv_len; i++ ) { bv.bv_val[ 2 * i - 1 ] = '%'; bv.bv_val[ 2 * i ] = filter_value->bv_val[ i ]; } bv.bv_val[ 2 * i - 1 ] = '\0'; (void)backsql_process_filter_like( bsi, at, casefold, &bv ); ch_free( bv.bv_val ); break; } /* NOTE: this is required by objectClass inheritance * and auxiliary objectClass use in filters for slightly * more efficient candidate selection. */ /* FIXME: a bit too many specializations to deal with * very specific cases... */ if ( at->bam_ad == slap_schema.si_ad_objectClass || at->bam_ad == slap_schema.si_ad_structuralObjectClass ) { backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "lbl", (ber_len_t)STRLENOF( "(ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ') */ ), "(ldap_entries.id=ldap_entry_objclasses.entry_id AND ldap_entry_objclasses.oc_name='" /* ') */, filter_value, (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); break; } /* * 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. */ (void)backsql_process_filter_eq( bsi, at, casefold, filter_value ); break; case LDAP_FILTER_GE: ordering.bv_val = ">="; /* fall thru to next case */ case LDAP_FILTER_LE: filter_value = &f->f_av_value; /* always uppercase strings by now */#ifdef BACKSQL_UPPERCASE_FILTER if ( at->bam_ad->ad_type->sat_ordering && SLAP_MR_ASSOCIATED( at->bam_ad->ad_type->sat_ordering, bi->sql_caseIgnoreMatch ) )#endif /* BACKSQL_UPPERCASE_FILTER */ { casefold = 1; } /* * FIXME: should we uppercase the operands? */ if ( casefold && BACKSQL_AT_CANUPPERCASE( at ) ) { ber_len_t start; backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "cbbc", '(', /* ) */ &at->bam_sel_expr_u, &ordering, '\'' ); start = bsi->bsi_flt_where.bb_val.bv_len; backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "bl", filter_value, (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); ldap_pvt_str2upper( &bsi->bsi_flt_where.bb_val.bv_val[ start ] ); } else { backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "cbbcbl", '(' /* ) */ , &at->bam_sel_expr, &ordering, '\'', &f->f_av_value, (ber_len_t)STRLENOF( /* (' */ "')" ), /* ( */ "')" ); } break; case LDAP_FILTER_PRESENT: backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "lbl", (ber_len_t)STRLENOF( "NOT (" /* ) */), "NOT (", /* ) */ &at->bam_sel_expr, (ber_len_t)STRLENOF( /* ( */ " IS NULL)" ), /* ( */ " IS NULL)" ); break; case LDAP_FILTER_SUBSTRINGS: backsql_process_sub_filter( bsi, f, at ); break; case LDAP_FILTER_APPROX: /* we do our best */ /* * 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. */ (void)backsql_process_filter_like( bsi, at, 1, &f->f_av_value ); break; default: /* unhandled filter type; should not happen */ assert( 0 ); backsql_strfcat_x( &bsi->bsi_flt_where, bsi->bsi_op->o_tmpmemctx, "l", (ber_len_t)STRLENOF( "8=8" ), "8=8" ); break; } Debug( LDAP_DEBUG_TRACE, "<==backsql_process_filter_attr(%s)\n", at->bam_ad->ad_cname.bv_val, 0, 0 ); return 1;}static intbacksql_srch_query( backsql_srch_info *bsi, struct berval *query ){ backsql_info *bi = (backsql_info *)bsi->bsi_op->o_bd->be_private; int rc; assert( query != NULL ); BER_BVZERO( query ); bsi->bsi_use_subtree_shortcut = 0; Debug( LDAP_DEBUG_TRACE, "==>backsql_srch_query()\n", 0, 0, 0 ); BER_BVZERO( &bsi->bsi_sel.bb_val ); BER_BVZERO( &bsi->bsi_sel.bb_val ); bsi->bsi_sel.bb_len = 0; BER_BVZERO( &bsi->bsi_from.bb_val ); bsi->bsi_from.bb_len = 0; BER_BVZERO( &bsi->bsi_join_where.bb_val ); bsi->bsi_join_where.bb_len = 0; BER_BVZERO( &bsi->bsi_flt_where.bb_val ); bsi->bsi_flt_where.bb_len = 0; backsql_strfcat_x( &bsi->bsi_sel, bsi->bsi_op->o_tmpmemctx, "lbcbc", (ber_len_t)STRLENOF( "SELECT DISTINCT ldap_entries.id," ), "SELECT DISTINCT ldap_entries.id,", &bsi->bsi_oc->bom_keytbl, '.', &bsi->bsi_oc->bom_keycol, ',' ); if ( !BER_BVISNULL( &bi->sql_strcast_func ) ) { backsql_strfcat_x( &bsi->bsi_sel, bsi->bsi_op->o_tmpmemctx, "blbl", &bi->sql_strcast_func, (ber_len_t)STRLENOF( "('" /* ') */ ), "('" /* ') */ , &bsi->bsi_oc->bom_oc->soc_cname, (ber_len_t)STRLENOF( /* (' */ "')" ), /* (' */ "')" ); } else { backsql_strfcat_x( &bsi->bsi_sel, bsi->bsi_op->o_tmpmemctx, "cbc", '\'', &bsi->bsi_oc->bom_oc->soc_cname, '\'' ); } backsql_strfcat_x( &bsi->bsi_sel, bsi->bsi_op->o_tmpmemctx, "b", &bi->sql_dn_oc_aliasing ); backsql_strfcat_x( &bsi->bsi_from, bsi->bsi_op->o_tmpmemctx, "lb", (ber_len_t)STRLENOF( " FROM ldap_entries," ), " FROM ldap_entries,", &bsi->bsi_oc->bom_keytbl ); backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "lbcbl", (ber_len_t)STRLENOF( " WHERE " ), " WHERE ", &bsi->bsi_oc->bom_keytbl, '.', &bsi->bsi_oc->bom_keycol, (ber_len_t)STRLENOF( "=ldap_entries.keyval AND ldap_entries.oc_map_id=? AND " ), "=ldap_entries.keyval AND ldap_entries.oc_map_id=? AND " ); switch ( bsi->bsi_scope ) { case LDAP_SCOPE_BASE: if ( BACKSQL_CANUPPERCASE( bi ) ) { backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "bl", &bi->sql_upper_func, (ber_len_t)STRLENOF( "(ldap_entries.dn)=?" ), "(ldap_entries.dn)=?" ); } else { backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "l", (ber_len_t)STRLENOF( "ldap_entries.dn=?" ), "ldap_entries.dn=?" ); } break; case BACKSQL_SCOPE_BASE_LIKE: if ( BACKSQL_CANUPPERCASE( bi ) ) { backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "bl", &bi->sql_upper_func, (ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE ?" ), "(ldap_entries.dn) LIKE ?" ); } else { backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "l", (ber_len_t)STRLENOF( "ldap_entries.dn LIKE ?" ), "ldap_entries.dn LIKE ?" ); } break; case LDAP_SCOPE_ONELEVEL: backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "l", (ber_len_t)STRLENOF( "ldap_entries.parent=?" ), "ldap_entries.parent=?" ); break; case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBTREE: if ( BACKSQL_USE_SUBTREE_SHORTCUT( bi ) ) { int i; BackendDB *bd = bsi->bsi_op->o_bd; assert( bd->be_nsuffix != NULL ); for ( i = 0; !BER_BVISNULL( &bd->be_nsuffix[ i ] ); i++ ) { if ( dn_match( &bd->be_nsuffix[ i ], bsi->bsi_base_ndn ) ) { /* pass this to the candidate selection * routine so that the DN is not bound * to the select statement */ bsi->bsi_use_subtree_shortcut = 1; break; } } } if ( bsi->bsi_use_subtree_shortcut ) { /* Skip the base DN filter, as every entry will match it */ backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "l", (ber_len_t)STRLENOF( "9=9"), "9=9"); } else if ( !BER_BVISNULL( &bi->sql_subtree_cond ) ) { backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "b", &bi->sql_subtree_cond ); } else if ( BACKSQL_CANUPPERCASE( bi ) ) { backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "bl", &bi->sql_upper_func, (ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE ?" ), "(ldap_entries.dn) LIKE ?" ); } else { backsql_strfcat_x( &bsi->bsi_join_where, bsi->bsi_op->o_tmpmemctx, "l", (ber_len_t)STRLENOF( "ldap_entries.dn LIKE ?" ), "ldap_entries.dn LIKE ?" ); } break; default: assert( 0 ); } rc = backsql_process_filter( bsi, bsi->bsi_filter ); if ( rc > 0 ) { struct berbuf bb = BB_NULL; backsql_strfcat_x( &bb, bsi->bsi_op->o_tmpmemctx, "bbblb", &bsi->bsi_sel.bb_val, &bsi->bsi_from.bb_val, &bsi->bsi_join_where.bb_val, (ber_len_t)STRLENOF( " AND " ), " AND ", &bsi->bsi_flt_where.bb_val ); *query = bb.bb_val; } else if ( rc < 0 ) { /* * Indicates that there's no possible way the filter matches * anything. No need to issue the query */ free( query->bv_val ); BER_BVZERO( query ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -