Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1f1ca18

Browse files
committed
Make inet/cidr << and <<= operators indexable. From Alex Pilosov <alex@pilosoft.com>.
1 parent2917f0a commit1f1ca18

File tree

6 files changed

+237
-16
lines changed

6 files changed

+237
-16
lines changed

‎src/backend/optimizer/path/indxpath.c

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.106 2001/06/05 17:13:51 tgl Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.107 2001/06/17 02:05:19 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -95,6 +95,7 @@ static bool match_special_index_operator(Expr *clause, Oid opclass, Oid relam,
9595
boolindexkey_on_left);
9696
staticList*prefix_quals(Var*leftop,Oidexpr_op,
9797
char*prefix,Pattern_Prefix_Statuspstatus);
98+
staticList*network_prefix_quals(Var*leftop,Oidexpr_op,Datumrightop);
9899
staticOidfind_operator(constchar*opname,Oiddatatype);
99100
staticDatumstring_to_datum(constchar*str,Oiddatatype);
100101
staticConst*string_to_const(constchar*str,Oiddatatype);
@@ -1761,6 +1762,13 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam,
17611762
pfree(patt);
17621763
}
17631764
break;
1765+
1766+
caseOID_INET_SUB_OP:
1767+
caseOID_INET_SUBEQ_OP:
1768+
caseOID_CIDR_SUB_OP:
1769+
caseOID_CIDR_SUBEQ_OP:
1770+
isIndexable= true;
1771+
break;
17641772
}
17651773

17661774
/* done if the expression doesn't look indexable */
@@ -1810,6 +1818,22 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam,
18101818
!op_class(find_operator("<",NAMEOID),opclass,relam))
18111819
isIndexable= false;
18121820
break;
1821+
1822+
caseOID_INET_SUB_OP:
1823+
caseOID_INET_SUBEQ_OP:
1824+
/* for SUB we actually need ">" not ">=", but this should do */
1825+
if (!op_class(find_operator(">=",INETOID),opclass,relam)||
1826+
!op_class(find_operator("<=",INETOID),opclass,relam))
1827+
isIndexable= false;
1828+
break;
1829+
1830+
caseOID_CIDR_SUB_OP:
1831+
caseOID_CIDR_SUBEQ_OP:
1832+
/* for SUB we actually need ">" not ">=", but this should do */
1833+
if (!op_class(find_operator(">=",CIDROID),opclass,relam)||
1834+
!op_class(find_operator("<=",CIDROID),opclass,relam))
1835+
isIndexable= false;
1836+
break;
18131837
}
18141838

18151839
returnisIndexable;
@@ -1924,6 +1948,16 @@ expand_indexqual_conditions(List *indexquals)
19241948
pfree(patt);
19251949
break;
19261950

1951+
caseOID_INET_SUB_OP:
1952+
caseOID_INET_SUBEQ_OP:
1953+
caseOID_CIDR_SUB_OP:
1954+
caseOID_CIDR_SUBEQ_OP:
1955+
constvalue= ((Const*)rightop)->constvalue;
1956+
resultquals=nconc(resultquals,
1957+
network_prefix_quals(leftop,expr_op,
1958+
constvalue));
1959+
break;
1960+
19271961
default:
19281962
resultquals=lappend(resultquals,clause);
19291963
break;
@@ -2037,6 +2071,86 @@ prefix_quals(Var *leftop, Oid expr_op,
20372071
returnresult;
20382072
}
20392073

2074+
/*
2075+
* Given a leftop and a rightop, and a inet-class sup/sub operator,
2076+
* generate suitable indexqual condition(s). expr_op is the original
2077+
* operator.
2078+
*/
2079+
staticList*
2080+
network_prefix_quals(Var*leftop,Oidexpr_op,Datumrightop)
2081+
{
2082+
boolis_eq;
2083+
char*opr1name;
2084+
Datumopr1right;
2085+
Datumopr2right;
2086+
Oidopr1oid;
2087+
Oidopr2oid;
2088+
List*result;
2089+
Oiddatatype;
2090+
Oper*op;
2091+
Expr*expr;
2092+
2093+
switch (expr_op)
2094+
{
2095+
caseOID_INET_SUB_OP:
2096+
datatype=INETOID;
2097+
is_eq= false;
2098+
break;
2099+
caseOID_INET_SUBEQ_OP:
2100+
datatype=INETOID;
2101+
is_eq= true;
2102+
break;
2103+
caseOID_CIDR_SUB_OP:
2104+
datatype=CIDROID;
2105+
is_eq= false;
2106+
break;
2107+
caseOID_CIDR_SUBEQ_OP:
2108+
datatype=CIDROID;
2109+
is_eq= true;
2110+
break;
2111+
default:
2112+
elog(ERROR,"network_prefix_quals: unexpected operator %u",
2113+
expr_op);
2114+
returnNIL;
2115+
}
2116+
2117+
/*
2118+
* create clause "key >= network_scan_first( rightop )", or ">"
2119+
* if the operator disallows equality.
2120+
*/
2121+
2122+
opr1name=is_eq ?">=" :">";
2123+
opr1oid=find_operator(opr1name,datatype);
2124+
if (opr1oid==InvalidOid)
2125+
elog(ERROR,"network_prefix_quals: no %s operator for type %u",
2126+
opr1name,datatype);
2127+
2128+
opr1right=network_scan_first(rightop );
2129+
2130+
op=makeOper(opr1oid,InvalidOid,BOOLOID);
2131+
expr=make_opclause(op,leftop,
2132+
(Var*)makeConst(datatype,-1,opr1right,
2133+
false, false, false, false));
2134+
result=makeList1(expr);
2135+
2136+
/* create clause "key <= network_scan_last( rightop )" */
2137+
2138+
opr2oid=find_operator("<=",datatype);
2139+
if (opr2oid==InvalidOid)
2140+
elog(ERROR,"network_prefix_quals: no <= operator for type %u",
2141+
datatype);
2142+
2143+
opr2right=network_scan_last(rightop );
2144+
2145+
op=makeOper(opr2oid,InvalidOid,BOOLOID);
2146+
expr=make_opclause(op,leftop,
2147+
(Var*)makeConst(datatype,-1,opr2right,
2148+
false, false, false, false));
2149+
result=lappend(result,expr);
2150+
2151+
returnresult;
2152+
}
2153+
20402154
/*
20412155
* Handy subroutines for match_special_index_operator() and friends.
20422156
*/

‎src/backend/utils/adt/network.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*is for IP V4 CIDR notation, but prepared for V6: just
44
*add the necessary bits where the comments indicate.
55
*
6-
*$Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.31 2001/06/13 21:08:59 momjian Exp $
6+
*$Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.32 2001/06/17 02:05:20 tgl Exp $
77
*
88
*Jon Postel RIP 16 Oct 1998
99
*/
@@ -707,3 +707,31 @@ v4addressOK(unsigned long a1, int bits)
707707
return true;
708708
return false;
709709
}
710+
711+
712+
/*
713+
* These functions are used by planner to generate indexscan limits
714+
* for clauses a << b and a <<= b
715+
*/
716+
717+
/* return the minimal value for an IP on a given network */
718+
Datum
719+
network_scan_first(Datumin)
720+
{
721+
returnDirectFunctionCall1(network_network,in);
722+
}
723+
724+
/*
725+
* return "last" IP on a given network. It's the broadcast address,
726+
* however, masklen has to be set to 32, since
727+
* 192.168.0.255/24 is considered less than 192.168.0.255/32
728+
*
729+
* NB: this is not IPv6 ready ...
730+
*/
731+
Datum
732+
network_scan_last(Datumin)
733+
{
734+
returnDirectFunctionCall2(inet_set_masklen,
735+
DirectFunctionCall1(network_broadcast,in),
736+
Int32GetDatum(32));
737+
}

‎src/include/catalog/pg_operator.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $Id: pg_operator.h,v 1.90 2001/06/10 22:32:35 tgl Exp $
11+
* $Id: pg_operator.h,v 1.91 2001/06/17 02:05:20 tgl Exp $
1212
*
1313
* NOTES
1414
* the genbki.sh script reads this file and generates .bki
@@ -674,9 +674,13 @@ DATA(insert OID = 1204 ( "<=" PGUID 0 b t f 869 869 16 1206 1205 0 0
674674
DATA(insertOID=1205 (">"PGUID0btf869869161203120400network_gtscalargtselscalargtjoinsel ));
675675
DATA(insertOID=1206 (">="PGUID0btf869869161204120300network_gescalargtselscalargtjoinsel ));
676676
DATA(insertOID=931 ("<<"PGUID0btf86986916933000network_sub-- ));
677+
#defineOID_INET_SUB_OP 931
677678
DATA(insertOID=932 ("<<="PGUID0btf86986916934000network_subeq-- ));
679+
#defineOID_INET_SUBEQ_OP 932
678680
DATA(insertOID=933 (">>"PGUID0btf86986916931000network_sup-- ));
681+
#defineOID_INET_SUP_OP 933
679682
DATA(insertOID=934 (">>="PGUID0btf86986916932000network_supeq-- ));
683+
#defineOID_INET_SUPEQ_OP 934
680684

681685
/* CIDR type */
682686
DATA(insertOID=820 ("="PGUID0btf65065016820821822822network_eqeqseleqjoinsel ));
@@ -686,9 +690,13 @@ DATA(insert OID = 823 ( "<=" PGUID 0 b t f 650 650 16 825 824 0 0 netwo
686690
DATA(insertOID=824 (">"PGUID0btf6506501682282300network_gtscalargtselscalargtjoinsel ));
687691
DATA(insertOID=825 (">="PGUID0btf6506501682382200network_gescalargtselscalargtjoinsel ));
688692
DATA(insertOID=826 ("<<"PGUID0btf65065016828000network_sub-- ));
693+
#defineOID_CIDR_SUB_OP 826
689694
DATA(insertOID=827 ("<<="PGUID0btf650650161004000network_subeq-- ));
695+
#defineOID_CIDR_SUBEQ_OP827
690696
DATA(insertOID=828 (">>"PGUID0btf65065016826000network_sup-- ));
697+
#defineOID_CIDR_SUP_OP828
691698
DATA(insertOID=1004 (">>="PGUID0btf65065016827000network_supeq-- ));
699+
#defineOID_CIDR_SUPEQ_OP1004
692700

693701
/* case-insensitive LIKE hacks */
694702
DATA(insertOID=1625 ("~~*"PGUID0btf1925160162600nameiclikeiclikeseliclikejoinsel ));

‎src/include/utils/builtins.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $Id: builtins.h,v 1.154 2001/06/14 01:09:22 tgl Exp $
10+
* $Id: builtins.h,v 1.155 2001/06/17 02:05:20 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -527,6 +527,8 @@ extern double convert_network_to_scalar(Datum value, Oid typid);
527527
externDatumtext_cidr(PG_FUNCTION_ARGS);
528528
externDatumtext_inet(PG_FUNCTION_ARGS);
529529
externDatuminet_set_masklen(PG_FUNCTION_ARGS);
530+
externDatumnetwork_scan_first(Datumin);
531+
externDatumnetwork_scan_last(Datumin);
530532

531533
/* mac.c */
532534
externDatummacaddr_in(PG_FUNCTION_ARGS);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp