|
34 | 34 | #include"commands/tablespace.h"
|
35 | 35 | #include"mb/pg_wchar.h"
|
36 | 36 | #include"miscadmin.h"
|
37 |
| -#include"funcapi.h" |
38 | 37 | #include"nodes/nodeFuncs.h"
|
39 | 38 | #include"optimizer/clauses.h"
|
40 | 39 | #include"optimizer/planner.h"
|
|
53 | 52 | #include"utils/snapmgr.h"
|
54 | 53 | #include"utils/syscache.h"
|
55 | 54 | #include"utils/tqual.h"
|
56 |
| -#include"utils/ruleutils.h" |
57 |
| -#include"executor/executor.h" |
58 |
| -#include"executor/spi.h" |
59 | 55 |
|
60 | 56 |
|
61 | 57 | /* non-export function prototypes */
|
@@ -284,160 +280,6 @@ CheckIndexCompatible(Oid oldId,
|
284 | 280 | returnret;
|
285 | 281 | }
|
286 | 282 |
|
287 |
| -staticvoid |
288 |
| -UpdateIndex(OidindexRelationId,Node*whereClause) |
289 |
| -{ |
290 |
| -Datumvalues[Natts_pg_index]; |
291 |
| -boolisnull[Natts_pg_index]; |
292 |
| -HeapTupleoldTuple; |
293 |
| -HeapTuplenewTuple; |
294 |
| -Relationpg_index; |
295 |
| - |
296 |
| -pg_index=heap_open(IndexRelationId,RowExclusiveLock); |
297 |
| -oldTuple=SearchSysCacheCopy1(INDEXRELID,ObjectIdGetDatum(indexRelationId)); |
298 |
| -if (!HeapTupleIsValid(oldTuple)) |
299 |
| -elog(ERROR,"cache lookup failed for index %u",indexRelationId); |
300 |
| - |
301 |
| -heap_deform_tuple(oldTuple,RelationGetDescr(pg_index),values,isnull); |
302 |
| -values[Anum_pg_index_indpred-1]=CStringGetTextDatum(nodeToString(whereClause)); |
303 |
| -isnull[Anum_pg_index_indpred-1]= false; |
304 |
| -newTuple=heap_form_tuple(RelationGetDescr(pg_index),values,isnull); |
305 |
| -simple_heap_update(pg_index,&oldTuple->t_self,newTuple); |
306 |
| -CatalogUpdateIndexes(pg_index,newTuple); |
307 |
| -heap_freetuple(newTuple); |
308 |
| -heap_freetuple(oldTuple); |
309 |
| -heap_close(pg_index,NoLock); |
310 |
| -} |
311 |
| - |
312 |
| -void |
313 |
| -AlterIndex(OidindexRelationId,IndexStmt*stmt) |
314 |
| -{ |
315 |
| -char*select; |
316 |
| -OidheapRelationId; |
317 |
| -IndexUniqueCheckcheckUnique; |
318 |
| -Datumvalues[INDEX_MAX_KEYS]; |
319 |
| -boolisnull[INDEX_MAX_KEYS]; |
320 |
| -RelationheapRelation; |
321 |
| -RelationindexRelation; |
322 |
| -SPIPlanPtrplan; |
323 |
| -Portalportal; |
324 |
| -HeapTupletuple; |
325 |
| -TupleTableSlot*slot; |
326 |
| -ItemPointertupleid; |
327 |
| -IndexInfo*indexInfo; |
328 |
| -EState*estate; |
329 |
| -OidnamespaceId; |
330 |
| -List*deparseCtx; |
331 |
| -char*oldIndexPredicate; |
332 |
| -char*newIndexPredicate; |
333 |
| -char*relationName; |
334 |
| - |
335 |
| -Assert(stmt->whereClause); |
336 |
| -CheckPredicate((Expr*)stmt->whereClause); |
337 |
| - |
338 |
| -/* Open and lock the parent heap relation */ |
339 |
| -heapRelationId=IndexGetRelation(indexRelationId, false); |
340 |
| -heapRelation=heap_open(heapRelationId,AccessShareLock); |
341 |
| - |
342 |
| -/* Open the target index relation */ |
343 |
| -/*indexRelation = index_open(indexRelationId, RowExclusiveLock); */ |
344 |
| -indexRelation=index_open(indexRelationId,ShareUpdateExclusiveLock); |
345 |
| -/* indexRelation = index_open(indexRelationId, AccessShareLock); */ |
346 |
| -namespaceId=RelationGetNamespace(indexRelation); |
347 |
| - |
348 |
| -indexInfo=BuildIndexInfo(indexRelation); |
349 |
| -Assert(!indexInfo->ii_ExclusionOps); |
350 |
| - |
351 |
| -/* |
352 |
| - * Generate the constraint and default execution states |
353 |
| - */ |
354 |
| -estate=CreateExecutorState(); |
355 |
| - |
356 |
| -checkUnique=indexRelation->rd_index->indisunique ?UNIQUE_CHECK_YES :UNIQUE_CHECK_NO; |
357 |
| - |
358 |
| -slot=MakeSingleTupleTableSlot(RelationGetDescr(heapRelation)); |
359 |
| - |
360 |
| -deparseCtx=deparse_context_for(RelationGetRelationName(heapRelation),heapRelationId); |
361 |
| -relationName=quote_qualified_identifier(get_namespace_name(namespaceId), |
362 |
| -get_rel_name(heapRelationId)), |
363 |
| -newIndexPredicate=deparse_expression(stmt->whereClause,deparseCtx, false, false); |
364 |
| -oldIndexPredicate=indexInfo->ii_Predicate |
365 |
| -?deparse_expression((Node*)make_ands_explicit(indexInfo->ii_Predicate),deparseCtx, false, false) |
366 |
| -:"true"; |
367 |
| - |
368 |
| -SPI_connect(); |
369 |
| - |
370 |
| -select=psprintf("select * from %s where %s and not (%s) limit 1", |
371 |
| -relationName,oldIndexPredicate,newIndexPredicate); |
372 |
| -if (SPI_execute(select, true,1)!=SPI_OK_SELECT) |
373 |
| -{ |
374 |
| -ereport(ERROR, |
375 |
| -(errcode(ERRCODE_INVALID_CURSOR_STATE), |
376 |
| -errmsg("Failed to execute statement %s",select))); |
377 |
| -} |
378 |
| -if (SPI_processed) { |
379 |
| -/* There is no way in Postgres to exclude records from index, so we have to completelty rebuild index in this case */ |
380 |
| -boolrelpersistence=indexRelation->rd_rel->relpersistence; |
381 |
| -index_close(indexRelation,NoLock); |
382 |
| -indexRelation->rd_indpred=make_ands_implicit((Expr*)stmt->whereClause); |
383 |
| -indexRelation=NULL; |
384 |
| -UpdateIndex(indexRelationId,stmt->whereClause); |
385 |
| -reindex_index(indexRelationId, false,relpersistence,0); |
386 |
| -}else { |
387 |
| -select=psprintf("select * from %s where %s and not (%s)", |
388 |
| -relationName,newIndexPredicate,oldIndexPredicate); |
389 |
| -plan=SPI_prepare(select,0,NULL); |
390 |
| -if (plan==NULL) { |
391 |
| -ereport(ERROR, |
392 |
| -(errcode(ERRCODE_INVALID_CURSOR_STATE), |
393 |
| -errmsg("Failed to preapre statement %s",select))); |
394 |
| -} |
395 |
| -portal=SPI_cursor_open(NULL,plan,NULL,NULL, true); |
396 |
| -if (portal==NULL) { |
397 |
| -ereport(ERROR, |
398 |
| -(errcode(ERRCODE_INVALID_CURSOR_STATE), |
399 |
| -errmsg("Failed to open cursor for %s",select))); |
400 |
| -} |
401 |
| -while (true) |
402 |
| -{ |
403 |
| -SPI_cursor_fetch(portal, true,1); |
404 |
| -if (!SPI_processed) { |
405 |
| -break; |
406 |
| -} |
407 |
| -tuple=SPI_tuptable->vals[0]; |
408 |
| -tupleid=&tuple->t_data->t_ctid; |
409 |
| -ExecStoreTuple(tuple,slot,InvalidBuffer, false); |
410 |
| - |
411 |
| -FormIndexDatum(indexInfo, |
412 |
| -slot, |
413 |
| -estate, |
414 |
| -values, |
415 |
| -isnull); |
416 |
| -index_insert(indexRelation,/* index relation */ |
417 |
| -values,/* array of index Datums */ |
418 |
| -isnull,/* null flags */ |
419 |
| -tupleid,/* tid of heap tuple */ |
420 |
| -heapRelation,/* heap relation */ |
421 |
| -checkUnique);/* type of uniqueness check to do */ |
422 |
| - |
423 |
| -SPI_freetuple(tuple); |
424 |
| -SPI_freetuptable(SPI_tuptable); |
425 |
| -} |
426 |
| -SPI_cursor_close(portal); |
427 |
| - |
428 |
| -UpdateIndex(indexRelationId,stmt->whereClause); |
429 |
| -} |
430 |
| -SPI_finish(); |
431 |
| - |
432 |
| -ExecDropSingleTupleTableSlot(slot); |
433 |
| -FreeExecutorState(estate); |
434 |
| - |
435 |
| -heap_close(heapRelation,NoLock); |
436 |
| -if (indexRelation) { |
437 |
| -index_close(indexRelation,NoLock); |
438 |
| -} |
439 |
| -} |
440 |
| - |
441 | 283 | /*
|
442 | 284 | * DefineIndex
|
443 | 285 | *Creates a new index.
|
|