text: /*-------------------------------------------------------------------------
   *
   * aoblkdir.c
   *   This file contains routines to support creation of append-only block
   *   directory tables. This file is identical in functionality to aoseg.c
   *   that exists in the same directory.
   *
   * Portions Copyright (c) 2009, Greenplum Inc.
   * Portions Copyright (c) 2012-Present Pivotal Software, Inc.
   *
   *
   * IDENTIFICATION
   *	    src/backend/catalog/aoblkdir.c
   *
   *-------------------------------------------------------------------------
   */
  #include "postgres.h"
  
  #include "catalog/pg_opclass.h"
  #include "catalog/aoblkdir.h"
  #include "catalog/aocatalog.h"
  #include "miscadmin.h"
  #include "nodes/makefuncs.h"
  
  void
  AlterTableCreateAoBlkdirTable(Oid relOid, bool is_part_child)
  {
  	Relation	rel;
  	TupleDesc	tupdesc;
  	IndexInfo  *indexInfo;
  	Oid			classObjectId[3];
  	int16		coloptions[3];
  	List	   *indexColNames;
  
  	/*
  	 * Grab an exclusive lock on the target table, which we will NOT release
  	 * until end of transaction.  (This is probably redundant in all present
  	 * uses...)
  	 */
  	if (is_part_child)
  		rel = heap_open(relOid, NoLock);
  	else
  		rel = heap_open(relOid, AccessExclusiveLock);
  
  	if (!RelationIsAoRows(rel) && !RelationIsAoCols(rel)) {
  		heap_close(rel, NoLock);
  		return;
  	}
  
  	/* Create a tuple descriptor */
  	tupdesc = CreateTemplateTupleDesc(4, false);
  	TupleDescInitEntry(tupdesc, (AttrNumber) 1,
  					   "segno",
  					   INT4OID,
  					   -1, 0);
  	TupleDescInitEntry(tupdesc, (AttrNumber) 2,
  					   "columngroup_no",
  					   INT4OID,
  					   -1, 0);
  	TupleDescInitEntry(tupdesc, (AttrNumber) 3,
  					   "first_row_no",
  					   INT8OID,
  					   -1, 0);
  	TupleDescInitEntry(tupdesc, (AttrNumber) 4,
  					   "minipage",
  					   BYTEAOID,
  					   -1, 0);
  
  	/*
  	 * We don't want any toast columns here.
  	 */
  	tupdesc->attrs[0]->attstorage = 'p';
  	tupdesc->attrs[1]->attstorage = 'p';
  	tupdesc->attrs[2]->attstorage = 'p';
  	tupdesc->attrs[3]->attstorage = 'p';
  
  	/*
  	 * Create index on segno, first_row_no.
  	 */
  	indexInfo = makeNode(IndexInfo);
  	indexInfo->ii_NumIndexAttrs = 3;
  	indexInfo->ii_KeyAttrNumbers[0] = 1;
  	indexInfo->ii_KeyAttrNumbers[1] = 2;
  	indexInfo->ii_KeyAttrNumbers[2] = 3;
  	indexInfo->ii_Expressions = NIL;
  	indexInfo->ii_ExpressionsState = NIL;
  	indexInfo->ii_Predicate = NIL;
  	indexInfo->ii_PredicateState = NIL;
  	indexInfo->ii_Unique = true;
  	indexInfo->ii_Concurrent = false;
  	indexColNames = list_make3("segno", "columngroup_no", "first_row_no");
  	
  	classObjectId[0] = INT4_BTREE_OPS_OID;
  	classObjectId[1] = INT4_BTREE_OPS_OID;
  	classObjectId[2] = INT8_BTREE_OPS_OID;
  
  	coloptions[0] = 0;
  	coloptions[1] = 0;
  	coloptions[2] = 0;
  
  	(void) CreateAOAuxiliaryTable(rel,
  								  "pg_aoblkdir",
  								  RELKIND_AOBLOCKDIR,
  								  tupdesc,
  								  indexInfo, indexColNames,
  								  classObjectId,
  								  coloptions);
  
  	heap_close(rel, NoLock);
  }
  
  