PostgreSQL Source Code git master
Loading...
Searching...
No Matches
like_support.c File Reference
#include "postgres.h"
#include <math.h>
#include "access/htup_details.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_operator.h"
#include "catalog/pg_opfamily.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "nodes/nodeFuncs.h"
#include "nodes/supportnodes.h"
#include "utils/builtins.h"
#include "utils/datum.h"
#include "utils/lsyscache.h"
#include "utils/pg_locale.h"
#include "utils/selfuncs.h"
#include "utils/varlena.h"
Include dependency graph for like_support.c:

Go to the source code of this file.

Macros

#define NONDETERMINISTIC(coll)    (OidIsValid(coll) && !get_collation_isdeterministic(coll))
 
#define FIXED_CHAR_SEL   0.20 /* about 1/5 */
 
#define CHAR_RANGE_SEL   0.25
 
#define ANY_CHAR_SEL   0.9 /* not 1, since it won't match end-of-string */
 
#define FULL_WILDCARD_SEL   5.0
 
#define PARTIAL_WILDCARD_SEL   2.0
 

Enumerations

enum  Pattern_Type {
  Pattern_Type_Like , Pattern_Type_Like_IC , Pattern_Type_Regex , Pattern_Type_Regex_IC ,
  Pattern_Type_Prefix
}
 
enum  Pattern_Prefix_Status { Pattern_Prefix_None , Pattern_Prefix_Partial , Pattern_Prefix_Exact }
 

Functions

static Nodelike_regex_support (Node *rawreq, Pattern_Type ptype)
 
static Listmatch_pattern_prefix (Node *leftop, Node *rightop, Pattern_Type ptype, Oid expr_coll, Oid opfamily, Oid indexcollation)
 
static double patternsel_common (PlannerInfo *root, Oid oprid, Oid opfuncid, List *args, int varRelid, Oid collation, Pattern_Type ptype, bool negate)
 
static Pattern_Prefix_Status pattern_fixed_prefix (Const *patt, Pattern_Type ptype, Oid collation, Const **prefix, Selectivity *rest_selec)
 
static Selectivity prefix_selectivity (PlannerInfo *root, VariableStatData *vardata, Oid eqopr, Oid ltopr, Oid geopr, Oid collation, Const *prefixcon)
 
static Selectivity like_selectivity (const char *patt, int pattlen, bool case_insensitive)
 
static Selectivity regex_selectivity (const char *patt, int pattlen, bool case_insensitive, int fixed_prefix_len)
 
static Constmake_greater_string (const Const *str_const, FmgrInfo *ltproc, Oid collation)
 
static Datum string_to_datum (const char *str, Oid datatype)
 
static Conststring_to_const (const char *str, Oid datatype)
 
static Conststring_to_bytea_const (const char *str, size_t str_len)
 
Datum textlike_support (PG_FUNCTION_ARGS)
 
Datum texticlike_support (PG_FUNCTION_ARGS)
 
Datum textregexeq_support (PG_FUNCTION_ARGS)
 
Datum texticregexeq_support (PG_FUNCTION_ARGS)
 
Datum text_starts_with_support (PG_FUNCTION_ARGS)
 
static double patternsel (PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate)
 
Datum regexeqsel (PG_FUNCTION_ARGS)
 
Datum icregexeqsel (PG_FUNCTION_ARGS)
 
Datum likesel (PG_FUNCTION_ARGS)
 
Datum prefixsel (PG_FUNCTION_ARGS)
 
Datum iclikesel (PG_FUNCTION_ARGS)
 
Datum regexnesel (PG_FUNCTION_ARGS)
 
Datum icregexnesel (PG_FUNCTION_ARGS)
 
Datum nlikesel (PG_FUNCTION_ARGS)
 
Datum icnlikesel (PG_FUNCTION_ARGS)
 
static double patternjoinsel (PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate)
 
Datum regexeqjoinsel (PG_FUNCTION_ARGS)
 
Datum icregexeqjoinsel (PG_FUNCTION_ARGS)
 
Datum likejoinsel (PG_FUNCTION_ARGS)
 
Datum prefixjoinsel (PG_FUNCTION_ARGS)
 
Datum iclikejoinsel (PG_FUNCTION_ARGS)
 
Datum regexnejoinsel (PG_FUNCTION_ARGS)
 
Datum icregexnejoinsel (PG_FUNCTION_ARGS)
 
Datum nlikejoinsel (PG_FUNCTION_ARGS)
 
Datum icnlikejoinsel (PG_FUNCTION_ARGS)
 
static Pattern_Prefix_Status like_fixed_prefix (Const *patt_const, Const **prefix_const, Selectivity *rest_selec)
 
static Pattern_Prefix_Status like_fixed_prefix_ci (Const *patt_const, Oid collation, Const **prefix_const, Selectivity *rest_selec)
 
static Pattern_Prefix_Status regex_fixed_prefix (Const *patt_const, bool case_insensitive, Oid collation, Const **prefix_const, Selectivity *rest_selec)
 
static Selectivity regex_selectivity_sub (const char *patt, int pattlen, bool case_insensitive)
 
static bool byte_increment (unsigned char *ptr, int len)
 

Macro Definition Documentation

◆ ANY_CHAR_SEL

#define ANY_CHAR_SEL   0.9 /* not 1, since it won't match end-of-string */

Definition at line 1395 of file like_support.c.

◆ CHAR_RANGE_SEL

#define CHAR_RANGE_SEL   0.25

Definition at line 1394 of file like_support.c.

◆ FIXED_CHAR_SEL

#define FIXED_CHAR_SEL   0.20 /* about 1/5 */

Definition at line 1393 of file like_support.c.

◆ FULL_WILDCARD_SEL

#define FULL_WILDCARD_SEL   5.0

Definition at line 1396 of file like_support.c.

◆ NONDETERMINISTIC

#define NONDETERMINISTIC (   coll)     (OidIsValid(coll) && !get_collation_isdeterministic(coll))

Definition at line 73 of file like_support.c.

117{
119
121}
122
123Datum
125{
127
129}
130
131Datum
133{
135
137}
138
139Datum
141{
143
145}
146
147Datum
149{
151
153}
154
155/* Common code for the above */
156static Node *
158{
159 Node *ret = NULL;
160
162 {
163 /*
164 * Make a selectivity estimate for a function call, just as we'd do if
165 * the call was via the corresponding operator.
166 */
169
170 if (req->is_join)
171 {
172 /*
173 * For the moment we just punt. If patternjoinsel is ever
174 * improved to do better, this should be made to call it.
175 */
177 }
178 else
179 {
180 /* Share code with operator restriction selectivity functions */
181 s1 = patternsel_common(req->root,
183 req->funcid,
184 req->args,
185 req->varRelid,
186 req->inputcollid,
187 ptype,
188 false);
189 }
190 req->selectivity = s1;
191 ret = (Node *) req;
192 }
194 {
195 /* Try to convert operator/function call to index conditions */
197
198 /*
199 * Currently we have no "reverse" match operators with the pattern on
200 * the left, so we only need consider cases with the indexkey on the
201 * left.
202 */
203 if (req->indexarg != 0)
204 return NULL;
205
206 if (is_opclause(req->node))
207 {
208 OpExpr *clause = (OpExpr *) req->node;
209
210 Assert(list_length(clause->args) == 2);
211 ret = (Node *)
212 match_pattern_prefix((Node *) linitial(clause->args),
213 (Node *) lsecond(clause->args),
214 ptype,
215 clause->inputcollid,
216 req->opfamily,
217 req->indexcollation);
218 }
219 else if (is_funcclause(req->node)) /* be paranoid */
220 {
221 FuncExpr *clause = (FuncExpr *) req->node;
222
223 Assert(list_length(clause->args) == 2);
224 ret = (Node *)
225 match_pattern_prefix((Node *) linitial(clause->args),
226 (Node *) lsecond(clause->args),
227 ptype,
228 clause->inputcollid,
229 req->opfamily,
230 req->indexcollation);
231 }
232 }
233
234 return ret;
235}
236
237/*
238 * match_pattern_prefix
239 * Try to generate an indexqual for a LIKE or regex operator.
240 */
241static List *
243 Node *rightop,
244 Pattern_Type ptype,
246 Oid opfamily,
247 Oid indexcollation)
248{
249 List *result;
250 Const *patt;
251 Const *prefix;
252 Pattern_Prefix_Status pstatus;
255 Oid eqopr;
256 Oid ltopr;
257 Oid geopr;
259 bool collation_aware;
260 Expr *expr;
263
264 /*
265 * Can't do anything with a non-constant or NULL pattern argument.
266 *
267 * Note that since we restrict ourselves to cases with a hard constant on
268 * the RHS, it's a-fortiori a pseudoconstant, and we don't need to worry
269 * about verifying that.
270 */
271 if (!IsA(rightop, Const) ||
273 return NIL;
274 patt = (Const *) rightop;
275
276 /*
277 * Try to extract a fixed prefix from the pattern.
278 */
279 pstatus = pattern_fixed_prefix(patt, ptype, expr_coll,
280 &prefix, NULL);
281
282 /* fail if no fixed prefix */
283 if (pstatus == Pattern_Prefix_None)
284 return NIL;
285
286 /*
287 * Identify the operators we want to use, based on the type of the
288 * left-hand argument. Usually these are just the type's regular
289 * comparison operators, but if we are considering one of the semi-legacy
290 * "pattern" opclasses, use the "pattern" operators instead. Those are
291 * not collation-sensitive but always use C collation, as we want. The
292 * selected operators also determine the needed type of the prefix
293 * constant.
294 */
296 switch (ldatatype)
297 {
298 case TEXTOID:
299 if (opfamily == TEXT_PATTERN_BTREE_FAM_OID)
300 {
301 eqopr = TextEqualOperator;
304 collation_aware = false;
305 }
306 else if (opfamily == TEXT_SPGIST_FAM_OID)
307 {
308 eqopr = TextEqualOperator;
311 /* This opfamily has direct support for prefixing */
313 collation_aware = false;
314 }
315 else
316 {
317 eqopr = TextEqualOperator;
318 ltopr = TextLessOperator;
320 collation_aware = true;
321 }
323 break;
324 case NAMEOID:
325
326 /*
327 * Note that here, we need the RHS type to be text, so that the
328 * comparison value isn't improperly truncated to NAMEDATALEN.
329 */
330 eqopr = NameEqualTextOperator;
331 ltopr = NameLessTextOperator;
333 collation_aware = true;
335 break;
336 case BPCHAROID:
337 if (opfamily == BPCHAR_PATTERN_BTREE_FAM_OID)
338 {
339 eqopr = BpcharEqualOperator;
342 collation_aware = false;
343 }
344 else
345 {
346 eqopr = BpcharEqualOperator;
347 ltopr = BpcharLessOperator;
349 collation_aware = true;
350 }
352 break;
353 case BYTEAOID:
354 eqopr = ByteaEqualOperator;
355 ltopr = ByteaLessOperator;
357 collation_aware = false;
359 break;
360 default:
361 /* Can't get here unless we're attached to the wrong operator */
362 return NIL;
363 }
364
365 /*
366 * If necessary, coerce the prefix constant to the right type. The given
367 * prefix constant is either text or bytea type, therefore the only case
368 * where we need to do anything is when converting text to bpchar. Those
369 * two types are binary-compatible, so relabeling the Const node is
370 * sufficient.
371 */
372 if (prefix->consttype != rdatatype)
373 {
374 Assert(prefix->consttype == TEXTOID &&
376 prefix->consttype = rdatatype;
377 }
378
379 /*
380 * If we found an exact-match pattern, generate an "=" indexqual.
381 *
382 * Here and below, check to see whether the desired operator is actually
383 * supported by the index opclass, and fail quietly if not. This allows
384 * us to not be concerned with specific opclasses (except for the legacy
385 * "pattern" cases); any index that correctly implements the operators
386 * will work.
387 *
388 * This case will work for LIKE/regex expressions with nondeterministic
389 * collation, so long as the index's collation is the same. If the
390 * expression's collation is deterministic, we can even use an index whose
391 * collation differs from the expression's. All deterministic collations
392 * agree on equality (it's bitwise), while we assume that an index with
393 * nondeterministic collation will return a superset of the bitwise-equal
394 * entries. Since the "=" indexqual is marked as lossy by default, we'll
395 * apply the LIKE/regex operator as a recheck, and that will filter out
396 * any non-matching entries.
397 */
398 if (pstatus == Pattern_Prefix_Exact)
399 {
400 if (!op_in_opfamily(eqopr, opfamily))
401 return NIL;
402 if (indexcollation != expr_coll && NONDETERMINISTIC(expr_coll))
403 return NIL;
404 expr = make_opclause(eqopr, BOOLOID, false,
405 (Expr *) leftop, (Expr *) prefix,
406 InvalidOid, indexcollation);
407 result = list_make1(expr);
408 return result;
409 }
410
411 /*
412 * Anything other than Pattern_Prefix_Exact is not supported if the
413 * expression collation is nondeterministic. The optimized equality or
414 * prefix tests use bytewise comparisons, which is not consistent with
415 * nondeterministic collations.
416 */
418 return NIL;
419
420 /*
421 * Otherwise, we have a nonempty required prefix of the values. Some
422 * opclasses support prefix checks directly, otherwise we'll try to
423 * generate a range constraint.
424 */
425 if (OidIsValid(preopr) && op_in_opfamily(preopr, opfamily))
426 {
427 expr = make_opclause(preopr, BOOLOID, false,
428 (Expr *) leftop, (Expr *) prefix,
429 InvalidOid, indexcollation);
430 result = list_make1(expr);
431 return result;
432 }
433
434 /*
435 * Since we need a range constraint, it's only going to work reliably if
436 * the index is collation-insensitive or has "C" collation. Note that
437 * here we are looking at the index's collation, not the expression's
438 * collation -- this test is *not* dependent on the LIKE/regex operator's
439 * collation.
440 */
441 if (collation_aware &&
442 !pg_newlocale_from_collation(indexcollation)->collate_is_c)
443 return NIL;
444
445 /*
446 * We can always say "x >= prefix".
447 */
448 if (!op_in_opfamily(geopr, opfamily))
449 return NIL;
450 expr = make_opclause(geopr, BOOLOID, false,
451 (Expr *) leftop, (Expr *) prefix,
452 InvalidOid, indexcollation);
453 result = list_make1(expr);
454
455 /*-------
456 * If we can create a string larger than the prefix, we can say
457 * "x < greaterstr". NB: we rely on make_greater_string() to generate
458 * a guaranteed-greater string, not just a probably-greater string.
459 * In general this is only guaranteed in C locale, so we'd better be
460 * using a C-locale index collation.
461 *-------
462 */
463 if (!op_in_opfamily(ltopr, opfamily))
464 return result;
465 fmgr_info(get_opcode(ltopr), &ltproc);
466 greaterstr = make_greater_string(prefix, &ltproc, indexcollation);
467 if (greaterstr)
468 {
469 expr = make_opclause(ltopr, BOOLOID, false,
470 (Expr *) leftop, (Expr *) greaterstr,
471 InvalidOid, indexcollation);
472 result = lappend(result, expr);
473 }
474
475 return result;
476}
477
478
479/*
480 * patternsel_common - generic code for pattern-match restriction selectivity.
481 *
482 * To support using this from either the operator or function paths, caller
483 * may pass either operator OID or underlying function OID; we look up the
484 * latter from the former if needed. (We could just have patternsel() call
485 * get_opcode(), but the work would be wasted if we don't have a need to
486 * compare a fixed prefix to the pg_statistic data.)
487 *
488 * Note that oprid and/or opfuncid should be for the positive-match operator
489 * even when negate is true.
490 */
491static double
493 Oid oprid,
495 List *args,
496 int varRelid,
497 Oid collation,
498 Pattern_Type ptype,
499 bool negate)
500{
502 Node *other;
503 bool varonleft;
504 Datum constval;
505 Oid consttype;
506 Oid vartype;
508 Oid eqopr;
509 Oid ltopr;
510 Oid geopr;
511 Pattern_Prefix_Status pstatus;
512 Const *patt;
513 Const *prefix = NULL;
515 double nullfrac = 0.0;
516 double result;
517
518 /*
519 * Initialize result to the appropriate default estimate depending on
520 * whether it's a match or not-match operator.
521 */
522 if (negate)
524 else
526
527 /*
528 * If expression is not variable op constant, then punt and return the
529 * default estimate.
530 */
531 if (!get_restriction_variable(root, args, varRelid,
532 &vardata, &other, &varonleft))
533 return result;
534 if (!varonleft || !IsA(other, Const))
535 {
537 return result;
538 }
539
540 /*
541 * If the constant is NULL, assume operator is strict and return zero, ie,
542 * operator will never return TRUE. (It's zero even for a negator op.)
543 */
544 if (((Const *) other)->constisnull)
545 {
547 return 0.0;
548 }
549 constval = ((Const *) other)->constvalue;
550 consttype = ((Const *) other)->consttype;
551
552 /*
553 * The right-hand const is type text or bytea for all supported operators.
554 * We do not expect to see binary-compatible types here, since
555 * const-folding should have relabeled the const to exactly match the
556 * operator's declared type.
557 */
558 if (consttype != TEXTOID && consttype != BYTEAOID)
559 {
561 return result;
562 }
563
564 /*
565 * Similarly, the exposed type of the left-hand side should be one of
566 * those we know. (Do not look at vardata.atttype, which might be
567 * something binary-compatible but different.) We can use it to identify
568 * the comparison operators and the required type of the comparison
569 * constant, much as in match_pattern_prefix().
570 */
571 vartype = vardata.vartype;
572
573 switch (vartype)
574 {
575 case TEXTOID:
576 eqopr = TextEqualOperator;
577 ltopr = TextLessOperator;
580 break;
581 case NAMEOID:
582
583 /*
584 * Note that here, we need the RHS type to be text, so that the
585 * comparison value isn't improperly truncated to NAMEDATALEN.
586 */
587 eqopr = NameEqualTextOperator;
588 ltopr = NameLessTextOperator;
591 break;
592 case BPCHAROID:
593 eqopr = BpcharEqualOperator;
594 ltopr = BpcharLessOperator;
597 break;
598 case BYTEAOID:
599 eqopr = ByteaEqualOperator;
600 ltopr = ByteaLessOperator;
603 break;
604 default:
605 /* Can't get here unless we're attached to the wrong operator */
607 return result;
608 }
609
610 /*
611 * Grab the nullfrac for use below.
612 */
613 if (HeapTupleIsValid(vardata.statsTuple))
614 {
615 Form_pg_statistic stats;
616
617 stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple);
618 nullfrac = stats->stanullfrac;
619 }
620
621 /*
622 * Pull out any fixed prefix implied by the pattern, and estimate the
623 * fractional selectivity of the remainder of the pattern. Unlike many
624 * other selectivity estimators, we use the pattern operator's actual
625 * collation for this step. This is not because we expect the collation
626 * to make a big difference in the selectivity estimate (it seldom would),
627 * but because we want to be sure we cache compiled regexps under the
628 * right cache key, so that they can be re-used at runtime.
629 */
630 patt = (Const *) other;
631 pstatus = pattern_fixed_prefix(patt, ptype, collation,
632 &prefix, &rest_selec);
633
634 /*
635 * If necessary, coerce the prefix constant to the right type. The only
636 * case where we need to do anything is when converting text to bpchar.
637 * Those two types are binary-compatible, so relabeling the Const node is
638 * sufficient.
639 */
640 if (prefix && prefix->consttype != rdatatype)
641 {
642 Assert(prefix->consttype == TEXTOID &&
644 prefix->consttype = rdatatype;
645 }
646
647 if (pstatus == Pattern_Prefix_Exact)
648 {
649 /*
650 * Pattern specifies an exact match, so estimate as for '='
651 */
652 result = var_eq_const(&vardata, eqopr, collation, prefix->constvalue,
653 false, true, false);
654 }
655 else
656 {
657 /*
658 * Not exact-match pattern. If we have a sufficiently large
659 * histogram, estimate selectivity for the histogram part of the
660 * population by counting matches in the histogram. If not, estimate
661 * selectivity of the fixed prefix and remainder of pattern
662 * separately, then combine the two to get an estimate of the
663 * selectivity for the part of the column population represented by
664 * the histogram. (For small histograms, we combine these
665 * approaches.)
666 *
667 * We then add up data for any most-common-values values; these are
668 * not in the histogram population, and we can get exact answers for
669 * them by applying the pattern operator, so there's no reason to
670 * approximate. (If the MCVs cover a significant part of the total
671 * population, this gives us a big leg up in accuracy.)
672 */
674 int hist_size;
676 double mcv_selec,
677 sumcommon;
678
679 /* Try to use the histogram entries to get selectivity */
680 if (!OidIsValid(opfuncid))
683
685 constval, true,
686 10, 1, &hist_size);
687
688 /* If not at least 100 entries, use the heuristic method */
689 if (hist_size < 100)
690 {
693
694 if (pstatus == Pattern_Prefix_Partial)
696 eqopr, ltopr, geopr,
697 collation,
698 prefix);
699 else
700 prefixsel = 1.0;
702
703 if (selec < 0) /* fewer than 10 histogram entries? */
704 selec = heursel;
705 else
706 {
707 /*
708 * For histogram sizes from 10 to 100, we combine the
709 * histogram and heuristic selectivities, putting increasingly
710 * more trust in the histogram for larger sizes.
711 */
712 double hist_weight = hist_size / 100.0;
713
714 selec = selec * hist_weight + heursel * (1.0 - hist_weight);
715 }
716 }
717
718 /* In any case, don't believe extremely small or large estimates. */
719 if (selec < 0.0001)
720 selec = 0.0001;
721 else if (selec > 0.9999)
722 selec = 0.9999;
723
724 /*
725 * If we have most-common-values info, add up the fractions of the MCV
726 * entries that satisfy MCV OP PATTERN. These fractions contribute
727 * directly to the result selectivity. Also add up the total fraction
728 * represented by MCV entries.
729 */
730 mcv_selec = mcv_selectivity(&vardata, &opproc, collation,
731 constval, true,
732 &sumcommon);
733
734 /*
735 * Now merge the results from the MCV and histogram calculations,
736 * realizing that the histogram covers only the non-null values that
737 * are not listed in MCV.
738 */
739 selec *= 1.0 - nullfrac - sumcommon;
740 selec += mcv_selec;
741 result = selec;
742 }
743
744 /* now adjust if we wanted not-match rather than match */
745 if (negate)
746 result = 1.0 - result - nullfrac;
747
748 /* result should be in range, but make sure... */
750
751 if (prefix)
752 {
753 pfree(DatumGetPointer(prefix->constvalue));
754 pfree(prefix);
755 }
756
758
759 return result;
760}
761
762/*
763 * Fix impedance mismatch between SQL-callable functions and patternsel_common
764 */
765static double
766patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate)
767{
769 Oid operator = PG_GETARG_OID(1);
771 int varRelid = PG_GETARG_INT32(3);
772 Oid collation = PG_GET_COLLATION();
773
774 /*
775 * If this is for a NOT LIKE or similar operator, get the corresponding
776 * positive-match operator and work with that.
777 */
778 if (negate)
779 {
780 operator = get_negator(operator);
781 if (!OidIsValid(operator))
782 elog(ERROR, "patternsel called for operator without a negator");
783 }
784
785 return patternsel_common(root,
786 operator,
788 args,
789 varRelid,
790 collation,
791 ptype,
792 negate);
793}
794
795/*
796 * regexeqsel - Selectivity of regular-expression pattern match.
797 */
798Datum
800{
802}
803
804/*
805 * icregexeqsel - Selectivity of case-insensitive regex match.
806 */
807Datum
809{
811}
812
813/*
814 * likesel - Selectivity of LIKE pattern match.
815 */
816Datum
818{
820}
821
822/*
823 * prefixsel - selectivity of prefix operator
824 */
825Datum
827{
829}
830
831/*
832 *
833 * iclikesel - Selectivity of ILIKE pattern match.
834 */
835Datum
837{
839}
840
841/*
842 * regexnesel - Selectivity of regular-expression pattern non-match.
843 */
844Datum
846{
848}
849
850/*
851 * icregexnesel - Selectivity of case-insensitive regex non-match.
852 */
853Datum
855{
857}
858
859/*
860 * nlikesel - Selectivity of LIKE pattern non-match.
861 */
862Datum
864{
866}
867
868/*
869 * icnlikesel - Selectivity of ILIKE pattern non-match.
870 */
871Datum
873{
875}
876
877/*
878 * patternjoinsel - Generic code for pattern-match join selectivity.
879 */
880static double
882{
883 /* For the moment we just punt. */
884 return negate ? (1.0 - DEFAULT_MATCH_SEL) : DEFAULT_MATCH_SEL;
885}
886
887/*
888 * regexeqjoinsel - Join selectivity of regular-expression pattern match.
889 */
890Datum
892{
894}
895
896/*
897 * icregexeqjoinsel - Join selectivity of case-insensitive regex match.
898 */
899Datum
901{
903}
904
905/*
906 * likejoinsel - Join selectivity of LIKE pattern match.
907 */
908Datum
910{
912}
913
914/*
915 * prefixjoinsel - Join selectivity of prefix operator
916 */
917Datum
919{
921}
922
923/*
924 * iclikejoinsel - Join selectivity of ILIKE pattern match.
925 */
926Datum
928{
930}
931
932/*
933 * regexnejoinsel - Join selectivity of regex non-match.
934 */
935Datum
937{
939}
940
941/*
942 * icregexnejoinsel - Join selectivity of case-insensitive regex non-match.
943 */
944Datum
946{
948}
949
950/*
951 * nlikejoinsel - Join selectivity of LIKE pattern non-match.
952 */
953Datum
955{
957}
958
959/*
960 * icnlikejoinsel - Join selectivity of ILIKE pattern non-match.
961 */
962Datum
964{
966}
967
968
969/*-------------------------------------------------------------------------
970 *
971 * Pattern analysis functions
972 *
973 * These routines support analysis of LIKE and regular-expression patterns
974 * by the planner/optimizer. It's important that they agree with the
975 * regular-expression code in backend/regex/ and the LIKE code in
976 * backend/utils/adt/like.c. Also, the computation of the fixed prefix
977 * must be conservative: if we report a string longer than the true fixed
978 * prefix, the query may produce actually wrong answers, rather than just
979 * getting a bad selectivity estimate!
980 *
981 *-------------------------------------------------------------------------
982 */
983
984/*
985 * Extract the fixed prefix, if any, for a pattern.
986 *
987 * *prefix is set to a palloc'd prefix string (in the form of a Const node),
988 * or to NULL if no fixed prefix exists for the pattern.
989 * If rest_selec is not NULL, *rest_selec is set to an estimate of the
990 * selectivity of the remainder of the pattern (without any fixed prefix).
991 * The prefix Const has the same type (TEXT or BYTEA) as the input pattern.
992 *
993 * The return value distinguishes no fixed prefix, a partial prefix,
994 * or an exact-match-only pattern.
995 */
996
1000{
1001 char *match;
1002 char *patt;
1003 int pattlen;
1004 Oid typeid = patt_const->consttype;
1005 int pos,
1006 match_pos;
1007
1008 /* the right-hand const is type text or bytea */
1009 Assert(typeid == BYTEAOID || typeid == TEXTOID);
1010
1011 if (typeid != BYTEAOID)
1012 {
1013 patt = TextDatumGetCString(patt_const->constvalue);
1014 pattlen = strlen(patt);
1015 }
1016 else
1017 {
1018 bytea *bstr = DatumGetByteaPP(patt_const->constvalue);
1019
1021 patt = (char *) palloc(pattlen);
1023 Assert(bstr == DatumGetPointer(patt_const->constvalue));
1024 }
1025
1026 match = palloc(pattlen + 1);
1027 match_pos = 0;
1028 for (pos = 0; pos < pattlen; pos++)
1029 {
1030 /* % and _ are wildcard characters in LIKE */
1031 if (patt[pos] == '%' ||
1032 patt[pos] == '_')
1033 break;
1034
1035 /* Backslash escapes the next character */
1036 if (patt[pos] == '\\')
1037 {
1038 pos++;
1039 if (pos >= pattlen)
1040 break;
1041 }
1042
1043 match[match_pos++] = patt[pos];
1044 }
1045
1046 match[match_pos] = '\0';
1047
1048 if (typeid != BYTEAOID)
1049 *prefix_const = string_to_const(match, typeid);
1050 else
1052
1053 if (rest_selec != NULL)
1054 *rest_selec = like_selectivity(&patt[pos], pattlen - pos, false);
1055
1056 pfree(patt);
1057 pfree(match);
1058
1059 /* in LIKE, an empty pattern is an exact match! */
1060 if (pos == pattlen)
1061 return Pattern_Prefix_Exact; /* reached end of pattern, so exact */
1062
1063 if (match_pos > 0)
1065
1066 return Pattern_Prefix_None;
1067}
1068
1069/*
1070 * Case-insensitive variant of like_fixed_prefix(). Multibyte and
1071 * locale-aware for detecting cased characters.
1072 */
1076{
1077 text *val = DatumGetTextPP(patt_const->constvalue);
1078 Oid typeid = patt_const->consttype;
1079 int nbytes = VARSIZE_ANY_EXHDR(val);
1080 int wpos;
1081 pg_wchar *wpatt;
1082 int wpattlen;
1084 int wmatch_pos = 0;
1085 char *match;
1086 int match_mblen;
1087 pg_locale_t locale = 0;
1088
1089 /* the right-hand const is type text or bytea */
1090 Assert(typeid == BYTEAOID || typeid == TEXTOID);
1091
1092 if (typeid == BYTEAOID)
1093 ereport(ERROR,
1095 errmsg("case insensitive matching not supported on type bytea")));
1096
1097 if (!OidIsValid(collation))
1098 {
1099 /*
1100 * This typically means that the parser could not resolve a conflict
1101 * of implicit collations, so report it that way.
1102 */
1103 ereport(ERROR,
1105 errmsg("could not determine which collation to use for ILIKE"),
1106 errhint("Use the COLLATE clause to set the collation explicitly.")));
1107 }
1108
1109 locale = pg_newlocale_from_collation(collation);
1110
1111 wpatt = palloc((nbytes + 1) * sizeof(pg_wchar));
1113
1114 wmatch = palloc((nbytes + 1) * sizeof(pg_wchar));
1115 for (wpos = 0; wpos < wpattlen; wpos++)
1116 {
1117 /* % and _ are wildcard characters in LIKE */
1118 if (wpatt[wpos] == '%' ||
1119 wpatt[wpos] == '_')
1120 break;
1121
1122 /* Backslash escapes the next character */
1123 if (wpatt[wpos] == '\\')
1124 {
1125 wpos++;
1126 if (wpos >= wpattlen)
1127 break;
1128 }
1129
1130 /*
1131 * For ILIKE, stop if it's a case-varying character (it's sort of a
1132 * wildcard).
1133 */
1134 if (pg_iswcased(wpatt[wpos], locale))
1135 break;
1136
1138 }
1139
1140 wmatch[wmatch_pos] = '\0';
1141
1144 match[match_mblen] = '\0';
1145 pfree(wmatch);
1146
1148 pfree(match);
1149
1150 if (rest_selec != NULL)
1151 {
1152 int wrestlen = wpattlen - wpos;
1153 char *rest;
1154 int rest_mblen;
1155
1158
1160 pfree(rest);
1161 }
1162
1163 pfree(wpatt);
1164
1165 /* in LIKE, an empty pattern is an exact match! */
1166 if (wpos == wpattlen)
1167 return Pattern_Prefix_Exact; /* reached end of pattern, so exact */
1168
1169 if (wmatch_pos > 0)
1171
1172 return Pattern_Prefix_None;
1173}
1174
1178{
1179 Oid typeid = patt_const->consttype;
1180 char *prefix;
1181 bool exact;
1182
1183 /*
1184 * Should be unnecessary, there are no bytea regex operators defined. As
1185 * such, it should be noted that the rest of this function has *not* been
1186 * made safe for binary (possibly NULL containing) strings.
1187 */
1188 if (typeid == BYTEAOID)
1189 ereport(ERROR,
1191 errmsg("regular-expression matching not supported on type bytea")));
1192
1193 /* Use the regexp machinery to extract the prefix, if any */
1194 prefix = regexp_fixed_prefix(DatumGetTextPP(patt_const->constvalue),
1195 case_insensitive, collation,
1196 &exact);
1197
1198 if (prefix == NULL)
1199 {
1200 *prefix_const = NULL;
1201
1202 if (rest_selec != NULL)
1203 {
1204 char *patt = TextDatumGetCString(patt_const->constvalue);
1205
1208 0);
1209 pfree(patt);
1210 }
1211
1212 return Pattern_Prefix_None;
1213 }
1214
1215 *prefix_const = string_to_const(prefix, typeid);
1216
1217 if (rest_selec != NULL)
1218 {
1219 if (exact)
1220 {
1221 /* Exact match, so there's no additional selectivity */
1222 *rest_selec = 1.0;
1223 }
1224 else
1225 {
1226 char *patt = TextDatumGetCString(patt_const->constvalue);
1227
1230 strlen(prefix));
1231 pfree(patt);
1232 }
1233 }
1234
1235 pfree(prefix);
1236
1237 if (exact)
1238 return Pattern_Prefix_Exact; /* pattern specifies exact match */
1239 else
1241}
1242
1245 Const **prefix, Selectivity *rest_selec)
1246{
1248
1249 switch (ptype)
1250 {
1251 case Pattern_Type_Like:
1253 break;
1255 result = like_fixed_prefix_ci(patt, collation, prefix,
1256 rest_selec);
1257 break;
1258 case Pattern_Type_Regex:
1259 result = regex_fixed_prefix(patt, false, collation,
1260 prefix, rest_selec);
1261 break;
1263 result = regex_fixed_prefix(patt, true, collation,
1264 prefix, rest_selec);
1265 break;
1267 /* Prefix type work is trivial. */
1269 *prefix = makeConst(patt->consttype,
1270 patt->consttypmod,
1271 patt->constcollid,
1272 patt->constlen,
1273 datumCopy(patt->constvalue,
1274 patt->constbyval,
1275 patt->constlen),
1276 patt->constisnull,
1277 patt->constbyval);
1278 if (rest_selec != NULL)
1279 *rest_selec = 1.0; /* all */
1280 break;
1281 default:
1282 elog(ERROR, "unrecognized ptype: %d", (int) ptype);
1283 result = Pattern_Prefix_None; /* keep compiler quiet */
1284 break;
1285 }
1286 return result;
1287}
1288
1289/*
1290 * Estimate the selectivity of a fixed prefix for a pattern match.
1291 *
1292 * A fixed prefix "foo" is estimated as the selectivity of the expression
1293 * "variable >= 'foo' AND variable < 'fop'".
1294 *
1295 * The selectivity estimate is with respect to the portion of the column
1296 * population represented by the histogram --- the caller must fold this
1297 * together with info about MCVs and NULLs.
1298 *
1299 * We use the given comparison operators and collation to do the estimation.
1300 * The given variable and Const must be of the associated datatype(s).
1301 *
1302 * XXX Note: we make use of the upper bound to estimate operator selectivity
1303 * even if the locale is such that we cannot rely on the upper-bound string.
1304 * The selectivity only needs to be approximately right anyway, so it seems
1305 * more useful to use the upper-bound code than not.
1306 */
1307static Selectivity
1309 Oid eqopr, Oid ltopr, Oid geopr,
1310 Oid collation,
1312{
1317
1318 /* Estimate the selectivity of "x >= prefix" */
1320
1322 geopr, &opproc, true, true,
1323 collation,
1324 prefixcon->constvalue,
1325 prefixcon->consttype);
1326
1327 if (prefixsel < 0.0)
1328 {
1329 /* No histogram is present ... return a suitable default estimate */
1330 return DEFAULT_MATCH_SEL;
1331 }
1332
1333 /*
1334 * If we can create a string larger than the prefix, say "x < greaterstr".
1335 */
1336 fmgr_info(get_opcode(ltopr), &opproc);
1338 if (greaterstrcon)
1339 {
1341
1343 ltopr, &opproc, false, false,
1344 collation,
1345 greaterstrcon->constvalue,
1346 greaterstrcon->consttype);
1347
1348 /* ineq_histogram_selectivity worked before, it shouldn't fail now */
1349 Assert(topsel >= 0.0);
1350
1351 /*
1352 * Merge the two selectivities in the same way as for a range query
1353 * (see clauselist_selectivity()). Note that we don't need to worry
1354 * about double-exclusion of nulls, since ineq_histogram_selectivity
1355 * doesn't count those anyway.
1356 */
1357 prefixsel = topsel + prefixsel - 1.0;
1358 }
1359
1360 /*
1361 * If the prefix is long then the two bounding values might be too close
1362 * together for the histogram to distinguish them usefully, resulting in a
1363 * zero estimate (plus or minus roundoff error). To avoid returning a
1364 * ridiculously small estimate, compute the estimated selectivity for
1365 * "variable = 'foo'", and clamp to that. (Obviously, the resultant
1366 * estimate should be at least that.)
1367 *
1368 * We apply this even if we couldn't make a greater string. That case
1369 * suggests that the prefix is near the maximum possible, and thus
1370 * probably off the end of the histogram, and thus we probably got a very
1371 * small estimate from the >= condition; so we still need to clamp.
1372 */
1373 eq_sel = var_eq_const(vardata, eqopr, collation, prefixcon->constvalue,
1374 false, true, false);
1375
1377
1378 return prefixsel;
1379}
1380
1381
1382/*
1383 * Estimate the selectivity of a pattern of the specified type.
1384 * Note that any fixed prefix of the pattern will have been removed already,
1385 * so actually we may be looking at just a fragment of the pattern.
1386 *
1387 * For now, we use a very simplistic approach: fixed characters reduce the
1388 * selectivity a good deal, character ranges reduce it a little,
1389 * wildcards (such as % for LIKE or .* for regex) increase it.
1390 */
1391
1392#define FIXED_CHAR_SEL 0.20 /* about 1/5 */
1393#define CHAR_RANGE_SEL 0.25
1394#define ANY_CHAR_SEL 0.9 /* not 1, since it won't match end-of-string */
1395#define FULL_WILDCARD_SEL 5.0
1396#define PARTIAL_WILDCARD_SEL 2.0
1397
1398static Selectivity
1399like_selectivity(const char *patt, int pattlen, bool case_insensitive)
1400{
1401 Selectivity sel = 1.0;
1402 int pos;
1403
1404 /* Skip any leading wildcard; it's already factored into initial sel */
1405 for (pos = 0; pos < pattlen; pos++)
1406 {
1407 if (patt[pos] != '%' && patt[pos] != '_')
1408 break;
1409 }
1410
1411 for (; pos < pattlen; pos++)
1412 {
1413 /* % and _ are wildcard characters in LIKE */
1414 if (patt[pos] == '%')
1416 else if (patt[pos] == '_')
1417 sel *= ANY_CHAR_SEL;
1418 else if (patt[pos] == '\\')
1419 {
1420 /* Backslash quotes the next character */
1421 pos++;
1422 if (pos >= pattlen)
1423 break;
1425 }
1426 else
1428 }
1429 /* Could get sel > 1 if multiple wildcards */
1430 if (sel > 1.0)
1431 sel = 1.0;
1432 return sel;
1433}
1434
1435static Selectivity
1436regex_selectivity_sub(const char *patt, int pattlen, bool case_insensitive)
1437{
1438 Selectivity sel = 1.0;
1439 int paren_depth = 0;
1440 int paren_pos = 0; /* dummy init to keep compiler quiet */
1441 int pos;
1442
1443 /* since this function recurses, it could be driven to stack overflow */
1445
1446 for (pos = 0; pos < pattlen; pos++)
1447 {
1448 if (patt[pos] == '(')
1449 {
1450 if (paren_depth == 0)
1451 paren_pos = pos; /* remember start of parenthesized item */
1452 paren_depth++;
1453 }
1454 else if (patt[pos] == ')' && paren_depth > 0)
1455 {
1456 paren_depth--;
1457 if (paren_depth == 0)
1459 pos - (paren_pos + 1),
1461 }
1462 else if (patt[pos] == '|' && paren_depth == 0)
1463 {
1464 /*
1465 * If unquoted | is present at paren level 0 in pattern, we have
1466 * multiple alternatives; sum their probabilities.
1467 */
1468 sel += regex_selectivity_sub(patt + (pos + 1),
1469 pattlen - (pos + 1),
1471 break; /* rest of pattern is now processed */
1472 }
1473 else if (patt[pos] == '[')
1474 {
1475 bool negclass = false;
1476
1477 if (patt[++pos] == '^')
1478 {
1479 negclass = true;
1480 pos++;
1481 }
1482 if (patt[pos] == ']') /* ']' at start of class is not special */
1483 pos++;
1484 while (pos < pattlen && patt[pos] != ']')
1485 pos++;
1486 if (paren_depth == 0)
1487 sel *= (negclass ? (1.0 - CHAR_RANGE_SEL) : CHAR_RANGE_SEL);
1488 }
1489 else if (patt[pos] == '.')
1490 {
1491 if (paren_depth == 0)
1492 sel *= ANY_CHAR_SEL;
1493 }
1494 else if (patt[pos] == '*' ||
1495 patt[pos] == '?' ||
1496 patt[pos] == '+')
1497 {
1498 /* Ought to be smarter about quantifiers... */
1499 if (paren_depth == 0)
1501 }
1502 else if (patt[pos] == '{')
1503 {
1504 while (pos < pattlen && patt[pos] != '}')
1505 pos++;
1506 if (paren_depth == 0)
1508 }
1509 else if (patt[pos] == '\\')
1510 {
1511 /* backslash quotes the next character */
1512 pos++;
1513 if (pos >= pattlen)
1514 break;
1515 if (paren_depth == 0)
1517 }
1518 else
1519 {
1520 if (paren_depth == 0)
1522 }
1523 }
1524 /* Could get sel > 1 if multiple wildcards */
1525 if (sel > 1.0)
1526 sel = 1.0;
1527 return sel;
1528}
1529
1530static Selectivity
1531regex_selectivity(const char *patt, int pattlen, bool case_insensitive,
1532 int fixed_prefix_len)
1533{
1535
1536 /* If patt doesn't end with $, consider it to have a trailing wildcard */
1537 if (pattlen > 0 && patt[pattlen - 1] == '$' &&
1538 (pattlen == 1 || patt[pattlen - 2] != '\\'))
1539 {
1540 /* has trailing $ */
1542 }
1543 else
1544 {
1545 /* no trailing $ */
1548 }
1549
1550 /*
1551 * If there's a fixed prefix, discount its selectivity. We have to be
1552 * careful here since a very long prefix could result in pow's result
1553 * underflowing to zero (in which case "sel" probably has as well).
1554 */
1555 if (fixed_prefix_len > 0)
1556 {
1558
1559 if (prefixsel > 0.0)
1560 sel /= prefixsel;
1561 }
1562
1563 /* Make sure result stays in range */
1565 return sel;
1566}
1567
1568
1569/*
1570 * For bytea, the increment function need only increment the current byte
1571 * (there are no multibyte characters to worry about).
1572 */
1573static bool
1574byte_increment(unsigned char *ptr, int len)
1575{
1576 if (*ptr >= 255)
1577 return false;
1578 (*ptr)++;
1579 return true;
1580}
1581
1582/*
1583 * Try to generate a string greater than the given string or any
1584 * string it is a prefix of. If successful, return a palloc'd string
1585 * in the form of a Const node; else return NULL.
1586 *
1587 * The caller must provide the appropriate "less than" comparison function
1588 * for testing the strings, along with the collation to use.
1589 *
1590 * The key requirement here is that given a prefix string, say "foo",
1591 * we must be able to generate another string "fop" that is greater than
1592 * all strings "foobar" starting with "foo". We can test that we have
1593 * generated a string greater than the prefix string, but in non-C collations
1594 * that is not a bulletproof guarantee that an extension of the string might
1595 * not sort after it; an example is that "foo " is less than "foo!", but it
1596 * is not clear that a "dictionary" sort ordering will consider "foo!" less
1597 * than "foo bar". CAUTION: Therefore, this function should be used only for
1598 * estimation purposes when working in a non-C collation.
1599 *
1600 * To try to catch most cases where an extended string might otherwise sort
1601 * before the result value, we determine which of the strings "Z", "z", "y",
1602 * and "9" is seen as largest by the collation, and append that to the given
1603 * prefix before trying to find a string that compares as larger.
1604 *
1605 * To search for a greater string, we repeatedly "increment" the rightmost
1606 * character, using an encoding-specific character incrementer function.
1607 * When it's no longer possible to increment the last character, we truncate
1608 * off that character and start incrementing the next-to-rightmost.
1609 * For example, if "z" were the last character in the sort order, then we
1610 * could produce "foo" as a string greater than "fonz".
1611 *
1612 * This could be rather slow in the worst case, but in most cases we
1613 * won't have to try more than one or two strings before succeeding.
1614 *
1615 * Note that it's important for the character incrementer not to be too anal
1616 * about producing every possible character code, since in some cases the only
1617 * way to get a larger string is to increment a previous character position.
1618 * So we don't want to spend too much time trying every possible character
1619 * code at the last position. A good rule of thumb is to be sure that we
1620 * don't try more than 256*K values for a K-byte character (and definitely
1621 * not 256^K, which is what an exhaustive search would approach).
1622 */
1623static Const *
1625{
1626 Oid datatype = str_const->consttype;
1627 char *workstr;
1628 int len;
1629 Datum cmpstr;
1630 char *cmptxt = NULL;
1632
1633 /*
1634 * Get a modifiable copy of the prefix string in C-string format, and set
1635 * up the string we will compare to as a Datum. In C locale this can just
1636 * be the given prefix string, otherwise we need to add a suffix. Type
1637 * BYTEA sorts bytewise so it never needs a suffix either.
1638 */
1639 if (datatype == BYTEAOID)
1640 {
1641 bytea *bstr = DatumGetByteaPP(str_const->constvalue);
1642
1644 workstr = (char *) palloc(len);
1646 Assert(bstr == DatumGetPointer(str_const->constvalue));
1647 cmpstr = str_const->constvalue;
1648 }
1649 else
1650 {
1651 if (datatype == NAMEOID)
1653 str_const->constvalue));
1654 else
1655 workstr = TextDatumGetCString(str_const->constvalue);
1656 len = strlen(workstr);
1657 if (len == 0 || pg_newlocale_from_collation(collation)->collate_is_c)
1658 cmpstr = str_const->constvalue;
1659 else
1660 {
1661 /* If first time through, determine the suffix to use */
1662 static char suffixchar = 0;
1663 static Oid suffixcollation = 0;
1664
1665 if (!suffixchar || suffixcollation != collation)
1666 {
1667 char *best;
1668
1669 best = "Z";
1670 if (varstr_cmp(best, 1, "z", 1, collation) < 0)
1671 best = "z";
1672 if (varstr_cmp(best, 1, "y", 1, collation) < 0)
1673 best = "y";
1674 if (varstr_cmp(best, 1, "9", 1, collation) < 0)
1675 best = "9";
1676 suffixchar = *best;
1677 suffixcollation = collation;
1678 }
1679
1680 /* And build the string to compare to */
1681 if (datatype == NAMEOID)
1682 {
1683 cmptxt = palloc(len + 2);
1686 cmptxt[len + 1] = '\0';
1688 }
1689 else
1690 {
1691 cmptxt = palloc(VARHDRSZ + len + 1);
1694 *(VARDATA(cmptxt) + len) = suffixchar;
1696 }
1697 }
1698 }
1699
1700 /* Select appropriate character-incrementer function */
1701 if (datatype == BYTEAOID)
1703 else
1705
1706 /* And search ... */
1707 while (len > 0)
1708 {
1709 int charlen;
1710 unsigned char *lastchar;
1711
1712 /* Identify the last character --- for bytea, just the last byte */
1713 if (datatype == BYTEAOID)
1714 charlen = 1;
1715 else
1716 charlen = len - pg_mbcliplen(workstr, len, len - 1);
1717 lastchar = (unsigned char *) (workstr + len - charlen);
1718
1719 /*
1720 * Try to generate a larger string by incrementing the last character
1721 * (for BYTEA, we treat each byte as a character).
1722 *
1723 * Note: the incrementer function is expected to return true if it's
1724 * generated a valid-per-the-encoding new character, otherwise false.
1725 * The contents of the character on false return are unspecified.
1726 */
1727 while (charinc(lastchar, charlen))
1728 {
1730
1731 if (datatype == BYTEAOID)
1733 else
1735
1737 collation,
1738 cmpstr,
1739 workstr_const->constvalue)))
1740 {
1741 /* Successfully made a string larger than cmpstr */
1742 if (cmptxt)
1743 pfree(cmptxt);
1744 pfree(workstr);
1745 return workstr_const;
1746 }
1747
1748 /* No good, release unusable value and try again */
1749 pfree(DatumGetPointer(workstr_const->constvalue));
1751 }
1752
1753 /*
1754 * No luck here, so truncate off the last character and try to
1755 * increment the next one.
1756 */
1757 len -= charlen;
1758 workstr[len] = '\0';
1759 }
1760
1761 /* Failed... */
1762 if (cmptxt)
1763 pfree(cmptxt);
1764 pfree(workstr);
1765
1766 return NULL;
1767}
1768
1769/*
1770 * Generate a Datum of the appropriate type from a C string.
1771 * Note that all of the supported types are pass-by-ref, so the
1772 * returned value should be pfree'd if no longer needed.
1773 */
1774static Datum
1775string_to_datum(const char *str, Oid datatype)
1776{
1777 Assert(str != NULL);
1778
1779 /*
1780 * We cheat a little by assuming that CStringGetTextDatum() will do for
1781 * bpchar and varchar constants too...
1782 */
1783 if (datatype == NAMEOID)
1785 else if (datatype == BYTEAOID)
1787 else
1788 return CStringGetTextDatum(str);
1789}
1790
1791/*
1792 * Generate a Const node of the appropriate type from a C string.
1793 */
1794static Const *
1795string_to_const(const char *str, Oid datatype)
1796{
1797 Datum conval = string_to_datum(str, datatype);
1798 Oid collation;
1799 int constlen;
1800
1801 /*
1802 * We only need to support a few datatypes here, so hard-wire properties
1803 * instead of incurring the expense of catalog lookups.
1804 */
1805 switch (datatype)
1806 {
1807 case TEXTOID:
1808 case VARCHAROID:
1809 case BPCHAROID:
1810 collation = DEFAULT_COLLATION_OID;
1811 constlen = -1;
1812 break;
1813
1814 case NAMEOID:
1815 collation = C_COLLATION_OID;
1817 break;
1818
1819 case BYTEAOID:
1820 collation = InvalidOid;
1821 constlen = -1;
1822 break;
1823
1824 default:
1825 elog(ERROR, "unexpected datatype in string_to_const: %u",
1826 datatype);
1827 return NULL;
1828 }
1829
1830 return makeConst(datatype, -1, collation, constlen,
1831 conval, false, false);
1832}
1833
1834/*
1835 * Generate a Const node of bytea type from a binary C string and a length.
1836 */
1837static Const *
1838string_to_bytea_const(const char *str, size_t str_len)
1839{
1841 Datum conval;
1842
1846
1847 return makeConst(BYTEAOID, -1, InvalidOid, -1, conval, false, false);
1848}
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define TextDatumGetCString(d)
Definition builtins.h:99
Datum byteain(PG_FUNCTION_ARGS)
Definition bytea.c:201
#define Max(x, y)
Definition c.h:1125
#define VARHDRSZ
Definition c.h:840
#define Assert(condition)
Definition c.h:1002
#define OidIsValid(objectId)
Definition c.h:917
uint32 result
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
Datum datumCopy(Datum value, bool typByVal, int typLen)
Definition datum.c:132
int errcode(int sqlerrcode)
Definition elog.c:875
int errhint(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
Definition fmgr.c:1151
void fmgr_info(Oid functionId, FmgrInfo *finfo)
Definition fmgr.c:129
#define PG_GETARG_OID(n)
Definition fmgr.h:275
#define DatumGetByteaPP(X)
Definition fmgr.h:292
#define PG_RETURN_FLOAT8(x)
Definition fmgr.h:369
#define DatumGetTextPP(X)
Definition fmgr.h:293
#define PG_GETARG_POINTER(n)
Definition fmgr.h:277
#define DirectFunctionCall1(func, arg1)
Definition fmgr.h:688
#define PG_GETARG_INT32(n)
Definition fmgr.h:269
#define PG_RETURN_POINTER(x)
Definition fmgr.h:363
#define PG_GET_COLLATION()
Definition fmgr.h:198
#define PG_FUNCTION_ARGS
Definition fmgr.h:193
const char * str
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
long val
Definition informix.c:689
#define NONDETERMINISTIC(coll)
Datum icregexnesel(PG_FUNCTION_ARGS)
Datum regexnesel(PG_FUNCTION_ARGS)
static Node * like_regex_support(Node *rawreq, Pattern_Type ptype)
Datum iclikesel(PG_FUNCTION_ARGS)
Datum texticregexeq_support(PG_FUNCTION_ARGS)
static Selectivity prefix_selectivity(PlannerInfo *root, VariableStatData *vardata, Oid eqopr, Oid ltopr, Oid geopr, Oid collation, Const *prefixcon)
#define FULL_WILDCARD_SEL
Datum iclikejoinsel(PG_FUNCTION_ARGS)
Datum prefixjoinsel(PG_FUNCTION_ARGS)
#define ANY_CHAR_SEL
static double patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate)
Datum regexeqsel(PG_FUNCTION_ARGS)
static Pattern_Prefix_Status pattern_fixed_prefix(Const *patt, Pattern_Type ptype, Oid collation, Const **prefix, Selectivity *rest_selec)
Datum likejoinsel(PG_FUNCTION_ARGS)
static Selectivity like_selectivity(const char *patt, int pattlen, bool case_insensitive)
Datum icregexnejoinsel(PG_FUNCTION_ARGS)
static List * match_pattern_prefix(Node *leftop, Node *rightop, Pattern_Type ptype, Oid expr_coll, Oid opfamily, Oid indexcollation)
Datum nlikejoinsel(PG_FUNCTION_ARGS)
static Datum string_to_datum(const char *str, Oid datatype)
Datum icnlikejoinsel(PG_FUNCTION_ARGS)
static Selectivity regex_selectivity_sub(const char *patt, int pattlen, bool case_insensitive)
Datum texticlike_support(PG_FUNCTION_ARGS)
Datum nlikesel(PG_FUNCTION_ARGS)
static Const * string_to_const(const char *str, Oid datatype)
#define PARTIAL_WILDCARD_SEL
Datum text_starts_with_support(PG_FUNCTION_ARGS)
#define CHAR_RANGE_SEL
static Const * string_to_bytea_const(const char *str, size_t str_len)
static Pattern_Prefix_Status like_fixed_prefix_ci(Const *patt_const, Oid collation, Const **prefix_const, Selectivity *rest_selec)
static Pattern_Prefix_Status regex_fixed_prefix(Const *patt_const, bool case_insensitive, Oid collation, Const **prefix_const, Selectivity *rest_selec)
Pattern_Type
@ Pattern_Type_Prefix
@ Pattern_Type_Regex_IC
@ Pattern_Type_Like
@ Pattern_Type_Regex
@ Pattern_Type_Like_IC
Pattern_Prefix_Status
@ Pattern_Prefix_Partial
@ Pattern_Prefix_None
@ Pattern_Prefix_Exact
static Const * make_greater_string(const Const *str_const, FmgrInfo *ltproc, Oid collation)
Datum icregexeqsel(PG_FUNCTION_ARGS)
#define FIXED_CHAR_SEL
static Pattern_Prefix_Status like_fixed_prefix(Const *patt_const, Const **prefix_const, Selectivity *rest_selec)
Datum regexnejoinsel(PG_FUNCTION_ARGS)
static bool byte_increment(unsigned char *ptr, int len)
static double patternsel_common(PlannerInfo *root, Oid oprid, Oid opfuncid, List *args, int varRelid, Oid collation, Pattern_Type ptype, bool negate)
static Selectivity regex_selectivity(const char *patt, int pattlen, bool case_insensitive, int fixed_prefix_len)
Datum icnlikesel(PG_FUNCTION_ARGS)
Datum textregexeq_support(PG_FUNCTION_ARGS)
Datum prefixsel(PG_FUNCTION_ARGS)
static double patternjoinsel(PG_FUNCTION_ARGS, Pattern_Type ptype, bool negate)
Datum likesel(PG_FUNCTION_ARGS)
Datum regexeqjoinsel(PG_FUNCTION_ARGS)
Datum icregexeqjoinsel(PG_FUNCTION_ARGS)
List * lappend(List *list, void *datum)
Definition list.c:339
RegProcedure get_opcode(Oid opno)
Definition lsyscache.c:1585
bool op_in_opfamily(Oid opno, Oid opfamily)
Definition lsyscache.c:70
Oid get_negator(Oid opno)
Definition lsyscache.c:1847
Expr * make_opclause(Oid opno, Oid opresulttype, bool opretset, Expr *leftop, Expr *rightop, Oid opcollid, Oid inputcollid)
Definition makefuncs.c:701
Const * makeConst(Oid consttype, int32 consttypmod, Oid constcollid, int constlen, Datum constvalue, bool constisnull, bool constbyval)
Definition makefuncs.c:350
unsigned int pg_wchar
Definition mbprint.c:31
mbcharacter_incrementer pg_database_encoding_character_incrementer(void)
Definition mbutils.c:1650
int pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len)
Definition mbutils.c:1019
int pg_mbcliplen(const char *mbstr, int len, int limit)
Definition mbutils.c:1212
int pg_database_encoding_max_length(void)
Definition mbutils.c:1673
int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
Definition mbutils.c:997
void pfree(void *pointer)
Definition mcxt.c:1619
void * palloc(Size size)
Definition mcxt.c:1390
Datum nameout(PG_FUNCTION_ARGS)
Definition name.c:71
Datum namein(PG_FUNCTION_ARGS)
Definition name.c:48
Oid exprType(const Node *expr)
Definition nodeFuncs.c:42
static bool is_opclause(const void *clause)
Definition nodeFuncs.h:76
static bool is_funcclause(const void *clause)
Definition nodeFuncs.h:69
#define IsA(nodeptr, _type_)
Definition nodes.h:162
double Selectivity
Definition nodes.h:258
static char * errmsg
Oid oprid(Operator op)
Definition parse_oper.c:241
#define NAMEDATALEN
const void size_t len
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
#define list_make1(x1)
Definition pg_list.h:244
#define linitial(l)
Definition pg_list.h:178
#define lsecond(l)
Definition pg_list.h:183
bool pg_iswcased(pg_wchar wc, pg_locale_t locale)
Definition pg_locale.c:1615
pg_locale_t pg_newlocale_from_collation(Oid collid)
Definition pg_locale.c:1189
FormData_pg_statistic * Form_pg_statistic
bool(* mbcharacter_incrementer)(unsigned char *mbstr, int len)
Definition pg_wchar.h:223
static bool DatumGetBool(Datum X)
Definition postgres.h:100
static char * DatumGetCString(Datum X)
Definition postgres.h:365
uint64_t Datum
Definition postgres.h:70
static Pointer DatumGetPointer(Datum X)
Definition postgres.h:332
static Datum CStringGetDatum(const char *X)
Definition postgres.h:383
#define PointerGetDatum(X)
Definition postgres.h:354
#define InvalidOid
unsigned int Oid
static int fb(int x)
char * s1
tree ctl root
Definition radixtree.h:1857
char * regexp_fixed_prefix(text *text_re, bool case_insensitive, Oid collation, bool *exact)
Definition regexp.c:2025
bool get_restriction_variable(PlannerInfo *root, List *args, int varRelid, VariableStatData *vardata, Node **other, bool *varonleft)
Definition selfuncs.c:5522
double var_eq_const(VariableStatData *vardata, Oid oproid, Oid collation, Datum constval, bool constisnull, bool varonleft, bool negate)
Definition selfuncs.c:370
double mcv_selectivity(VariableStatData *vardata, FmgrInfo *opproc, Oid collation, Datum constval, bool varonleft, double *sumcommonp)
Definition selfuncs.c:807
double ineq_histogram_selectivity(PlannerInfo *root, VariableStatData *vardata, Oid opoid, FmgrInfo *opproc, bool isgt, bool iseq, Oid collation, Datum constval, Oid consttype)
Definition selfuncs.c:1116
double histogram_selectivity(VariableStatData *vardata, FmgrInfo *opproc, Oid collation, Datum constval, bool varonleft, int min_hist_size, int n_skip, int *hist_size)
Definition selfuncs.c:898
#define ReleaseVariableStats(vardata)
Definition selfuncs.h:101
#define CLAMP_PROBABILITY(p)
Definition selfuncs.h:63
#define DEFAULT_MATCH_SEL
Definition selfuncs.h:46
void check_stack_depth(void)
Definition stack_depth.c:96
Oid consttype
Definition primnodes.h:333
Definition pg_list.h:54
Definition nodes.h:133
Definition c.h:835
#define wpos(wep)
Definition tsrank.c:27
static Size VARSIZE_ANY_EXHDR(const void *PTR)
Definition varatt.h:472
static char * VARDATA(const void *PTR)
Definition varatt.h:305
static char * VARDATA_ANY(const void *PTR)
Definition varatt.h:486
static void SET_VARSIZE(void *PTR, Size len)
Definition varatt.h:432
int varstr_cmp(const char *arg1, int len1, const char *arg2, int len2, Oid collid)
Definition varlena.c:1355

◆ PARTIAL_WILDCARD_SEL

#define PARTIAL_WILDCARD_SEL   2.0

Definition at line 1397 of file like_support.c.

Enumeration Type Documentation

◆ Pattern_Prefix_Status

Enumerator
Pattern_Prefix_None 
Pattern_Prefix_Partial 
Pattern_Prefix_Exact 

Definition at line 67 of file like_support.c.

◆ Pattern_Type

Enumerator
Pattern_Type_Like 
Pattern_Type_Like_IC 
Pattern_Type_Regex 
Pattern_Type_Regex_IC 
Pattern_Type_Prefix 

Definition at line 58 of file like_support.c.

Function Documentation

◆ byte_increment()

static bool byte_increment ( unsigned char ptr,
int  len 
)
static

Definition at line 1575 of file like_support.c.

1576{
1577 if (*ptr >= 255)
1578 return false;
1579 (*ptr)++;
1580 return true;
1581}

Referenced by make_greater_string().

◆ iclikejoinsel()

Datum iclikejoinsel ( PG_FUNCTION_ARGS  )

Definition at line 928 of file like_support.c.

929{
931}

References Pattern_Type_Like_IC, patternjoinsel(), and PG_RETURN_FLOAT8.

◆ iclikesel()

Datum iclikesel ( PG_FUNCTION_ARGS  )

Definition at line 837 of file like_support.c.

838{
840}

References Pattern_Type_Like_IC, patternsel(), and PG_RETURN_FLOAT8.

◆ icnlikejoinsel()

Datum icnlikejoinsel ( PG_FUNCTION_ARGS  )

Definition at line 964 of file like_support.c.

965{
967}

References Pattern_Type_Like_IC, patternjoinsel(), and PG_RETURN_FLOAT8.

◆ icnlikesel()

Datum icnlikesel ( PG_FUNCTION_ARGS  )

Definition at line 873 of file like_support.c.

874{
876}

References Pattern_Type_Like_IC, patternsel(), and PG_RETURN_FLOAT8.

◆ icregexeqjoinsel()

Datum icregexeqjoinsel ( PG_FUNCTION_ARGS  )

Definition at line 901 of file like_support.c.

902{
904}

References Pattern_Type_Regex_IC, patternjoinsel(), and PG_RETURN_FLOAT8.

◆ icregexeqsel()

Datum icregexeqsel ( PG_FUNCTION_ARGS  )

Definition at line 809 of file like_support.c.

810{
812}

References Pattern_Type_Regex_IC, patternsel(), and PG_RETURN_FLOAT8.

◆ icregexnejoinsel()

Datum icregexnejoinsel ( PG_FUNCTION_ARGS  )

Definition at line 946 of file like_support.c.

947{
949}

References Pattern_Type_Regex_IC, patternjoinsel(), and PG_RETURN_FLOAT8.

◆ icregexnesel()

Datum icregexnesel ( PG_FUNCTION_ARGS  )

Definition at line 855 of file like_support.c.

856{
858}

References Pattern_Type_Regex_IC, patternsel(), and PG_RETURN_FLOAT8.

◆ like_fixed_prefix()

static Pattern_Prefix_Status like_fixed_prefix ( Const patt_const,
Const **  prefix_const,
Selectivity rest_selec 
)
static

Definition at line 999 of file like_support.c.

1001{
1002 char *match;
1003 char *patt;
1004 int pattlen;
1005 Oid typeid = patt_const->consttype;
1006 int pos,
1007 match_pos;
1008
1009 /* the right-hand const is type text or bytea */
1010 Assert(typeid == BYTEAOID || typeid == TEXTOID);
1011
1012 if (typeid != BYTEAOID)
1013 {
1014 patt = TextDatumGetCString(patt_const->constvalue);
1015 pattlen = strlen(patt);
1016 }
1017 else
1018 {
1019 bytea *bstr = DatumGetByteaPP(patt_const->constvalue);
1020
1022 patt = (char *) palloc(pattlen);
1024 Assert(bstr == DatumGetPointer(patt_const->constvalue));
1025 }
1026
1027 match = palloc(pattlen + 1);
1028 match_pos = 0;
1029 for (pos = 0; pos < pattlen; pos++)
1030 {
1031 /* % and _ are wildcard characters in LIKE */
1032 if (patt[pos] == '%' ||
1033 patt[pos] == '_')
1034 break;
1035
1036 /* Backslash escapes the next character */
1037 if (patt[pos] == '\\')
1038 {
1039 pos++;
1040 if (pos >= pattlen)
1041 break;
1042 }
1043
1044 match[match_pos++] = patt[pos];
1045 }
1046
1047 match[match_pos] = '\0';
1048
1049 if (typeid != BYTEAOID)
1050 *prefix_const = string_to_const(match, typeid);
1051 else
1053
1054 if (rest_selec != NULL)
1055 *rest_selec = like_selectivity(&patt[pos], pattlen - pos, false);
1056
1057 pfree(patt);
1058 pfree(match);
1059
1060 /* in LIKE, an empty pattern is an exact match! */
1061 if (pos == pattlen)
1062 return Pattern_Prefix_Exact; /* reached end of pattern, so exact */
1063
1064 if (match_pos > 0)
1066
1067 return Pattern_Prefix_None;
1068}

References Assert, DatumGetByteaPP, DatumGetPointer(), fb(), like_selectivity(), memcpy(), palloc(), Pattern_Prefix_Exact, Pattern_Prefix_None, Pattern_Prefix_Partial, pfree(), string_to_bytea_const(), string_to_const(), TextDatumGetCString, VARDATA_ANY(), and VARSIZE_ANY_EXHDR().

Referenced by pattern_fixed_prefix().

◆ like_fixed_prefix_ci()

static Pattern_Prefix_Status like_fixed_prefix_ci ( Const patt_const,
Oid  collation,
Const **  prefix_const,
Selectivity rest_selec 
)
static

Definition at line 1075 of file like_support.c.

1077{
1078 text *val = DatumGetTextPP(patt_const->constvalue);
1079 Oid typeid = patt_const->consttype;
1080 int nbytes = VARSIZE_ANY_EXHDR(val);
1081 int wpos;
1082 pg_wchar *wpatt;
1083 int wpattlen;
1085 int wmatch_pos = 0;
1086 char *match;
1087 int match_mblen;
1088 pg_locale_t locale = 0;
1089
1090 /* the right-hand const is type text or bytea */
1091 Assert(typeid == BYTEAOID || typeid == TEXTOID);
1092
1093 if (typeid == BYTEAOID)
1094 ereport(ERROR,
1096 errmsg("case insensitive matching not supported on type bytea")));
1097
1098 if (!OidIsValid(collation))
1099 {
1100 /*
1101 * This typically means that the parser could not resolve a conflict
1102 * of implicit collations, so report it that way.
1103 */
1104 ereport(ERROR,
1106 errmsg("could not determine which collation to use for ILIKE"),
1107 errhint("Use the COLLATE clause to set the collation explicitly.")));
1108 }
1109
1110 locale = pg_newlocale_from_collation(collation);
1111
1112 wpatt = palloc((nbytes + 1) * sizeof(pg_wchar));
1114
1115 wmatch = palloc((nbytes + 1) * sizeof(pg_wchar));
1116 for (wpos = 0; wpos < wpattlen; wpos++)
1117 {
1118 /* % and _ are wildcard characters in LIKE */
1119 if (wpatt[wpos] == '%' ||
1120 wpatt[wpos] == '_')
1121 break;
1122
1123 /* Backslash escapes the next character */
1124 if (wpatt[wpos] == '\\')
1125 {
1126 wpos++;
1127 if (wpos >= wpattlen)
1128 break;
1129 }
1130
1131 /*
1132 * For ILIKE, stop if it's a case-varying character (it's sort of a
1133 * wildcard).
1134 */
1135 if (pg_iswcased(wpatt[wpos], locale))
1136 break;
1137
1139 }
1140
1141 wmatch[wmatch_pos] = '\0';
1142
1145 match[match_mblen] = '\0';
1146 pfree(wmatch);
1147
1149 pfree(match);
1150
1151 if (rest_selec != NULL)
1152 {
1153 int wrestlen = wpattlen - wpos;
1154 char *rest;
1155 int rest_mblen;
1156
1159
1161 pfree(rest);
1162 }
1163
1164 pfree(wpatt);
1165
1166 /* in LIKE, an empty pattern is an exact match! */
1167 if (wpos == wpattlen)
1168 return Pattern_Prefix_Exact; /* reached end of pattern, so exact */
1169
1170 if (wmatch_pos > 0)
1172
1173 return Pattern_Prefix_None;
1174}

References Assert, DatumGetTextPP, ereport, errcode(), errhint(), errmsg, ERROR, fb(), like_selectivity(), OidIsValid, palloc(), Pattern_Prefix_Exact, Pattern_Prefix_None, Pattern_Prefix_Partial, pfree(), pg_database_encoding_max_length(), pg_iswcased(), pg_mb2wchar_with_len(), pg_newlocale_from_collation(), pg_wchar2mb_with_len(), string_to_const(), val, VARDATA_ANY(), VARSIZE_ANY_EXHDR(), and wpos.

Referenced by pattern_fixed_prefix().

◆ like_regex_support()

static Node * like_regex_support ( Node rawreq,
Pattern_Type  ptype 
)
static

Definition at line 158 of file like_support.c.

159{
160 Node *ret = NULL;
161
163 {
164 /*
165 * Make a selectivity estimate for a function call, just as we'd do if
166 * the call was via the corresponding operator.
167 */
170
171 if (req->is_join)
172 {
173 /*
174 * For the moment we just punt. If patternjoinsel is ever
175 * improved to do better, this should be made to call it.
176 */
178 }
179 else
180 {
181 /* Share code with operator restriction selectivity functions */
182 s1 = patternsel_common(req->root,
184 req->funcid,
185 req->args,
186 req->varRelid,
187 req->inputcollid,
188 ptype,
189 false);
190 }
191 req->selectivity = s1;
192 ret = (Node *) req;
193 }
195 {
196 /* Try to convert operator/function call to index conditions */
198
199 /*
200 * Currently we have no "reverse" match operators with the pattern on
201 * the left, so we only need consider cases with the indexkey on the
202 * left.
203 */
204 if (req->indexarg != 0)
205 return NULL;
206
207 if (is_opclause(req->node))
208 {
209 OpExpr *clause = (OpExpr *) req->node;
210
211 Assert(list_length(clause->args) == 2);
212 ret = (Node *)
213 match_pattern_prefix((Node *) linitial(clause->args),
214 (Node *) lsecond(clause->args),
215 ptype,
216 clause->inputcollid,
217 req->opfamily,
218 req->indexcollation);
219 }
220 else if (is_funcclause(req->node)) /* be paranoid */
221 {
222 FuncExpr *clause = (FuncExpr *) req->node;
223
224 Assert(list_length(clause->args) == 2);
225 ret = (Node *)
226 match_pattern_prefix((Node *) linitial(clause->args),
227 (Node *) lsecond(clause->args),
228 ptype,
229 clause->inputcollid,
230 req->opfamily,
231 req->indexcollation);
232 }
233 }
234
235 return ret;
236}

References FuncExpr::args, OpExpr::args, Assert, DEFAULT_MATCH_SEL, fb(), InvalidOid, is_funcclause(), is_opclause(), IsA, linitial, list_length(), lsecond, match_pattern_prefix(), patternsel_common(), and s1.

Referenced by text_starts_with_support(), texticlike_support(), texticregexeq_support(), textlike_support(), and textregexeq_support().

◆ like_selectivity()

static Selectivity like_selectivity ( const char patt,
int  pattlen,
bool  case_insensitive 
)
static

Definition at line 1400 of file like_support.c.

1401{
1402 Selectivity sel = 1.0;
1403 int pos;
1404
1405 /* Skip any leading wildcard; it's already factored into initial sel */
1406 for (pos = 0; pos < pattlen; pos++)
1407 {
1408 if (patt[pos] != '%' && patt[pos] != '_')
1409 break;
1410 }
1411
1412 for (; pos < pattlen; pos++)
1413 {
1414 /* % and _ are wildcard characters in LIKE */
1415 if (patt[pos] == '%')
1417 else if (patt[pos] == '_')
1418 sel *= ANY_CHAR_SEL;
1419 else if (patt[pos] == '\\')
1420 {
1421 /* Backslash quotes the next character */
1422 pos++;
1423 if (pos >= pattlen)
1424 break;
1426 }
1427 else
1429 }
1430 /* Could get sel > 1 if multiple wildcards */
1431 if (sel > 1.0)
1432 sel = 1.0;
1433 return sel;
1434}

References ANY_CHAR_SEL, fb(), FIXED_CHAR_SEL, and FULL_WILDCARD_SEL.

Referenced by like_fixed_prefix(), and like_fixed_prefix_ci().

◆ likejoinsel()

Datum likejoinsel ( PG_FUNCTION_ARGS  )

Definition at line 910 of file like_support.c.

911{
913}

References Pattern_Type_Like, patternjoinsel(), and PG_RETURN_FLOAT8.

◆ likesel()

Datum likesel ( PG_FUNCTION_ARGS  )

Definition at line 818 of file like_support.c.

819{
821}

References Pattern_Type_Like, patternsel(), and PG_RETURN_FLOAT8.

◆ make_greater_string()

static Const * make_greater_string ( const Const str_const,
FmgrInfo ltproc,
Oid  collation 
)
static

Definition at line 1625 of file like_support.c.

1626{
1627 Oid datatype = str_const->consttype;
1628 char *workstr;
1629 int len;
1630 Datum cmpstr;
1631 char *cmptxt = NULL;
1633
1634 /*
1635 * Get a modifiable copy of the prefix string in C-string format, and set
1636 * up the string we will compare to as a Datum. In C locale this can just
1637 * be the given prefix string, otherwise we need to add a suffix. Type
1638 * BYTEA sorts bytewise so it never needs a suffix either.
1639 */
1640 if (datatype == BYTEAOID)
1641 {
1642 bytea *bstr = DatumGetByteaPP(str_const->constvalue);
1643
1645 workstr = (char *) palloc(len);
1647 Assert(bstr == DatumGetPointer(str_const->constvalue));
1648 cmpstr = str_const->constvalue;
1649 }
1650 else
1651 {
1652 if (datatype == NAMEOID)
1654 str_const->constvalue));
1655 else
1656 workstr = TextDatumGetCString(str_const->constvalue);
1657 len = strlen(workstr);
1658 if (len == 0 || pg_newlocale_from_collation(collation)->collate_is_c)
1659 cmpstr = str_const->constvalue;
1660 else
1661 {
1662 /* If first time through, determine the suffix to use */
1663 static char suffixchar = 0;
1664 static Oid suffixcollation = 0;
1665
1666 if (!suffixchar || suffixcollation != collation)
1667 {
1668 char *best;
1669
1670 best = "Z";
1671 if (varstr_cmp(best, 1, "z", 1, collation) < 0)
1672 best = "z";
1673 if (varstr_cmp(best, 1, "y", 1, collation) < 0)
1674 best = "y";
1675 if (varstr_cmp(best, 1, "9", 1, collation) < 0)
1676 best = "9";
1677 suffixchar = *best;
1678 suffixcollation = collation;
1679 }
1680
1681 /* And build the string to compare to */
1682 if (datatype == NAMEOID)
1683 {
1684 cmptxt = palloc(len + 2);
1687 cmptxt[len + 1] = '\0';
1689 }
1690 else
1691 {
1692 cmptxt = palloc(VARHDRSZ + len + 1);
1695 *(VARDATA(cmptxt) + len) = suffixchar;
1697 }
1698 }
1699 }
1700
1701 /* Select appropriate character-incrementer function */
1702 if (datatype == BYTEAOID)
1704 else
1706
1707 /* And search ... */
1708 while (len > 0)
1709 {
1710 int charlen;
1711 unsigned char *lastchar;
1712
1713 /* Identify the last character --- for bytea, just the last byte */
1714 if (datatype == BYTEAOID)
1715 charlen = 1;
1716 else
1717 charlen = len - pg_mbcliplen(workstr, len, len - 1);
1718 lastchar = (unsigned char *) (workstr + len - charlen);
1719
1720 /*
1721 * Try to generate a larger string by incrementing the last character
1722 * (for BYTEA, we treat each byte as a character).
1723 *
1724 * Note: the incrementer function is expected to return true if it's
1725 * generated a valid-per-the-encoding new character, otherwise false.
1726 * The contents of the character on false return are unspecified.
1727 */
1728 while (charinc(lastchar, charlen))
1729 {
1731
1732 if (datatype == BYTEAOID)
1734 else
1736
1738 collation,
1739 cmpstr,
1740 workstr_const->constvalue)))
1741 {
1742 /* Successfully made a string larger than cmpstr */
1743 if (cmptxt)
1744 pfree(cmptxt);
1745 pfree(workstr);
1746 return workstr_const;
1747 }
1748
1749 /* No good, release unusable value and try again */
1750 pfree(DatumGetPointer(workstr_const->constvalue));
1752 }
1753
1754 /*
1755 * No luck here, so truncate off the last character and try to
1756 * increment the next one.
1757 */
1758 len -= charlen;
1759 workstr[len] = '\0';
1760 }
1761
1762 /* Failed... */
1763 if (cmptxt)
1764 pfree(cmptxt);
1765 pfree(workstr);
1766
1767 return NULL;
1768}

References Assert, byte_increment(), Const::consttype, DatumGetBool(), DatumGetByteaPP, DatumGetCString(), DatumGetPointer(), DirectFunctionCall1, fb(), FunctionCall2Coll(), len, memcpy(), nameout(), palloc(), pfree(), pg_database_encoding_character_incrementer(), pg_mbcliplen(), pg_newlocale_from_collation(), PointerGetDatum, SET_VARSIZE(), string_to_bytea_const(), string_to_const(), TextDatumGetCString, VARDATA(), VARDATA_ANY(), VARHDRSZ, VARSIZE_ANY_EXHDR(), and varstr_cmp().

Referenced by match_pattern_prefix(), and prefix_selectivity().

◆ match_pattern_prefix()

static List * match_pattern_prefix ( Node leftop,
Node rightop,
Pattern_Type  ptype,
Oid  expr_coll,
Oid  opfamily,
Oid  indexcollation 
)
static

Definition at line 243 of file like_support.c.

249{
250 List *result;
251 Const *patt;
252 Const *prefix;
253 Pattern_Prefix_Status pstatus;
256 Oid eqopr;
257 Oid ltopr;
258 Oid geopr;
260 bool collation_aware;
261 Expr *expr;
264
265 /*
266 * Can't do anything with a non-constant or NULL pattern argument.
267 *
268 * Note that since we restrict ourselves to cases with a hard constant on
269 * the RHS, it's a-fortiori a pseudoconstant, and we don't need to worry
270 * about verifying that.
271 */
272 if (!IsA(rightop, Const) ||
274 return NIL;
275 patt = (Const *) rightop;
276
277 /*
278 * Try to extract a fixed prefix from the pattern.
279 */
280 pstatus = pattern_fixed_prefix(patt, ptype, expr_coll,
281 &prefix, NULL);
282
283 /* fail if no fixed prefix */
284 if (pstatus == Pattern_Prefix_None)
285 return NIL;
286
287 /*
288 * Identify the operators we want to use, based on the type of the
289 * left-hand argument. Usually these are just the type's regular
290 * comparison operators, but if we are considering one of the semi-legacy
291 * "pattern" opclasses, use the "pattern" operators instead. Those are
292 * not collation-sensitive but always use C collation, as we want. The
293 * selected operators also determine the needed type of the prefix
294 * constant.
295 */
297 switch (ldatatype)
298 {
299 case TEXTOID:
300 if (opfamily == TEXT_PATTERN_BTREE_FAM_OID)
301 {
302 eqopr = TextEqualOperator;
305 collation_aware = false;
306 }
307 else if (opfamily == TEXT_SPGIST_FAM_OID)
308 {
309 eqopr = TextEqualOperator;
312 /* This opfamily has direct support for prefixing */
314 collation_aware = false;
315 }
316 else
317 {
318 eqopr = TextEqualOperator;
319 ltopr = TextLessOperator;
321 collation_aware = true;
322 }
324 break;
325 case NAMEOID:
326
327 /*
328 * Note that here, we need the RHS type to be text, so that the
329 * comparison value isn't improperly truncated to NAMEDATALEN.
330 */
331 eqopr = NameEqualTextOperator;
332 ltopr = NameLessTextOperator;
334 collation_aware = true;
336 break;
337 case BPCHAROID:
338 if (opfamily == BPCHAR_PATTERN_BTREE_FAM_OID)
339 {
340 eqopr = BpcharEqualOperator;
343 collation_aware = false;
344 }
345 else
346 {
347 eqopr = BpcharEqualOperator;
348 ltopr = BpcharLessOperator;
350 collation_aware = true;
351 }
353 break;
354 case BYTEAOID:
355 eqopr = ByteaEqualOperator;
356 ltopr = ByteaLessOperator;
358 collation_aware = false;
360 break;
361 default:
362 /* Can't get here unless we're attached to the wrong operator */
363 return NIL;
364 }
365
366 /*
367 * If necessary, coerce the prefix constant to the right type. The given
368 * prefix constant is either text or bytea type, therefore the only case
369 * where we need to do anything is when converting text to bpchar. Those
370 * two types are binary-compatible, so relabeling the Const node is
371 * sufficient.
372 */
373 if (prefix->consttype != rdatatype)
374 {
375 Assert(prefix->consttype == TEXTOID &&
377 prefix->consttype = rdatatype;
378 }
379
380 /*
381 * If we found an exact-match pattern, generate an "=" indexqual.
382 *
383 * Here and below, check to see whether the desired operator is actually
384 * supported by the index opclass, and fail quietly if not. This allows
385 * us to not be concerned with specific opclasses (except for the legacy
386 * "pattern" cases); any index that correctly implements the operators
387 * will work.
388 *
389 * This case will work for LIKE/regex expressions with nondeterministic
390 * collation, so long as the index's collation is the same. If the
391 * expression's collation is deterministic, we can even use an index whose
392 * collation differs from the expression's. All deterministic collations
393 * agree on equality (it's bitwise), while we assume that an index with
394 * nondeterministic collation will return a superset of the bitwise-equal
395 * entries. Since the "=" indexqual is marked as lossy by default, we'll
396 * apply the LIKE/regex operator as a recheck, and that will filter out
397 * any non-matching entries.
398 */
399 if (pstatus == Pattern_Prefix_Exact)
400 {
401 if (!op_in_opfamily(eqopr, opfamily))
402 return NIL;
403 if (indexcollation != expr_coll && NONDETERMINISTIC(expr_coll))
404 return NIL;
405 expr = make_opclause(eqopr, BOOLOID, false,
406 (Expr *) leftop, (Expr *) prefix,
407 InvalidOid, indexcollation);
408 result = list_make1(expr);
409 return result;
410 }
411
412 /*
413 * Anything other than Pattern_Prefix_Exact is not supported if the
414 * expression collation is nondeterministic. The optimized equality or
415 * prefix tests use bytewise comparisons, which is not consistent with
416 * nondeterministic collations.
417 */
419 return NIL;
420
421 /*
422 * Otherwise, we have a nonempty required prefix of the values. Some
423 * opclasses support prefix checks directly, otherwise we'll try to
424 * generate a range constraint.
425 */
426 if (OidIsValid(preopr) && op_in_opfamily(preopr, opfamily))
427 {
428 expr = make_opclause(preopr, BOOLOID, false,
429 (Expr *) leftop, (Expr *) prefix,
430 InvalidOid, indexcollation);
431 result = list_make1(expr);
432 return result;
433 }
434
435 /*
436 * Since we need a range constraint, it's only going to work reliably if
437 * the index is collation-insensitive or has "C" collation. Note that
438 * here we are looking at the index's collation, not the expression's
439 * collation -- this test is *not* dependent on the LIKE/regex operator's
440 * collation.
441 */
442 if (collation_aware &&
443 !pg_newlocale_from_collation(indexcollation)->collate_is_c)
444 return NIL;
445
446 /*
447 * We can always say "x >= prefix".
448 */
449 if (!op_in_opfamily(geopr, opfamily))
450 return NIL;
451 expr = make_opclause(geopr, BOOLOID, false,
452 (Expr *) leftop, (Expr *) prefix,
453 InvalidOid, indexcollation);
454 result = list_make1(expr);
455
456 /*-------
457 * If we can create a string larger than the prefix, we can say
458 * "x < greaterstr". NB: we rely on make_greater_string() to generate
459 * a guaranteed-greater string, not just a probably-greater string.
460 * In general this is only guaranteed in C locale, so we'd better be
461 * using a C-locale index collation.
462 *-------
463 */
464 if (!op_in_opfamily(ltopr, opfamily))
465 return result;
466 fmgr_info(get_opcode(ltopr), &ltproc);
467 greaterstr = make_greater_string(prefix, &ltproc, indexcollation);
468 if (greaterstr)
469 {
470 expr = make_opclause(ltopr, BOOLOID, false,
471 (Expr *) leftop, (Expr *) greaterstr,
472 InvalidOid, indexcollation);
473 result = lappend(result, expr);
474 }
475
476 return result;
477}

References Assert, Const::consttype, exprType(), fb(), fmgr_info(), get_opcode(), InvalidOid, IsA, lappend(), list_make1, make_greater_string(), make_opclause(), NIL, NONDETERMINISTIC, OidIsValid, op_in_opfamily(), pattern_fixed_prefix(), Pattern_Prefix_Exact, Pattern_Prefix_None, pg_newlocale_from_collation(), and result.

Referenced by like_regex_support().

◆ nlikejoinsel()

Datum nlikejoinsel ( PG_FUNCTION_ARGS  )

Definition at line 955 of file like_support.c.

956{
958}

References Pattern_Type_Like, patternjoinsel(), and PG_RETURN_FLOAT8.

◆ nlikesel()

Datum nlikesel ( PG_FUNCTION_ARGS  )

Definition at line 864 of file like_support.c.

865{
867}

References Pattern_Type_Like, patternsel(), and PG_RETURN_FLOAT8.

◆ pattern_fixed_prefix()

static Pattern_Prefix_Status pattern_fixed_prefix ( Const patt,
Pattern_Type  ptype,
Oid  collation,
Const **  prefix,
Selectivity rest_selec 
)
static

Definition at line 1245 of file like_support.c.

1247{
1249
1250 switch (ptype)
1251 {
1252 case Pattern_Type_Like:
1254 break;
1256 result = like_fixed_prefix_ci(patt, collation, prefix,
1257 rest_selec);
1258 break;
1259 case Pattern_Type_Regex:
1260 result = regex_fixed_prefix(patt, false, collation,
1261 prefix, rest_selec);
1262 break;
1264 result = regex_fixed_prefix(patt, true, collation,
1265 prefix, rest_selec);
1266 break;
1268 /* Prefix type work is trivial. */
1270 *prefix = makeConst(patt->consttype,
1271 patt->consttypmod,
1272 patt->constcollid,
1273 patt->constlen,
1274 datumCopy(patt->constvalue,
1275 patt->constbyval,
1276 patt->constlen),
1277 patt->constisnull,
1278 patt->constbyval);
1279 if (rest_selec != NULL)
1280 *rest_selec = 1.0; /* all */
1281 break;
1282 default:
1283 elog(ERROR, "unrecognized ptype: %d", (int) ptype);
1284 result = Pattern_Prefix_None; /* keep compiler quiet */
1285 break;
1286 }
1287 return result;
1288}

References datumCopy(), elog, ERROR, fb(), like_fixed_prefix(), like_fixed_prefix_ci(), makeConst(), Pattern_Prefix_None, Pattern_Prefix_Partial, Pattern_Type_Like, Pattern_Type_Like_IC, Pattern_Type_Prefix, Pattern_Type_Regex, Pattern_Type_Regex_IC, regex_fixed_prefix(), and result.

Referenced by match_pattern_prefix(), and patternsel_common().

◆ patternjoinsel()

static double patternjoinsel ( PG_FUNCTION_ARGS  ,
Pattern_Type  ptype,
bool  negate 
)
static

Definition at line 882 of file like_support.c.

883{
884 /* For the moment we just punt. */
885 return negate ? (1.0 - DEFAULT_MATCH_SEL) : DEFAULT_MATCH_SEL;
886}

References DEFAULT_MATCH_SEL.

Referenced by iclikejoinsel(), icnlikejoinsel(), icregexeqjoinsel(), icregexnejoinsel(), likejoinsel(), nlikejoinsel(), prefixjoinsel(), regexeqjoinsel(), and regexnejoinsel().

◆ patternsel()

static double patternsel ( PG_FUNCTION_ARGS  ,
Pattern_Type  ptype,
bool  negate 
)
static

Definition at line 767 of file like_support.c.

768{
770 Oid operator = PG_GETARG_OID(1);
772 int varRelid = PG_GETARG_INT32(3);
773 Oid collation = PG_GET_COLLATION();
774
775 /*
776 * If this is for a NOT LIKE or similar operator, get the corresponding
777 * positive-match operator and work with that.
778 */
779 if (negate)
780 {
781 operator = get_negator(operator);
782 if (!OidIsValid(operator))
783 elog(ERROR, "patternsel called for operator without a negator");
784 }
785
786 return patternsel_common(root,
787 operator,
789 args,
790 varRelid,
791 collation,
792 ptype,
793 negate);
794}

References elog, ERROR, get_negator(), InvalidOid, OidIsValid, patternsel_common(), PG_GET_COLLATION, PG_GETARG_INT32, PG_GETARG_OID, PG_GETARG_POINTER, and root.

Referenced by iclikesel(), icnlikesel(), icregexeqsel(), icregexnesel(), likesel(), nlikesel(), prefixsel(), regexeqsel(), and regexnesel().

◆ patternsel_common()

static double patternsel_common ( PlannerInfo root,
Oid  oprid,
Oid  opfuncid,
List args,
int  varRelid,
Oid  collation,
Pattern_Type  ptype,
bool  negate 
)
static

Definition at line 493 of file like_support.c.

501{
503 Node *other;
504 bool varonleft;
505 Datum constval;
506 Oid consttype;
507 Oid vartype;
509 Oid eqopr;
510 Oid ltopr;
511 Oid geopr;
512 Pattern_Prefix_Status pstatus;
513 Const *patt;
514 Const *prefix = NULL;
516 double nullfrac = 0.0;
517 double result;
518
519 /*
520 * Initialize result to the appropriate default estimate depending on
521 * whether it's a match or not-match operator.
522 */
523 if (negate)
525 else
527
528 /*
529 * If expression is not variable op constant, then punt and return the
530 * default estimate.
531 */
532 if (!get_restriction_variable(root, args, varRelid,
533 &vardata, &other, &varonleft))
534 return result;
535 if (!varonleft || !IsA(other, Const))
536 {
538 return result;
539 }
540
541 /*
542 * If the constant is NULL, assume operator is strict and return zero, ie,
543 * operator will never return TRUE. (It's zero even for a negator op.)
544 */
545 if (((Const *) other)->constisnull)
546 {
548 return 0.0;
549 }
550 constval = ((Const *) other)->constvalue;
551 consttype = ((Const *) other)->consttype;
552
553 /*
554 * The right-hand const is type text or bytea for all supported operators.
555 * We do not expect to see binary-compatible types here, since
556 * const-folding should have relabeled the const to exactly match the
557 * operator's declared type.
558 */
559 if (consttype != TEXTOID && consttype != BYTEAOID)
560 {
562 return result;
563 }
564
565 /*
566 * Similarly, the exposed type of the left-hand side should be one of
567 * those we know. (Do not look at vardata.atttype, which might be
568 * something binary-compatible but different.) We can use it to identify
569 * the comparison operators and the required type of the comparison
570 * constant, much as in match_pattern_prefix().
571 */
572 vartype = vardata.vartype;
573
574 switch (vartype)
575 {
576 case TEXTOID:
577 eqopr = TextEqualOperator;
578 ltopr = TextLessOperator;
581 break;
582 case NAMEOID:
583
584 /*
585 * Note that here, we need the RHS type to be text, so that the
586 * comparison value isn't improperly truncated to NAMEDATALEN.
587 */
588 eqopr = NameEqualTextOperator;
589 ltopr = NameLessTextOperator;
592 break;
593 case BPCHAROID:
594 eqopr = BpcharEqualOperator;
595 ltopr = BpcharLessOperator;
598 break;
599 case BYTEAOID:
600 eqopr = ByteaEqualOperator;
601 ltopr = ByteaLessOperator;
604 break;
605 default:
606 /* Can't get here unless we're attached to the wrong operator */
608 return result;
609 }
610
611 /*
612 * Grab the nullfrac for use below.
613 */
614 if (HeapTupleIsValid(vardata.statsTuple))
615 {
616 Form_pg_statistic stats;
617
618 stats = (Form_pg_statistic) GETSTRUCT(vardata.statsTuple);
619 nullfrac = stats->stanullfrac;
620 }
621
622 /*
623 * Pull out any fixed prefix implied by the pattern, and estimate the
624 * fractional selectivity of the remainder of the pattern. Unlike many
625 * other selectivity estimators, we use the pattern operator's actual
626 * collation for this step. This is not because we expect the collation
627 * to make a big difference in the selectivity estimate (it seldom would),
628 * but because we want to be sure we cache compiled regexps under the
629 * right cache key, so that they can be re-used at runtime.
630 */
631 patt = (Const *) other;
632 pstatus = pattern_fixed_prefix(patt, ptype, collation,
633 &prefix, &rest_selec);
634
635 /*
636 * If necessary, coerce the prefix constant to the right type. The only
637 * case where we need to do anything is when converting text to bpchar.
638 * Those two types are binary-compatible, so relabeling the Const node is
639 * sufficient.
640 */
641 if (prefix && prefix->consttype != rdatatype)
642 {
643 Assert(prefix->consttype == TEXTOID &&
645 prefix->consttype = rdatatype;
646 }
647
648 if (pstatus == Pattern_Prefix_Exact)
649 {
650 /*
651 * Pattern specifies an exact match, so estimate as for '='
652 */
653 result = var_eq_const(&vardata, eqopr, collation, prefix->constvalue,
654 false, true, false);
655 }
656 else
657 {
658 /*
659 * Not exact-match pattern. If we have a sufficiently large
660 * histogram, estimate selectivity for the histogram part of the
661 * population by counting matches in the histogram. If not, estimate
662 * selectivity of the fixed prefix and remainder of pattern
663 * separately, then combine the two to get an estimate of the
664 * selectivity for the part of the column population represented by
665 * the histogram. (For small histograms, we combine these
666 * approaches.)
667 *
668 * We then add up data for any most-common-values values; these are
669 * not in the histogram population, and we can get exact answers for
670 * them by applying the pattern operator, so there's no reason to
671 * approximate. (If the MCVs cover a significant part of the total
672 * population, this gives us a big leg up in accuracy.)
673 */
675 int hist_size;
677 double mcv_selec,
678 sumcommon;
679
680 /* Try to use the histogram entries to get selectivity */
681 if (!OidIsValid(opfuncid))
684
686 constval, true,
687 10, 1, &hist_size);
688
689 /* If not at least 100 entries, use the heuristic method */
690 if (hist_size < 100)
691 {
694
695 if (pstatus == Pattern_Prefix_Partial)
697 eqopr, ltopr, geopr,
698 collation,
699 prefix);
700 else
701 prefixsel = 1.0;
703
704 if (selec < 0) /* fewer than 10 histogram entries? */
705 selec = heursel;
706 else
707 {
708 /*
709 * For histogram sizes from 10 to 100, we combine the
710 * histogram and heuristic selectivities, putting increasingly
711 * more trust in the histogram for larger sizes.
712 */
713 double hist_weight = hist_size / 100.0;
714
715 selec = selec * hist_weight + heursel * (1.0 - hist_weight);
716 }
717 }
718
719 /* In any case, don't believe extremely small or large estimates. */
720 if (selec < 0.0001)
721 selec = 0.0001;
722 else if (selec > 0.9999)
723 selec = 0.9999;
724
725 /*
726 * If we have most-common-values info, add up the fractions of the MCV
727 * entries that satisfy MCV OP PATTERN. These fractions contribute
728 * directly to the result selectivity. Also add up the total fraction
729 * represented by MCV entries.
730 */
731 mcv_selec = mcv_selectivity(&vardata, &opproc, collation,
732 constval, true,
733 &sumcommon);
734
735 /*
736 * Now merge the results from the MCV and histogram calculations,
737 * realizing that the histogram covers only the non-null values that
738 * are not listed in MCV.
739 */
740 selec *= 1.0 - nullfrac - sumcommon;
741 selec += mcv_selec;
742 result = selec;
743 }
744
745 /* now adjust if we wanted not-match rather than match */
746 if (negate)
747 result = 1.0 - result - nullfrac;
748
749 /* result should be in range, but make sure... */
751
752 if (prefix)
753 {
754 pfree(DatumGetPointer(prefix->constvalue));
755 pfree(prefix);
756 }
757
759
760 return result;
761}

References Assert, CLAMP_PROBABILITY, Const::consttype, DatumGetPointer(), DEFAULT_MATCH_SEL, fb(), fmgr_info(), get_opcode(), get_restriction_variable(), GETSTRUCT(), HeapTupleIsValid, histogram_selectivity(), IsA, mcv_selectivity(), OidIsValid, oprid(), pattern_fixed_prefix(), Pattern_Prefix_Exact, Pattern_Prefix_Partial, pfree(), prefix_selectivity(), prefixsel(), ReleaseVariableStats, result, root, and var_eq_const().

Referenced by like_regex_support(), and patternsel().

◆ prefix_selectivity()

static Selectivity prefix_selectivity ( PlannerInfo root,
VariableStatData vardata,
Oid  eqopr,
Oid  ltopr,
Oid  geopr,
Oid  collation,
Const prefixcon 
)
static

Definition at line 1309 of file like_support.c.

1313{
1318
1319 /* Estimate the selectivity of "x >= prefix" */
1321
1323 geopr, &opproc, true, true,
1324 collation,
1325 prefixcon->constvalue,
1326 prefixcon->consttype);
1327
1328 if (prefixsel < 0.0)
1329 {
1330 /* No histogram is present ... return a suitable default estimate */
1331 return DEFAULT_MATCH_SEL;
1332 }
1333
1334 /*
1335 * If we can create a string larger than the prefix, say "x < greaterstr".
1336 */
1337 fmgr_info(get_opcode(ltopr), &opproc);
1339 if (greaterstrcon)
1340 {
1342
1344 ltopr, &opproc, false, false,
1345 collation,
1346 greaterstrcon->constvalue,
1347 greaterstrcon->consttype);
1348
1349 /* ineq_histogram_selectivity worked before, it shouldn't fail now */
1350 Assert(topsel >= 0.0);
1351
1352 /*
1353 * Merge the two selectivities in the same way as for a range query
1354 * (see clauselist_selectivity()). Note that we don't need to worry
1355 * about double-exclusion of nulls, since ineq_histogram_selectivity
1356 * doesn't count those anyway.
1357 */
1358 prefixsel = topsel + prefixsel - 1.0;
1359 }
1360
1361 /*
1362 * If the prefix is long then the two bounding values might be too close
1363 * together for the histogram to distinguish them usefully, resulting in a
1364 * zero estimate (plus or minus roundoff error). To avoid returning a
1365 * ridiculously small estimate, compute the estimated selectivity for
1366 * "variable = 'foo'", and clamp to that. (Obviously, the resultant
1367 * estimate should be at least that.)
1368 *
1369 * We apply this even if we couldn't make a greater string. That case
1370 * suggests that the prefix is near the maximum possible, and thus
1371 * probably off the end of the histogram, and thus we probably got a very
1372 * small estimate from the >= condition; so we still need to clamp.
1373 */
1374 eq_sel = var_eq_const(vardata, eqopr, collation, prefixcon->constvalue,
1375 false, true, false);
1376
1378
1379 return prefixsel;
1380}

References Assert, DEFAULT_MATCH_SEL, fb(), fmgr_info(), get_opcode(), ineq_histogram_selectivity(), make_greater_string(), Max, prefixsel(), root, and var_eq_const().

Referenced by patternsel_common().

◆ prefixjoinsel()

Datum prefixjoinsel ( PG_FUNCTION_ARGS  )

Definition at line 919 of file like_support.c.

920{
922}

References Pattern_Type_Prefix, patternjoinsel(), and PG_RETURN_FLOAT8.

◆ prefixsel()

Datum prefixsel ( PG_FUNCTION_ARGS  )

◆ regex_fixed_prefix()

static Pattern_Prefix_Status regex_fixed_prefix ( Const patt_const,
bool  case_insensitive,
Oid  collation,
Const **  prefix_const,
Selectivity rest_selec 
)
static

Definition at line 1177 of file like_support.c.

1179{
1180 Oid typeid = patt_const->consttype;
1181 char *prefix;
1182 bool exact;
1183
1184 /*
1185 * Should be unnecessary, there are no bytea regex operators defined. As
1186 * such, it should be noted that the rest of this function has *not* been
1187 * made safe for binary (possibly NULL containing) strings.
1188 */
1189 if (typeid == BYTEAOID)
1190 ereport(ERROR,
1192 errmsg("regular-expression matching not supported on type bytea")));
1193
1194 /* Use the regexp machinery to extract the prefix, if any */
1195 prefix = regexp_fixed_prefix(DatumGetTextPP(patt_const->constvalue),
1196 case_insensitive, collation,
1197 &exact);
1198
1199 if (prefix == NULL)
1200 {
1201 *prefix_const = NULL;
1202
1203 if (rest_selec != NULL)
1204 {
1205 char *patt = TextDatumGetCString(patt_const->constvalue);
1206
1209 0);
1210 pfree(patt);
1211 }
1212
1213 return Pattern_Prefix_None;
1214 }
1215
1216 *prefix_const = string_to_const(prefix, typeid);
1217
1218 if (rest_selec != NULL)
1219 {
1220 if (exact)
1221 {
1222 /* Exact match, so there's no additional selectivity */
1223 *rest_selec = 1.0;
1224 }
1225 else
1226 {
1227 char *patt = TextDatumGetCString(patt_const->constvalue);
1228
1231 strlen(prefix));
1232 pfree(patt);
1233 }
1234 }
1235
1236 pfree(prefix);
1237
1238 if (exact)
1239 return Pattern_Prefix_Exact; /* pattern specifies exact match */
1240 else
1242}

References DatumGetTextPP, ereport, errcode(), errmsg, ERROR, fb(), Pattern_Prefix_Exact, Pattern_Prefix_None, Pattern_Prefix_Partial, pfree(), regex_selectivity(), regexp_fixed_prefix(), string_to_const(), and TextDatumGetCString.

Referenced by pattern_fixed_prefix().

◆ regex_selectivity()

static Selectivity regex_selectivity ( const char patt,
int  pattlen,
bool  case_insensitive,
int  fixed_prefix_len 
)
static

Definition at line 1532 of file like_support.c.

1534{
1536
1537 /* If patt doesn't end with $, consider it to have a trailing wildcard */
1538 if (pattlen > 0 && patt[pattlen - 1] == '$' &&
1539 (pattlen == 1 || patt[pattlen - 2] != '\\'))
1540 {
1541 /* has trailing $ */
1543 }
1544 else
1545 {
1546 /* no trailing $ */
1549 }
1550
1551 /*
1552 * If there's a fixed prefix, discount its selectivity. We have to be
1553 * careful here since a very long prefix could result in pow's result
1554 * underflowing to zero (in which case "sel" probably has as well).
1555 */
1556 if (fixed_prefix_len > 0)
1557 {
1559
1560 if (prefixsel > 0.0)
1561 sel /= prefixsel;
1562 }
1563
1564 /* Make sure result stays in range */
1566 return sel;
1567}

References CLAMP_PROBABILITY, fb(), FIXED_CHAR_SEL, FULL_WILDCARD_SEL, prefixsel(), and regex_selectivity_sub().

Referenced by regex_fixed_prefix().

◆ regex_selectivity_sub()

static Selectivity regex_selectivity_sub ( const char patt,
int  pattlen,
bool  case_insensitive 
)
static

Definition at line 1437 of file like_support.c.

1438{
1439 Selectivity sel = 1.0;
1440 int paren_depth = 0;
1441 int paren_pos = 0; /* dummy init to keep compiler quiet */
1442 int pos;
1443
1444 /* since this function recurses, it could be driven to stack overflow */
1446
1447 for (pos = 0; pos < pattlen; pos++)
1448 {
1449 if (patt[pos] == '(')
1450 {
1451 if (paren_depth == 0)
1452 paren_pos = pos; /* remember start of parenthesized item */
1453 paren_depth++;
1454 }
1455 else if (patt[pos] == ')' && paren_depth > 0)
1456 {
1457 paren_depth--;
1458 if (paren_depth == 0)
1460 pos - (paren_pos + 1),
1462 }
1463 else if (patt[pos] == '|' && paren_depth == 0)
1464 {
1465 /*
1466 * If unquoted | is present at paren level 0 in pattern, we have
1467 * multiple alternatives; sum their probabilities.
1468 */
1469 sel += regex_selectivity_sub(patt + (pos + 1),
1470 pattlen - (pos + 1),
1472 break; /* rest of pattern is now processed */
1473 }
1474 else if (patt[pos] == '[')
1475 {
1476 bool negclass = false;
1477
1478 if (patt[++pos] == '^')
1479 {
1480 negclass = true;
1481 pos++;
1482 }
1483 if (patt[pos] == ']') /* ']' at start of class is not special */
1484 pos++;
1485 while (pos < pattlen && patt[pos] != ']')
1486 pos++;
1487 if (paren_depth == 0)
1488 sel *= (negclass ? (1.0 - CHAR_RANGE_SEL) : CHAR_RANGE_SEL);
1489 }
1490 else if (patt[pos] == '.')
1491 {
1492 if (paren_depth == 0)
1493 sel *= ANY_CHAR_SEL;
1494 }
1495 else if (patt[pos] == '*' ||
1496 patt[pos] == '?' ||
1497 patt[pos] == '+')
1498 {
1499 /* Ought to be smarter about quantifiers... */
1500 if (paren_depth == 0)
1502 }
1503 else if (patt[pos] == '{')
1504 {
1505 while (pos < pattlen && patt[pos] != '}')
1506 pos++;
1507 if (paren_depth == 0)
1509 }
1510 else if (patt[pos] == '\\')
1511 {
1512 /* backslash quotes the next character */
1513 pos++;
1514 if (pos >= pattlen)
1515 break;
1516 if (paren_depth == 0)
1518 }
1519 else
1520 {
1521 if (paren_depth == 0)
1523 }
1524 }
1525 /* Could get sel > 1 if multiple wildcards */
1526 if (sel > 1.0)
1527 sel = 1.0;
1528 return sel;
1529}

References ANY_CHAR_SEL, CHAR_RANGE_SEL, check_stack_depth(), fb(), FIXED_CHAR_SEL, PARTIAL_WILDCARD_SEL, and regex_selectivity_sub().

Referenced by regex_selectivity(), and regex_selectivity_sub().

◆ regexeqjoinsel()

Datum regexeqjoinsel ( PG_FUNCTION_ARGS  )

Definition at line 892 of file like_support.c.

893{
895}

References Pattern_Type_Regex, patternjoinsel(), and PG_RETURN_FLOAT8.

◆ regexeqsel()

Datum regexeqsel ( PG_FUNCTION_ARGS  )

Definition at line 800 of file like_support.c.

801{
803}

References Pattern_Type_Regex, patternsel(), and PG_RETURN_FLOAT8.

◆ regexnejoinsel()

Datum regexnejoinsel ( PG_FUNCTION_ARGS  )

Definition at line 937 of file like_support.c.

938{
940}

References Pattern_Type_Regex, patternjoinsel(), and PG_RETURN_FLOAT8.

◆ regexnesel()

Datum regexnesel ( PG_FUNCTION_ARGS  )

Definition at line 846 of file like_support.c.

847{
849}

References Pattern_Type_Regex, patternsel(), and PG_RETURN_FLOAT8.

◆ string_to_bytea_const()

static Const * string_to_bytea_const ( const char str,
size_t  str_len 
)
static

Definition at line 1839 of file like_support.c.

1840{
1842 Datum conval;
1843
1847
1848 return makeConst(BYTEAOID, -1, InvalidOid, -1, conval, false, false);
1849}

References fb(), InvalidOid, makeConst(), memcpy(), palloc(), PointerGetDatum, SET_VARSIZE(), str, VARDATA(), and VARHDRSZ.

Referenced by like_fixed_prefix(), and make_greater_string().

◆ string_to_const()

static Const * string_to_const ( const char str,
Oid  datatype 
)
static

Definition at line 1796 of file like_support.c.

1797{
1798 Datum conval = string_to_datum(str, datatype);
1799 Oid collation;
1800 int constlen;
1801
1802 /*
1803 * We only need to support a few datatypes here, so hard-wire properties
1804 * instead of incurring the expense of catalog lookups.
1805 */
1806 switch (datatype)
1807 {
1808 case TEXTOID:
1809 case VARCHAROID:
1810 case BPCHAROID:
1811 collation = DEFAULT_COLLATION_OID;
1812 constlen = -1;
1813 break;
1814
1815 case NAMEOID:
1816 collation = C_COLLATION_OID;
1818 break;
1819
1820 case BYTEAOID:
1821 collation = InvalidOid;
1822 constlen = -1;
1823 break;
1824
1825 default:
1826 elog(ERROR, "unexpected datatype in string_to_const: %u",
1827 datatype);
1828 return NULL;
1829 }
1830
1831 return makeConst(datatype, -1, collation, constlen,
1832 conval, false, false);
1833}

References elog, ERROR, fb(), InvalidOid, makeConst(), NAMEDATALEN, str, and string_to_datum().

Referenced by like_fixed_prefix(), like_fixed_prefix_ci(), make_greater_string(), and regex_fixed_prefix().

◆ string_to_datum()

static Datum string_to_datum ( const char str,
Oid  datatype 
)
static

Definition at line 1776 of file like_support.c.

1777{
1778 Assert(str != NULL);
1779
1780 /*
1781 * We cheat a little by assuming that CStringGetTextDatum() will do for
1782 * bpchar and varchar constants too...
1783 */
1784 if (datatype == NAMEOID)
1786 else if (datatype == BYTEAOID)
1788 else
1789 return CStringGetTextDatum(str);
1790}

References Assert, byteain(), CStringGetDatum(), CStringGetTextDatum, DirectFunctionCall1, fb(), namein(), and str.

Referenced by string_to_const().

◆ text_starts_with_support()

◆ texticlike_support()

◆ texticregexeq_support()

◆ textlike_support()

◆ textregexeq_support()