Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite84bf65

Browse files
committed
Ensure an index that uses a whole-row Var still depends on its table.
We failed to record any dependency on the underlying table for an indexdeclared like "create index i on t (foo(t.*))". This would create troubleif the table were dropped without previously dropping the index. To fix,simplify some overly-cute code in index_create(), accepting the possibilitythat sometimes the whole-table dependency will be redundant. Also documentthis hazard in dependency.c. Per report from Kevin Grittner.In passing, prevent a core dump in pg_get_indexdef() if the index's tablecan't be found. I came across this while experimenting with Kevin'sexample. Not sure it's a real issue when the catalogs aren't corrupt, butmight as well be cautious.Back-patch to all supported versions.
1 parent77459eb commite84bf65

File tree

3 files changed

+40
-14
lines changed

3 files changed

+40
-14
lines changed

‎src/backend/catalog/dependency.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1235,6 +1235,12 @@ recordDependencyOnExpr(const ObjectAddress *depender,
12351235
* range table. An additional frammish is that dependencies on that
12361236
* relation (or its component columns) will be marked with 'self_behavior',
12371237
* whereas 'behavior' is used for everything else.
1238+
*
1239+
* NOTE: the caller should ensure that a whole-table dependency on the
1240+
* specified relation is created separately, if one is needed. In particular,
1241+
* a whole-row Var "relation.*" will not cause this routine to emit any
1242+
* dependency item. This is appropriate behavior for subexpressions of an
1243+
* ordinary query, so other cases need to cope as necessary.
12381244
*/
12391245
void
12401246
recordDependencyOnSingleRelExpr(constObjectAddress*depender,
@@ -1347,7 +1353,14 @@ find_expr_references_walker(Node *node,
13471353

13481354
/*
13491355
* A whole-row Var references no specific columns, so adds no new
1350-
* dependency.
1356+
* dependency. (We assume that there is a whole-table dependency
1357+
* arising from each underlying rangetable entry. While we could
1358+
* record such a dependency when finding a whole-row Var that
1359+
* references a relation directly, it's quite unclear how to extend
1360+
* that to whole-row Vars for JOINs, so it seems better to leave the
1361+
* responsibility with the range table. Note that this poses some
1362+
* risks for identifying dependencies of stand-alone expressions:
1363+
* whole-table references may need to be created separately.)
13511364
*/
13521365
if (var->varattno==InvalidAttrNumber)
13531366
return false;

‎src/backend/catalog/index.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
#include"nodes/makefuncs.h"
5151
#include"nodes/nodeFuncs.h"
5252
#include"optimizer/clauses.h"
53-
#include"optimizer/var.h"
5453
#include"parser/parser.h"
5554
#include"storage/bufmgr.h"
5655
#include"storage/lmgr.h"
@@ -853,16 +852,12 @@ index_create(Oid heapRelationId,
853852
}
854853

855854
/*
856-
* It's possible for an index to not depend on any columns of the
857-
* table at all, in which case we need to give it a dependency on
858-
* the table as a whole; else it won't get dropped when the table
859-
* is dropped.This edge case is not totally useless; for
860-
* example, a unique index on a constant expression can serve to
861-
* prevent a table from containing more than one row.
855+
* If there are no simply-referenced columns, give the index an
856+
* auto dependency on the whole table. In most cases, this will
857+
* be redundant, but it might not be if the index expressions and
858+
* predicate contain no Vars or only whole-row Vars.
862859
*/
863-
if (!have_simple_col&&
864-
!contain_vars_of_level((Node*)indexInfo->ii_Expressions,0)&&
865-
!contain_vars_of_level((Node*)indexInfo->ii_Predicate,0))
860+
if (!have_simple_col)
866861
{
867862
referenced.classId=RelationRelationId;
868863
referenced.objectId=heapRelationId;

‎src/backend/utils/adt/ruleutils.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ static void get_opclass_name(Oid opclass, Oid actual_datatype,
219219
staticNode*processIndirection(Node*node,deparse_context*context,
220220
boolprintit);
221221
staticvoidprintSubscripts(ArrayRef*aref,deparse_context*context);
222+
staticchar*get_relation_name(Oidrelid);
222223
staticchar*generate_relation_name(Oidrelid,List*namespaces);
223224
staticchar*generate_function_name(Oidfuncid,intnargs,List*argnames,
224225
Oid*argtypes,bool*is_variadic);
@@ -832,7 +833,7 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
832833

833834
indexpr_item=list_head(indexprs);
834835

835-
context=deparse_context_for(get_rel_name(indrelid),indrelid);
836+
context=deparse_context_for(get_relation_name(indrelid),indrelid);
836837

837838
/*
838839
* Start the index definition.Note that the index's name should never be
@@ -1236,7 +1237,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
12361237
if (conForm->conrelid!=InvalidOid)
12371238
{
12381239
/* relation constraint */
1239-
context=deparse_context_for(get_rel_name(conForm->conrelid),
1240+
context=deparse_context_for(get_relation_name(conForm->conrelid),
12401241
conForm->conrelid);
12411242
}
12421243
else
@@ -6074,7 +6075,7 @@ get_from_clause_item(Node *jtnode, Query *query, deparse_context *context)
60746075
gavealias= true;
60756076
}
60766077
elseif (rte->rtekind==RTE_RELATION&&
6077-
strcmp(rte->eref->aliasname,get_rel_name(rte->relid))!=0)
6078+
strcmp(rte->eref->aliasname,get_relation_name(rte->relid))!=0)
60786079
{
60796080
/*
60806081
* Apparently the rel has been renamed since the rule was made.
@@ -6574,6 +6575,23 @@ quote_qualified_identifier(const char *qualifier,
65746575
returnbuf.data;
65756576
}
65766577

6578+
/*
6579+
* get_relation_name
6580+
*Get the unqualified name of a relation specified by OID
6581+
*
6582+
* This differs from the underlying get_rel_name() function in that it will
6583+
* throw error instead of silently returning NULL if the OID is bad.
6584+
*/
6585+
staticchar*
6586+
get_relation_name(Oidrelid)
6587+
{
6588+
char*relname=get_rel_name(relid);
6589+
6590+
if (!relname)
6591+
elog(ERROR,"cache lookup failed for relation %u",relid);
6592+
returnrelname;
6593+
}
6594+
65776595
/*
65786596
* generate_relation_name
65796597
*Compute the name to display for a relation specified by OID

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp