⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plancat.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * plancat.c *	   routines for accessing the system catalogs * * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.31 1999/07/07 16:09:33 momjian Exp $ * *------------------------------------------------------------------------- */#include <stdio.h>#include <math.h>#include "postgres.h"#include "access/heapam.h"#include "access/genam.h"#include "access/htup.h"#include "access/itup.h"#include "catalog/catname.h"#include "catalog/pg_amop.h"#include "catalog/pg_index.h"#include "catalog/pg_inherits.h"#include "catalog/pg_version.h"#include "parser/parsetree.h"	/* for getrelid() */#include "fmgr.h"#include "optimizer/internal.h"#include "optimizer/plancat.h"#include "utils/syscache.h"#ifndef HAVE_MEMMOVE#include <regex/utils.h>#else#include <string.h>#endifstatic void IndexSelectivity(Oid indexrelid, Oid indrelid, int32 nIndexKeys,				 Oid *AccessMethodOperatorClasses, Oid *operatorObjectIds,	   int32 *varAttributeNumbers, char **constValues, int32 *constFlags,				 float *idxPages, float *idxSelec);/* * relation_info - *	  Retrieves catalog information for a given relation. Given the oid of *	  the relation, return the following information: *				whether the relation has secondary indices *				number of pages *				number of tuples */voidrelation_info(Query *root, Index relid,			  bool *hasindex, int *pages, int *tuples){	HeapTuple	relationTuple;	Form_pg_class relation;	Oid			relationObjectId;	relationObjectId = getrelid(relid, root->rtable);	relationTuple = SearchSysCacheTuple(RELOID,									  ObjectIdGetDatum(relationObjectId),										0, 0, 0);	if (HeapTupleIsValid(relationTuple))	{		relation = (Form_pg_class) GETSTRUCT(relationTuple);		*hasindex = (relation->relhasindex) ? TRUE : FALSE;		*pages = relation->relpages;		*tuples = relation->reltuples;	}	else	{		elog(ERROR, "RelationCatalogInformation: Relation %u not found",			 relationObjectId);	}	return;}/* * index_info *	  Retrieves catalog information on an index on a given relation. * *	  The index relation is opened on the first invocation. The current *	  retrieves the next index relation within the catalog that has not *	  already been retrieved by a previous call.  The index catalog *	  is closed when no more indices for 'relid' can be found. * * 'first' is 1 if this is the first call * * Returns true if successful and false otherwise. Index info is returned * via the transient data structure 'info'. * */boolindex_info(Query *root, bool first, int relid, IdxInfoRetval *info){	int			i;	HeapTuple	indexTuple,				amopTuple;	Form_pg_index index;	Relation	indexRelation;	uint16		amstrategy;	Oid			relam;	Oid			indrelid;	static Relation relation = (Relation) NULL;	static HeapScanDesc scan = (HeapScanDesc) NULL;	static ScanKeyData indexKey;	/* find the oid of the indexed relation */	indrelid = getrelid(relid, root->rtable);	MemSet(info, 0, sizeof(IdxInfoRetval));	/*	 * the maximum number of elements in each of the following arrays is	 * 8. We allocate one more for a terminating 0 to indicate the end of	 * the array.	 */	info->indexkeys = (int *) palloc(sizeof(int) * 9);	MemSet(info->indexkeys, 0, sizeof(int) * 9);	info->orderOprs = (Oid *) palloc(sizeof(Oid) * 9);	MemSet(info->orderOprs, 0, sizeof(Oid) * 9);	info->classlist = (Oid *) palloc(sizeof(Oid) * 9);	MemSet(info->classlist, 0, sizeof(Oid) * 9);	/* Find an index on the given relation */	if (first)	{		if (RelationIsValid(relation))			heap_close(relation);		if (HeapScanIsValid(scan))			heap_endscan(scan);		ScanKeyEntryInitialize(&indexKey, 0,							   Anum_pg_index_indrelid,							   F_OIDEQ,							   ObjectIdGetDatum(indrelid));		relation = heap_openr(IndexRelationName);		scan = heap_beginscan(relation, 0, SnapshotNow,							  1, &indexKey);	}	if (!HeapScanIsValid(scan))		elog(ERROR, "index_info: scan not started");	indexTuple = heap_getnext(scan, 0);	if (!HeapTupleIsValid(indexTuple))	{		heap_endscan(scan);		heap_close(relation);		scan = (HeapScanDesc) NULL;		relation = (Relation) NULL;		return 0;	}	/* Extract info from the index tuple */	index = (Form_pg_index) GETSTRUCT(indexTuple);	info->relid = index->indexrelid;	/* index relation */	for (i = 0; i < INDEX_MAX_KEYS; i++)		info->indexkeys[i] = index->indkey[i];	for (i = 0; i < INDEX_MAX_KEYS; i++)		info->classlist[i] = index->indclass[i];	info->indproc = index->indproc;		/* functional index ?? */	/* partial index ?? */	if (VARSIZE(&index->indpred) != 0)	{		/*		 * The memory allocated here for the predicate (in lispReadString)		 * only needs to stay around until it's used in find_index_paths,		 * which is all within a command, so the automatic pfree at end of		 * transaction should be ok.		 */		char	   *predString;		predString = fmgr(F_TEXTOUT, &index->indpred);		info->indpred = (Node *) stringToNode(predString);		pfree(predString);	}	/* Extract info from the relation descriptor for the index */	indexRelation = index_open(index->indexrelid);#ifdef notdef	/* XXX should iterate through strategies -- but how?  use #1 for now */	amstrategy = indexRelation->rd_am->amstrategies;#endif	 /* notdef */	amstrategy = 1;	relam = indexRelation->rd_rel->relam;	info->relam = relam;	info->pages = indexRelation->rd_rel->relpages;	info->tuples = indexRelation->rd_rel->reltuples;	heap_close(indexRelation);	/*	 * Find the index ordering keys	 *	 * Must use indclass to know when to stop looking since with functional	 * indices there could be several keys (args) for one opclass. -mer 27	 * Sept 1991	 */	for (i = 0; i < 8 && index->indclass[i]; ++i)	{		amopTuple = SearchSysCacheTuple(AMOPSTRATEGY,										ObjectIdGetDatum(relam),									ObjectIdGetDatum(index->indclass[i]),										UInt16GetDatum(amstrategy),										0);		if (!HeapTupleIsValid(amopTuple))			elog(ERROR, "index_info: no amop %u %u %d",				 relam, index->indclass[i], amstrategy);		info->orderOprs[i] = ((Form_pg_amop) GETSTRUCT(amopTuple))->amopopr;	}	return TRUE;}/* * index_selectivity * *	  Call util/plancat.c:IndexSelectivity with the indicated arguments. * * 'indid' is the index OID * 'classes' is a list of index key classes * 'opnos' is a list of index key operator OIDs * 'relid' is the OID of the relation indexed * 'attnos' is a list of the relation attnos which the index keys over * 'values' is a list of the values of the clause's constants * 'flags' is a list of fixnums which describe the constants * 'nkeys' is the number of index keys * * Returns two floats: index pages and index selectivity in 'idxPages' and *		'idxSelec'. * */voidindex_selectivity(Oid indid,				  Oid *classes,				  List *opnos,				  Oid relid,				  List *attnos,				  List *values,				  List *flags,				  int32 nkeys,				  float *idxPages,				  float *idxSelec){	Oid		   *opno_array;	int		   *attno_array,			   *flag_array;	char	  **value_array;	int			i = 0;	List	   *xopno,			   *xattno,			   *value,			   *flag;	if (length(opnos) != nkeys || length(attnos) != nkeys ||		length(values) != nkeys || length(flags) != nkeys)	{		*idxPages = 0.0;		*idxSelec = 1.0;		return;	}	opno_array = (Oid *) palloc(nkeys * sizeof(Oid));	attno_array = (int *) palloc(nkeys * sizeof(int32));	value_array = (char **) palloc(nkeys * sizeof(char *));	flag_array = (int *) palloc(nkeys * sizeof(int32));	i = 0;	foreach(xopno, opnos)		opno_array[i++] = lfirsti(xopno);	i = 0;	foreach(xattno, attnos)		attno_array[i++] = lfirsti(xattno);	i = 0;	foreach(value, values)		value_array[i++] = (char *) lfirst(value);	i = 0;	foreach(flag, flags)		flag_array[i++] = lfirsti(flag);	IndexSelectivity(indid,					 relid,					 nkeys,					 classes,	/* not used */					 opno_array,					 attno_array,					 value_array,					 flag_array,					 idxPages,					 idxSelec);	return;}/* * restriction_selectivity in lisp system. * *	  NOTE: The routine is now merged with RestrictionClauseSelectivity *	  as defined in plancat.c * * Returns the selectivity of a specified operator. * This code executes registered procedures stored in the * operator relation, by calling the function manager. * * XXX The assumption in the selectivity procedures is that if the *		relation OIDs or attribute numbers are -1, then the clause *		isn't of the form (op var const). */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -