|
9 | 9 | *
|
10 | 10 | *
|
11 | 11 | * 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 $ |
13 | 13 | *
|
14 | 14 | *-------------------------------------------------------------------------
|
15 | 15 | */
|
@@ -95,6 +95,7 @@ static bool match_special_index_operator(Expr *clause, Oid opclass, Oid relam,
|
95 | 95 | boolindexkey_on_left);
|
96 | 96 | staticList*prefix_quals(Var*leftop,Oidexpr_op,
|
97 | 97 | char*prefix,Pattern_Prefix_Statuspstatus);
|
| 98 | +staticList*network_prefix_quals(Var*leftop,Oidexpr_op,Datumrightop); |
98 | 99 | staticOidfind_operator(constchar*opname,Oiddatatype);
|
99 | 100 | staticDatumstring_to_datum(constchar*str,Oiddatatype);
|
100 | 101 | staticConst*string_to_const(constchar*str,Oiddatatype);
|
@@ -1761,6 +1762,13 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam,
|
1761 | 1762 | pfree(patt);
|
1762 | 1763 | }
|
1763 | 1764 | 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; |
1764 | 1772 | }
|
1765 | 1773 |
|
1766 | 1774 | /* done if the expression doesn't look indexable */
|
@@ -1810,6 +1818,22 @@ match_special_index_operator(Expr *clause, Oid opclass, Oid relam,
|
1810 | 1818 | !op_class(find_operator("<",NAMEOID),opclass,relam))
|
1811 | 1819 | isIndexable= false;
|
1812 | 1820 | 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; |
1813 | 1837 | }
|
1814 | 1838 |
|
1815 | 1839 | returnisIndexable;
|
@@ -1924,6 +1948,16 @@ expand_indexqual_conditions(List *indexquals)
|
1924 | 1948 | pfree(patt);
|
1925 | 1949 | break;
|
1926 | 1950 |
|
| 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 | + |
1927 | 1961 | default:
|
1928 | 1962 | resultquals=lappend(resultquals,clause);
|
1929 | 1963 | break;
|
@@ -2037,6 +2071,86 @@ prefix_quals(Var *leftop, Oid expr_op,
|
2037 | 2071 | returnresult;
|
2038 | 2072 | }
|
2039 | 2073 |
|
| 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 | + |
2040 | 2154 | /*
|
2041 | 2155 | * Handy subroutines for match_special_index_operator() and friends.
|
2042 | 2156 | */
|
|