mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	I checked the alter table code, and started suspecting the relation
cache. I found if I manually added a line to flush the whole relation cache, the assert error disappeared. Looking through the code, I found that the relation cache is flushed at the end of each query if the reference count is zero for the relation. However, printf's showed that the rd_relcnt(reference count) for the accessed query was not returning to zero after each query. It turns out the parser was doing a heap_ropen in parser/analyze.c to get information about the table's columns, but was not doing a heap_close. This was causing the query after the ALTER TABLE ADD to see the old table structure, and the executor's assert was reporting the problem.
This commit is contained in:
		@@ -7,7 +7,7 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# IDENTIFICATION
 | 
					# IDENTIFICATION
 | 
				
			||||||
#    $Header: /cvsroot/pgsql/src/Attic/Makefile.global,v 1.37 1996/10/11 02:38:16 scrappy Exp $
 | 
					#    $Header: /cvsroot/pgsql/src/Attic/Makefile.global,v 1.38 1996/10/13 04:25:23 momjian Exp $
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# NOTES
 | 
					# NOTES
 | 
				
			||||||
#    This is seen by any Makefiles that include mk/postgres.mk. To
 | 
					#    This is seen by any Makefiles that include mk/postgres.mk. To
 | 
				
			||||||
@@ -214,7 +214,10 @@ X11_INCDIR = /usr/include
 | 
				
			|||||||
X11_LIBDIR = /usr/lib
 | 
					X11_LIBDIR = /usr/lib
 | 
				
			||||||
X11_LIB = -lX11 -lsocket -lnsl
 | 
					X11_LIB = -lX11 -lsocket -lnsl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#  These must match include/config.h 
 | 
				
			||||||
 | 
					NAMEDATALEN=	32
 | 
				
			||||||
 | 
					OIDNAMELEN=	36
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# include port specific rules and variables. For instance:
 | 
					# include port specific rules and variables. For instance:
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# signal(2) handling - this is here because it affects some of 
 | 
					# signal(2) handling - this is here because it affects some of 
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * IDENTIFICATION
 | 
					 * IDENTIFICATION
 | 
				
			||||||
 *    $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.5 1996/08/06 16:37:58 scrappy Exp $
 | 
					 *    $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.6 1996/10/13 04:25:42 momjian Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *-------------------------------------------------------------------------
 | 
					 *-------------------------------------------------------------------------
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -95,10 +95,11 @@ makeParseState() {
 | 
				
			|||||||
    pstate = malloc(sizeof(ParseState));
 | 
					    pstate = malloc(sizeof(ParseState));
 | 
				
			||||||
    pstate->p_last_resno = 1;
 | 
					    pstate->p_last_resno = 1;
 | 
				
			||||||
    pstate->p_target_resnos = NIL;
 | 
					    pstate->p_target_resnos = NIL;
 | 
				
			||||||
 | 
					    pstate->p_current_rel = NULL;
 | 
				
			||||||
    pstate->p_rtable = NIL;
 | 
					    pstate->p_rtable = NIL;
 | 
				
			||||||
    pstate->p_query_is_rule = 0;
 | 
					    pstate->p_query_is_rule = 0;
 | 
				
			||||||
    pstate->p_numAgg = 0;
 | 
					    pstate->p_numAgg = 0;
 | 
				
			||||||
    pstate->p_aggs = NULL;
 | 
					    pstate->p_aggs = NIL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (pstate);
 | 
					    return (pstate);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -126,6 +127,8 @@ parse_analyze(List *pl)
 | 
				
			|||||||
	pstate = makeParseState();
 | 
						pstate = makeParseState();
 | 
				
			||||||
	result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
 | 
						result->qtrees[i++] = transformStmt(pstate, lfirst(pl));
 | 
				
			||||||
	pl = lnext(pl);
 | 
						pl = lnext(pl);
 | 
				
			||||||
 | 
						if (pstate->p_current_rel != NULL)
 | 
				
			||||||
 | 
						    heap_close(pstate->p_current_rel);
 | 
				
			||||||
	free(pstate);
 | 
						free(pstate);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -828,8 +831,8 @@ makeRangeTable(ParseState *pstate, char *relname, List *frmList)
 | 
				
			|||||||
	pstate->p_rtable = lappend(pstate->p_rtable, ent);
 | 
						pstate->p_rtable = lappend(pstate->p_rtable, ent);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    x = RangeTablePosn(pstate->p_rtable, relname);
 | 
					    x = RangeTablePosn(pstate->p_rtable, relname);
 | 
				
			||||||
    pstate->parser_current_rel = heap_openr(VarnoGetRelname(pstate,x));
 | 
					    pstate->p_current_rel = heap_openr(VarnoGetRelname(pstate,x));
 | 
				
			||||||
    if (pstate->parser_current_rel == NULL)
 | 
					    if (pstate->p_current_rel == NULL)
 | 
				
			||||||
	elog(WARN,"invalid relation name");
 | 
						elog(WARN,"invalid relation name");
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1036,7 +1039,7 @@ makeTargetList(ParseState *pstate, List *cols, List *exprs)
 | 
				
			|||||||
		exprs = lnext(exprs);
 | 
							exprs = lnext(exprs);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
	    Relation insertRel = pstate->parser_current_rel;
 | 
						    Relation insertRel = pstate->p_current_rel;
 | 
				
			||||||
	    int numcol;
 | 
						    int numcol;
 | 
				
			||||||
	    int i;
 | 
						    int i;
 | 
				
			||||||
	    AttributeTupleForm *attr = insertRel->rd_att->attrs;
 | 
						    AttributeTupleForm *attr = insertRel->rd_att->attrs;
 | 
				
			||||||
@@ -1155,7 +1158,7 @@ transformTargetList(ParseState *pstate,
 | 
				
			|||||||
		    i++;
 | 
							    i++;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		sprintf(str, "=%s", val);
 | 
							sprintf(str, "=%s", val);
 | 
				
			||||||
		rd = pstate->parser_current_rel;
 | 
							rd = pstate->p_current_rel;
 | 
				
			||||||
		Assert(rd != NULL);
 | 
							Assert(rd != NULL);
 | 
				
			||||||
		resdomno = varattno(rd, res->name);
 | 
							resdomno = varattno(rd, res->name);
 | 
				
			||||||
		ndims = att_attnelems(rd, resdomno);
 | 
							ndims = att_attnelems(rd, resdomno);
 | 
				
			||||||
@@ -1334,7 +1337,7 @@ make_targetlist_expr(ParseState *pstate,
 | 
				
			|||||||
	   * append, replace work only on one relation,
 | 
						   * append, replace work only on one relation,
 | 
				
			||||||
	   * so multiple occurence of same resdomno is bogus
 | 
						   * so multiple occurence of same resdomno is bogus
 | 
				
			||||||
	   */
 | 
						   */
 | 
				
			||||||
	  rd = pstate->parser_current_rel;
 | 
						  rd = pstate->p_current_rel;
 | 
				
			||||||
	  Assert(rd != NULL);
 | 
						  Assert(rd != NULL);
 | 
				
			||||||
	  resdomno = varattno(rd,name);
 | 
						  resdomno = varattno(rd,name);
 | 
				
			||||||
	  attrisset = varisset(rd,name);
 | 
						  attrisset = varisset(rd,name);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 * Copyright (c) 1994, Regents of the University of California
 | 
					 * Copyright (c) 1994, Regents of the University of California
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * $Id: parse_state.h,v 1.1 1996/08/28 07:23:56 scrappy Exp $
 | 
					 * $Id: parse_state.h,v 1.2 1996/10/13 04:26:39 momjian Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *-------------------------------------------------------------------------
 | 
					 *-------------------------------------------------------------------------
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -16,7 +16,7 @@
 | 
				
			|||||||
typedef struct ParseState {
 | 
					typedef struct ParseState {
 | 
				
			||||||
    int 	p_last_resno; 
 | 
					    int 	p_last_resno; 
 | 
				
			||||||
    List 	*p_target_resnos;
 | 
					    List 	*p_target_resnos;
 | 
				
			||||||
    Relation 	parser_current_rel;
 | 
					    Relation 	p_parser_current_rel;
 | 
				
			||||||
    List 	*p_rtable;
 | 
					    List 	*p_rtable;
 | 
				
			||||||
    int 	p_query_is_rule;
 | 
					    int 	p_query_is_rule;
 | 
				
			||||||
    int		p_numAgg;
 | 
					    int		p_numAgg;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user