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

Commit49b0e30

Browse files
committed
Support index INCLUDE in the AM properties interface.
This rectifies an oversight in commit8224de4, by adding a newproperty 'can_include' for pg_indexam_has_property, and adjusting theresults of pg_index_column_has_property to give more appropriateresults for INCLUDEd columns.
1 parentd234602 commit49b0e30

File tree

5 files changed

+185
-62
lines changed

5 files changed

+185
-62
lines changed

‎doc/src/sgml/func.sgml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17555,6 +17555,12 @@ SELECT currval(pg_get_serial_sequence('sometable', 'id'));
1755517555
<entry>Does the access method support exclusion constraints?
1755617556
</entry>
1755717557
</row>
17558+
<row>
17559+
<entry><literal>can_include</literal></entry>
17560+
<entry>Does the access method support the <literal>INCLUDE</literal>
17561+
clause of <literal>CREATE INDEX</literal>?
17562+
</entry>
17563+
</row>
1755817564
</tbody>
1755917565
</tgroup>
1756017566
</table>

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

Lines changed: 106 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,10 @@ static const struct am_propname am_propnames[] =
8080
},
8181
{
8282
"can_exclude",AMPROP_CAN_EXCLUDE
83-
}
83+
},
84+
{
85+
"can_include",AMPROP_CAN_INCLUDE
86+
},
8487
};
8588

8689
staticIndexAMProperty
@@ -101,7 +104,8 @@ lookup_prop_name(const char *name)
101104
/*
102105
* Common code for properties that are just bit tests of indoptions.
103106
*
104-
* relid/attno: identify the index column to test the indoptions of.
107+
* tuple: the pg_index heaptuple
108+
* attno: identify the index column to test the indoptions of.
105109
* guard: if false, a boolean false result is forced (saves code in caller).
106110
* iopt_mask: mask for interesting indoption bit.
107111
* iopt_expect: value for a "true" result (should be 0 or iopt_mask).
@@ -110,12 +114,10 @@ lookup_prop_name(const char *name)
110114
* otherwise sets *res to the boolean value to return.
111115
*/
112116
staticbool
113-
test_indoption(Oidrelid,intattno,boolguard,
117+
test_indoption(HeapTupletuple,intattno,boolguard,
114118
int16iopt_mask,int16iopt_expect,
115119
bool*res)
116120
{
117-
HeapTupletuple;
118-
Form_pg_indexrd_indexPG_USED_FOR_ASSERTS_ONLY;
119121
Datumdatum;
120122
boolisnull;
121123
int2vector*indoption;
@@ -127,14 +129,6 @@ test_indoption(Oid relid, int attno, bool guard,
127129
return true;
128130
}
129131

130-
tuple=SearchSysCache1(INDEXRELID,ObjectIdGetDatum(relid));
131-
if (!HeapTupleIsValid(tuple))
132-
return false;
133-
rd_index= (Form_pg_index)GETSTRUCT(tuple);
134-
135-
Assert(relid==rd_index->indexrelid);
136-
Assert(attno>0&&attno <=rd_index->indnatts);
137-
138132
datum=SysCacheGetAttr(INDEXRELID,tuple,
139133
Anum_pg_index_indoption,&isnull);
140134
Assert(!isnull);
@@ -144,8 +138,6 @@ test_indoption(Oid relid, int attno, bool guard,
144138

145139
*res= (indoption_val&iopt_mask)==iopt_expect;
146140

147-
ReleaseSysCache(tuple);
148-
149141
return true;
150142
}
151143

@@ -195,9 +187,10 @@ indexam_property(FunctionCallInfo fcinfo,
195187
}
196188

197189
/*
198-
* At this point, either index_oid == InvalidOid or it's a valid index
199-
* OID. Also, after this test, either attno == 0 for index-wide or
200-
* AM-wide tests, or it's a valid column number in a valid index.
190+
* At this point, either index_oid == InvalidOid or it's a valid index OID.
191+
* Also, after this test and the one below, either attno == 0 for
192+
* index-wide or AM-wide tests, or it's a valid column number in a valid
193+
* index.
201194
*/
202195
if (attno<0||attno>natts)
203196
PG_RETURN_NULL();
@@ -224,80 +217,138 @@ indexam_property(FunctionCallInfo fcinfo,
224217

225218
if (attno>0)
226219
{
227-
/* Handle column-level properties */
220+
HeapTupletuple;
221+
Form_pg_indexrd_index;
222+
booliskey= true;
223+
224+
/*
225+
* Handle column-level properties. Many of these need the pg_index row
226+
* (which we also need to use to check for nonkey atts) so we fetch
227+
* that first.
228+
*/
229+
tuple=SearchSysCache1(INDEXRELID,ObjectIdGetDatum(index_oid));
230+
if (!HeapTupleIsValid(tuple))
231+
PG_RETURN_NULL();
232+
rd_index= (Form_pg_index)GETSTRUCT(tuple);
233+
234+
Assert(index_oid==rd_index->indexrelid);
235+
Assert(attno>0&&attno <=rd_index->indnatts);
236+
237+
isnull= true;
238+
239+
/*
240+
* If amcaninclude, we might be looking at an attno for a nonkey
241+
* column, for which we (generically) assume that most properties are
242+
* null.
243+
*/
244+
if (routine->amcaninclude
245+
&&attno>rd_index->indnkeyatts)
246+
iskey= false;
247+
228248
switch (prop)
229249
{
230250
caseAMPROP_ASC:
231-
if (test_indoption(index_oid,attno,routine->amcanorder,
251+
if (iskey&&
252+
test_indoption(tuple,attno,routine->amcanorder,
232253
INDOPTION_DESC,0,&res))
233-
PG_RETURN_BOOL(res);
234-
PG_RETURN_NULL();
254+
isnull= false;
255+
break;
235256

236257
caseAMPROP_DESC:
237-
if (test_indoption(index_oid,attno,routine->amcanorder,
258+
if (iskey&&
259+
test_indoption(tuple,attno,routine->amcanorder,
238260
INDOPTION_DESC,INDOPTION_DESC,&res))
239-
PG_RETURN_BOOL(res);
240-
PG_RETURN_NULL();
261+
isnull= false;
262+
break;
241263

242264
caseAMPROP_NULLS_FIRST:
243-
if (test_indoption(index_oid,attno,routine->amcanorder,
265+
if (iskey&&
266+
test_indoption(tuple,attno,routine->amcanorder,
244267
INDOPTION_NULLS_FIRST,INDOPTION_NULLS_FIRST,&res))
245-
PG_RETURN_BOOL(res);
246-
PG_RETURN_NULL();
268+
isnull= false;
269+
break;
247270

248271
caseAMPROP_NULLS_LAST:
249-
if (test_indoption(index_oid,attno,routine->amcanorder,
272+
if (iskey&&
273+
test_indoption(tuple,attno,routine->amcanorder,
250274
INDOPTION_NULLS_FIRST,0,&res))
251-
PG_RETURN_BOOL(res);
252-
PG_RETURN_NULL();
275+
isnull= false;
276+
break;
253277

254278
caseAMPROP_ORDERABLE:
255-
PG_RETURN_BOOL(routine->amcanorder);
279+
/*
280+
* generic assumption is that nonkey columns are not orderable
281+
*/
282+
res=iskey ?routine->amcanorder : false;
283+
isnull= false;
284+
break;
256285

257286
caseAMPROP_DISTANCE_ORDERABLE:
258287

259288
/*
260289
* The conditions for whether a column is distance-orderable
261290
* are really up to the AM (at time of writing, only GiST
262-
* supports it at all).The planner has its own idea based on
291+
* supports it at all). The planner has its own idea based on
263292
* whether it finds an operator with amoppurpose 'o', but
264293
* getting there from just the index column type seems like a
265-
* lot of work.So instead we expect the AM to handle this in
266-
* its amproperty routine.The generic result is to return
267-
* false if the AM says it never supports this,and null
268-
* otherwise (meaning we don't know).
294+
* lot of work. So instead we expect the AM to handle this in
295+
* its amproperty routine. The generic result is to return
296+
* false if the AM says it never supports this,or if this is a
297+
*nonkey column, and nullotherwise (meaning we don't know).
269298
*/
270-
if (!routine->amcanorderbyop)
271-
PG_RETURN_BOOL(false);
272-
PG_RETURN_NULL();
299+
if (!iskey|| !routine->amcanorderbyop)
300+
{
301+
res= false;
302+
isnull= false;
303+
}
304+
break;
273305

274306
caseAMPROP_RETURNABLE:
275-
if (!routine->amcanreturn)
276-
PG_RETURN_BOOL(false);
277307

278-
/*
279-
* If possible, the AM should handle this test in its
280-
* amproperty function without opening the rel. But this is
281-
* the generic fallback if it does not.
282-
*/
308+
/* note that we ignore iskey for this property */
309+
310+
isnull= false;
311+
res= false;
312+
313+
if (routine->amcanreturn)
283314
{
315+
/*
316+
* If possible, the AM should handle this test in its
317+
* amproperty function without opening the rel. But this is the
318+
* generic fallback if it does not.
319+
*/
284320
Relationindexrel=index_open(index_oid,AccessShareLock);
285321

286322
res=index_can_return(indexrel,attno);
287323
index_close(indexrel,AccessShareLock);
288324
}
289-
290-
PG_RETURN_BOOL(res);
325+
break;
291326

292327
caseAMPROP_SEARCH_ARRAY:
293-
PG_RETURN_BOOL(routine->amsearcharray);
328+
if (iskey)
329+
{
330+
res=routine->amsearcharray;
331+
isnull= false;
332+
}
333+
break;
294334

295335
caseAMPROP_SEARCH_NULLS:
296-
PG_RETURN_BOOL(routine->amsearchnulls);
336+
if (iskey)
337+
{
338+
res=routine->amsearchnulls;
339+
isnull= false;
340+
}
341+
break;
297342

298343
default:
299-
PG_RETURN_NULL();
344+
break;
300345
}
346+
347+
ReleaseSysCache(tuple);
348+
349+
if (!isnull)
350+
PG_RETURN_BOOL(res);
351+
PG_RETURN_NULL();
301352
}
302353

303354
if (OidIsValid(index_oid))
@@ -344,6 +395,9 @@ indexam_property(FunctionCallInfo fcinfo,
344395
caseAMPROP_CAN_EXCLUDE:
345396
PG_RETURN_BOOL(routine->amgettuple ? true : false);
346397

398+
caseAMPROP_CAN_INCLUDE:
399+
PG_RETURN_BOOL(routine->amcaninclude);
400+
347401
default:
348402
PG_RETURN_NULL();
349403
}

‎src/include/access/amapi.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ typedef enum IndexAMProperty
5050
AMPROP_CAN_ORDER,/* AM properties */
5151
AMPROP_CAN_UNIQUE,
5252
AMPROP_CAN_MULTI_COL,
53-
AMPROP_CAN_EXCLUDE
53+
AMPROP_CAN_EXCLUDE,
54+
AMPROP_CAN_INCLUDE
5455
}IndexAMProperty;
5556

5657

@@ -196,6 +197,12 @@ typedef struct IndexAmRoutine
196197
/* type of data stored in index, or InvalidOid if variable */
197198
Oidamkeytype;
198199

200+
/*
201+
* If you add new properties to either the above or the below lists, then
202+
* they should also (usually) be exposed via the property API (see
203+
* IndexAMProperty at the top of the file, and utils/adt/amutils.c).
204+
*/
205+
199206
/* interface functions */
200207
ambuild_functionambuild;
201208
ambuildempty_functionambuildempty;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp