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

Commitf8f994f

Browse files
committed
Add ALTER INDEX WHERE construction
1 parent0bb319a commitf8f994f

File tree

12 files changed

+314
-83
lines changed

12 files changed

+314
-83
lines changed

‎src/backend/commands/indexcmds.c‎

Lines changed: 53 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include"commands/tablespace.h"
3333
#include"mb/pg_wchar.h"
3434
#include"miscadmin.h"
35+
#include"funcapi.h"
3536
#include"nodes/nodeFuncs.h"
3637
#include"optimizer/clauses.h"
3738
#include"optimizer/planner.h"
@@ -50,6 +51,9 @@
5051
#include"utils/snapmgr.h"
5152
#include"utils/syscache.h"
5253
#include"utils/tqual.h"
54+
#include"utils/ruleutils.h"
55+
#include"executor/executor.h"
56+
#include"executor/spi.h"
5357

5458

5559
/* non-export function prototypes */
@@ -275,33 +279,40 @@ CheckIndexCompatible(Oid oldId,
275279
returnret;
276280
}
277281

278-
#if0
279282
void
280-
AlterIndex(OidrelationId,IndexStmt*stmt,OidindexRelationId)
283+
AlterIndex(OidindexRelationId,IndexStmt*stmt)
281284
{
282285
char*select;
286+
OidheapRelationId;
283287
IndexUniqueCheckcheckUnique;
284-
boolsatisfiesConstraint;
285288
Datumvalues[INDEX_MAX_KEYS];
286289
boolisnull[INDEX_MAX_KEYS];
287290
RelationheapRelation;
288291
RelationindexRelation;
289292
SPIPlanPtrplan;
290293
Portalportal;
291294
HeapTupletuple;
292-
TupleDesctupdesc;
295+
HeapTupleupdatedTuple;
293296
TupleTableSlot*slot;
294297
ItemPointertupleid;
295298
IndexInfo*indexInfo;
296299
EState*estate;
300+
OidnamespaceId;
301+
Relationpg_index;
302+
List*deparseCtx;
297303

298304
Assert(stmt->whereClause);
305+
CheckPredicate((Expr*)stmt->whereClause);
306+
307+
/* Open the target index relation */
308+
indexRelation=index_open(indexRelationId,RowExclusiveLock);
309+
namespaceId=RelationGetNamespace(indexRelation);
299310

300311
/* Open and lock the parent heap relation */
301-
heapRelation=heap_openrv(stmt->relation,ShareUpdateExclusiveLock);
312+
heapRelationId=IndexGetRelation(indexRelationId, false);
313+
heapRelation=heap_open(heapRelationId,ShareLock);
302314

303-
/* And the target index relation */
304-
indexRelation=index_open(indexRelationId,RowExclusiveLock);
315+
pg_index=heap_open(IndexRelationId,RowExclusiveLock);
305316

306317
indexInfo=BuildIndexInfo(indexRelation);
307318
Assert(indexInfo->ii_Predicate);
@@ -314,58 +325,40 @@ AlterIndex(Oid relationId, IndexStmt *stmt, Oid indexRelationId)
314325

315326
checkUnique=indexRelation->rd_index->indisunique ?UNIQUE_CHECK_YES :UNIQUE_CHECK_NO;
316327

317-
SPI_connect();
318-
select=psprintf("select * from %s where %s and not (%s)",
319-
quote_qualified_identifier(get_namespace_name(RelationGetNamespace(heapRelation)),
320-
get_rel_name(relationId)),
321-
nodeToString(indexInfo->ii_Predicate),
322-
nodeToString(stmt->whereClause)
323-
);
324-
plan=SPI_parepare(select,0,NULL);
325-
if (plan==NULL) {
326-
ereport(ERROR,
327-
(errcode(ERRCODE_INVALID_CURSOR_STATE),
328-
errmsg("Failed to preapre statement ",select)));
329-
}
330-
portal=SPI_cursor_open(NULL,plan,NULL,NULL, true);
331-
if (portal==NULL) {
332-
ereport(ERROR,
333-
(errcode(ERRCODE_INVALID_CURSOR_STATE),
334-
errmsg("Failed to open cursor for ",select)));
335-
}
336-
while (true)
337-
{
338-
SPI_cursor_fetch(portal, true,1);
339-
if (!SPI_processed) {
340-
break;
341-
}
342-
tuple=SPI_tuptable->vals[0];
343-
tupdesc=SPI_tuptable->tupdesc;
344-
slot=TupleDescGetSlot(tupdesc);
345-
tupleid=&tuple->t_datat->t_ctid;
328+
/* Update pg_index tuple */
329+
tuple=SearchSysCacheCopy1(INDEXRELID,ObjectIdGetDatum(indexRelationId));
330+
if (!HeapTupleIsValid(tuple))
331+
elog(ERROR,"cache lookup failed for index %u",indexRelationId);
346332

347-
/* delete tuple from index */
348-
}
349-
SPI_cursor_close(portal);
333+
Assert(Natts_pg_index <=INDEX_MAX_KEYS);
334+
heap_deform_tuple(tuple,RelationGetDescr(pg_index),values,isnull);
335+
values[Anum_pg_index_indpred-1]=CStringGetTextDatum(nodeToString(stmt->whereClause));
336+
updatedTuple=heap_form_tuple(RelationGetDescr(pg_index),values,isnull);
337+
simple_heap_update(pg_index,&tuple->t_self,updatedTuple);
338+
CatalogUpdateIndexes(pg_index,updatedTuple);
339+
heap_freetuple(updatedTuple);
340+
heap_freetuple(tuple);
350341

342+
slot=MakeSingleTupleTableSlot(RelationGetDescr(heapRelation));
351343

344+
SPI_connect();
345+
deparseCtx=deparse_context_for(RelationGetRelationName(heapRelation),heapRelationId);
352346
select=psprintf("select * from %s where %s and not (%s)",
353-
quote_qualified_identifier(get_namespace_name(RelationGetNamespace(heapRelation)),
354-
get_rel_name(relationId)),
355-
nodeToString(stmt->whereClause),
356-
nodeToString(indexInfo->ii_Predicate)
357-
);
358-
plan=SPI_parepare(select,0,NULL);
347+
quote_qualified_identifier(get_namespace_name(namespaceId),
348+
get_rel_name(heapRelationId)),
349+
deparse_expression(stmt->whereClause,deparseCtx, false, false),
350+
deparse_expression((Node*)make_ands_explicit(indexInfo->ii_Predicate),deparseCtx, false, false));
351+
plan=SPI_prepare(select,0,NULL);
359352
if (plan==NULL) {
360353
ereport(ERROR,
361354
(errcode(ERRCODE_INVALID_CURSOR_STATE),
362-
errmsg("Failed to preapre statement ",select)));
355+
errmsg("Failed to preapre statement%s",select)));
363356
}
364357
portal=SPI_cursor_open(NULL,plan,NULL,NULL, true);
365358
if (portal==NULL) {
366359
ereport(ERROR,
367360
(errcode(ERRCODE_INVALID_CURSOR_STATE),
368-
errmsg("Failed to open cursor for ",select)));
361+
errmsg("Failed to open cursor for%s",select)));
369362
}
370363
while (true)
371364
{
@@ -374,40 +367,34 @@ AlterIndex(Oid relationId, IndexStmt *stmt, Oid indexRelationId)
374367
break;
375368
}
376369
tuple=SPI_tuptable->vals[0];
377-
tupdesc=SPI_tuptable->tupdesc;
378-
slot=TupleDescGetSlot(tupdesc);
379-
tupleid=&tuple->t_datat->t_ctid;
370+
tupleid=&tuple->t_data->t_ctid;
371+
ExecStoreTuple(tuple,slot,InvalidBuffer, false);
380372

381373
FormIndexDatum(indexInfo,
382374
slot,
383375
estate,
384376
values,
385377
isnull);
386-
satisfiesConstraint=
387-
index_insert(indexRelation,/* index relation */
388-
values,/* array of index Datums */
389-
isnull,/* null flags */
390-
tupleid,/* tid of heap tuple */
391-
heapRelation,/* heap relation */
392-
checkUnique);/* type of uniqueness check to do */
393-
394-
if (!satisfiesConstraint)
395-
{
396-
ereport(ERROR,
397-
(errcode(ERRCODE_INTEGRITY_CONSTRAINT_VIOLATION),
398-
errmsg("Index constraint violation")));
399-
}
378+
index_insert(indexRelation,/* index relation */
379+
values,/* array of index Datums */
380+
isnull,/* null flags */
381+
tupleid,/* tid of heap tuple */
382+
heapRelation,/* heap relation */
383+
checkUnique);/* type of uniqueness check to do */
384+
400385
SPI_freetuple(tuple);
401386
SPI_freetuptable(SPI_tuptable);
402387
}
403388
SPI_cursor_close(portal);
404389
SPI_finish();
405390

406-
/* Close both the relations, but keep the locks */
391+
ExecDropSingleTupleTableSlot(slot);
392+
FreeExecutorState(estate);
393+
394+
heap_close(pg_index,NoLock);
407395
heap_close(heapRelation,NoLock);
408396
index_close(indexRelation,NoLock);
409397
}
410-
#endif
411398

412399
/*
413400
* DefineIndex

‎src/backend/nodes/copyfuncs.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3123,6 +3123,7 @@ _copyIndexStmt(const IndexStmt *from)
31233123
COPY_SCALAR_FIELD(transformed);
31243124
COPY_SCALAR_FIELD(concurrent);
31253125
COPY_SCALAR_FIELD(if_not_exists);
3126+
COPY_SCALAR_FIELD(is_alter);
31263127

31273128
returnnewnode;
31283129
}

‎src/backend/nodes/equalfuncs.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,6 +1243,7 @@ _equalIndexStmt(const IndexStmt *a, const IndexStmt *b)
12431243
COMPARE_SCALAR_FIELD(transformed);
12441244
COMPARE_SCALAR_FIELD(concurrent);
12451245
COMPARE_SCALAR_FIELD(if_not_exists);
1246+
COMPARE_SCALAR_FIELD(is_alter);
12461247

12471248
return true;
12481249
}

‎src/backend/nodes/outfuncs.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2184,6 +2184,7 @@ _outIndexStmt(StringInfo str, const IndexStmt *node)
21842184
WRITE_BOOL_FIELD(transformed);
21852185
WRITE_BOOL_FIELD(concurrent);
21862186
WRITE_BOOL_FIELD(if_not_exists);
2187+
WRITE_BOOL_FIELD(is_alter);
21872188
}
21882189

21892190
staticvoid

‎src/backend/parser/gram.y‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,6 +1801,15 @@ AlterTableStmt:
18011801
n->nowait =$13;
18021802
$$ = (Node *)n;
18031803
}
1804+
|ALTERINDEXqualified_nameWHEREa_expr
1805+
{
1806+
IndexStmt* n = makeNode(IndexStmt);
1807+
n->relation =$3;
1808+
n->whereClause =$5;
1809+
n->is_alter =true;
1810+
$$ = (Node *)n;
1811+
}
1812+
18041813
|ALTERINDEXqualified_namealter_table_cmds
18051814
{
18061815
AlterTableStmt *n = makeNode(AlterTableStmt);

‎src/backend/parser/parse_utilcmd.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2016,6 +2016,10 @@ transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString)
20162016
* to its fields without qualification. Caller is responsible for locking
20172017
* relation, but we still need to open it.
20182018
*/
2019+
if (stmt->is_alter)
2020+
{
2021+
relid=IndexGetRelation(relid, false);
2022+
}
20192023
rel=relation_open(relid,NoLock);
20202024
rte=addRangeTableEntryForRelation(pstate,rel,NULL, false, true);
20212025

‎src/backend/tcop/utility.c‎

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,22 +1257,29 @@ ProcessUtilitySlow(Node *parsetree,
12571257

12581258
/* ... and do it */
12591259
EventTriggerAlterTableStart(parsetree);
1260-
address=
1261-
DefineIndex(relid,/* OID of heap relation */
1262-
stmt,
1263-
InvalidOid,/* no predefined OID */
1264-
false,/* is_alter_table */
1265-
true,/* check_rights */
1266-
false,/* skip_build */
1267-
false);/* quiet */
1268-
1269-
/*
1270-
* Add the CREATE INDEX node itself to stash right away;
1271-
* if there were any commands stashed in the ALTER TABLE
1272-
* code, we need them to appear after this one.
1273-
*/
1274-
EventTriggerCollectSimpleCommand(address,secondaryObject,
1275-
parsetree);
1260+
if (stmt->is_alter)
1261+
{
1262+
AlterIndex(relid,stmt);
1263+
}
1264+
else
1265+
{
1266+
address=
1267+
DefineIndex(relid,/* OID of heap relation */
1268+
stmt,
1269+
InvalidOid,/* no predefined OID */
1270+
false,/* is_alter_table */
1271+
true,/* check_rights */
1272+
false,/* skip_build */
1273+
false);/* quiet */
1274+
1275+
/*
1276+
* Add the CREATE INDEX node itself to stash right away;
1277+
* if there were any commands stashed in the ALTER TABLE
1278+
* code, we need them to appear after this one.
1279+
*/
1280+
EventTriggerCollectSimpleCommand(address,secondaryObject,
1281+
parsetree);
1282+
}
12761283
commandCollected= true;
12771284
EventTriggerAlterTableEnd();
12781285
}

‎src/bin/insbench/core‎

9.32 MB
Binary file not shown.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp