Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
efeffae2
Commit
efeffae2
authored
Mar 23, 2003
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tweak selectivity and related routines to cope with domains. Per report
from Andreas Pflug.
parent
8f5fb5f2
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
83 additions
and
24 deletions
+83
-24
src/backend/optimizer/path/indxpath.c
src/backend/optimizer/path/indxpath.c
+8
-5
src/backend/utils/adt/selfuncs.c
src/backend/utils/adt/selfuncs.c
+75
-19
No files found.
src/backend/optimizer/path/indxpath.c
View file @
efeffae2
...
...
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.13
5 2003/02/08 20:20:54
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.13
6 2003/03/23 01:49:02
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -2039,7 +2039,7 @@ expand_indexqual_conditions(List *indexquals)
* Given a fixed prefix that all the "leftop" values must have,
* generate suitable indexqual condition(s). expr_op is the original
* LIKE or regex operator; we use it to deduce the appropriate comparison
* operators.
* operators
and operand datatypes
.
*/
static
List
*
prefix_quals
(
Node
*
leftop
,
Oid
expr_op
,
...
...
@@ -2094,10 +2094,13 @@ prefix_quals(Node *leftop, Oid expr_op,
return
NIL
;
}
if
(
prefix_const
->
consttype
!=
BYTEAOID
)
prefix
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
prefix_const
->
constvalue
));
/* Prefix constant is text for all except BYTEA_LIKE */
if
(
datatype
!=
BYTEAOID
)
prefix
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
prefix_const
->
constvalue
));
else
prefix
=
DatumGetCString
(
DirectFunctionCall1
(
byteaout
,
prefix_const
->
constvalue
));
prefix
=
DatumGetCString
(
DirectFunctionCall1
(
byteaout
,
prefix_const
->
constvalue
));
/*
* If we found an exact-match pattern, generate an "=" indexqual.
...
...
src/backend/utils/adt/selfuncs.c
View file @
efeffae2
...
...
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.13
2 2003/02/08 20:20:55
tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.13
3 2003/03/23 01:49:02
tgl Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -94,6 +94,7 @@
#include "optimizer/prep.h"
#include "optimizer/tlist.h"
#include "optimizer/var.h"
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
#include "parser/parsetree.h"
...
...
@@ -176,7 +177,8 @@ static bool get_restriction_var(List *args, int varRelid,
Var
**
var
,
Node
**
other
,
bool
*
varonleft
);
static
void
get_join_vars
(
List
*
args
,
Var
**
var1
,
Var
**
var2
);
static
Selectivity
prefix_selectivity
(
Query
*
root
,
Var
*
var
,
Const
*
prefix
);
static
Selectivity
prefix_selectivity
(
Query
*
root
,
Var
*
var
,
Oid
vartype
,
Const
*
prefix
);
static
Selectivity
pattern_selectivity
(
Const
*
patt
,
Pattern_Type
ptype
);
static
bool
string_lessthan
(
const
char
*
str1
,
const
char
*
str2
,
Oid
datatype
);
...
...
@@ -227,7 +229,8 @@ eqsel(PG_FUNCTION_ARGS)
* If the something is a NULL constant, assume operator is strict and
* return zero, ie, operator will never return TRUE.
*/
if
(
IsA
(
other
,
Const
)
&&
((
Const
*
)
other
)
->
constisnull
)
if
(
IsA
(
other
,
Const
)
&&
((
Const
*
)
other
)
->
constisnull
)
PG_RETURN_FLOAT8
(
0
.
0
);
/* get stats for the attribute, if available */
...
...
@@ -834,6 +837,8 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
bool
varonleft
;
Oid
relid
;
Datum
constval
;
Oid
consttype
;
Oid
vartype
;
Pattern_Prefix_Status
pstatus
;
Const
*
patt
=
NULL
;
Const
*
prefix
=
NULL
;
...
...
@@ -861,13 +866,25 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
if
(((
Const
*
)
other
)
->
constisnull
)
return
0
.
0
;
constval
=
((
Const
*
)
other
)
->
constvalue
;
consttype
=
((
Const
*
)
other
)
->
consttype
;
/*
* The right-hand const is type text or bytea for all supported
* operators. We do not expect to see binary-compatible types here,
* since const-folding should have relabeled the const to exactly match
* the operator's declared type.
*/
if
(
consttype
!=
TEXTOID
&&
consttype
!=
BYTEAOID
)
return
DEFAULT_MATCH_SEL
;
/*
* the right-hand const is type text or bytea for all supported
* operators
* The var, on the other hand, might be a binary-compatible type;
* particularly a domain. Try to fold it if it's not recognized
* immediately.
*/
Assert
(((
Const
*
)
other
)
->
consttype
==
TEXTOID
||
((
Const
*
)
other
)
->
consttype
==
BYTEAOID
);
vartype
=
var
->
vartype
;
if
(
vartype
!=
consttype
)
vartype
=
getBaseType
(
vartype
);
/* divide pattern into fixed prefix and remainder */
patt
=
(
Const
*
)
other
;
...
...
@@ -878,12 +895,12 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
/*
* Pattern specifies an exact match, so pretend operator is '='
*/
Oid
eqopr
=
find_operator
(
"="
,
var
->
var
type
);
Oid
eqopr
=
find_operator
(
"="
,
vartype
);
List
*
eqargs
;
if
(
eqopr
==
InvalidOid
)
elog
(
ERROR
,
"patternsel: no = operator for type %u"
,
var
->
var
type
);
vartype
);
eqargs
=
makeList2
(
var
,
prefix
);
result
=
DatumGetFloat8
(
DirectFunctionCall4
(
eqsel
,
PointerGetDatum
(
root
),
...
...
@@ -903,7 +920,7 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
Selectivity
selec
;
if
(
pstatus
==
Pattern_Prefix_Partial
)
prefixsel
=
prefix_selectivity
(
root
,
var
,
prefix
);
prefixsel
=
prefix_selectivity
(
root
,
var
,
vartype
,
prefix
);
else
prefixsel
=
1
.
0
;
restsel
=
pattern_selectivity
(
rest
,
ptype
);
...
...
@@ -1033,7 +1050,8 @@ booltestsel(Query *root, BoolTestType booltesttype, Node *arg,
if
(
IsA
(
arg
,
RelabelType
))
arg
=
(
Node
*
)
((
RelabelType
*
)
arg
)
->
arg
;
if
(
IsA
(
arg
,
Var
)
&&
(
varRelid
==
0
||
varRelid
==
((
Var
*
)
arg
)
->
varno
))
if
(
IsA
(
arg
,
Var
)
&&
(
varRelid
==
0
||
varRelid
==
((
Var
*
)
arg
)
->
varno
))
var
=
(
Var
*
)
arg
;
else
{
...
...
@@ -1775,6 +1793,8 @@ mergejoinscansel(Query *root, Node *clause,
{
Var
*
left
,
*
right
;
Oid
lefttype
,
righttype
;
Oid
opno
,
lsortop
,
rsortop
,
...
...
@@ -1799,6 +1819,24 @@ mergejoinscansel(Query *root, Node *clause,
if
(
!
right
)
return
;
/* shouldn't happen */
/* Save the direct input types of the operator */
lefttype
=
exprType
((
Node
*
)
left
);
righttype
=
exprType
((
Node
*
)
right
);
/*
* Now skip any binary-compatible relabeling; there can only be one level
* since constant-expression folder eliminates adjacent RelabelTypes.
*
* XXX can't enable this quite yet, it exposes regproc uncertainty problems
* in regression tests. FIXME soon.
*/
#if 0
if (IsA(left, RelabelType))
left = (Var *) ((RelabelType *) left)->arg;
if (IsA(right, RelabelType))
right = (Var *) ((RelabelType *) right)->arg;
#endif
/* Can't do anything if inputs are not Vars */
if
(
!
IsA
(
left
,
Var
)
||
!
IsA
(
right
,
Var
))
...
...
@@ -1841,13 +1879,13 @@ mergejoinscansel(Query *root, Node *clause,
* non-default estimates, else stick with our 1.0.
*/
selec
=
scalarineqsel
(
root
,
leop
,
false
,
left
,
rightmax
,
right
->
var
type
);
rightmax
,
righttype
);
if
(
selec
!=
DEFAULT_INEQ_SEL
)
*
leftscan
=
selec
;
/* And similarly for the right variable. */
selec
=
scalarineqsel
(
root
,
revleop
,
false
,
right
,
leftmax
,
left
->
var
type
);
leftmax
,
lefttype
);
if
(
selec
!=
DEFAULT_INEQ_SEL
)
*
rightscan
=
selec
;
...
...
@@ -2263,6 +2301,19 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
Datum
lobound
,
Datum
hibound
,
Oid
boundstypid
,
double
*
scaledlobound
,
double
*
scaledhibound
)
{
/*
* In present usage, we can assume that the valuetypid exactly matches
* the declared input type of the operator we are invoked for (because
* constant-folding will ensure that any Const passed to the operator
* has been reduced to the correct type). However, the boundstypid is
* the type of some variable that might be only binary-compatible with
* the declared type; in particular it might be a domain type. Must
* fold the variable type down to base type so we can recognize it.
* (But we can skip that lookup if the variable type matches the const.)
*/
if
(
boundstypid
!=
valuetypid
)
boundstypid
=
getBaseType
(
boundstypid
);
switch
(
valuetypid
)
{
/*
...
...
@@ -3234,13 +3285,18 @@ pattern_fixed_prefix(Const *patt, Pattern_Type ptype,
* A fixed prefix "foo" is estimated as the selectivity of the expression
* "var >= 'foo' AND var < 'fop'" (see also indxqual.c).
*
* Because of constant-folding, we can assume that the prefixcon constant's
* type exactly matches the operator's declared input type; but it's not
* safe to make the same assumption for the Var, so the type to use for the
* Var must be passed in separately.
*
* XXX Note: we make use of the upper bound to estimate operator selectivity
* even if the locale is such that we cannot rely on the upper-bound string.
* The selectivity only needs to be approximately right anyway, so it seems
* more useful to use the upper-bound code than not.
*/
static
Selectivity
prefix_selectivity
(
Query
*
root
,
Var
*
var
,
Const
*
prefixcon
)
prefix_selectivity
(
Query
*
root
,
Var
*
var
,
Oid
vartype
,
Const
*
prefixcon
)
{
Selectivity
prefixsel
;
Oid
cmpopr
;
...
...
@@ -3248,17 +3304,17 @@ prefix_selectivity(Query *root, Var *var, Const *prefixcon)
List
*
cmpargs
;
Const
*
greaterstrcon
;
cmpopr
=
find_operator
(
">="
,
var
->
var
type
);
cmpopr
=
find_operator
(
">="
,
vartype
);
if
(
cmpopr
==
InvalidOid
)
elog
(
ERROR
,
"prefix_selectivity: no >= operator for type %u"
,
var
->
var
type
);
vartype
);
if
(
prefixcon
->
consttype
!=
BYTEAOID
)
prefix
=
DatumGetCString
(
DirectFunctionCall1
(
textout
,
prefixcon
->
constvalue
));
else
prefix
=
DatumGetCString
(
DirectFunctionCall1
(
byteaout
,
prefixcon
->
constvalue
));
/* If var is type NAME, must adjust type of comparison constant */
if
(
var
->
var
type
==
NAMEOID
)
if
(
vartype
==
NAMEOID
)
prefixcon
=
string_to_const
(
prefix
,
NAMEOID
);
cmpargs
=
makeList2
(
var
,
prefixcon
);
...
...
@@ -3279,10 +3335,10 @@ prefix_selectivity(Query *root, Var *var, Const *prefixcon)
{
Selectivity
topsel
;
cmpopr
=
find_operator
(
"<"
,
var
->
var
type
);
cmpopr
=
find_operator
(
"<"
,
vartype
);
if
(
cmpopr
==
InvalidOid
)
elog
(
ERROR
,
"prefix_selectivity: no < operator for type %u"
,
var
->
var
type
);
vartype
);
cmpargs
=
makeList2
(
var
,
greaterstrcon
);
/* Assume scalarltsel is appropriate for all supported types */
topsel
=
DatumGetFloat8
(
DirectFunctionCall4
(
scalarltsel
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment