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

📄 print.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
字号:
/*------------------------------------------------------------------------- * * print.c *	  various print routines (used mostly for debugging) * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/nodes/print.c,v 1.28 1999/05/25 16:09:10 momjian Exp $ * * HISTORY *	  AUTHOR			DATE			MAJOR EVENT *	  Andrew Yu			Oct 26, 1994	file creation * *------------------------------------------------------------------------- */#include <stdio.h>#include <string.h>#include "postgres.h"#include "access/printtup.h"#include "nodes/pg_list.h"#include "nodes/execnodes.h"#include "nodes/parsenodes.h"#include "nodes/print.h"#include "parser/parsetree.h"#include "access/heapam.h"#include "utils/lsyscache.h"#include "nodes/nodes.h"#include "nodes/plannodes.h"#include "parser/parse_relation.h"#include "optimizer/clauses.h"static char *plannode_type(Plan *p);/* * print *	  print contents of Node to stdout */voidprint(void *obj){	char	   *s;	s = nodeToString(obj);	printf("%s\n", s);	fflush(stdout);	return;}/* * pretty print hack extraordinaire.  -ay 10/94 */voidpprint(void *obj){	char	   *s;	int			i;	char		line[80];	int			indentLev;	int			j;	s = nodeToString(obj);	indentLev = 0;	i = 0;	for (;;)	{		for (j = 0; j < indentLev * 3; j++)			line[j] = ' ';		for (; j < 75 && s[i] != '\0'; i++, j++)		{			line[j] = s[i];			switch (line[j])			{				case '}':					if (j != indentLev * 3)					{						line[j] = '\0';						printf("%s\n", line);						line[indentLev * 3] = '\0';						printf("%s}\n", line);					}					else					{						line[j] = '\0';						printf("%s}\n", line);					}					indentLev--;					j = indentLev * 3 - 1;		/* print the line before :												 * and resets */					break;				case ')':					line[j + 1] = '\0';					printf("%s\n", line);					j = indentLev * 3 - 1;					break;				case '{':					indentLev++;					/* !!! FALLS THROUGH */				case ':':					if (j != 0)					{						line[j] = '\0';						printf("%s\n", line);						/* print the line before : and resets */						for (j = 0; j < indentLev * 3; j++)							line[j] = ' ';					}					line[j] = s[i];					break;			}		}		line[j] = '\0';		if (s[i] == '\0')			break;		printf("%s\n", line);	}	if (j != 0)		printf("%s\n", line);	fflush(stdout);	return;}/* * print_rt *	  print contents of range table */voidprint_rt(List *rtable){	List	   *l;	int			i = 1;	printf("resno\trelname(refname)\trelid\tinFromCl\n");	printf("-----\t----------------\t-----\t--------\n");	foreach(l, rtable)	{		RangeTblEntry *rte = lfirst(l);		printf("%d\t%s(%s)\t%u\t%d\t%s\n",			   i, rte->relname, rte->refname, rte->relid,			   rte->inFromCl,			   (rte->inh ? "inh" : ""));		i++;	}}/* * print_expr *	  print an expression */voidprint_expr(Node *expr, List *rtable){	if (expr == NULL)	{		printf("<>");		return;	}	if (IsA(expr, Var))	{		Var		   *var = (Var *) expr;		RangeTblEntry *rt;		char	   *relname,				   *attname;		switch (var->varno)		{			case INNER:				relname = "INNER";				attname = "?";				break;			case OUTER:				relname = "OUTER";				attname = "?";				break;			default:				{					rt = rt_fetch(var->varno, rtable);					relname = rt->relname;					if (rt->refname)						relname = rt->refname;	/* table renamed */					attname = get_attname(rt->relid, var->varattno);				}				break;		}		printf("%s.%s", relname, attname);	}	else if (IsA(expr, Expr))	{		Expr	   *e = (Expr *) expr;		if (is_opclause(expr))		{			char	   *opname;			print_expr((Node *) get_leftop(e), rtable);			opname = get_opname(((Oper *) e->oper)->opno);			printf(" %s ", ((opname != NULL) ? opname : "(invalid operator)"));			print_expr((Node *) get_rightop(e), rtable);		}		else			printf("an expr");	}	else		printf("not an expr");}/* * print_pathkeys - *	  pathkeys list of list of Var's */voidprint_pathkeys(List *pathkeys, List *rtable){	List	   *i,			   *k;	printf("(");	foreach(i, pathkeys)	{		List	   *pathkey = lfirst(i);		printf("(");		foreach(k, pathkey)		{			Node	   *var = lfirst(k);			print_expr(var, rtable);			if (lnext(k))				printf(", ");		}		printf(") ");		if (lnext(i))			printf(", ");	}	printf(")\n");}/* * print_tl *	  print targetlist in a more legible way. */voidprint_tl(List *tlist, List *rtable){	List	   *tl;	printf("(\n");	foreach(tl, tlist)	{		TargetEntry *tle = lfirst(tl);		printf("\t%d %s\t", tle->resdom->resno, tle->resdom->resname);		if (tle->resdom->reskey != 0)			printf("(%d):\t", tle->resdom->reskey);		else			printf("    :\t");		print_expr(tle->expr, rtable);		printf("\n");	}	printf(")\n");}/* * print_slot *	  print out the tuple with the given TupleTableSlot */voidprint_slot(TupleTableSlot *slot){	if (!slot->val)	{		printf("tuple is null.\n");		return;	}	if (!slot->ttc_tupleDescriptor)	{		printf("no tuple descriptor.\n");		return;	}	debugtup(slot->val, slot->ttc_tupleDescriptor, NULL);}static char *plannode_type(Plan *p){	switch (nodeTag(p))	{			case T_Plan:			return "PLAN";			break;		case T_Result:			return "RESULT";			break;		case T_Append:			return "APPEND";			break;		case T_Scan:			return "SCAN";			break;		case T_SeqScan:			return "SEQSCAN";			break;		case T_IndexScan:			return "INDEXSCAN";			break;		case T_Join:			return "JOIN";			break;		case T_NestLoop:			return "NESTLOOP";			break;		case T_MergeJoin:			return "MERGEJOIN";			break;		case T_HashJoin:			return "HASHJOIN";			break;		case T_Noname:			return "NONAME";			break;		case T_Material:			return "MATERIAL";			break;		case T_Sort:			return "SORT";			break;		case T_Agg:			return "AGG";			break;		case T_Unique:			return "UNIQUE";			break;		case T_Hash:			return "HASH";			break;		case T_Choose:			return "CHOOSE";			break;		case T_Group:			return "GROUP";			break;		default:			return "UNKNOWN";			break;	}}/*   prints the ascii description of the plan nodes   does this recursively by doing a depth-first traversal of the   plan tree.  for SeqScan and IndexScan, the name of the table is also   printed out*/voidprint_plan_recursive(Plan *p, Query *parsetree, int indentLevel, char *label){	int			i;	char		extraInfo[100];	if (!p)		return;	for (i = 0; i < indentLevel; i++)		printf(" ");	printf("%s%s :c=%.4f :s=%d :w=%d ", label, plannode_type(p),		   p->cost, p->plan_size, p->plan_width);	if (IsA(p, Scan) ||IsA(p, SeqScan))	{		RangeTblEntry *rte;		rte = rt_fetch(((Scan *) p)->scanrelid, parsetree->rtable);		StrNCpy(extraInfo, rte->relname, NAMEDATALEN);	}	else if (IsA(p, IndexScan))	{		StrNCpy(extraInfo,		   ((RangeTblEntry *) (nth(((IndexScan *) p)->scan.scanrelid - 1,								   parsetree->rtable)))->relname,				NAMEDATALEN);	}	else		extraInfo[0] = '\0';	if (extraInfo[0] != '\0')		printf(" ( %s )\n", extraInfo);	else		printf("\n");	print_plan_recursive(p->lefttree, parsetree, indentLevel + 3, "l: ");	print_plan_recursive(p->righttree, parsetree, indentLevel + 3, "r: ");	if (nodeTag(p) == T_Append)	{		List	   *lst;		int			whichplan = 0;		Append	   *appendplan = (Append *) p;		foreach(lst, appendplan->appendplans)		{			Plan	   *subnode = (Plan *) lfirst(lst);			/*			 * I don't think we need to fiddle with the range table here,			 * bjm			 */			print_plan_recursive(subnode, parsetree, indentLevel + 3, "a: ");			whichplan++;		}	}}/* print_plan  prints just the plan node types */voidprint_plan(Plan *p, Query *parsetree){	print_plan_recursive(p, parsetree, 0, "");}

⌨️ 快捷键说明

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