mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-04 00:02:52 -05:00 
			
		
		
		
	Fix fuzzy thinking about amcanmulticol versus amcaninclude.
These flags should be independent: in particular an index AM should be able to say that it supports include columns without necessarily supporting multiple key columns. The included-columns patch got this wrong, possibly aided by the fact that it didn't bother to update the documentation. While here, clarify some text about amcanreturn, which was a little vague about what should happen when amcanreturn reports that only some of the index columns are returnable. Noted while reviewing the SP-GiST included-columns patch, which quite incorrectly (and unsafely) changed SP-GiST to claim amcanmulticol = true as a workaround for this bug. Backpatch to v11 where included columns were introduced.
This commit is contained in:
		
							parent
							
								
									46cf3c72c3
								
							
						
					
					
						commit
						29d29d652f
					
				@ -197,7 +197,7 @@ typedef struct IndexAmRoutine
 | 
			
		||||
   implications.  The requirements of <structfield>amcanunique</structfield>
 | 
			
		||||
   are discussed in <xref linkend="index-unique-checks"/>.
 | 
			
		||||
   The <structfield>amcanmulticol</structfield> flag asserts that the
 | 
			
		||||
   access method supports multicolumn indexes, while
 | 
			
		||||
   access method supports multi-key-column indexes, while
 | 
			
		||||
   <structfield>amoptionalkey</structfield> asserts that it allows scans
 | 
			
		||||
   where no indexable restriction clause is given for the first index column.
 | 
			
		||||
   When <structfield>amcanmulticol</structfield> is false,
 | 
			
		||||
@ -233,6 +233,19 @@ typedef struct IndexAmRoutine
 | 
			
		||||
   conditions.
 | 
			
		||||
  </para>
 | 
			
		||||
 | 
			
		||||
  <para>
 | 
			
		||||
   The <structfield>amcaninclude</structfield> flag indicates whether the
 | 
			
		||||
   access method supports <quote>included</quote> columns, that is it can
 | 
			
		||||
   store (without processing) additional columns beyond the key column(s).
 | 
			
		||||
   The requirements of the preceding paragraph apply only to the key
 | 
			
		||||
   columns.  In particular, the combination
 | 
			
		||||
   of <structfield>amcanmulticol</structfield>=<literal>false</literal>
 | 
			
		||||
   and <structfield>amcaninclude</structfield>=<literal>true</literal> is
 | 
			
		||||
   sensible: it means that there can only be one key column, but there can
 | 
			
		||||
   also be included column(s).  Also, included columns must be allowed to be
 | 
			
		||||
   null, independently of <structfield>amoptionalkey</structfield>.
 | 
			
		||||
  </para>
 | 
			
		||||
 | 
			
		||||
 </sect1>
 | 
			
		||||
 | 
			
		||||
 <sect1 id="index-functions">
 | 
			
		||||
@ -383,10 +396,13 @@ amcanreturn (Relation indexRelation, int attno);
 | 
			
		||||
</programlisting>
 | 
			
		||||
   Check whether the index can support <link
 | 
			
		||||
   linkend="indexes-index-only-scans"><firstterm>index-only scans</firstterm></link> on
 | 
			
		||||
   the given column, by returning the indexed column values for an index entry
 | 
			
		||||
   in the form of an <structname>IndexTuple</structname>.  The attribute number
 | 
			
		||||
   is 1-based, i.e., the first column's attno is 1. Returns true if supported,
 | 
			
		||||
   else false.  If the access method does not support index-only scans at all,
 | 
			
		||||
   the given column, by returning the column's original indexed value.
 | 
			
		||||
   The attribute number is 1-based, i.e., the first column's attno is 1.
 | 
			
		||||
   Returns true if supported, else false.
 | 
			
		||||
   This function should always return true for included columns
 | 
			
		||||
   (if those are supported), since there's little point in an included
 | 
			
		||||
   column that can't be retrieved.
 | 
			
		||||
   If the access method does not support index-only scans at all,
 | 
			
		||||
   the <structfield>amcanreturn</structfield> field in its <structname>IndexAmRoutine</structname>
 | 
			
		||||
   struct can be set to NULL.
 | 
			
		||||
  </para>
 | 
			
		||||
@ -476,7 +492,7 @@ amproperty (Oid index_oid, int attno,
 | 
			
		||||
   core code does not know how to do that and will return NULL.  It may
 | 
			
		||||
   also be advantageous to implement <literal>AMPROP_RETURNABLE</literal> testing,
 | 
			
		||||
   if that can be done more cheaply than by opening the index and calling
 | 
			
		||||
   <structfield>amcanreturn</structfield>, which is the core code's default behavior.
 | 
			
		||||
   <function>amcanreturn</function>, which is the core code's default behavior.
 | 
			
		||||
   The default behavior should be satisfactory for all other standard
 | 
			
		||||
   properties.
 | 
			
		||||
  </para>
 | 
			
		||||
@ -621,10 +637,13 @@ amgettuple (IndexScanDesc scan,
 | 
			
		||||
 | 
			
		||||
  <para>
 | 
			
		||||
   If the index supports <link linkend="indexes-index-only-scans">index-only
 | 
			
		||||
   scans</link> (i.e., <function>amcanreturn</function> returns true for it),
 | 
			
		||||
   scans</link> (i.e., <function>amcanreturn</function> returns true for any
 | 
			
		||||
   of its columns),
 | 
			
		||||
   then on success the AM must also check <literal>scan->xs_want_itup</literal>,
 | 
			
		||||
   and if that is true it must return the originally indexed data for the
 | 
			
		||||
   index entry.  The data can be returned in the form of an
 | 
			
		||||
   index entry.  Columns for which <function>amcanreturn</function> returns
 | 
			
		||||
   false can be returned as nulls.
 | 
			
		||||
   The data can be returned in the form of an
 | 
			
		||||
   <structname>IndexTuple</structname> pointer stored at <literal>scan->xs_itup</literal>,
 | 
			
		||||
   with tuple descriptor <literal>scan->xs_itupdesc</literal>; or in the form of
 | 
			
		||||
   a <structname>HeapTuple</structname> pointer stored at <literal>scan->xs_hitup</literal>,
 | 
			
		||||
 | 
			
		||||
@ -597,7 +597,7 @@ DefineIndex(Oid relationId,
 | 
			
		||||
									  stmt->indexIncludingParams);
 | 
			
		||||
	numberOfAttributes = list_length(allIndexParams);
 | 
			
		||||
 | 
			
		||||
	if (numberOfAttributes <= 0)
 | 
			
		||||
	if (numberOfKeyAttributes <= 0)
 | 
			
		||||
		ereport(ERROR,
 | 
			
		||||
				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
 | 
			
		||||
				 errmsg("must specify at least one column")));
 | 
			
		||||
@ -820,7 +820,7 @@ DefineIndex(Oid relationId,
 | 
			
		||||
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 | 
			
		||||
				 errmsg("access method \"%s\" does not support included columns",
 | 
			
		||||
						accessMethodName)));
 | 
			
		||||
	if (numberOfAttributes > 1 && !amRoutine->amcanmulticol)
 | 
			
		||||
	if (numberOfKeyAttributes > 1 && !amRoutine->amcanmulticol)
 | 
			
		||||
		ereport(ERROR,
 | 
			
		||||
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 | 
			
		||||
				 errmsg("access method \"%s\" does not support multicolumn indexes",
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user